Transfer most available gtk-xt code to xoptions.c
[xboard.git] / xboard.c
index 99af048..2857317 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -63,6 +63,7 @@
 #include <math.h>
 #include <cairo/cairo.h>
 #include <cairo/cairo-xlib.h>
+#include <gtk/gtk.h>
 
 #if !OMIT_SOCKETS
 # if HAVE_SYS_SOCKET_H
@@ -185,11 +186,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"
@@ -201,17 +200,17 @@ extern char *getenv();
 #include "backendz.h"
 #include "moves.h"
 #include "xboard.h"
+#include "xboard2.h"
 #include "childio.h"
 #include "xgamelist.h"
 #include "xhistory.h"
-#include "xevalgraph.h"
-#include "xedittags.h"
 #include "menus.h"
 #include "board.h"
 #include "dialogs.h"
 #include "engineoutput.h"
 #include "usystem.h"
 #include "gettext.h"
+#include "draw.h"
 
 
 #ifdef __EMX__
@@ -233,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));
@@ -248,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,19 +272,13 @@ int CopyMemoProc P(());
 */
 int xtVersion = XtSpecificationRelease;
 
+#ifdef TODO_GTK
 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
@@ -302,6 +288,12 @@ XFontStruct *clockFontStruct;
 Font coordFontID, countFontID;
 XFontStruct *coordFontStruct, *countFontStruct;
 XtAppContext appContext;
+#else
+void *shellWidget, *formWidget, *boardWidget, *titleWidget, *dropMenu, *menuBarWidget;
+void *appContext;
+GtkWidget       *mainwindow;
+#endif
+Option *optList; // contains all widgets of main window
 char *layoutName;
 
 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
@@ -336,30 +328,19 @@ WindowPlacement wpEngineOutput;
 WindowPlacement wpGameList;
 WindowPlacement wpTags;
 
+#define INPUT_SOURCE_BUF_SIZE 8192
 
-#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)
+typedef struct {
+    CPKind kind;
+    int fd;
+    int lineByLine;
+    char *unused;
+    InputCallback func;
+    XtInputId xid;
+    char buf[INPUT_SOURCE_BUF_SIZE];
+    VOIDSTAR closure;
+} InputSource;
 
-/* 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
@@ -381,6 +362,7 @@ DropMenuEnables dmEnables[] = {
     { 'Q', "Queen" }
 };
 
+#ifdef TODO_GTK
 Arg shellArgs[] = {
     { XtNwidth, 0 },
     { XtNheight, 0 },
@@ -426,6 +408,7 @@ XtActionsRec boardActions[] = {
     { "WheelProc", WheelProc },
     { "TabProc", TabProc },
 };
+#endif
 
 char globalTranslations[] =
   ":<Key>F9: MenuItem(Actions.Resign) \n \
@@ -506,11 +489,12 @@ char ICSInputTranslations[] =
 //             as the widget is destroyed before the up-click can call extend-end
 char commentTranslations[] = "<Btn3Down>: extend-end() select-start() CommentClick() \n";
 
+#ifdef TODO_GTK
 String xboardResources[] = {
     "*Error*translations: #override\\n <Key>Return: ErrorPopDown()",
     NULL
   };
-
+#endif
 
 /* Max possible square size */
 #define MAXSQSIZE 256
@@ -637,6 +621,7 @@ Warning: No DIR structure found on this system --\n\
 #endif /* HAVE_DIR_STRUCT */
 
 
+#ifdef TODO_GTK
 /* Arrange to catch delete-window events */
 Atom wm_delete_window;
 void
@@ -647,15 +632,12 @@ CatchDeleteWindow (Widget w, String procname)
   snprintf(buf, sizeof(buf), "<Message>WM_PROTOCOLS: %s() \n", procname);
   XtAugmentTranslations(w, XtParseTranslationTable(buf));
 }
+#endif
 
 void
 BoardToTop ()
 {
-  Arg args[16];
-  XtSetArg(args[0], XtNiconic, False);
-  XtSetValues(shellWidget, args, 1);
-
-  XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
+  gtk_window_present(GTK_WINDOW(mainwindow));
 }
 
 //---------------------------------------------------------------------------------------------------------
@@ -833,6 +815,7 @@ ParseCommPortSettings (char *s)
 
 int frameX, frameY;
 
+#ifdef TODO_GTK
 void
 GetActualPlacement (Widget wg, WindowPlacement *wp)
 {
@@ -851,11 +834,13 @@ GetActualPlacement (Widget wg, WindowPlacement *wp)
   wp->width = winAt.width;
   frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch
 }
