Prepare xoptions.c for middle-end changes
[xboard.git] / xboard.c
index 0fd1d3e..69079be 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -61,6 +61,8 @@
 #include <sys/stat.h>
 #include <pwd.h>
 #include <math.h>
+#include <cairo/cairo.h>
+#include <cairo/cairo-xlib.h>
 
 #if !OMIT_SOCKETS
 # if HAVE_SYS_SOCKET_H
@@ -183,11 +185,9 @@ extern char *getenv();
 
 #if HAVE_LIBXPM
 #include <X11/xpm.h>
-#include "pixmaps/pixmaps.h"
 #define IMAGE_EXT "xpm"
 #else
 #define IMAGE_EXT "xim"
-#include "bitmaps/bitmaps.h"
 #endif
 
 #include "bitmaps/icon_white.bm"
@@ -202,6 +202,7 @@ extern char *getenv();
 #include "childio.h"
 #include "xgamelist.h"
 #include "xhistory.h"
+#include "xevalgraph.h"
 #include "xedittags.h"
 #include "menus.h"
 #include "board.h"
@@ -209,6 +210,7 @@ extern char *getenv();
 #include "engineoutput.h"
 #include "usystem.h"
 #include "gettext.h"
+#include "draw.h"
 
 
 #ifdef __EMX__
@@ -230,12 +232,6 @@ int main P((int argc, char **argv));
 RETSIGTYPE CmailSigHandler P((int sig));
 RETSIGTYPE IntSigHandler P((int sig));
 RETSIGTYPE TermSizeSigHandler P((int sig));
-static void CreateGCs P((int redo));
-static void CreateAnyPieces P((void));
-void CreateXIMPieces P((void));
-void CreateXPMPieces P((void));
-void CreateXPMBoard P((char *s, int n));
-void CreatePieces P((void));
 Widget CreateMenuBar P((Menu *mb, int boardWidth));
 #if ENABLE_NLS
 char *InsertPxlSize P((char *pattern, int targetPxlSize));
@@ -245,7 +241,6 @@ char *FindFont P((char *pattern, int targetPxlSize));
 #endif
 void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
                   u_int wreq, u_int hreq));
-void CreateGrid P((void));
 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
 void DelayedDrag P((void));
 static void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event));
@@ -280,16 +275,10 @@ int xtVersion = XtSpecificationRelease;
 int xScreen;
 Display *xDisplay;
 Window xBoardWindow;
-Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
-  highlightSquareColor, premoveHighlightColor, dialogColor, buttonColor;
-Pixel lowTimeWarningColor;
-GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
-  bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
-  prelineGC, countGC;
+Pixel lowTimeWarningColor, dialogColor, buttonColor; // used in widgets
 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
 Widget shellWidget, formWidget, boardWidget, titleWidget, dropMenu, menuBarWidget;
 Option *optList; // contains all widgets of main window
-XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 #if ENABLE_NLS
 XFontSet fontSet, clockFontSet;
 #else
@@ -334,30 +323,6 @@ WindowPlacement wpGameList;
 WindowPlacement wpTags;
 
 
-#define SOLID 0
-#define OUTLINE 1
-Pixmap pieceBitmap[2][(int)BlackPawn];
-Pixmap pieceBitmap2[2][(int)BlackPawn+4];       /* [HGM] pieces */
-Pixmap xpmPieceBitmap[4][(int)BlackPawn];      /* LL, LD, DL, DD actually used*/
-Pixmap xpmPieceBitmap2[4][(int)BlackPawn+4];   /* LL, LD, DL, DD set to select from */
-Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
-Pixmap xpmBoardBitmap[2];
-int useImages, useImageSqs, useTexture, textureW[2], textureH[2];
-XImage *ximPieceBitmap[4][(int)BlackPawn+4];   /* LL, LD, DL, DD */
-Pixmap ximMaskPm[(int)BlackPawn];               /* clipmasks, used for XIM pieces */
-Pixmap ximMaskPm2[(int)BlackPawn+4];            /* clipmasks, used for XIM pieces */
-XImage *ximLightSquare, *ximDarkSquare;
-XImage *xim_Cross;
-
-#define pieceToSolid(piece) &pieceBitmap[SOLID][(piece) % (int)BlackPawn]
-#define pieceToOutline(piece) &pieceBitmap[OUTLINE][(piece) % (int)BlackPawn]
-
-#define White(piece) ((int)(piece) < (int)BlackPawn)
-
-/* Bitmaps for use as masks when drawing XPM pieces.
-   Need one for each black and white piece.            */
-static Pixmap xpmMask[BlackKing + 1];
-
 /* This magic number is the number of intermediate frames used
    in each half of the animation. For short moves it's reduced
    by 1. The total number of frames will be factor * 2 + 1.  */
@@ -879,17 +844,6 @@ 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
@@ -918,122 +872,18 @@ ConvertToLine (int argc, char **argv)
 
 //--------------------------------------------------------------------------------------------
 
-#define BoardSize int
 void
-InitDrawingSizes (BoardSize boardSize, int flags)
-{   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
-    Dimension boardWidth, boardHeight, w, h;
-    int i;
-    static Dimension oldWidth, oldHeight;
-    static VariantClass oldVariant;
-    static int oldMono = -1, oldTwoBoards = 0;
-
-    if(!formWidget) return;
-
-    if(oldTwoBoards && !twoBoards) PopDown(DummyDlg);
-    oldTwoBoards = twoBoards;
-
-    if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
-    boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
-    boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
-
-  if(boardWidth != oldWidth || boardHeight != oldHeight) { // do resizing stuff only if size actually changed
-
-    oldWidth = boardWidth; oldHeight = boardHeight;
-    CreateGrid();
-
-    /*
-     * Inhibit shell resizing.
-     */
-    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW ;
-    shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
+ResizeBoardWindow (int w, int h, int inhibit)
+{
+    w += marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed...
+    h += marginH;
+    shellArgs[0].value = w;
+    shellArgs[1].value = h;
     shellArgs[4].value = shellArgs[2].value = w;
     shellArgs[5].value = shellArgs[3].value = h;
-    XtSetValues(shellWidget, &shellArgs[0], 6);
+    XtSetValues(shellWidget, &shellArgs[0], inhibit ? 6 : 2);
 
     XSync(xDisplay, False);
-    DelayedDrag();
-  }
-
-    // [HGM] pieces: tailor piece bitmaps to needs of specific variant
-    // (only for xpm)
-
-  if(gameInfo.variant != oldVariant) { // and only if variant changed
-
-    if(useImages) {
-      for(i=0; i<4; i++) {
-       int p;
-       for(p=0; p<=(int)WhiteKing; p++)
-          xpmPieceBitmap[i][p] = xpmPieceBitmap2[i][p]; // defaults
-       if(gameInfo.variant == VariantShogi) {
-          xpmPieceBitmap[i][(int)WhiteCannon] = xpmPieceBitmap2[i][(int)WhiteKing+1];
-          xpmPieceBitmap[i][(int)WhiteNightrider] = xpmPieceBitmap2[i][(int)WhiteKing+2];
-          xpmPieceBitmap[i][(int)WhiteSilver] = xpmPieceBitmap2[i][(int)WhiteKing+3];
-          xpmPieceBitmap[i][(int)WhiteGrasshopper] = xpmPieceBitmap2[i][(int)WhiteKing+4];
-          xpmPieceBitmap[i][(int)WhiteQueen] = xpmPieceBitmap2[i][(int)WhiteLance];
-       }
-#ifdef GOTHIC
-       if(gameInfo.variant == VariantGothic) {
-          xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteSilver];
-       }
-#endif
-       if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) {
-          xpmPieceBitmap[i][(int)WhiteAngel]    = xpmPieceBitmap2[i][(int)WhiteFalcon];
-          xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteAlfil];
-       }
-#if !HAVE_LIBXPM
-       // [HGM] why are thee ximMasks used at all? the ximPieceBitmaps seem to be never used!
-       for(p=0; p<=(int)WhiteKing; p++)
-          ximMaskPm[p] = ximMaskPm2[p]; // defaults
-       if(gameInfo.variant == VariantShogi) {
-          ximMaskPm[(int)WhiteCannon] = ximMaskPm2[(int)WhiteKing+1];
-          ximMaskPm[(int)WhiteNightrider] = ximMaskPm2[(int)WhiteKing+2];
-          ximMaskPm[(int)WhiteSilver] = ximMaskPm2[(int)WhiteKing+3];
-          ximMaskPm[(int)WhiteGrasshopper] = ximMaskPm2[(int)WhiteKing+4];
-          ximMaskPm[(int)WhiteQueen] = ximMaskPm2[(int)WhiteLance];
-       }
-#ifdef GOTHIC
-       if(gameInfo.variant == VariantGothic) {
-           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteSilver];
-       }
-#endif
-       if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) {
-           ximMaskPm[(int)WhiteAngel]    = ximMaskPm2[(int)WhiteFalcon];
-           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteAlfil];
-       }
-#endif
-      }
-    } else {
-      for(i=0; i<2; i++) {
-       int p;
-       for(p=0; p<=(int)WhiteKing; p++)
-          pieceBitmap[i][p] = pieceBitmap2[i][p]; // defaults
-       if(gameInfo.variant == VariantShogi) {
-          pieceBitmap[i][(int)WhiteCannon] = pieceBitmap2[i][(int)WhiteKing+1];
-          pieceBitmap[i][(int)WhiteNightrider] = pieceBitmap2[i][(int)WhiteKing+2];
-          pieceBitmap[i][(int)WhiteSilver] = pieceBitmap2[i][(int)WhiteKing+3];
-          pieceBitmap[i][(int)WhiteGrasshopper] = pieceBitmap2[i][(int)WhiteKing+4];
-          pieceBitmap[i][(int)WhiteQueen] = pieceBitmap2[i][(int)WhiteLance];
-       }
-#ifdef GOTHIC
-       if(gameInfo.variant == VariantGothic) {
-          pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteSilver];
-       }
-#endif
-       if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) {
-          pieceBitmap[i][(int)WhiteAngel]    = pieceBitmap2[i][(int)WhiteFalcon];
-          pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteAlfil];
-       }
-      }
-    }
-    oldMono = -10; // kludge to force recreation of animation masks
-    oldVariant = gameInfo.variant;
-  }
-#if HAVE_LIBXPM
-  if(appData.monoMode != oldMono)
-    CreateAnimVars();
-#endif
-  oldMono = appData.monoMode;
 }
 
 static int
