Improve arrow drawing
[xboard.git] / xboard.c
index 293f781..0726ade 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -293,7 +293,6 @@ GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
 Widget shellWidget, formWidget, boardWidget, titleWidget, dropMenu, menuBarWidget;
 Option *optList; // contains all widgets of main window
-XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2];
 XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 #if ENABLE_NLS
 XFontSet fontSet, clockFontSet;
@@ -889,6 +888,16 @@ MainWindowUp ()
   return xBoardWindow != 0;
 }
 
+void SwitchWindow()
+{
+    extern Option dualOptions[];
+    static Window dual;
+    Window tmp = xBoardWindow;
+    if(!dual) dual = XtWindow(dualOptions[3].handle); // must be first call
+    xBoardWindow = dual; // swap them
+    dual = tmp;
+}
+
 void
 PopUpStartupDialog ()
 {  // start menu not implemented in XBoard
@@ -927,7 +936,7 @@ InitDrawingSizes (BoardSize boardSize, int flags)
     int i;
     static Dimension oldWidth, oldHeight;
     static VariantClass oldVariant;
-    static int oldDual = -1, oldMono = -1;
+    static int oldMono = -1;
 
     if(!formWidget) return;
 
@@ -935,21 +944,15 @@ InitDrawingSizes (BoardSize boardSize, int flags)
     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 
-  if(boardWidth != oldWidth || boardHeight != oldHeight || oldDual != twoBoards) { // do resizing stuff only if size actually changed
+  if(boardWidth != oldWidth || boardHeight != oldHeight) { // do resizing stuff only if size actually changed
 
-    oldWidth = boardWidth; oldHeight = boardHeight; oldDual = twoBoards;
+    oldWidth = boardWidth; oldHeight = boardHeight;
     CreateGrid();
-    hOffset = boardWidth + 10;
-    for(i=0; i<BOARD_WIDTH+BOARD_HEIGHT+2; i++) { // [HGM] dual: grid for second board
-       secondSegments[i] = gridSegments[i];
-       secondSegments[i].x1 += hOffset;
-       secondSegments[i].x2 += hOffset;
-    }
 
     /*
      * Inhibit shell resizing.
      */
-    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW + twoBoards*hOffset; // [HGM] dual
+    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW ;
     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
     shellArgs[4].value = shellArgs[2].value = w;
     shellArgs[5].value = shellArgs[3].value = h;
@@ -1069,6 +1072,8 @@ MakeColors ()
     forceMono |= MakeOneColor(appData.blackPieceColor, &blackPieceColor);
     forceMono |= MakeOneColor(appData.highlightSquareColor, &highlightSquareColor);
     forceMono |= MakeOneColor(appData.premoveHighlightColor, &premoveHighlightColor);
+    if (appData.lowTimeWarning)
+       forceMono |= MakeOneColor(appData.lowTimeWarningColor, &lowTimeWarningColor);
     if(appData.dialogColor[0]) MakeOneColor(appData.dialogColor, &dialogColor);
     if(appData.buttonColor[0]) MakeOneColor(appData.buttonColor, &buttonColor);
 
@@ -1104,6 +1109,61 @@ InitDrawingParams ()
     CreateAnyPieces();
 }
 
+void
+InitializeFonts (int clockFontPxlSize, int coordFontPxlSize, int fontPxlSize)
+{   // determine what fonts to use, and create them
+    XrmValue vFrom, vTo;
+    XrmDatabase xdb;
+
+    if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
+       appData.clockFont = fontTable[CLOCK_FONT][squareSize];
+    if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
+       appData.font = fontTable[MESSAGE_FONT][squareSize];
+    if(!fontIsSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
+       appData.coordFont = fontTable[COORD_FONT][squareSize];
+
+#if ENABLE_NLS
+    appData.font = InsertPxlSize(appData.font, fontPxlSize);
+    appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize);
+    fontSet = CreateFontSet(appData.font);
+    clockFontSet = CreateFontSet(appData.clockFont);
+    {
+      /* For the coordFont, use the 0th font of the fontset. */
+      XFontSet coordFontSet = CreateFontSet(appData.coordFont);
+      XFontStruct **font_struct_list;
+      XFontSetExtents *fontSize;
+      char **font_name_list;
+      XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list);
+      coordFontID = XLoadFont(xDisplay, font_name_list[0]);
+      coordFontStruct = XQueryFont(xDisplay, coordFontID);
+      fontSize = XExtentsOfFontSet(fontSet); // [HGM] figure out how much vertical space font takes
+      textHeight = fontSize->max_logical_extent.height + 5; // add borderWidth
+    }
+#else
+    appData.font = FindFont(appData.font, fontPxlSize);
+    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
+    clockFontID = XLoadFont(xDisplay, appData.clockFont);
+    clockFontStruct = XQueryFont(xDisplay, clockFontID);
+    coordFontID = XLoadFont(xDisplay, appData.coordFont);
+    coordFontStruct = XQueryFont(xDisplay, coordFontID);
+    // textHeight in !NLS mode!
+#endif
+    countFontID = coordFontID;  // [HGM] holdings
+    countFontStruct = coordFontStruct;
+
+    xdb = XtDatabase(xDisplay);
+#if ENABLE_NLS
+    XrmPutLineResource(&xdb, "*international: True");
+    vTo.size = sizeof(XFontSet);
+    vTo.addr = (XtPointer) &fontSet;
+    XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo);
+#else
+    XrmPutStringResource(&xdb, "*font", appData.font);
+#endif
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1111,10 +1171,8 @@ main (int argc, char **argv)
     XSetWindowAttributes window_attributes;
     Arg args[16];
     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
-    XrmValue vFrom, vTo;
     XtGeometryResult gres;
     char *p;
-    XrmDatabase xdb;
     int forceMono = False;
 
     srandom(time(0)); // [HGM] book: make random truly random
@@ -1136,14 +1194,14 @@ main (int argc, char **argv)
 
 #ifdef ENABLE_NLS
     XtSetLanguageProc(NULL, NULL, NULL);
+    if (appData.debugMode) {
+      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
+    }
+
     bindtextdomain(PACKAGE, LOCALEDIR);
     textdomain(PACKAGE);
 #endif
 
-    shellWidget =
-      XtAppInitialize(&appContext, "XBoard", shellOptions,
-                     XtNumber(shellOptions),
-                     &argc, argv, xboardResources, NULL, 0);
     appData.boardSize = "";
     InitAppData(ConvertToLine(argc, argv));
     p = getenv("HOME");
@@ -1154,10 +1212,6 @@ main (int argc, char **argv)
     snprintf(gameCopyFilename,i, "%s/.xboard%05uc.pgn", p, getpid());
     snprintf(gamePasteFilename,i, "%s/.xboard%05up.pgn", p, getpid());
 
-    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
-                             clientResources, XtNumber(clientResources),
-                             NULL, 0);
-
     { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
        static char buf[MSG_SIZ];
        EscapeExpand(buf, appData.firstInitString);
@@ -1189,12 +1243,6 @@ main (int argc, char **argv)
         setbuf(debugFP, NULL);
     }
 