+#endif
 
 void
 GetWindowCoords ()
 { // wrapper to shield use of window handles from back-end (make addressible by number?)
   // In XBoard this will have to wait until awareness of window parameters is implemented
+#ifdef TODO_GTK
   GetActualPlacement(shellWidget, &wpMain);
   if(shellUp[EngOutDlg]) GetActualPlacement(shells[EngOutDlg], &wpEngineOutput);
   if(shellUp[HistoryDlg]) GetActualPlacement(shells[HistoryDlg], &wpMoveHistory);
@@ -863,6 +848,7 @@ GetWindowCoords ()
   if(shellUp[GameListDlg]) GetActualPlacement(shells[GameListDlg], &wpGameList);
   if(shellUp[CommentDlg]) GetActualPlacement(shells[CommentDlg], &wpComment);
   if(shellUp[TagsDlg]) GetActualPlacement(shells[TagsDlg], &wpTags);
+#endif
 }
 
 void
@@ -879,18 +865,11 @@ EnsureOnScreen (int *x, int *y, int minX, int minY)
 int
 MainWindowUp ()
 { // [HGM] args: allows testing if main window is realized from back-end
+#ifdef TODO_GTK
   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;
+#else
+  return 0;
+#endif
 }
 
 void
@@ -921,124 +900,23 @@ 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)
+{
+#ifdef TODO_GTK
+    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;
 }
 
+#ifdef TODO_GTK
 static int
 MakeOneColor (char *name, Pixel *color)
 {
@@ -1056,58 +934,27 @@ MakeOneColor (char *name, Pixel *color)
     }
     return False;
 }
+#endif
 
-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);
+#ifdef TODO_GTK
     if (appData.lowTimeWarning)
        forceMono |= MakeOneColor(appData.lowTimeWarningColor, &lowTimeWarningColor);
     if(appData.dialogColor[0]) MakeOneColor(appData.dialogColor, &dialogColor);
     if(appData.buttonColor[0]) MakeOneColor(appData.buttonColor, &buttonColor);
-
-    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();
+    return forceMono;
 }
 
 void
 InitializeFonts (int clockFontPxlSize, int coordFontPxlSize, int fontPxlSize)
 {   // detervtomine what fonts to use, and create them
+#ifdef TODO_GTK
     XrmValue vTo;
     XrmDatabase xdb;
 
@@ -1158,6 +1005,7 @@ InitializeFonts (int clockFontPxlSize, int coordFontPxlSize, int fontPxlSize)
 #else
     XrmPutStringResource(&xdb, "*font", appData.font);
 #endif
+#endif
 }
 
 char *
@@ -1221,11 +1069,15 @@ int
 main (int argc, char **argv)
 {
     int i, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
+#ifdef TODO_GTK
     XSetWindowAttributes window_attributes;
     Arg args[16];
+#else
+#endif
     Dimension boardWidth, boardHeight, w, h;
     char *p;
     int forceMono = False;
+    GError *gtkerror=NULL;
 
     srandom(time(0)); // [HGM] book: make random truly random
 
@@ -1243,6 +1095,9 @@ main (int argc, char **argv)
        exit(0);
     }
 
+    /* set up GTK */
+    gtk_init (&argc, &argv);
+
     programName = strrchr(argv[0], '/');
     if (programName == NULL)
       programName = argv[0];
@@ -1250,10 +1105,9 @@ main (int argc, char **argv)
       programName++;
 
 #ifdef ENABLE_NLS
-    XtSetLanguageProc(NULL, NULL, NULL);
-    if (appData.debugMode) {
-      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
-    }
+//    if (appData.debugMode) {
+//      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
+//    }
 
     bindtextdomain(PACKAGE, LOCALEDIR);
     textdomain(PACKAGE);
@@ -1300,6 +1154,12 @@ 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   )
@@ -1314,6 +1174,17 @@ main (int argc, char **argv)
        gameInfo.variant = StringToVariant(appData.variant);
        InitPosition(FALSE);
 