@@ -1054,17 +904,11 @@ MakeOneColor (char *name, Pixel *color)
     return False;
 }
 
-static int
+int
 MakeColors ()
 {   // [HGM] taken out of main(), so it can be called from BoardOptions dialog
     int forceMono = False;
 
-    forceMono |= MakeOneColor(appData.lightSquareColor, &lightSquareColor);
-    forceMono |= MakeOneColor(appData.darkSquareColor, &darkSquareColor);
-    forceMono |= MakeOneColor(appData.whitePieceColor, &whitePieceColor);
-    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);
@@ -1073,35 +917,6 @@ MakeColors ()
     return forceMono;
 }
 
-static void
-CreateAnyPieces ()
-{   // [HGM] taken out of main
-#if HAVE_LIBXPM
-    if (appData.monoMode && // [HGM] no sense to go on to certain doom
-       (appData.bitmapDirectory == NULL || appData.bitmapDirectory[0] == NULLCHAR))
-           appData.bitmapDirectory = strdup(DEF_BITMAP_DIR);
-
-    if (appData.bitmapDirectory[0] != NULLCHAR) {
-      CreatePieces();
-    } else {
-      CreateXPMPieces();
-      CreateXPMBoard(appData.liteBackTextureFile, 1);
-      CreateXPMBoard(appData.darkBackTextureFile, 0);
-    }
-#else
-    CreateXIMPieces();
-    /* Create regular pieces */
-    if (!useImages) CreatePieces();
-#endif
-}
-
-void
-InitDrawingParams ()
-{
-    MakeColors(); CreateGCs(True);
-    CreateAnyPieces();
-}
-
 void
 InitializeFonts (int clockFontPxlSize, int coordFontPxlSize, int fontPxlSize)
 {   // detervtomine what fonts to use, and create them
@@ -1384,24 +1199,6 @@ main (int argc, char **argv)
        // [HGM] font: use defaults from settings file if available and not overruled
     }
 