-#if ENABLE_NLS
-    if (appData.debugMode) {
-      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
-    }
-#endif
-
     /* [HGM,HR] make sure board size is acceptable */
     if(appData.NrFiles > BOARD_FILES ||
        appData.NrRanks > BOARD_RANKS   )
@@ -1206,13 +1254,25 @@ main (int argc, char **argv)
 #endif
     InitBackEnd1();
 
+       gameInfo.variant = StringToVariant(appData.variant);
+       InitPosition(FALSE);
+
+    shellWidget =
+      XtAppInitialize(&appContext, "XBoard", shellOptions,
+                     XtNumber(shellOptions),
+                     &argc, argv, xboardResources, NULL, 0);
+
+    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
+                             clientResources, XtNumber(clientResources),
+                             NULL, 0);
+
     xDisplay = XtDisplay(shellWidget);
     xScreen = DefaultScreen(xDisplay);
     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
 
-       gameInfo.variant = StringToVariant(appData.variant);
-       InitPosition(FALSE);
-
+    /*
+     * determine size, based on supplied or remembered -size, or screen size
+     */
     if (isdigit(appData.boardSize[0])) {
         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
                   &lineGap, &clockFontPxlSize, &coordFontPxlSize,
@@ -1269,12 +1329,6 @@ main (int argc, char **argv)
        tinyLayout = szd->tinyLayout;
        // [HGM] font: use defaults from settings file if available and not overruled
     }