+#ifdef TODO_GTK
+    /* GTK */
+    builder = gtk_builder_new();
+    filename = get_glade_filename ("mainboard.glade");
+    if(! gtk_builder_add_from_file (builder, filename, &gtkerror) )
+      {
+      if(gtkerror)
+        printf ("Error: %d %s\n",gtkerror->code,gtkerror->message);
+      }
+    mainwindow = GTK_WIDGET(gtk_builder_get_object (builder, "mainwindow"));
+
     shellWidget =
       XtAppInitialize(&appContext, "XBoard", shellOptions,
                      XtNumber(shellOptions),
@@ -1326,6 +1197,7 @@ main (int argc, char **argv)
     xDisplay = XtDisplay(shellWidget);
     xScreen = DefaultScreen(xDisplay);
     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
+#endif
 
     /*
      * determine size, based on supplied or remembered -size, or screen size
@@ -1362,10 +1234,20 @@ main (int argc, char **argv)
     } else {
         SizeDefaults *szd = sizeDefaults;
         if (*appData.boardSize == NULLCHAR) {
+#ifdef TODO_GTK
            while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
                   DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
              szd++;
            }
+#else
+            GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(mainwindow));
+            guint screenwidth = gdk_screen_get_width(screen);
+            guint screenheight = gdk_screen_get_height(screen);
+           while (screenwidth < szd->minScreenSize ||
+                  screenheight < szd->minScreenSize) {
+             szd++;
+           }
+#endif
            if (szd->name == NULL) szd--;
            appData.boardSize = strdup(szd->name); // [HGM] settings: remember name for saving settings
        } else {
@@ -1387,24 +1269,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;
 
@@ -1415,14 +1279,18 @@ XBoard square size (hint): %d\n\
     /*
      * Determine what fonts to use.
      */
+#ifdef TODO_GTK
     InitializeFonts(clockFontPxlSize, coordFontPxlSize, fontPxlSize);
+#endif
 
     /*
      * Detect if there are not enough colors available and adapt.
      */
+#ifdef TODO_GTK
     if (DefaultDepth(xDisplay, xScreen) <= 2) {
       appData.monoMode = True;
     }
+#endif
 
     forceMono = MakeColors();
 
@@ -1433,14 +1301,18 @@ XBoard square size (hint): %d\n\
     }
 
     if (appData.monoMode && appData.debugMode) {
+#ifdef TODO_GTK
        fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
                (unsigned long) XWhitePixel(xDisplay, xScreen),
                (unsigned long) XBlackPixel(xDisplay, xScreen));
+#endif
     }
 
     ParseIcsTextColors();
 
+#ifdef TODO_GTK
     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
+#endif
 
     /*
      * widget hierarchy
@@ -1454,16 +1326,23 @@ XBoard square size (hint): %d\n\
     }
 
     optList = BoardPopUp(squareSize, lineGap, (void*)
+#ifdef TODO_GTK
 #if ENABLE_NLS
                                                &clockFontSet);
 #else
                                                clockFontStruct);
 #endif
+#else
+0);
+#endif
+    InitDrawingHandle(optList + W_BOARD);
+    currBoard        = &optList[W_BOARD];
     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);
+#ifdef TODO_GTK
     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
     XtGetValues(optList[W_WHITE].handle, args, 2);
@@ -1472,9 +1351,12 @@ XBoard square size (hint): %d\n\
       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
       XtGetValues(optList[W_PAUSE].handle, args, 2);
     }
+#endif
     AppendEnginesToMenu(appData.recentEngineList);
 
+#ifdef TODO_GTK
     xBoardWindow = XtWindow(boardWidget);
+#endif
 
     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
     //       not need to go into InitDrawingSizes().
@@ -1482,13 +1364,16 @@ XBoard square size (hint): %d\n\
     /*
      * Create X checkmark bitmap and initialize option menu checks.
      */
+#ifdef TODO_GTK
     ReadBitmap(&xMarkPixmap, "checkmark.bm",
               checkmark_bits, checkmark_width, checkmark_height);
+#endif
     InitMenuMarkers();
 
     /*
      * Create an icon.
      */
+#ifdef TODO_GTK
     ReadBitmap(&wIconPixmap, "icon_white.bm",
               icon_white_bits, icon_white_width, icon_white_height);
     ReadBitmap(&bIconPixmap, "icon_black.bm",
@@ -1497,31 +1382,37 @@ XBoard square size (hint): %d\n\
     i = 0;
     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
     XtSetValues(shellWidget, args, i);
+#endif
 
     /*
      * Create a cursor for the board widget.
      */
+#ifdef TODO_GTK
     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
     XChangeWindowAttributes(xDisplay, xBoardWindow,
                            CWCursor, &window_attributes);
+#endif
 
     /*
      * Inhibit shell resizing.
      */
+#ifdef TODO_GTK
     shellArgs[0].value = (XtArgVal) &w;
     shellArgs[1].value = (XtArgVal) &h;
     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);
+#endif
     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
     marginH =  h - boardHeight;
 