-    /* Now, using squareSize as a hint, find a good XPM/XIM set size */
-    if (strlen(appData.pixmapDirectory) > 0) {
-       p = ExpandPathName(appData.pixmapDirectory);
-       if (!p) {
-           fprintf(stderr, _("Error expanding path name \"%s\"\n"),
-                  appData.pixmapDirectory);
-           exit(1);
-       }
-       if (appData.debugMode) {
-          fprintf(stderr, _("\
-XBoard square size (hint): %d\n\
-%s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
-       }
-       squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
-       if (appData.debugMode) {
-           fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
-       }
-    }
     defaultLineGap = lineGap;
     if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
 
@@ -1456,6 +1253,8 @@ XBoard square size (hint): %d\n\
 #else
                                                clockFontStruct);
 #endif
+    InitDrawingHandle(optList + W_BOARD);
+    currBoard        = &optList[W_BOARD];
     boardWidget      = optList[W_BOARD].handle;
     menuBarWidget    = optList[W_MENU].handle;
     dropMenu         = optList[W_DROP].handle;
@@ -1510,15 +1309,14 @@ XBoard square size (hint): %d\n\
     XtGetValues(shellWidget, shellArgs, 2);
     shellArgs[4].value = shellArgs[2].value = w;
     shellArgs[5].value = shellArgs[3].value = h;
-    XtSetValues(shellWidget, &shellArgs[2], 4);
+//    XtSetValues(shellWidget, &shellArgs[2], 4);
     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
     marginH =  h - boardHeight;
 
     CatchDeleteWindow(shellWidget, "QuitProc");
 
-    CreateGCs(False);
-    CreateGrid();
     CreateAnyPieces();
+    CreateGrid();
 
     if(appData.logoSize)
     {   // locate and read user logo
@@ -1774,566 +1572,15 @@ FindFont (char *pattern, int targetPxlSize)
 }
 #endif
 
-void
-DeleteGCs ()
-{   // [HGM] deletes GCs that are to be remade, to prevent resource leak;
-    // must be called before all non-first callse to CreateGCs()
-    XtReleaseGC(shellWidget, highlineGC);
-    XtReleaseGC(shellWidget, lightSquareGC);
-    XtReleaseGC(shellWidget, darkSquareGC);
-    XtReleaseGC(shellWidget, lineGC);
-    if (appData.monoMode) {
-       if (DefaultDepth(xDisplay, xScreen) == 1) {
-           XtReleaseGC(shellWidget, wbPieceGC);
-       } else {
-           XtReleaseGC(shellWidget, bwPieceGC);
-       }
-    } else {
-       XtReleaseGC(shellWidget, prelineGC);
-       XtReleaseGC(shellWidget, wdPieceGC);
-       XtReleaseGC(shellWidget, wlPieceGC);
-       XtReleaseGC(shellWidget, bdPieceGC);
-       XtReleaseGC(shellWidget, blPieceGC);
-    }
-}
-
-static GC
-CreateOneGC (XGCValues *gc_values, Pixel foreground, Pixel background)
-{
-    XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
-      | GCBackground | GCFunction | GCPlaneMask;
-    gc_values->foreground = foreground;
-    gc_values->background = background;
-    return XtGetGC(shellWidget, value_mask, gc_values);
-}
-
-static void
-CreateGCs (int redo)
-{
-    XGCValues gc_values;
-    GC copyInvertedGC;
-    Pixel white = XWhitePixel(xDisplay, xScreen);
-    Pixel black = XBlackPixel(xDisplay, xScreen);
-
-    gc_values.plane_mask = AllPlanes;
-    gc_values.line_width = lineGap;
-    gc_values.line_style = LineSolid;
-    gc_values.function = GXcopy;
-
-  if(redo) {
-    DeleteGCs(); // called a second time; clean up old GCs first
-  } else { // [HGM] grid and font GCs created on first call only
-    coordGC = CreateOneGC(&gc_values, black, white);
-    XSetFont(xDisplay, coordGC, coordFontID);
-
-    // [HGM] make font for holdings counts (white on black)
-    countGC = CreateOneGC(&gc_values, white, black);
-    XSetFont(xDisplay, countGC, countFontID);
-  }
-    lineGC = CreateOneGC(&gc_values, black, black);
-
-    if (appData.monoMode) {
-
-       highlineGC = CreateOneGC(&gc_values, white, white);
-       lightSquareGC = wbPieceGC = CreateOneGC(&gc_values, white, black);
-       darkSquareGC = bwPieceGC = CreateOneGC(&gc_values, black, white);
-
-       if (DefaultDepth(xDisplay, xScreen) == 1) {
-           /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
-           gc_values.function = GXcopyInverted;
-           copyInvertedGC = CreateOneGC(&gc_values, black, white);
-           gc_values.function = GXcopy;
-           if (XBlackPixel(xDisplay, xScreen) == 1) {
-               bwPieceGC = darkSquareGC;
-               wbPieceGC = copyInvertedGC;
-           } else {
-               bwPieceGC = copyInvertedGC;
-               wbPieceGC = lightSquareGC;
-           }
-       }
-    } else {
-
-       highlineGC = CreateOneGC(&gc_values, highlightSquareColor, highlightSquareColor);
-       prelineGC = CreateOneGC(&gc_values, premoveHighlightColor, premoveHighlightColor);
-       lightSquareGC = CreateOneGC(&gc_values, lightSquareColor, darkSquareColor);
-       darkSquareGC = CreateOneGC(&gc_values, darkSquareColor, lightSquareColor);
-       wdPieceGC = CreateOneGC(&gc_values, whitePieceColor, darkSquareColor);
-       wlPieceGC = CreateOneGC(&gc_values, whitePieceColor, lightSquareColor);
-       bdPieceGC = CreateOneGC(&gc_values, blackPieceColor, darkSquareColor);
-       blPieceGC = CreateOneGC(&gc_values, blackPieceColor, lightSquareColor);
-    }
-}
-
-void
-loadXIM (XImage *xim, XImage *xmask, char *filename, Pixmap *dest, Pixmap *mask)
-{
-    int x, y, w, h, p;
-    FILE *fp;
-    Pixmap temp;
-    XGCValues  values;
-    GC maskGC;
-
-    fp = fopen(filename, "rb");
-    if (!fp) {
-       fprintf(stderr, _("%s: error loading XIM!\n"), programName);
-       exit(1);
-    }
-
-    w = fgetc(fp);
-    h = fgetc(fp);
-
-    for (y=0; y<h; ++y) {
-       for (x=0; x<h; ++x) {
-           p = fgetc(fp);
-
-           switch (p) {
-             case 0:
-               XPutPixel(xim, x, y, blackPieceColor);
-               if (xmask)
-                 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
-               break;
-             case 1:
-               XPutPixel(xim, x, y, darkSquareColor);
-               if (xmask)
-                 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
-               break;
-             case 2:
-               XPutPixel(xim, x, y, whitePieceColor);
-               if (xmask)
-                 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
-               break;
-             case 3:
-               XPutPixel(xim, x, y, lightSquareColor);
-               if (xmask)
-                 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
-               break;
-           }
-       }
-    }
-
-    fclose(fp);
-
-    /* create Pixmap of piece */
-    *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
-                         w, h, xim->depth);
-    XPutImage(xDisplay, *dest, lightSquareGC, xim,
-             0, 0, 0, 0, w, h);
-
-    /* create Pixmap of clipmask
-       Note: We assume the white/black pieces have the same
-             outline, so we make only 6 masks. This is okay
-             since the XPM clipmask routines do the same. */
-    if (xmask) {
-      temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
-                           w, h, xim->depth);
-      XPutImage(xDisplay, temp, lightSquareGC, xmask,
-             0, 0, 0, 0, w, h);
-
-      /* now create the 1-bit version */
-      *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
-                         w, h, 1);
-
-      values.foreground = 1;
-      values.background = 0;
-
-      /* Don't use XtGetGC, not read only */
-      maskGC = XCreateGC(xDisplay, *mask,
-                   GCForeground | GCBackground, &values);
-      XCopyPlane(xDisplay, temp, *mask, maskGC,
-                 0, 0, squareSize, squareSize, 0, 0, 1);
-      XFreePixmap(xDisplay, temp);
-    }
-}
-
-
-char pieceBitmapNames[] = "pnbrqfeacwmohijgdvlsukpnsl";
-
-void
-CreateXIMPieces ()
-{
-    int piece, kind;
-    char buf[MSG_SIZ];
-    u_int ss;
-    static char *ximkind[] = { "ll", "ld", "dl", "dd" };
-    XImage *ximtemp;
-
-    ss = squareSize;
-
-    /* The XSynchronize calls were copied from CreatePieces.
-       Not sure if needed, but can't hurt */
-    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
-                                    buffering bug */
-
-    /* temp needed by loadXIM() */
-    ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
-                0, 0, ss, ss, AllPlanes, XYPixmap);
-
-    if (strlen(appData.pixmapDirectory) == 0) {
-      useImages = 0;
-    } else {
-       useImages = 1;
-       if (appData.monoMode) {
-         DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
-                           0, 2);
-         ExitEvent(2);
-       }
-       fprintf(stderr, _("\nLoading XIMs...\n"));
-       /* Load pieces */
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
-           fprintf(stderr, "%d", piece+1);
-           for (kind=0; kind<4; kind++) {
-               fprintf(stderr, ".");
-               snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xim",
-                       ExpandPathName(appData.pixmapDirectory),
-                       piece <= (int) WhiteKing ? "" : "w",
-                       pieceBitmapNames[piece],
-                       ximkind[kind], ss);
-               ximPieceBitmap[kind][piece] =
-                 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
-                           0, 0, ss, ss, AllPlanes, XYPixmap);
-               if (appData.debugMode)
-                 fprintf(stderr, _("(File:%s:) "), buf);
-               loadXIM(ximPieceBitmap[kind][piece],
-                       ximtemp, buf,
-                       &(xpmPieceBitmap2[kind][piece]),
-                       &(ximMaskPm2[piece]));
-               if(piece <= (int)WhiteKing)
-                   xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
-           }
-           fprintf(stderr," ");
-       }
-       /* Load light and dark squares */
-       /* If the LSQ and DSQ pieces don't exist, we will
-          draw them with solid squares. */
-       snprintf(buf,sizeof(buf), "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
-       if (access(buf, 0) != 0) {
-           useImageSqs = 0;
-       } else {
-           useImageSqs = 1;
-           fprintf(stderr, _("light square "));
-           ximLightSquare=
-             XGetImage(xDisplay, DefaultRootWindow(xDisplay),
-                       0, 0, ss, ss, AllPlanes, XYPixmap);
-           if (appData.debugMode)
-             fprintf(stderr, _("(File:%s:) "), buf);
-
-           loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
-           fprintf(stderr, _("dark square "));
-           snprintf(buf,sizeof(buf), "%s/dsq%u.xim",
-                   ExpandPathName(appData.pixmapDirectory), ss);
-           if (appData.debugMode)
-             fprintf(stderr, _("(File:%s:) "), buf);
-           ximDarkSquare=
-             XGetImage(xDisplay, DefaultRootWindow(xDisplay),
-                       0, 0, ss, ss, AllPlanes, XYPixmap);
-           loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
-           xpmJailSquare = xpmLightSquare;
-       }
-       fprintf(stderr, _("Done.\n"));
-    }
-    XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
-}
-
-static VariantClass oldVariant = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
-
-#if HAVE_LIBXPM
-void
-CreateXPMBoard (char *s, int kind)
-{
-    XpmAttributes attr;
-    attr.valuemask = 0;
-    if(!appData.useBitmaps || s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; }
-    if (XpmReadFileToPixmap(xDisplay, xBoardWindow, s, &(xpmBoardBitmap[kind]), NULL, &attr) == 0) {
-       useTexture |= kind + 1; textureW[kind] = attr.width; textureH[kind] = attr.height;
-    }
-}
-
-void
-FreeXPMPieces ()
-{   // [HGM] to prevent resoucre leak on calling CreaeXPMPieces() a second time,
-    // thisroutine has to be called t free the old piece pixmaps
-    int piece, kind;
-    for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++)
-       for (kind=0; kind<4; kind++) XFreePixmap(xDisplay, xpmPieceBitmap2[kind][piece]);
-    if(useImageSqs) {
-       XFreePixmap(xDisplay, xpmLightSquare);
-       XFreePixmap(xDisplay, xpmDarkSquare);
-    }
-}
-
-void
-CreateXPMPieces ()
-{
-    int piece, kind, r;
-    char buf[MSG_SIZ];
-    u_int ss = squareSize;
-    XpmAttributes attr;
-    static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
-    XpmColorSymbol symbols[4];
-    static int redo = False;
-
-    if(redo) FreeXPMPieces(); else redo = 1;
-
-    /* The XSynchronize calls were copied from CreatePieces.
-       Not sure if needed, but can't hurt */
-    XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
-
-    /* Setup translations so piece colors match square colors */
-    symbols[0].name = "light_piece";
-    symbols[0].value = appData.whitePieceColor;
-    symbols[1].name = "dark_piece";
-    symbols[1].value = appData.blackPieceColor;
-    symbols[2].name = "light_square";
-    symbols[2].value = appData.lightSquareColor;
-    symbols[3].name = "dark_square";
-    symbols[3].value = appData.darkSquareColor;
-
-    attr.valuemask = XpmColorSymbols;
-    attr.colorsymbols = symbols;
-    attr.numsymbols = 4;
-
-    if (appData.monoMode) {
-      DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
-                       0, 2);
-      ExitEvent(2);
-    }
-    if (strlen(appData.pixmapDirectory) == 0) {
-       XpmPieces* pieces = builtInXpms;
-       useImages = 1;
-       /* Load pieces */
-       while (pieces->size != squareSize && pieces->size) pieces++;
-       if (!pieces->size) {
-         fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
-         exit(1);
-       }
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
-           for (kind=0; kind<4; kind++) {
-
-               if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
-                                              pieces->xpm[piece][kind],
-                                              &(xpmPieceBitmap2[kind][piece]),
-                                              NULL, &attr)) != 0) {
-                 fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
-                         r, buf);
-                 exit(1);
-               }
-               if(piece <= (int) WhiteKing)
-                   xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
-           }
-       }
-       useImageSqs = 0;
-       xpmJailSquare = xpmLightSquare;
-    } else {
-       useImages = 1;
-
-       fprintf(stderr, _("\nLoading XPMs...\n"));
-
-       /* Load pieces */
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
-           fprintf(stderr, "%d ", piece+1);
-           for (kind=0; kind<4; kind++) {
-             snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xpm",
-                       ExpandPathName(appData.pixmapDirectory),
-                       piece > (int) WhiteKing ? "w" : "",
-                       pieceBitmapNames[piece],
-                       xpmkind[kind], ss);
-               if (appData.debugMode) {
-                   fprintf(stderr, _("(File:%s:) "), buf);
-               }
-               if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
-                                          &(xpmPieceBitmap2[kind][piece]),
-                                          NULL, &attr)) != 0) {
-                   if(piece != (int)WhiteKing && piece > (int)WhiteQueen) {
-                     // [HGM] missing: read of unorthodox piece failed; substitute King.
-                     snprintf(buf, sizeof(buf), "%s/k%s%u.xpm",
-                               ExpandPathName(appData.pixmapDirectory),
-                               xpmkind[kind], ss);
-                       if (appData.debugMode) {
-                           fprintf(stderr, _("(Replace by File:%s:) "), buf);
-                       }
-                       r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
-                                               &(xpmPieceBitmap2[kind][piece]),
-                                               NULL, &attr);
-                   }
-                   if (r != 0) {
-                       fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
-                               r, buf);
-                       exit(1);
-                   }
-               }
-               if(piece <= (int) WhiteKing)
-                   xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
-           }
-       }
-       /* Load light and dark squares */
-       /* If the LSQ and DSQ pieces don't exist, we will
-          draw them with solid squares. */
-       fprintf(stderr, _("light square "));
-       snprintf(buf, sizeof(buf), "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
-       if (access(buf, 0) != 0) {
-           useImageSqs = 0;
-       } else {
-           useImageSqs = 1;
-           if (appData.debugMode)
-             fprintf(stderr, _("(File:%s:) "), buf);
-
-           if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
-                                      &xpmLightSquare, NULL, &attr)) != 0) {
-               fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
-               exit(1);
-           }
-           fprintf(stderr, _("dark square "));
-           snprintf(buf, sizeof(buf), "%s/dsq%u.xpm",
-                   ExpandPathName(appData.pixmapDirectory), ss);
-           if (appData.debugMode) {
-               fprintf(stderr, _("(File:%s:) "), buf);
-           }
-           if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
-                                      &xpmDarkSquare, NULL, &attr)) != 0) {
-               fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
-               exit(1);
-           }
-       }
-       xpmJailSquare = xpmLightSquare;
-       fprintf(stderr, _("Done.\n"));
-    }
-    oldVariant = -1; // kludge to force re-makig of animation masks
-    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
-                                     buffering bug */
-}
-#endif /* HAVE_LIBXPM */
-
-#if HAVE_LIBXPM
-/* No built-in bitmaps */
-void CreatePieces()
-{
-    int piece, kind;
-    char buf[MSG_SIZ];
-    u_int ss = squareSize;
-
-    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
-                                    buffering bug */
-
-    for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
-         snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
-                  pieceBitmapNames[piece],
-                  ss, kind == SOLID ? 's' : 'o');
-         ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss);
-         if(piece <= (int)WhiteKing)
-           pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
-       }
-    }
-
-    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
-                                     buffering bug */
-}
-#else
-/* With built-in bitmaps */
-void
-CreatePieces ()
-{
-    BuiltInBits* bib = builtInBits;
-    int piece, kind;
-    char buf[MSG_SIZ];
-    u_int ss = squareSize;
-
-    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
-                                    buffering bug */
-
-    while (bib->squareSize != ss && bib->squareSize != 0) bib++;
-
-    for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
-         snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
-                  pieceBitmapNames[piece],
-                  ss, kind == SOLID ? 's' : 'o');
-         ReadBitmap(&pieceBitmap2[kind][piece], buf,
-                    bib->bits[kind][piece], ss, ss);
-         if(piece <= (int)WhiteKing)
-           pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
-       }
-    }
-
-    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
-                                     buffering bug */
-}
-#endif
-
 void
 ReadBitmap (Pixmap *pm, String name, unsigned char bits[], u_int wreq, u_int hreq)
 {
-    int x_hot, y_hot;
-    u_int w, h;
-    int errcode;
-    char msg[MSG_SIZ], fullname[MSG_SIZ];
-
-    if (*appData.bitmapDirectory != NULLCHAR) {
-      safeStrCpy(fullname, appData.bitmapDirectory, sizeof(fullname)/sizeof(fullname[0]) );
-      strncat(fullname, "/", MSG_SIZ - strlen(fullname) - 1);
-      strncat(fullname, name, MSG_SIZ - strlen(fullname) - 1);
-      errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
-                               &w, &h, pm, &x_hot, &y_hot);
-      fprintf(stderr, "load %s\n", name);
-       if (errcode != BitmapSuccess) {
-           switch (errcode) {
-             case BitmapOpenFailed:
-               snprintf(msg, sizeof(msg), _("Can't open bitmap file %s"), fullname);
-               break;
-             case BitmapFileInvalid:
-               snprintf(msg, sizeof(msg), _("Invalid bitmap in file %s"), fullname);
-               break;
-             case BitmapNoMemory:
-               snprintf(msg, sizeof(msg), _("Ran out of memory reading bitmap file %s"),
-                       fullname);
-               break;
-             default:
-               snprintf(msg, sizeof(msg), _("Unknown XReadBitmapFile error %d on file %s"),
-                       errcode, fullname);
-               break;
-           }
-           fprintf(stderr, _("%s: %s...using built-in\n"),
-                   programName, msg);
-       } else if (w != wreq || h != hreq) {
-           fprintf(stderr,
-                   _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
-                   programName, fullname, w, h, wreq, hreq);
-       } else {
-           return;
-       }
-    }
     if (bits != NULL) {
        *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
                                    wreq, hreq);
     }
 }
 
