Merge gamelistopt sources into gamelist source files
[xboard.git] / xboard.c
index 88bc31d..cc04327 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -49,6 +49,8 @@
  *------------------------------------------------------------------------
  ** See the file ChangeLog for a revision history.  */
 
+#define HIGHDRAG 1
+
 #include "config.h"
 
 #include <stdio.h>
@@ -256,6 +258,8 @@ void HandleUserMove P((Widget w, XEvent *event,
                     String *prms, Cardinal *nprms));
 void AnimateUserMove P((Widget w, XEvent * event,
                     String * params, Cardinal * nParams));
+void HandlePV P((Widget w, XEvent * event,
+                    String * params, Cardinal * nParams));
 void WhiteClock P((Widget w, XEvent *event,
                   String *prms, Cardinal *nprms));
 void BlackClock P((Widget w, XEvent *event,
@@ -440,6 +444,8 @@ void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms))
 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void GameListOptionsPopDown P(());
 void ShufflePopDown P(());
 void EnginePopDown P(());
 void UciPopDown P(());
@@ -660,6 +666,7 @@ MenuItem optionsMenu[] = {
     {N_("Engine #1 Settings ..."), FirstSettingsProc},
     {N_("Engine #2 Settings ..."), SecondSettingsProc},
     {N_("Time Control ..."), TimeControlProc},
+    {N_("Game List ..."), GameListOptionsPopUp},
     {"----", NothingProc},
     {N_("Always Queen"), AlwaysQueenProc},
     {N_("Animate Dragging"), AnimateDraggingProc},
@@ -832,6 +839,8 @@ XtActionsRec boardActions[] = {
     { "DrawPosition", DrawPositionProc },
     { "HandleUserMove", HandleUserMove },
     { "AnimateUserMove", AnimateUserMove },
+    { "HandlePV", HandlePV },
+    { "UnLoadPV", UnLoadPV },
     { "FileNameAction", FileNameAction },
     { "AskQuestionProc", AskQuestionProc },
     { "AskQuestionReplyAction", AskQuestionReplyAction },
@@ -844,6 +853,7 @@ XtActionsRec boardActions[] = {
     { "LoadNextGameProc", LoadNextGameProc },
     { "LoadPrevGameProc", LoadPrevGameProc },
     { "LoadSelectedProc", LoadSelectedProc },
+    { "SetFilterProc", SetFilterProc },
     { "ReloadGameProc", ReloadGameProc },
     { "LoadPositionProc", LoadPositionProc },
     { "LoadNextPositionProc", LoadNextPositionProc },
@@ -945,6 +955,7 @@ XtActionsRec boardActions[] = {
     { "FileNamePopDown", (XtActionProc) FileNamePopDown },
     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
     { "GameListPopDown", (XtActionProc) GameListPopDown },
+    { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown },
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
     { "HistoryPopDown", (XtActionProc) HistoryPopDown },
     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
@@ -988,6 +999,8 @@ char boardTranslations[] =
    "<Btn1Down>: HandleUserMove() \n \
    <Btn1Up>: HandleUserMove() \n \
    <Btn1Motion>: AnimateUserMove() \n \
+   <Btn3Motion>: HandlePV() \n \
+   <Btn3Up>: UnLoadPV() \n \
    Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
                  PieceMenuPopup(menuB) \n \
    Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
@@ -1258,7 +1271,6 @@ BoardToTop()
 #define SEPCHAR " "
 
 // these two must some day move to frontend.h, when they are implemented
-Boolean MoveHistoryIsUp();
 Boolean GameListIsUp();
 
 // The option definition and parsing code common to XBoard and WinBoard is collected in this file
@@ -1277,7 +1289,7 @@ colorVariable[] = {
   &appData.darkSquareColor, 
   &appData.highlightSquareColor,
   &appData.premoveHighlightColor,
-  NULL,
+  &appData.lowTimeWarningColor,
   NULL,
   NULL,
   NULL,
@@ -1288,9 +1300,25 @@ colorVariable[] = {
   NULL
 };
 
+// [HGM] font: keep a font for each square size, even non-stndard ones
+#define NUM_SIZES 18
+#define MAX_SIZE 130
+Boolean fontSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE];
+char *fontTable[NUM_FONTS][MAX_SIZE];
+
 void
 ParseFont(char *name, int number)
 { // in XBoard, only 2 of the fonts are currently implemented, and we just copy their name
+  int size;
+  if(sscanf(name, "size%d:", &size)) {
+    // [HGM] font: font is meant for specific boardSize (likely from settings file);
+    //       defer processing it until we know if it matches our board size
+    if(size >= 0 && size<MAX_SIZE) { // for now, fixed limit
+       fontTable[number][size] = strdup(strchr(name, ':')+1);
+       fontValid[number][size] = True;
+    }
+    return;
+  }
   switch(number) {
     case 0: // CLOCK_FONT
        appData.clockFont = strdup(name);
@@ -1304,6 +1332,7 @@ ParseFont(char *name, int number)
     default:
       return;
   }
+  fontSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file)
 }
 
 void
@@ -1351,8 +1380,9 @@ SetCommPortDefaults()
 void
 SaveFontArg(FILE *f, ArgDescriptor *ad)
 {
-  char *name;
-  switch((int)ad->argLoc) {
+  char *name, buf[MSG_SIZ];
+  int i, n = (int)ad->argLoc;
+  switch(n) {
     case 0: // CLOCK_FONT
        name = appData.clockFont;
       break;
@@ -1365,9 +1395,14 @@ SaveFontArg(FILE *f, ArgDescriptor *ad)
     default:
       return;
   }
-//  Do not save fonts for now, as the saved font would be board-size specific
-//  and not suitable for a re-start at another board size
-//  fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, name); 
+  for(i=0; i<NUM_SIZES; i++) // [HGM] font: current font becomes standard for current size
+    if(sizeDefaults[i].squareSize == squareSize) { // only for standard sizes!
+       fontTable[n][squareSize] = strdup(name);
+       fontValid[n][squareSize] = True;
+       break;
+  }
+  for(i=0; i<MAX_SIZE; i++) if(fontValid[n][i]) // [HGM] font: store all standard fonts
+    fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]); 
 }
 
 void
@@ -1808,7 +1843,14 @@ main(argc, argv)
        fontPxlSize = szd->fontPxlSize;
        smallLayout = szd->smallLayout;
        tinyLayout = szd->tinyLayout;
+       // [HGM] font: use defaults from settings file if available and not overruled
     }
+    if(!fontSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
+       appData.clockFont = fontTable[CLOCK_FONT][squareSize];
+    if(!fontSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
+       appData.font = fontTable[MESSAGE_FONT][squareSize];
+    if(!fontSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
+       appData.coordFont = fontTable[COORD_FONT][squareSize];
 
     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
     if (strlen(appData.pixmapDirectory) > 0) {
@@ -3673,6 +3715,8 @@ void PieceMenuPopup(w, event, params, num_params)
      Cardinal *num_params;
 {
     String whichMenu;
+
+    if (event->type == ButtonRelease) UnLoadPV(); // [HGM] pv
     if (event->type != ButtonPress) return;
     if (errorUp) ErrorPopDown();
     switch (gameMode) {
@@ -3680,12 +3724,25 @@ void PieceMenuPopup(w, event, params, num_params)
       case IcsExamining:
        whichMenu = params[0];
        break;
+      case IcsObserving:
+       if(!appData.icsEngineAnalyze) return;
       case IcsPlayingWhite:
       case IcsPlayingBlack:
-      case EditGame:
+       if(!appData.zippyPlay) goto noZip;
+      case AnalyzeMode:
+      case AnalyzeFile:
       case MachinePlaysWhite:
       case MachinePlaysBlack:
-       if (appData.testLegality &&
+      case TwoMachinesPlay: // [HGM] pv: use for showing PV
+       if (!appData.dropMenu) {
+         LoadPV(event->xbutton.x, event->xbutton.y);
+         return;
+       }
+       if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode ||
+           gameMode == AnalyzeFile || gameMode == IcsObserving) return;
+      case EditGame:
+      noZip:
+       if (!appData.dropMenu || appData.testLegality &&
            gameInfo.variant != VariantBughouse &&
            gameInfo.variant != VariantCrazyhouse) return;
        SetupDropMenu();
@@ -4177,6 +4234,10 @@ void DrawSquare(row, column, piece, do_flash)
                        x + 2, y + font_ascent + 1, string, 1);
        }
     }
+    if(marker[row][column]) {
+       XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, 
+               x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360);
+    }
 }
 
 
@@ -4430,6 +4491,12 @@ void AnimateUserMove (Widget w, XEvent * event,
     DragPieceMove(event->xmotion.x, event->xmotion.y);
 }
 
+void HandlePV (Widget w, XEvent * event,
+                     String * params, Cardinal * nParams)
+{   // [HGM] pv: walk PV
+    MovePV(event->xmotion.x, event->xmotion.y, lineGap + BOARD_HEIGHT * (squareSize + lineGap));
+}
+
 Widget CommentCreate(name, text, mutable, callback, lines)
      char *name, *text;
      int /*Boolean*/ mutable;
@@ -8606,7 +8673,7 @@ DragPieceMove(x, y)
     corner.x = x - player.mouseDelta.x;
     corner.y = y - player.mouseDelta.y;
     AnimationFrame(&player, &corner, player.dragPiece);
-#if HIGHDRAG
+#if HIGHDRAG*0
     if (appData.highlightDragging) {
        int boardX, boardY;
        BoardSquare(x, y, &boardX, &boardY);