+#ifdef TODO_GTK
     CatchDeleteWindow(shellWidget, "QuitProc");
+#endif
 
-    CreateGCs(False);
-    CreateGrid();
     CreateAnyPieces();
+    CreateGrid();
 
     if(appData.logoSize)
     {   // locate and read user logo
@@ -1533,6 +1424,7 @@ XBoard square size (hint): %d\n\
     if (appData.animate || appData.animateDragging)
       CreateAnimVars();
 
+#ifdef TODO_GTK
     XtAugmentTranslations(formWidget,
                          XtParseTranslationTable(globalTranslations));
 
@@ -1540,6 +1432,7 @@ XBoard square size (hint): %d\n\
                      (XtEventHandler) MoveTypeInProc, NULL);
     XtAddEventHandler(shellWidget, StructureNotifyMask, False,
                      (XtEventHandler) EventProc, NULL);
+#endif
 
     /* [AS] Restore layout */
     if( wpMoveHistory.visible ) {
@@ -1579,9 +1472,13 @@ XBoard square size (hint): %d\n\
     InitPosition(TRUE);
     UpdateLogos(TRUE);
 //    XtSetKeyboardFocus(shellWidget, formWidget);
+#ifdef TODO_GTK
     XSetInputFocus(xDisplay, XtWindow(formWidget), RevertToPointerRoot, CurrentTime);
+#endif
+
+    /* check for GTK events and process them */
+    gtk_main();
 
-    XtAppMainLoop(appContext);
     if (appData.debugMode) fclose(debugFP); // [DM] debug
     return 0;
 }
@@ -1675,6 +1572,7 @@ InsertPxlSize (char *pattern, int targetPxlSize)
     return base_fnt_lst;
 }
 
+#ifdef TODO_GTK
 XFontSet
 CreateFontSet (char *base_fnt_lst)
 {
@@ -1709,6 +1607,7 @@ CreateFontSet (char *base_fnt_lst)
     }
     return fntSet;
 }
+#endif
 #else // not ENABLE_NLS
 /*
  * Find a font that matches "pattern" that is as close as
@@ -1725,6 +1624,7 @@ FindFont (char *pattern, int targetPxlSize)
     char **fonts, *p, *best, *scalable, *scalableTail;
     int i, j, nfonts, minerr, err, pxlSize;
 
+#ifdef TODO_GTK
     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
     if (nfonts < 1) {
        fprintf(stderr, _("%s: no fonts match pattern %s\n"),
@@ -1773,579 +1673,19 @@ FindFont (char *pattern, int targetPxlSize)
                pattern, targetPxlSize, p);
     }
     XFreeFontNames(fonts);
-    return p;
-}
 #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 */
+    return p;
 }
 #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) {
+#ifdef TODO_GTK
        *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)
-{
-    MenuItem *item = MenuNameToItem(menuRef);
-
-    if(item) {
-       Arg args[2];
-       XtSetArg(args[0], XtNleftBitmap, state ? xMarkPixmap : None);
-       XtSetValues(item->handle, args, 1);
+#endif
     }
 }
 
@@ -2354,13 +1694,17 @@ EnableNamedMenuItem (char *menuRef, int state)
 {
     MenuItem *item = MenuNameToItem(menuRef);
 
+#ifdef TODO_GTK
     if(item) XtSetSensitive(item->handle, state);
+#endif
 }
 
 void
 EnableButtonBar (int state)
 {
+#ifdef TODO_GTK
     XtSetSensitive(optList[W_BUTTON].handle, state);
+#endif
 }
 
 
@@ -2373,6 +1717,7 @@ SetMenuEnables (Enables *enab)
   }
 }
 
+#ifdef TODO_GTK
 void
 KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {   // [HGM] new method of key binding: specify MenuItem(FlipView) in stead of FlipViewProc in translation string
@@ -2381,22 +1726,28 @@ KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
     item = MenuNameToItem(prms[0]);
     if(item) ((MenuProc *) item->proc) ();
 }
+#endif
 
+#ifdef TODO_GTK
 static void
 MenuEngineSelect (Widget w, caddr_t addr, caddr_t index)
 {
     RecentEngineEvent((int) (intptr_t) addr);
 }
+#endif
 
 void
 AppendMenuItem (char *msg, int n)
 {
+#ifdef TODO_GTK
     CreateMenuItem((Widget) optList[W_ENGIN].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
+#endif
 }
 
 void
 SetupDropMenu ()
 {
+#ifdef TODO_GTK
     int i, j, count;
     char label[32];
     Arg args[16];
@@ -2417,316 +1768,22 @@ SetupDropMenu ()
        XtSetArg(args[j], XtNlabel, label); j++;
        XtSetValues(entry, args, j);
     }
+#endif
 }
 