-void
-CreateGrid ()
-{
-    int i, j;
-
-    if (lineGap == 0) return;
-
-    /* [HR] Split this into 2 loops for non-square boards. */
-
-    for (i = 0; i < BOARD_HEIGHT + 1; i++) {
-        gridSegments[i].x1 = 0;
-        gridSegments[i].x2 =
-          lineGap + BOARD_WIDTH * (squareSize + lineGap);
-        gridSegments[i].y1 = gridSegments[i].y2
-          = lineGap / 2 + (i * (squareSize + lineGap));
-    }
-
-    for (j = 0; j < BOARD_WIDTH + 1; j++) {
-        gridSegments[j + i].y1 = 0;
-        gridSegments[j + i].y2 =
-          lineGap + BOARD_HEIGHT * (squareSize + lineGap);
-        gridSegments[j + i].x1 = gridSegments[j + i].x2
-          = lineGap / 2 + (j * (squareSize + lineGap));
-    }
-}
-
 void
 MarkMenuItem (char *menuRef, int state)
 {
@@ -2416,298 +1663,12 @@ SetupDropMenu ()
     }
 }
 
-
 static void
 do_flash_delay (unsigned long msec)
 {
     TimeDelay(msec);
 }
 
-void
-DrawBorder (int x, int y, int type)
-{
-    GC gc = lineGC;
-
-    if(type == 1) gc = highlineGC; else if(type == 2) gc = prelineGC;
-
-    XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
-                  squareSize+lineGap, squareSize+lineGap);
-}
-
-static int
-CutOutSquare (int x, int y, int *x0, int *y0, int  kind)
-{
-    int W = BOARD_WIDTH, H = BOARD_HEIGHT;
-    int nx = x/(squareSize + lineGap), ny = y/(squareSize + lineGap);
-    *x0 = 0; *y0 = 0;
-    if(textureW[kind] < squareSize || textureH[kind] < squareSize) return 0;
-    if(textureW[kind] < W*squareSize)
-       *x0 = (textureW[kind] - squareSize) * nx/(W-1);
-    else
-       *x0 = textureW[kind]*nx / W + (textureW[kind] - W*squareSize) / (2*W);
-    if(textureH[kind] < H*squareSize)
-       *y0 = (textureH[kind] - squareSize) * ny/(H-1);
-    else
-       *y0 = textureH[kind]*ny / H + (textureH[kind] - H*squareSize) / (2*H);
-    return 1;
-}
-
-#include <cairo/cairo.h>
-#include <cairo/cairo-xlib.h>
-
-void
-DrawLogo (void *handle, void *logo)
-{
-    cairo_surface_t *img, *cs;
-    cairo_t *cr;
-    int w, h;
-
-    if(!logo || !handle) return;
-    cs = cairo_xlib_surface_create(xDisplay, XtWindow(handle), DefaultVisual(xDisplay, 0), appData.logoSize, appData.logoSize/2);
-    img = cairo_image_surface_create_from_png (logo);
-    w = cairo_image_surface_get_width (img);
-    h = cairo_image_surface_get_height (img);
-    cr = cairo_create(cs);
-    cairo_scale(cr, (float)appData.logoSize/w, appData.logoSize/(2.*h));
-    cairo_set_source_surface (cr, img, 0, 0);
-    cairo_paint (cr);
-    cairo_destroy (cr);
-    cairo_surface_destroy (img);
-    cairo_surface_destroy (cs);
-}
-
-static void
-BlankSquare (int x, int y, int color, ChessSquare piece, Drawable dest, int fac)
-{   // [HGM] extra param 'fac' for forcing destination to (0,0) for copying to animation buffer
-    int x0, y0;
-    if (useImages && color != 2 && (useTexture & color+1) && CutOutSquare(x, y, &x0, &y0, color)) {
-       XCopyArea(xDisplay, xpmBoardBitmap[color], dest, wlPieceGC, x0, y0,
-                 squareSize, squareSize, x*fac, y*fac);
-    } else
-    if (useImages && useImageSqs) {
-       Pixmap pm;
-       switch (color) {
-         case 1: /* light */
-           pm = xpmLightSquare;
-           break;
-         case 0: /* dark */
-           pm = xpmDarkSquare;
-           break;
-         case 2: /* neutral */
-         default:
-           pm = xpmJailSquare; // [HGM] this is wrong, but apparently never used?
-           break;
-       }
-       XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
-                 squareSize, squareSize, x*fac, y*fac);
-    } else {
-       GC gc;
-       switch (color) {
-         case 1: /* light */
-           gc = lightSquareGC;
-           break;
-         case 0: /* dark */
-           gc = darkSquareGC;
-           break;
-         case 2: /* neutral */
-         default:
-           gc = lineGC;
-           break;
-       }
-       XFillRectangle(xDisplay, dest, gc, x*fac, y*fac, squareSize, squareSize);
-    }
-}
-
-/*
-   I split out the routines to draw a piece so that I could
-   make a generic flash routine.
-*/
-static void
-monoDrawPiece_1bit (ChessSquare piece, int square_color, int x, int y, Drawable dest)
-{
-    /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
-    switch (square_color) {
-      case 1: /* light */
-      case 2: /* neutral */
-      default:
-       XCopyArea(xDisplay, (int) piece < (int) BlackPawn
-                 ? *pieceToOutline(piece)
-                 : *pieceToSolid(piece),
-                 dest, bwPieceGC, 0, 0,
-                 squareSize, squareSize, x, y);
-       break;
-      case 0: /* dark */
-       XCopyArea(xDisplay, (int) piece < (int) BlackPawn
-                 ? *pieceToSolid(piece)
-                 : *pieceToOutline(piece),
-                 dest, wbPieceGC, 0, 0,
-                 squareSize, squareSize, x, y);
-       break;
-    }
-}
-
-static void
-monoDrawPiece (ChessSquare piece, int square_color, int x, int y, Drawable dest)
-{
-    switch (square_color) {
-      case 1: /* light */
-      case 2: /* neutral */
-      default:
-       XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
-                  ? *pieceToOutline(piece)
-                  : *pieceToSolid(piece),
-                  dest, bwPieceGC, 0, 0,
-                  squareSize, squareSize, x, y, 1);
-       break;
-      case 0: /* dark */
-       XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
-                  ? *pieceToSolid(piece)
-                  : *pieceToOutline(piece),
-                  dest, wbPieceGC, 0, 0,
-                  squareSize, squareSize, x, y, 1);
-       break;
-    }
-}
-
-static void
-colorDrawPiece (ChessSquare piece, int square_color, int x, int y, Drawable dest)
-{
-    if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
-    switch (square_color) {
-      case 1: /* light */
-       XCopyPlane(xDisplay, *pieceToSolid(piece),
-                  dest, (int) piece < (int) BlackPawn
-                  ? wlPieceGC : blPieceGC, 0, 0,
-                  squareSize, squareSize, x, y, 1);
-       break;
-      case 0: /* dark */
-       XCopyPlane(xDisplay, *pieceToSolid(piece),
-                  dest, (int) piece < (int) BlackPawn
-                  ? wdPieceGC : bdPieceGC, 0, 0,
-                  squareSize, squareSize, x, y, 1);
-       break;
-      case 2: /* neutral */
-      default:
-       break; // should never contain pieces
-    }
-}
-
-static void
-colorDrawPieceImage (ChessSquare piece, int square_color, int x, int y, Drawable dest)
-{
-    int kind, p = piece;
-
-    switch (square_color) {
-      case 1: /* light */
-      case 2: /* neutral */
-      default:
-       if ((int)piece < (int) BlackPawn) {
-           kind = 0;
-       } else {
-           kind = 2;
-           piece -= BlackPawn;
-       }
-       break;
-      case 0: /* dark */
-       if ((int)piece < (int) BlackPawn) {
-           kind = 1;
-       } else {
-           kind = 3;
-           piece -= BlackPawn;
-       }
-       break;
-    }
-    if(appData.upsideDown && flipView) { kind ^= 2; p += p < BlackPawn ? BlackPawn : -BlackPawn; }// swap white and black pieces
-    if(useTexture & square_color+1) {
-        BlankSquare(x, y, square_color, piece, dest, 1); // erase previous contents with background
-       XSetClipMask(xDisplay, wlPieceGC, xpmMask[p]);
-       XSetClipOrigin(xDisplay, wlPieceGC, x, y);
-       XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, wlPieceGC, 0, 0, squareSize, squareSize, x, y);
-       XSetClipMask(xDisplay, wlPieceGC, None);
-       XSetClipOrigin(xDisplay, wlPieceGC, 0, 0);
-    } else
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
-             dest, wlPieceGC, 0, 0,
-             squareSize, squareSize, x, y);
-}
-
-typedef void (*DrawFunc)();
-
-DrawFunc
-ChooseDrawFunc ()
-{
-    if (appData.monoMode) {
-       if (DefaultDepth(xDisplay, xScreen) == 1) {
-           return monoDrawPiece_1bit;
-       } else {
-           return monoDrawPiece;
-       }
-    } else {
-       if (useImages)
-         return colorDrawPieceImage;
-       else
-         return colorDrawPiece;
-    }
-}
-
-void
-DrawDot (int marker, int x, int y, int r)
-{
-       if(appData.monoMode) {
-           XFillArc(xDisplay, xBoardWindow, marker == 2 ? darkSquareGC : lightSquareGC,
-                   x, y, r, r, 0, 64*360);
-           XDrawArc(xDisplay, xBoardWindow, marker == 2 ? lightSquareGC : darkSquareGC,
-                   x, y, r, r, 0, 64*360);
-       } else
-       XFillArc(xDisplay, xBoardWindow, marker == 2 ? prelineGC : highlineGC,
-                   x, y, r, r, 0, 64*360);
-}
-
-void
-DrawOneSquare (int x, int y, ChessSquare piece, int square_color, int marker, char *string, int align)
-{   // basic front-end board-draw function: takes care of everything that can be in square:
-    // piece, background, coordinate/count, marker dot
-    int direction, font_ascent, font_descent;
-    XCharStruct overall;
-    DrawFunc drawfunc;
-
-    if (piece == EmptySquare) {
-       BlankSquare(x, y, square_color, piece, xBoardWindow, 1);
-    } else {
-       drawfunc = ChooseDrawFunc();
-       drawfunc(piece, square_color, x, y, xBoardWindow);
-    }
-
-    if(align) { // square carries inscription (coord or piece count)
-       int xx = x, yy = y;
-       GC hGC = align < 3 ? coordGC : countGC;
-       // first calculate where it goes
-       XTextExtents(countFontStruct, string, 1, &direction,
-                        &font_ascent, &font_descent, &overall);
-       if (align == 1) {
-           xx += squareSize - overall.width - 2;
-           yy += squareSize - font_descent - 1;
-       } else if (align == 2) {
-           xx += 2, yy += font_ascent + 1;
-       } else if (align == 3) {
-           xx += squareSize - overall.width - 2;
-           yy += font_ascent + 1;
-       } else if (align == 4) {
-           xx += 2, yy += font_ascent + 1;
-       }
-       // then draw it
-       if (appData.monoMode) {
-           XDrawImageString(xDisplay, xBoardWindow, hGC, xx, yy, string, 1);
-       } else {
-           XDrawString(xDisplay, xBoardWindow, hGC, xx, yy, string, 1);
-       }
-    }
-
-    if(marker) { // print fat marker dot, if requested
-       DrawDot(marker, x + squareSize/4, y+squareSize/4, squareSize/2);
-    }
-}
-
 void
 FlashDelay (int flash_delay)
 {
@@ -2760,15 +1721,40 @@ CoDrag (Widget sh, WindowPlacement *wp)
     XtSetValues(sh, args, j);
 }
 