-    if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
-       appData.clockFont = fontTable[CLOCK_FONT][squareSize];
-    if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
-       appData.font = fontTable[MESSAGE_FONT][squareSize];
-    if(!fontIsSet[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) {
@@ -1304,46 +1358,7 @@ XBoard square size (hint): %d\n\
     /*
      * Determine what fonts to use.
      */
-#if ENABLE_NLS
-    appData.font = InsertPxlSize(appData.font, fontPxlSize);
-    appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize);
-    appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize);
-    fontSet = CreateFontSet(appData.font);
-    clockFontSet = CreateFontSet(appData.clockFont);
-    {
-      /* For the coordFont, use the 0th font of the fontset. */
-      XFontSet coordFontSet = CreateFontSet(appData.coordFont);
-      XFontStruct **font_struct_list;
-      XFontSetExtents *fontSize;
-      char **font_name_list;
-      XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list);
-      coordFontID = XLoadFont(xDisplay, font_name_list[0]);
-      coordFontStruct = XQueryFont(xDisplay, coordFontID);
-      fontSize = XExtentsOfFontSet(fontSet); // [HGM] figure out how much vertical space font takes
-      textHeight = fontSize->max_logical_extent.height + 5; // add borderWidth
-    }
-#else
-    appData.font = FindFont(appData.font, fontPxlSize);
-    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
-    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
-    clockFontID = XLoadFont(xDisplay, appData.clockFont);
-    clockFontStruct = XQueryFont(xDisplay, clockFontID);
-    coordFontID = XLoadFont(xDisplay, appData.coordFont);
-    coordFontStruct = XQueryFont(xDisplay, coordFontID);
-    // textHeight in !NLS mode!
-#endif
-    countFontID = coordFontID;  // [HGM] holdings
-    countFontStruct = coordFontStruct;
-
-    xdb = XtDatabase(xDisplay);
-#if ENABLE_NLS
-    XrmPutLineResource(&xdb, "*international: True");
-    vTo.size = sizeof(XFontSet);
-    vTo.addr = (XtPointer) &fontSet;
-    XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo);
-#else
-    XrmPutStringResource(&xdb, "*font", appData.font);
-#endif
+    InitializeFonts(clockFontPxlSize, coordFontPxlSize, fontPxlSize);
 
     /*
      * Detect if there are not enough colors available and adapt.
@@ -1360,16 +1375,6 @@ XBoard square size (hint): %d\n\
        appData.monoMode = True;
     }
 
-    if (appData.lowTimeWarning && !appData.monoMode) {
-      vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
-      vFrom.size = strlen(appData.lowTimeWarningColor);
-      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-      if (vTo.addr == NULL)
-               appData.monoMode = True;
-      else
-               lowTimeWarningColor = *(Pixel *) vTo.addr;
-    }
-
     if (appData.monoMode && appData.debugMode) {
        fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
                (unsigned long) XWhitePixel(xDisplay, xScreen),
@@ -1397,18 +1402,18 @@ XBoard square size (hint): %d\n\
 #else
                                                &clockFonStruct);
 #endif
-    boardWidget      = optList[22].handle;
-    menuBarWidget    = optList[ 0].handle;
-    dropMenu         = optList[25].handle;
-    titleWidget = optList[optList[10].type != -1 ? 10 : 13].handle;
+    boardWidget      = optList[W_BOARD].handle;
+    menuBarWidget    = optList[W_MENU].handle;
+    dropMenu         = optList[W_DROP].handle;
+    titleWidget = optList[optList[W_TITLE].type != -1 ? W_TITLE : W_SMALL].handle;
     formWidget  = XtParent(boardWidget);
     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
-    XtGetValues(optList[11].handle, args, 2);
+    XtGetValues(optList[W_WHITE].handle, args, 2);
     if (appData.showButtonBar) { // can't we use timer pixels for this? (Or better yet, just black & white?)
       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
-      XtGetValues(optList[18].handle, args, 2);
+      XtGetValues(optList[W_PAUSE].handle, args, 2);
     }
     AppendEnginesToMenu(appData.recentEngineList);
 
@@ -2292,7 +2297,7 @@ EnableMenuItem (char *menuRef, int state)
 void
 EnableButtonBar (int state)
 {
-    XtSetSensitive(optList[15].handle, state);
+    XtSetSensitive(optList[W_BUTTON].handle, state);
 }
 
 
@@ -2333,7 +2338,7 @@ MenuEngineSelect (Widget w, caddr_t addr, caddr_t index)
 void
 AppendMenuItem (char *msg, int n)
 {
-    CreateMenuItem((Widget) optList[6].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
+    CreateMenuItem((Widget) optList[W_ENGIN].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
 }
 
 void
@@ -2750,10 +2755,9 @@ DrawSeekDot (int x, int y, int colorNr)
 }
 
 void
-DrawGrid (int second)
+DrawGrid ()
 {
          XDrawSegments(xDisplay, xBoardWindow, lineGC,
-                       second ? secondSegments : // [HGM] dual
                        gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
 }
 
@@ -2828,10 +2832,7 @@ FileNamePopUp (char *label, char *def, char *filter, FileProc proc, char *openMo
     fileOpenMode = openMode;   /*   to use globals here */
     {   // [HGM] use file-selector dialog stolen from Ghostview
        int index; // this is not supported yet
-       if(openFP = XsraSelFile(shellWidget, label, NULL, NULL, _("could not open: "),
-                          (def[0] ? def : NULL), filter, openMode, NULL, &openName))
-         // [HGM] delay to give expose event opportunity to redraw board after browser-dialog popdown before lengthy load starts
-         ScheduleDelayedEvent(&DelayedLoad, 50);
+       Browse(BoardWindow, label, (def[0] ? def : NULL), filter, False, openMode, &openName, &openFP);
     }
 }
 
