X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=a42ef8a99dc237878fbc0602a5bd15402f4dcf94;hb=aa694af0138b799c4de3e031d15c2a9be3112b6c;hp=3153450bc6aa8c6c98b2303c82a6ac5dcf5022f6;hpb=bd6d724db6ab9d0ab09e61c5536b2be4d6674ce5;p=xboard.git diff --git a/xboard.c b/xboard.c index 3153450..a42ef8a 100644 --- a/xboard.c +++ b/xboard.c @@ -185,11 +185,9 @@ extern char *getenv(); #if HAVE_LIBXPM #include -#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 +199,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,13 +231,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 CreatePNGPieces 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)); @@ -249,7 +240,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)); @@ -284,16 +274,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 @@ -337,35 +321,19 @@ WindowPlacement wpEngineOutput; WindowPlacement wpGameList; WindowPlacement wpTags; +#define INPUT_SOURCE_BUF_SIZE 8192 + +typedef struct { + CPKind kind; + int fd; + int lineByLine; + char *unused; + InputCallback func; + XtInputId xid; + char buf[INPUT_SOURCE_BUF_SIZE]; + VOIDSTAR closure; +} InputSource; -#define SOLID 0 -#define OUTLINE 1 -Boolean cairoAnimate; -static cairo_surface_t *csBoardWindow, *csBoardBackup, *csDualBoard; -static cairo_surface_t *pngPieceBitmaps[2][(int)BlackPawn]; // scaled pieces as used -static cairo_surface_t *pngPieceBitmaps2[2][(int)BlackPawn+4]; // scaled pieces in store -static cairo_surface_t *pngBoardBitmap[2]; -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 @@ -889,24 +857,6 @@ MainWindowUp () } void -SwitchWindow () -{ - extern Option dualOptions[]; - static Window dual; - Window tmp = xBoardWindow; - cairo_surface_t *cstmp = csBoardWindow; - if(!dual) dual = XtWindow(dualOptions[3].handle); // must be first call - xBoardWindow = dual; // swap them - dual = tmp; - csBoardWindow = csDualBoard; - if(!csDualBoard && cstmp) { - int boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); - int boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); - csBoardWindow = cairo_xlib_surface_create(xDisplay, xBoardWindow, DefaultVisual(xDisplay, 0), boardWidth, boardHeight); - } -} - -void PopUpStartupDialog () { // start menu not implemented in XBoard } @@ -935,151 +885,17 @@ ConvertToLine (int argc, char **argv) //-------------------------------------------------------------------------------------------- void -NewSurfaces () +ResizeBoardWindow (int w, int h, int inhibit) { - // delete surfaces after size becomes invalid, so they will be recreated - if(csBoardWindow) cairo_surface_destroy(csBoardWindow); - if(csBoardBackup) cairo_surface_destroy(csBoardBackup); - if(csDualBoard) cairo_surface_destroy(csDualBoard); - csBoardWindow = csBoardBackup = csDualBoard = NULL; -} - -#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(); - NewSurfaces(); - - /* - * Inhibit shell resizing. - */ - shellArgs[0].value = w = (XtArgVal) boardWidth + marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed... - shellArgs[1].value = h = (XtArgVal) boardHeight + marginH; + 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], cairoAnimate ? 2 : 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]; - } - } - } - for(i=0; i<2; i++) { - int p; - for(p=0; p<=(int)WhiteKing; p++) - pngPieceBitmaps[i][p] = pngPieceBitmaps2[i][p]; // defaults - if(gameInfo.variant == VariantShogi) { - pngPieceBitmaps[i][(int)WhiteCannon] = pngPieceBitmaps2[i][(int)WhiteKing+1]; - pngPieceBitmaps[i][(int)WhiteNightrider] = pngPieceBitmaps2[i][(int)WhiteKing+2]; - pngPieceBitmaps[i][(int)WhiteSilver] = pngPieceBitmaps2[i][(int)WhiteKing+3]; - pngPieceBitmaps[i][(int)WhiteGrasshopper] = pngPieceBitmaps2[i][(int)WhiteKing+4]; - pngPieceBitmaps[i][(int)WhiteQueen] = pngPieceBitmaps2[i][(int)WhiteLance]; - } - if(gameInfo.variant == VariantGothic) { - pngPieceBitmaps[i][(int)WhiteMarshall] = pngPieceBitmaps2[i][(int)WhiteSilver]; - } - if(gameInfo.variant == VariantSChess) { - pngPieceBitmaps[i][(int)WhiteAngel] = pngPieceBitmaps2[i][(int)WhiteFalcon]; - pngPieceBitmaps[i][(int)WhiteMarshall] = pngPieceBitmaps2[i][(int)WhiteAlfil]; - } - } - oldMono = -10; // kludge to force recreation of animation masks - oldVariant = gameInfo.variant; - } -#if HAVE_LIBXPM - if(appData.monoMode != oldMono || cairoAnimate) - CreateAnimVars(); -#endif - oldMono = appData.monoMode; } static int @@ -1100,17 +916,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); @@ -1119,38 +929,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); - } - if (appData.pngDirectory[0] != NULLCHAR) { // for now do in parallel - CreatePNGPieces(); - } -#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 @@ -1433,24 +1211,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; @@ -1505,6 +1265,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; @@ -1554,23 +1316,18 @@ XBoard square size (hint): %d\n\ /* * Inhibit shell resizing. */ - - CreateAnyPieces(); - cairoAnimate = *appData.pngDirectory && useTexture == 3 - && strstr(appData.liteBackTextureFile, ".png") && strstr(appData.darkBackTextureFile, ".png"); - 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; - if(!cairoAnimate) 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); + CreateAnyPieces(); CreateGrid(); if(appData.logoSize) @@ -1828,586 +1585,8 @@ 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; ydepth); - 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(strstr(s, ".png")) { - cairo_surface_t *img = cairo_image_surface_create_from_png (s); - if(img) { - useTexture |= kind + 1; pngBoardBitmap[kind] = img; - textureW[kind] = cairo_image_surface_get_width (img); - textureH[kind] = cairo_image_surface_get_height (img); - } - } else - 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 */ - -char *pngPieceNames[] = // must be in same order as internal piece encoding -{ "Pawn", "Knight", "Bishop", "Rook", "Queen", "Advisor", "Elephant", "Archbishop", "Marshall", "Gold", "Commoner", - "Canon", "Nightrider", "CrownedBishop", "CrownedRook", "Princess", "Chancellor", "Hawk", "Lance", "Cobra", "Unicorn", "King", - "GoldKnight", "GoldLance", "GoldPawn", "GoldSilver", NULL -}; - -void -ScaleOnePiece (char *name, int color, int piece) -{ - int w, h; - char buf[MSG_SIZ]; - cairo_surface_t *img, *cs; - cairo_t *cr; - static cairo_surface_t *pngPieceImages[2][(int)BlackPawn+4]; // png 256 x 256 images - - if((img = pngPieceImages[color][piece]) == NULL) { // if PNG file for this piece was not yet read, read it now and store it - snprintf(buf, MSG_SIZ, "%s/%s%s.png", appData.pngDirectory, color ? "Black" : "White", pngPieceNames[piece]); - pngPieceImages[color][piece] = img = cairo_image_surface_create_from_png (buf); - w = cairo_image_surface_get_width (img); - h = cairo_image_surface_get_height (img); - if(w != 64 || h != 64) { printf("Bad png size %dx%d in %s\n", w, h, buf); exit(1); } - } - // create new bitmap to hold scaled piece image (and remove any old) - if(pngPieceBitmaps2[color][piece]) cairo_surface_destroy (pngPieceBitmaps2[color][piece]); - pngPieceBitmaps2[color][piece] = cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, squareSize, squareSize); - if(piece <= WhiteKing) pngPieceBitmaps[color][piece] = cs; - // scaled copying of the raw png image - cr = cairo_create(cs); - cairo_scale(cr, squareSize/64., squareSize/64.); - cairo_set_source_surface (cr, img, 0, 0); - cairo_paint (cr); - cairo_destroy (cr); -} - -void -CreatePNGPieces () -{ - int p; - - for(p=0; pngPieceNames[p]; p++) { - ScaleOnePiece(pngPieceNames[p], 0, p); - ScaleOnePiece(pngPieceNames[p], 1, p); - } -} - -#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); @@ -2415,44 +1594,6 @@ ReadBitmap (Pixmap *pm, String name, unsigned char bits[], u_int wreq, u_int hre } 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); - } -} - -void EnableNamedMenuItem (char *menuRef, int state) { MenuItem *item = MenuNameToItem(menuRef); @@ -2522,7 +1663,6 @@ SetupDropMenu () } } - static void do_flash_delay (unsigned long msec) { @@ -2530,407 +1670,6 @@ do_flash_delay (unsigned long msec) } void -DoDrawBorder (cairo_surface_t *cs, int x, int y, int type) -{ - cairo_t *cr; - DrawSeekOpen(); - char *col; - - switch(type) { - case 0: col = "#000000"; break; - case 1: col = appData.highlightSquareColor; break; - case 2: col = appData.premoveHighlightColor; break; - } - cr = cairo_create(cs); - cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); - cairo_rectangle(cr, x, y, squareSize+lineGap, squareSize+lineGap); - SetPen(cr, lineGap, col, 0); - cairo_stroke(cr); -} - -void -DrawBorder (int x, int y, int type) -{ - DoDrawBorder(csBoardWindow, x, y, type); - DoDrawBorder(csBoardBackup, x, y, type); -} - -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)) { - if(pngBoardBitmap[color]) { - cairo_t *cr; - if(!fac && !cairoAnimate) return; - DrawSeekOpen(); - cr = cairo_create (fac ? csBoardWindow : (cairo_surface_t *) dest); - cairo_set_source_surface (cr, pngBoardBitmap[color], x*fac - x0, y*fac - y0); - cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); - cairo_rectangle (cr, x*fac, y*fac, squareSize, squareSize); - cairo_fill (cr); - cairo_destroy (cr); - if(fac) { - cr = cairo_create (csBoardBackup); - cairo_set_source_surface (cr, pngBoardBitmap[color], x*fac - x0, y*fac - y0); - cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); - cairo_rectangle (cr, x*fac, y*fac, squareSize, squareSize); - cairo_fill (cr); - cairo_destroy (cr); - } - } else - XCopyArea(xDisplay, xpmBoardBitmap[color], dest, wlPieceGC, x0, y0, - squareSize, squareSize, x*fac, y*fac); - } else - if(csBoardWindow) { - cairo_t *cr = cairo_create (csBoardWindow); - char *col; - switch (color) { - case 0: col = appData.darkSquareColor; break; - case 1: col = appData.lightSquareColor; break; - case 2: col = "#000000"; break; - } - SetPen(cr, 2.0, col, 0); - cairo_rectangle (cr, x, y, squareSize, squareSize); - cairo_fill (cr); - cairo_destroy (cr); - cr = cairo_create (csBoardBackup); - SetPen(cr, 2.0, col, 0); - cairo_rectangle (cr, x, y, squareSize, squareSize); - cairo_fill (cr); - cairo_destroy (cr); - } 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); -} - -static void -pngDrawPiece (ChessSquare piece, int square_color, int x, int y, Drawable dest) -{ - int kind, p = piece; - cairo_t *cr; - - if ((int)piece < (int) BlackPawn) { - kind = 0; - } else { - kind = 1; - piece -= BlackPawn; - } - if(appData.upsideDown && flipView) { p += p < BlackPawn ? BlackPawn : -BlackPawn; }// swap white and black pieces - BlankSquare(x, y, square_color, piece, dest, 1); // erase previous contents with background - DrawSeekOpen(); - cr = cairo_create (csBoardWindow); - cairo_set_source_surface (cr, pngPieceBitmaps[kind][piece], x, y); - cairo_paint(cr); - cairo_destroy (cr); - cr = cairo_create (csBoardBackup); - cairo_set_source_surface (cr, pngPieceBitmaps[kind][piece], x, y); - cairo_paint(cr); - cairo_destroy (cr); -} - -typedef void (*DrawFunc)(); - -DrawFunc -ChooseDrawFunc () -{ - if (appData.monoMode) { - if (DefaultDepth(xDisplay, xScreen) == 1) { - return monoDrawPiece_1bit; - } else { - return monoDrawPiece; - } - } else if(appData.pngDirectory[0]) { - return pngDrawPiece; - } else { - if (useImages) - return colorDrawPieceImage; - else - return colorDrawPiece; - } -} - -void -DoDrawDot (int marker, int x, int y, int r, cairo_surface_t *cs) -{ - 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); -} - -void -DrawDot (int marker, int x, int y, int r) -{ - DoDrawDot(marker, x, y, r, csBoardWindow); - DoDrawDot(marker, x, y, r, csBoardBackup); -} - -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 { - if(*appData.pngDirectory) { - cairo_t *cr = cairo_create (csBoardWindow); - cairo_select_font_face (cr, "Sans", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - - cairo_set_font_size (cr, squareSize/4); - - cairo_move_to (cr, xx-1, yy); - if(align < 3) cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - else cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); - cairo_show_text (cr, string); - cairo_destroy (cr); - cr = cairo_create (csBoardBackup); - cairo_select_font_face (cr, "Sans", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - - cairo_set_font_size (cr, squareSize/4); - - cairo_move_to (cr, xx-1, yy); - if(align < 3) cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - else cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); - cairo_show_text (cr, string); - cairo_destroy (cr); - } 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) { XSync(xDisplay, False); @@ -2985,17 +1724,20 @@ CoDrag (Widget sh, WindowPlacement *wp) void ReSize (WindowPlacement *wp) { - int sqx, sqy; + 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 - NewSurfaces(); 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; @@ -3029,7 +1771,7 @@ DelayedDrag () { if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending delayedDragID = - XtAppAddTimeOut(appContext, 100, (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 @@ -3039,150 +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) - -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 (csBoardWindow); - - 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 (csBoardWindow); - - 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 (csBoardWindow); - - 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_set_source_rgba(cr, 0, 0, 0,1.0); - cairo_show_text( cr, buf); - - /* free memory */ - cairo_destroy (cr); -} - -void DrawSeekDot(int x, int y, int colorNr) -{ - cairo_t *cr = cairo_create (csBoardWindow); - 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); - if(!csBoardWindow) { - csBoardWindow = cairo_xlib_surface_create(xDisplay, xBoardWindow, DefaultVisual(xDisplay, 0), boardWidth, boardHeight); - csBoardBackup = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, boardWidth, boardHeight); - } -} - -void -DrawSeekClose () -{ -} - -void -DoDrawGrid(cairo_surface_t *cs) -{ - /* 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); - - return; -} - -void -DrawGrid() -{ - DoDrawGrid(csBoardWindow); - DoDrawGrid(csBoardBackup); -} - /* * event handler for redrawing the board */ @@ -3304,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]); } @@ -3883,154 +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 cairo_surface_t *c_animBufs[3*NrOfAnims]; // newBuf, saveBuf - -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; - - if(cairoAnimate) { - DrawSeekOpen(); // set cs to board widget - if(c_animBufs[anr]) cairo_surface_destroy (c_animBufs[anr]); - if(c_animBufs[anr+2]) cairo_surface_destroy (c_animBufs[anr+2]); - c_animBufs[anr+4] = csBoardWindow; - c_animBufs[anr+2] = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, squareSize, squareSize); - c_animBufs[anr] = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, squareSize, squareSize); - } - - /* 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 (!cairoAnimate && 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 & !xpmDone) - CreateAnimMasks(info.depth), xpmDone = 1; -} - #ifndef HAVE_USLEEP static Boolean frameWaiting; @@ -4078,178 +2528,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); - } -} - -static void -CairoOverlayPiece (ChessSquare piece, cairo_surface_t *dest) -{ - static ChessSquare oldPiece = -1; - static int oldSize; - static cairo_t *pieceSource; - extern int doubleClick; // in backend.c -// if(piece != oldPiece || squareSize != oldSize) { // try make it faster by only changing cr if we need other piece -// if(pieceSource) cairo_destroy (pieceSource); -// pieceSource = cairo_create (dest); -// cairo_set_source_surface (pieceSource, pngPieceBitmaps[!White(piece)][piece % BlackPawn], 0, 0); -// oldPiece = piece; oldSize = squareSize; -// } - pieceSource = cairo_create (dest); - cairo_set_source_surface (pieceSource, pngPieceBitmaps[!White(piece)][piece % BlackPawn], 0, 0); - if(doubleClick) cairo_paint_with_alpha (pieceSource, 0.6); - else cairo_paint(pieceSource); - cairo_destroy (pieceSource); -} - -void -InsertPiece (AnimNr anr, ChessSquare piece) -{ - if(cairoAnimate) { - CairoOverlayPiece(piece, c_animBufs[anr]); - } else - OverlayPiece(piece, animGCs[anr+2], animGCs[anr+4], animBufs[anr]); -} - -void -DrawBlank (AnimNr anr, int x, int y, int startColor) -{ - if(cairoAnimate) - BlankSquare(x, y, startColor, EmptySquare, (Drawable) c_animBufs[anr+2], 0); - else - 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) -{ - if(cairoAnimate) { - cairo_t *cr;// = cairo_create (c_animBufs[anr+destBuf]); - cr = cairo_create (c_animBufs[anr+destBuf]); - if(c_animBufs[anr+srcBuf] == csBoardWindow) - cairo_set_source_surface (cr, csBoardBackup, destX - srcX, destY - srcY); - else - cairo_set_source_surface (cr, c_animBufs[anr+srcBuf], destX - srcX, destY - srcY); - cairo_rectangle (cr, destX, destY, width, height); - cairo_fill (cr); - cairo_destroy (cr); - if(c_animBufs[anr+destBuf] == csBoardWindow) { - cr = cairo_create (csBoardBackup); // also draw to backup - cairo_set_source_surface (cr, c_animBufs[anr+srcBuf], destX - srcX, destY - srcY); - cairo_rectangle (cr, destX, destY, width, height); - cairo_fill (cr); - cairo_destroy (cr); - } - } else - XCopyArea(xDisplay, animBufs[anr+srcBuf], animBufs[anr+destBuf], animGCs[anr], - srcX, srcY, width, height, destX, destY); -} - -void -SetDragPiece (AnimNr anr, ChessSquare piece) -{ - Pixmap mask; - if(cairoAnimate) return; - /* 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 -DoDrawPolygon (cairo_surface_t *cs, Pnt arrow[], int nr) -{ - cairo_t *cr; - int i; - cr = cairo_create (cs); - cairo_move_to (cr, arrow[nr-1].x, arrow[nr-1].y); - for (i=0;i