+void
+ReSize (WindowPlacement *wp)
+{
+       int sqx, sqy, w, h;
+       if(wp->width == wpMain.width && wp->height == wpMain.height) return; // not sized
+       sqx = (wp->width  - lineGap - marginW) / BOARD_WIDTH - lineGap;
+       sqy = (wp->height - lineGap - marginH) / BOARD_HEIGHT - lineGap;
+       if(sqy < sqx) sqx = sqy;
+       if(sqx != squareSize) {
+           squareSize = sqx; // adopt new square size
+           CreatePNGPieces(); // make newly scaled pieces
+           InitDrawingSizes(0, 0); // creates grid etc.
+       } else ResizeBoardWindow(BOARD_WIDTH * (squareSize + lineGap) + lineGap, BOARD_HEIGHT * (squareSize + lineGap) + lineGap, 0);
+       w = BOARD_WIDTH * (squareSize + lineGap) + lineGap;
+       h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap;
+       if(optList[W_BOARD].max   > w) optList[W_BOARD].max = w;
+       if(optList[W_BOARD].value > h) optList[W_BOARD].value = h;
+}
+
 static XtIntervalId delayedDragID = 0;
 
 void
 DragProc ()
 {
+       static int busy;
+       if(busy) return;
+
+       busy = 1;
        GetActualPlacement(shellWidget, &wpNew);
        if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved
-          wpNew.width == wpMain.width && wpNew.height == wpMain.height) // not sized
-           return; // false alarm
+          wpNew.width == wpMain.width && wpNew.height == wpMain.height) { // not sized
+           busy = 0; return; // false alarm
+       }
+       ReSize(&wpNew);
        if(shellUp[EngOutDlg]) CoDrag(shells[EngOutDlg], &wpEngineOutput);
        if(shellUp[HistoryDlg]) CoDrag(shells[HistoryDlg], &wpMoveHistory);
        if(shellUp[EvalGraphDlg]) CoDrag(shells[EvalGraphDlg], &wpEvalGraph);