-
 static void
 do_flash_delay (unsigned long msec)
 {
     TimeDelay(msec);
 }
 
-static cairo_surface_t *cs; // to keep out of back-end :-(
-
-void
-DrawBorder (int x, int y, int type)
-{
-    cairo_t *cr;
-    DrawSeekOpen();
-
-    cr = cairo_create(cs);
-    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-    cairo_rectangle(cr, x, y, squareSize+lineGap, squareSize+lineGap);
-    SetPen(cr, lineGap, type == 1 ? appData.highlightSquareColor : appData.premoveHighlightColor, 0);
-    cairo_stroke(cr);
-
-    DrawSeekClose();
-}
-
-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;
-}
-
-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)
-{
-       cairo_t *cr;
-       DrawSeekOpen();
-       cr = cairo_create(cs);
-       cairo_arc(cr, x+r/2, y+r/2, r/2, 0.0, 2*M_PI);
-       if(appData.monoMode) {
-           SetPen(cr, 2, marker == 2 ? "#000000" : "#FFFFFF", 0);
-           cairo_stroke_preserve(cr);
-           SetPen(cr, 2, marker == 2 ? "#FFFFFF" : "#000000", 0);
-       } else {
-           SetPen(cr, 2, marker == 2 ? "#FF0000" : "#FFFF00", 0);
-       }
-       cairo_fill(cr);
-       cairo_stroke(cr);
-
-       cairo_destroy(cr);
-       DrawSeekClose();
-}
-
-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)
 {
+#ifdef TODO_GTK
        XSync(xDisplay, False);
        if(flash_delay) do_flash_delay(flash_delay);
+#endif
 }
 
 double
@@ -2739,6 +1796,7 @@ Fraction (int x, int start, int stop)
 
 static WindowPlacement wpNew;
 
+#ifdef TODO_GTK
 void
 CoDrag (Widget sh, WindowPlacement *wp)
 {
@@ -2769,20 +1827,51 @@ CoDrag (Widget sh, WindowPlacement *wp)
     wp->y += wpNew.y - wpMain.y;
     if(touch == 1) wp->x += wpNew.width - wpMain.width; else
     if(touch == 3) wp->y += wpNew.height - wpMain.height;
+#ifdef TODO_GTK
     XtSetArg(args[j], XtNx, wp->x); j++;
     XtSetArg(args[j], XtNy, wp->y); j++;
     XtSetValues(sh, args, j);
+#endif
 }
 
+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;
+}
+
+#ifdef TODO_GTK
 static XtIntervalId delayedDragID = 0;
+#else
+static int delayedDragID = 0;
+#endif
 
 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);
@@ -2790,160 +1879,27 @@ 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;
 }
-
+#endif
 
 void
 DelayedDrag ()
 {
+#ifdef TODO_GTK
     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
+#endif
 }
 
 void
 EventProc (Widget widget, caddr_t unused, XEvent *event)
 {
+#ifdef TODO_GTK
     if(XtIsRealized(widget) && event->type == ConfigureNotify || appData.useStickyWindows)
        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)
-
-float
-Color (char *col, int n)
-{
-  int c;
-  sscanf(col, "#%x", &c);
-  c = c >> 4*n & 255;
-  return c/255.;
-}
-
-void
-SetPen (cairo_t *cr, float w, char *col, int dash)
-{
-  static const double dotted[] = {4.0, 4.0};
-  static int len  = sizeof(dotted) / sizeof(dotted[0]);
-  cairo_set_line_width (cr, w);
-  cairo_set_source_rgba (cr, Color(col, 4), Color(col, 2), Color(col, 0), 1.0);
-  if(dash) cairo_set_dash (cr, dotted, len, 0.0);
-}
-
-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 );
-
-    SetPen(cr, 2, "#000000", 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);
-
-    SetPen(cr, 2, "#000000", 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);
-  SetPen(cr, lineGap, "#000000", 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;
+#endif
 }
 
 /*
@@ -2956,17 +1912,20 @@ DrawPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 
 
+#ifdef TODO_GTK
 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));
 }
+#endif
 
 static int savedIndex;  /* gross that this is global */
 
 void
 CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams)
 {
+#ifdef TODO_GTK
        String val;
        XawTextPosition index, dummy;
        Arg arg;
@@ -2977,6 +1936,7 @@ CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams)
        ReplaceComment(savedIndex, val);
        if(savedIndex != currentMove) ToNrEvent(savedIndex);
        LoadVariation( index, val ); // [HGM] also does the actual moving to it, now