@@ -2844,7 +2845,7 @@ FreezeUI ()
 {
   if (frozen) return;
   /* Grab by a widget that doesn't accept input */
-  XtAddGrab(optList[14].handle, TRUE, FALSE);
+  XtAddGrab(optList[W_MESSG].handle, TRUE, FALSE);
   frozen = 1;
 }
 
@@ -2853,7 +2854,7 @@ void
 ThawUI ()
 {
   if (!frozen) return;
-  XtRemoveGrab(optList[14].handle);
+  XtRemoveGrab(optList[W_MESSG].handle);
   frozen = 0;
 }
 
@@ -2879,12 +2880,12 @@ ModeHighlight ()
            Pixel oldbg, oldfg;
            XtSetArg(args[0], XtNbackground, &oldbg);
            XtSetArg(args[1], XtNforeground, &oldfg);
-           XtGetValues(optList[18].handle,
+           XtGetValues(optList[W_PAUSE].handle,
                        args, 2);
            XtSetArg(args[0], XtNbackground, oldfg);
            XtSetArg(args[1], XtNforeground, oldbg);
          }
-         XtSetValues(optList[18].handle, args, 2);
+         XtSetValues(optList[W_PAUSE].handle, args, 2);
        }
     }
 
@@ -3348,11 +3349,11 @@ StartClockTimer (long millisec)
 }
 
 void
-DisplayTimerLabel (int optNr, char *color, long timer, int highlight)
+DisplayTimerLabel (Option *opt, char *color, long timer, int highlight)
 {
     char buf[MSG_SIZ];
     Arg args[16];
-    Widget w = optList[optNr].handle;
+    Widget w = (Widget) opt->handle;
 
     /* check for low time warning */
     Pixel foregroundOrWarningColor = timerForegroundPixel;