@@ -2776,6 +1762,7 @@ DragProc ()
        wpMain = wpNew;
        DrawPosition(True, NULL);
        delayedDragID = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other)
+       busy = 0;
 }
 
 
@@ -2784,7 +1771,7 @@ DelayedDrag ()
 {
     if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending
     delayedDragID =
-      XtAppAddTimeOut(appContext, 50, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later
+      XtAppAddTimeOut(appContext, 200, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later
 }
 
 void
@@ -2794,132 +1781,6 @@ EventProc (Widget widget, caddr_t unused, XEvent *event)
        DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other
 }
 
-// [HGM] seekgraph: some low-level drawing routines (by JC, mostly)
-
-static cairo_surface_t *cs; // to keep out of back-end :-(
-
-void DrawSeekAxis( int x, int y, int xTo, int yTo )
-{
-    cairo_t *cr;
-
-    /* get a cairo_t */
-    cr = cairo_create (cs);
-
-    cairo_move_to (cr, x, y);
-    cairo_line_to(cr, xTo, yTo );
-
-    cairo_set_line_width(cr, 2);
-    cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
-    cairo_stroke(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-}
-
-void DrawSeekBackground( int left, int top, int right, int bottom )
-{
-    cairo_t *cr = cairo_create (cs);
-
-    cairo_rectangle (cr, left, top, right-left, bottom-top);
-
-    cairo_set_source_rgba(cr, 0.8, 0.8, 0.4,1.0);
-    cairo_fill(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-}
-
-void DrawSeekText(char *buf, int x, int y)
-{
-    cairo_t *cr = cairo_create (cs);
-
-    cairo_select_font_face (cr, "Sans",
-                           CAIRO_FONT_SLANT_NORMAL,
-                           CAIRO_FONT_WEIGHT_NORMAL);
-
-    cairo_set_font_size (cr, 12.0);
-
-    cairo_move_to (cr, x, y+4);
-    cairo_show_text( cr, buf);
-
-    cairo_set_source_rgba(cr, 0, 0, 0,1.0);
-    cairo_stroke(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-}
-
-void DrawSeekDot(int x, int y, int colorNr)
-{
-    cairo_t *cr = cairo_create (cs);
-    int square = colorNr & 0x80;
-    colorNr &= 0x7F;
-
-    if(square)
-       cairo_rectangle (cr, x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9);
-    else
-       cairo_arc(cr, x, y, squareSize/8, 0.0, 2*M_PI);
-
-    cairo_set_line_width(cr, 2);
-    cairo_set_source_rgba(cr, 0, 0, 0,1.0);
-    cairo_stroke_preserve(cr);
-    switch (colorNr) {
-      case 0: cairo_set_source_rgba(cr, 1.0, 0, 0,1.0);        break;
-      case 1: cairo_set_source_rgba (cr, 0.0, 0.7, 0.2, 1.0); break;
-      default: cairo_set_source_rgba (cr, 1.0, 1.0, 0.0, 1.0); break;
-    }
-    cairo_fill(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-}
-
-void
-DrawSeekOpen ()
-{
-    int boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
-    int boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
-    cs = cairo_xlib_surface_create(xDisplay, xBoardWindow, DefaultVisual(xDisplay, 0), boardWidth, boardHeight);
-}
-
-void
-DrawSeekClose ()
-{
-    cairo_surface_destroy(cs);
-}
-
-void
-DrawGrid()
-{
-  /* draws a grid starting around Nx, Ny squares starting at x,y */
-  int i;
-  cairo_t *cr;
-
-  DrawSeekOpen();
-  /* get a cairo_t */
-  cr = cairo_create (cs);
-
-  cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
-  cairo_set_line_width (cr, lineGap);
-
-  /* TODO: use appdata colors */
-  cairo_set_source_rgba (cr, 0, 0, 0, 1.0);
-
-  /* lines in X */
-  for (i = 0; i < BOARD_WIDTH + BOARD_HEIGHT + 2; i++)
-    {
-      cairo_move_to (cr, gridSegments[i].x1, gridSegments[i].y1);
-      cairo_line_to (cr, gridSegments[i].x2, gridSegments[i].y2);
-      cairo_stroke (cr);
-    }
-
-  /* free memory */
-  cairo_destroy (cr);
-  DrawSeekClose();
-
-  return;
-}
-
 /*
  * event handler for redrawing the board
  */
@@ -3041,7 +1902,7 @@ ModeHighlight ()
     /* Maybe all the enables should be handled here, not just this one */
     EnableNamedMenuItem("Mode.Training", gameMode == Training || gameMode == PlayFromGameFile);
 
-    DisplayLogos(optList[W_WHITE-1].handle, optList[W_BLACK+1].handle);
+    DisplayLogos(&optList[W_WHITE-1], &optList[W_BLACK+1]);
 }
 
 
@@ -3620,144 +2481,6 @@ RemoveInputSource (InputSourceRef isr)
     is->xid = 0;
 }
 
-/****  Animation code by Hugh Fisher, DCS, ANU. ****/
-
-/*     Masks for XPM pieces. Black and white pieces can have
-       different shapes, but in the interest of retaining my
-       sanity pieces must have the same outline on both light
-       and dark squares, and all pieces must use the same
-       background square colors/images.                */
-
-static int xpmDone = 0;
-static Pixmap animBufs[3*NrOfAnims]; // newBuf, saveBuf
-static GC animGCs[3*NrOfAnims]; // blitGC, pieceGC, outlineGC;
-
-static void
-CreateAnimMasks (int pieceDepth)
-{
-  ChessSquare   piece;
-  Pixmap       buf;
-  GC           bufGC, maskGC;
-  int          kind, n;
-  unsigned long        plane;
-  XGCValues    values;
-
-  /* Need a bitmap just to get a GC with right depth */
-  buf = XCreatePixmap(xDisplay, xBoardWindow,
-                       8, 8, 1);
-  values.foreground = 1;
-  values.background = 0;
-  /* Don't use XtGetGC, not read only */
-  maskGC = XCreateGC(xDisplay, buf,
-                   GCForeground | GCBackground, &values);
-  XFreePixmap(xDisplay, buf);
-
-  buf = XCreatePixmap(xDisplay, xBoardWindow,
-                     squareSize, squareSize, pieceDepth);
-  values.foreground = XBlackPixel(xDisplay, xScreen);
-  values.background = XWhitePixel(xDisplay, xScreen);
-  bufGC = XCreateGC(xDisplay, buf,
-                   GCForeground | GCBackground, &values);
-
-  for (piece = WhitePawn; piece <= BlackKing; piece++) {
-    /* Begin with empty mask */
-    if(!xpmDone) // [HGM] pieces: keep using existing
-    xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
-                                squareSize, squareSize, 1);
-    XSetFunction(xDisplay, maskGC, GXclear);
-    XFillRectangle(xDisplay, xpmMask[piece], maskGC,
-                  0, 0, squareSize, squareSize);
-
-    /* Take a copy of the piece */
-    if (White(piece))
-      kind = 0;
-    else
-      kind = 2;
-    XSetFunction(xDisplay, bufGC, GXcopy);
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
-             buf, bufGC,
-             0, 0, squareSize, squareSize, 0, 0);
-
-    /* XOR the background (light) over the piece */
-    XSetFunction(xDisplay, bufGC, GXxor);
-    if (useImageSqs)
-      XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
-               0, 0, squareSize, squareSize, 0, 0);
-    else {
-      XSetForeground(xDisplay, bufGC, lightSquareColor);
-      XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
-    }
-
-    /* We now have an inverted piece image with the background
-       erased. Construct mask by just selecting all the non-zero
-       pixels - no need to reconstruct the original image.     */
-    XSetFunction(xDisplay, maskGC, GXor);
-    plane = 1;
-    /* Might be quicker to download an XImage and create bitmap
-       data from it rather than this N copies per piece, but it
-       only takes a fraction of a second and there is a much
-       longer delay for loading the pieces.            */
-    for (n = 0; n < pieceDepth; n ++) {
-      XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
-                0, 0, squareSize, squareSize,
-                0, 0, plane);
-      plane = plane << 1;
-    }
-  }
-  /* Clean up */
-  XFreePixmap(xDisplay, buf);
-  XFreeGC(xDisplay, bufGC);
-  XFreeGC(xDisplay, maskGC);
-}
-
-static void
-InitAnimState (AnimNr anr, XWindowAttributes *info)
-{
-  XtGCMask  mask;
-  XGCValues values;
-
-  /* Each buffer is square size, same depth as window */
-  animBufs[anr+4] = xBoardWindow;
-  animBufs[anr+2] = XCreatePixmap(xDisplay, xBoardWindow,
-                       squareSize, squareSize, info->depth);
-  animBufs[anr] = XCreatePixmap(xDisplay, xBoardWindow,
-                       squareSize, squareSize, info->depth);
-
-  /* Create a plain GC for blitting */
-  mask = GCForeground | GCBackground | GCFunction |
-         GCPlaneMask | GCGraphicsExposures;
-  values.foreground = XBlackPixel(xDisplay, xScreen);
-  values.background = XWhitePixel(xDisplay, xScreen);
-  values.function   = GXcopy;
-  values.plane_mask = AllPlanes;
-  values.graphics_exposures = False;
-  animGCs[anr] = XCreateGC(xDisplay, xBoardWindow, mask, &values);
-
-  /* Piece will be copied from an existing context at
-     the start of each new animation/drag. */
-  animGCs[anr+2] = XCreateGC(xDisplay, xBoardWindow, 0, &values);
-
-  /* Outline will be a read-only copy of an existing */
-  animGCs[anr+4] = None;
-}
-
-void
-CreateAnimVars ()
-{
-  XWindowAttributes info;
-
-  if (xpmDone && gameInfo.variant == oldVariant) return;
-  if(xpmDone) oldVariant = gameInfo.variant; // first time pieces might not be created yet
-  XGetWindowAttributes(xDisplay, xBoardWindow, &info);
-
-  InitAnimState(Game, &info);
-  InitAnimState(Player, &info);
-
-  /* For XPM pieces, we need bitmaps to use as masks. */
-  if (useImages)
-    CreateAnimMasks(info.depth), xpmDone = 1;
-}
-
 #ifndef HAVE_USLEEP
 
 static Boolean frameWaiting;