+#endif
 }
 
 void
@@ -3018,17 +1978,20 @@ void
 ThawUI ()
 {
   if (!frozen) return;
+#ifdef TODO_GTK
   XtRemoveGrab(optList[W_MESSG].handle);
+#endif
   frozen = 0;
 }
 
 void
 ModeHighlight ()
 {
-    Arg args[16];
     static int oldPausing = FALSE;
     static GameMode oldmode = (GameMode) -1;
     char *wname;
+#ifdef TODO_GTK
+    Arg args[16];
 
     if (!boardWidget || !XtIsRealized(boardWidget)) return;
 
@@ -3052,6 +2015,7 @@ ModeHighlight ()
          XtSetValues(optList[W_PAUSE].handle, args, 2);
        }
     }
+#endif
 
     wname = ModeToWidgetName(oldmode);
     if (wname != NULL) {
@@ -3067,7 +2031,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]);
 }
 
 
@@ -3075,6 +2039,7 @@ ModeHighlight ()
  * Button/menu procedures
  */
 
+#ifdef TODO_GTK
 /* this variable is shared between CopyPositionProc and SendPositionSelection */
 char *selected_fen_position=NULL;
 
@@ -3141,6 +2106,7 @@ SendPositionSelection (Widget w, Atom *selection, Atom *target,
     return False;
   }
 }
+#endif
 
 /* note: when called from menu all parameters are NULL, so no clue what the
  * Widget which was clicked on was, or what the click event was
@@ -3148,6 +2114,7 @@ SendPositionSelection (Widget w, Atom *selection, Atom *target,
 void
 CopySomething (char *src)
 {
+#ifdef TODO_GTK
     selected_fen_position = src;
     /*
      * Set both PRIMARY (the selection) and CLIPBOARD, since we don't
@@ -3164,8 +2131,10 @@ CopySomething (char *src)
                   SendPositionSelection,
                   NULL/* lose_ownership_proc */ ,
                   NULL/* transfer_done_proc */);
+#endif
 }
 
+#ifdef TODO_GTK
 /* function called when the data to Paste is ready */
 static void
 PastePositionCB (Widget w, XtPointer client_data, Atom *selection,
@@ -3177,12 +2146,14 @@ PastePositionCB (Widget w, XtPointer client_data, Atom *selection,
   EditPositionPasteFEN(fenstr);
   XtFree(value);
 }
+#endif
 
 /* called when Paste Position button is pressed,
  * all parameters will be NULL */
 void
 PastePositionProc ()
 {
+#ifdef TODO_GTK
     XtGetSelectionValue(menuBarWidget,
       appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
       /* (XtSelectionCallbackProc) */ PastePositionCB,
@@ -3194,8 +2165,10 @@ PastePositionProc ()
       CurrentTime
     );
     return;
+#endif
 }
 
+#ifdef TODO_GTK
 /* note: when called from menu all parameters are NULL, so no clue what the
  * Widget which was clicked on was, or what the click event was
  */
@@ -3218,12 +2191,14 @@ PasteGameCB (Widget w, XtPointer client_data, Atom *selection,
   XtFree(value);
   LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
 }
+#endif
 
 /* called when Paste Game button is pressed,
  * all parameters will be NULL */
 void
 PasteGameProc ()
 {
+#ifdef TODO_GTK
     XtGetSelectionValue(menuBarWidget,
       appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
       /* (XtSelectionCallbackProc) */ PasteGameCB,
@@ -3235,6 +2210,7 @@ PasteGameProc ()
       CurrentTime
     );
     return;
+#endif
 }
 
 
@@ -3247,29 +2223,34 @@ QuitWrapper (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 int
 ShiftKeys ()
 {   // bassic primitive for determining if modifier keys are pressed
+    int i,j,  k=0;
+#ifdef TODO_GTK
     long int codes[] = { XK_Meta_L, XK_Meta_R, XK_Control_L, XK_Control_R, XK_Shift_L, XK_Shift_R };
     char keys[32];
-    int i,j,  k=0;
     XQueryKeymap(xDisplay,keys);
     for(i=0; i<6; i++) {
        k <<= 1;
        j = XKeysymToKeycode(xDisplay, codes[i]);
        k += ( (keys[j>>3]&1<<(j&7)) != 0 );
     }
+#endif
     return k;
 }
 
 static void
 MoveTypeInProc (Widget widget, caddr_t unused, XEvent *event)
 {
+#ifdef TODO_GTK
     char buf[10];
     KeySym sym;
     int n = XLookupString(&(event->xkey), buf, 10, &sym, NULL);
     if ( n == 1 && *buf >= 32 // printable
         && !(ShiftKeys() & 0x3C) // no Alt, Ctrl
        ) BoxAutoPopUp (buf);
+#endif
 }
 
+#ifdef TODO_GTK
 static void
 UpKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {   // [HGM] input: let up-arrow recall previous line from history
@@ -3288,6 +2269,7 @@ EnterKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
     IcsKey(0);
 }
 
+
 void
 TempBackwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {
@@ -3325,16 +2307,20 @@ ManInner (Widget w, XEvent *event, String *prms, Cardinal *nprms)
     snprintf(buf, sizeof(buf), "xterm -e man %s &", name);
     system(buf);
 }
+#endif
 
 void
 ManProc ()
 {   // called from menu
+#ifdef TODO_GTK
     ManInner(NULL, NULL, NULL, NULL);
+#endif
 }
 
 void
 SetWindowTitle (char *text, char *title, char *icon)
 {
+#ifdef TODO_GTK
     Arg args[16];
     int i;
     if (appData.titleInWindow) {
@@ -3347,6 +2333,7 @@ SetWindowTitle (char *text, char *title, char *icon)
     XtSetArg(args[i], XtNtitle, (XtArgVal) title);      i++;
     XtSetValues(shellWidget, args, i);
     XSync(xDisplay, False);
+#endif
 }
 
 
@@ -3359,6 +2346,7 @@ NullXErrorCheck (Display *dpy, XErrorEvent *error_event)
 void
 DisplayIcsInteractionTitle (String message)
 {
+#ifdef TODO_GTK
   if (oldICSInteractionTitle == NULL) {
     /* Magic to find the old window title, adapted from vim */
     char *wina = getenv("WINDOWID");
@@ -3383,146 +2371,14 @@ DisplayIcsInteractionTitle (String message)
   }
   printf("\033]0;%s\007", message);
   fflush(stdout);
+#endif
 }
 
 
-XtIntervalId delayedEventTimerXID = 0;
-DelayedEventCallback delayedEventCallback = 0;
-
-void
-FireDelayedEvent ()
-{
-    delayedEventTimerXID = 0;
-    delayedEventCallback();
-}
-
-void
-ScheduleDelayedEvent (DelayedEventCallback cb, long millisec)
-{
-    if(delayedEventTimerXID && delayedEventCallback == cb)
-       // [HGM] alive: replace, rather than add or flush identical event
-       XtRemoveTimeOut(delayedEventTimerXID);
-    delayedEventCallback = cb;
-    delayedEventTimerXID =
-      XtAppAddTimeOut(appContext, millisec,
-                     (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
-}
-
-DelayedEventCallback
-GetDelayedEvent ()
-{
-  if (delayedEventTimerXID) {
-    return delayedEventCallback;
-  } else {
-    return NULL;
-  }
-}
-
-void
-CancelDelayedEvent ()
-{
-  if (delayedEventTimerXID) {
-    XtRemoveTimeOut(delayedEventTimerXID);
-    delayedEventTimerXID = 0;
-  }
-}
-
-XtIntervalId loadGameTimerXID = 0;
-
-int
-LoadGameTimerRunning ()
-{
-    return loadGameTimerXID != 0;
-}
-
-int
-StopLoadGameTimer ()
-{
-    if (loadGameTimerXID != 0) {
-       XtRemoveTimeOut(loadGameTimerXID);
-       loadGameTimerXID = 0;
-       return TRUE;
-    } else {
-       return FALSE;
-    }
-}
-
-void
-LoadGameTimerCallback (XtPointer arg, XtIntervalId *id)
-{
-    loadGameTimerXID = 0;
-    AutoPlayGameLoop();
-}
-
-void
-StartLoadGameTimer (long millisec)
-{
-    loadGameTimerXID =
-      XtAppAddTimeOut(appContext, millisec,
-                     (XtTimerCallbackProc) LoadGameTimerCallback,
-                     (XtPointer) 0);
-}
-
-XtIntervalId analysisClockXID = 0;
-
-void
-AnalysisClockCallback (XtPointer arg, XtIntervalId *id)
-{
-    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
-         || appData.icsEngineAnalyze) { // [DM]
-       AnalysisPeriodicEvent(0);
-       StartAnalysisClock();
-    }
-}
-
-void
-StartAnalysisClock ()
-{
-    analysisClockXID =
-      XtAppAddTimeOut(appContext, 2000,
-                     (XtTimerCallbackProc) AnalysisClockCallback,
-                     (XtPointer) 0);
-}
-
-XtIntervalId clockTimerXID = 0;
-
-int
-ClockTimerRunning ()
-{
-    return clockTimerXID != 0;
-}
-
-int
-StopClockTimer ()
-{
-    if (clockTimerXID != 0) {
-       XtRemoveTimeOut(clockTimerXID);
-       clockTimerXID = 0;
-       return TRUE;
-    } else {
-       return FALSE;
-    }
-}
-
-void
-ClockTimerCallback (XtPointer arg, XtIntervalId *id)
-{
-    clockTimerXID = 0;
-    DecrementClocks();
-}
-
-void
-StartClockTimer (long millisec)
-{
-    clockTimerXID =
-      XtAppAddTimeOut(appContext, millisec,
-                     (XtTimerCallbackProc) ClockTimerCallback,
-                     (XtPointer) 0);
-}
-
 void
 DisplayTimerLabel (Option *opt, char *color, long timer, int highlight)
 {
+#ifdef TODO_GTK
     char buf[MSG_SIZ];
     Arg args[16];
     Widget w = (Widget) opt->handle;
@@ -3553,13 +2409,17 @@ DisplayTimerLabel (Option *opt, char *color, long timer, int highlight)
     }
 
     XtSetValues(w, args, 3);
+#endif
 }
 
+#ifdef TODO_GTK
 static Pixmap *clockIcons[] = { &wIconPixmap, &bIconPixmap };
+#endif
 
 void
 SetClockIcon (int color)
 {
+#ifdef TODO_GTK
     Arg args[16];
     Pixmap pm = *clockIcons[color];
     if (iconPixmap != pm) {
@@ -3567,8 +2427,10 @@ SetClockIcon (int color)
        XtSetArg(args[0], XtNiconPixmap, iconPixmap);
        XtSetValues(shellWidget, args, 1);
     }
+#endif
 }
 
+#ifdef TODO_GTK
 void
 DoInputCallback (caddr_t closure, int *source, XtInputId *xid)
 {
@@ -3607,10 +2469,12 @@ DoInputCallback (caddr_t closure, int *source, XtInputId *xid)
        (is->func)(is, is->closure, is->buf, count, error);
     }
 }
+#endif
 
 InputSourceRef
 AddInputSource (ProcRef pr, int lineByLine, InputCallback func, VOIDSTAR closure)
 {
+#ifdef TODO_GTK
     InputSource *is;
     ChildProc *cp = (ChildProc *) pr;
 
@@ -3634,154 +2498,21 @@ AddInputSource (ProcRef pr, int lineByLine, InputCallback func, VOIDSTAR closure
                            (XtPointer) is);
     is->closure = closure;
     return (InputSourceRef) is;
+#else
+    return (InputSourceRef) 0;
+#endif
 }
 
 void
 RemoveInputSource (InputSourceRef isr)
 {
+#ifdef TODO_GTK
     InputSource *is = (InputSource *) isr;
 
     if (is->xid == 0) return;
     XtRemoveInput(is->xid);
     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;
+#endif
 }
 
 #ifndef HAVE_USLEEP
@@ -3799,6 +2530,7 @@ FrameAlarm (int sig)
 void
 FrameDelay (int time)
 {
+#ifdef TODO_GTK
   struct itimerval delay;
 
   XSync(xDisplay, False);
@@ -3816,6 +2548,7 @@ FrameDelay (int time)
     delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL, &delay, NULL);
   }
+#endif
 }
 
 #else
@@ -3823,7 +2556,9 @@ FrameDelay (int time)
 void
 FrameDelay (int time)
 {
+#ifdef TODO_GTK
   XSync(xDisplay, False);
+#endif
   if (time > 0)
     usleep(time * 1000);
 }
@@ -3831,130 +2566,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);
-        SetPen(cr, 2, "#000000", 0);
-        cairo_stroke_preserve(cr);
-    }
-    SetPen(cr, 2, appData.highlightSquareColor, 0);
-    cairo_fill(cr);
-
-    /* free memory */
-    cairo_destroy (cr);
-    cairo_surface_destroy (boardSurface);
-}
-
-static void
 LoadLogo (ChessProgramState *cps, int n, Boolean ics)
 {
     char buf[MSG_SIZ], *logoName = buf;
@@ -3977,7 +2588,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;
 }