@@ -3804,132 +2527,6 @@ FrameDelay (int time)
 
 #endif
 
-static void
-SelectGCMask (ChessSquare piece, GC *clip, GC *outline, Pixmap *mask)
-{
-  GC source;
-
-  /* Bitmap for piece being moved. */
-  if (appData.monoMode) {
-      *mask = *pieceToSolid(piece);
-  } else if (useImages) {
-#if HAVE_LIBXPM
-      *mask = xpmMask[piece];
-#else
-      *mask = ximMaskPm[piece];
-#endif
-  } else {
-      *mask = *pieceToSolid(piece);
-  }
-
-  /* GC for piece being moved. Square color doesn't matter, but
-     since it gets modified we make a copy of the original. */
-  if (White(piece)) {
-    if (appData.monoMode)
-      source = bwPieceGC;
-    else
-      source = wlPieceGC;
-  } else {
-    if (appData.monoMode)
-      source = wbPieceGC;
-    else
-      source = blPieceGC;
-  }
-  XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
-
-  /* Outline only used in mono mode and is not modified */
-  if (White(piece))
-    *outline = bwPieceGC;
-  else
-    *outline = wbPieceGC;
-}
-
-static void
-OverlayPiece (ChessSquare piece, GC clip, GC outline,  Drawable dest)
-{
-  int  kind;
-
-  if (!useImages) {
-    /* Draw solid rectangle which will be clipped to shape of piece */
-    XFillRectangle(xDisplay, dest, clip,
-                  0, 0, squareSize, squareSize);
-    if (appData.monoMode)
-      /* Also draw outline in contrasting color for black
-        on black / white on white cases                */
-      XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
-                0, 0, squareSize, squareSize, 0, 0, 1);
-  } else {
-    /* Copy the piece */
-    if (White(piece))
-      kind = 0;
-    else
-      kind = 2;
-    if(appData.upsideDown && flipView) kind ^= 2;
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
-             dest, clip,
-             0, 0, squareSize, squareSize,
-             0, 0);
-  }
-}
-
-void
-InsertPiece (AnimNr anr, ChessSquare piece)
-{
-  OverlayPiece(piece, animGCs[anr+2], animGCs[anr+4], animBufs[anr]);
-}
-
-void
-DrawBlank (AnimNr anr, int x, int y, int startColor)
-{
-    BlankSquare(x, y, startColor, EmptySquare, animBufs[anr+2], 0);
-}
-
-void CopyRectangle (AnimNr anr, int srcBuf, int destBuf,
-                int srcX, int srcY, int width, int height, int destX, int destY)
-{
-    XCopyArea(xDisplay, animBufs[anr+srcBuf], animBufs[anr+destBuf], animGCs[anr],
-               srcX, srcY, width, height, destX, destY);
-}
-
-void
-SetDragPiece (AnimNr anr, ChessSquare piece)
-{
-  Pixmap mask;
-  /* The piece will be drawn using its own bitmap as a matte   */
-  SelectGCMask(piece, &animGCs[anr+2], &animGCs[anr+4], &mask);
-  XSetClipMask(xDisplay, animGCs[anr+2], mask);
-}
-
-/* [AS] Arrow highlighting support */
-
-void DrawPolygon(Pnt arrow[], int nr)
-{   // for now on own surface; eventually this should become a global that is only destroyed on resize
-    cairo_surface_t *boardSurface;
-    cairo_t *cr;
-    int i;
-    int w = lineGap + BOARD_WIDTH * (squareSize + lineGap);
-    int h = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
-    boardSurface = cairo_xlib_surface_create(xDisplay, xBoardWindow, DefaultVisual(xDisplay, 0), w, h);
-    cr = cairo_create (boardSurface);
-    cairo_move_to (cr, arrow[nr-1].x, arrow[nr-1].y);
-    for (i=0;i<nr;i++) {
-        cairo_line_to(cr, arrow[i].x, arrow[i].y);
-    }
-    if(appData.monoMode) { // should we always outline arrow?
-        cairo_line_to(cr, arrow[0].x, arrow[0].y);
-        cairo_set_line_width(cr, 2);
-        cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
-        cairo_stroke_preserve(cr);
-    }
-    cairo_set_line_width(cr, 2);
-    cairo_set_source_rgba(cr, 1, 1, 0, 1.0);
-    cairo_fill(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-    cairo_surface_destroy (boardSurface);
-}
-
 static void
 LoadLogo (ChessProgramState *cps, int n, Boolean ics)
 {
@@ -3953,7 +2550,7 @@ UpdateLogos (int displ)
     if(optList[W_WHITE-1].handle == NULL) return;
     LoadLogo(&first, 0, 0);
     LoadLogo(&second, 1, appData.icsActive);
-    if(displ) DisplayLogos(optList[W_WHITE-1].handle, optList[W_BLACK+1].handle);
+    if(displ) DisplayLogos(&optList[W_WHITE-1], &optList[W_BLACK+1]);
     return;
 }