From 31573922e3486455dacb0462099a0804b553f7e7 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Fri, 1 Apr 2011 21:52:48 +0200 Subject: [PATCH] Add board dialog XBoard The GenericPopUp() is used to implement a dialog for board options. The board dialog needs to trigger redraw and redefinition of the colors, through an OK callback. Color-pickers are used for the 6 basic color settings. To allow changing board settings during the session (i.e. from a menu dialog), the routines to allocate resources have to free the resources for the previous settings first. This patch take care of XtCreateGCs(), preventing re-creation of resources that are unchangeable (such as the grid color), and calling XtReleastGC() on GCs that can be changed. To prevent resource leaks the old pixmaps are deleted before making new ones on second or later calls of CreateXPMPieces(). --- xboard.c | 245 +++++++++++++++++++++++++++++++++++++----------------------- xoptions.c | 77 ++++++++++++++++++- 2 files changed, 228 insertions(+), 94 deletions(-) diff --git a/xboard.c b/xboard.c index 1b95e50..af78d61 100644 --- a/xboard.c +++ b/xboard.c @@ -242,7 +242,7 @@ FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *fail RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); RETSIGTYPE TermSizeSigHandler P((int sig)); -void CreateGCs P((void)); +void CreateGCs P((int redo)); void CreateXIMPieces P((void)); void CreateXPMPieces P((void)); void CreateXPMBoard P((char *s, int n)); @@ -454,6 +454,7 @@ void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopDown P(()); @@ -647,6 +648,9 @@ MenuItem viewMenu[] = { {N_("Tags"), "Show Tags", EditTagsProc}, {N_("Comments"), "Show Comments", EditCommentProc}, {N_("ICS Input Box"), "ICS Input Box", IcsInputBoxProc}, + {"----", NULL, NothingProc}, + {N_("Board..."), "Board Options", BoardOptionsProc}, + {N_("Game List Tags..."), "Game List", GameListOptionsPopUp}, {NULL, NULL, NULL} }; @@ -1650,6 +1654,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags) XtSetArg(args[0], XtNdefaultDistance, &sep); XtGetValues(formWidget, args, 1); + if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); CreateGrid(); @@ -1777,6 +1782,104 @@ void InitDrawingSizes(BoardSize boardSize, int flags) } #endif +void ParseIcsTextColors() +{ // [HGM] tken out of main(), so it can be called from ICS-Options dialog + if (parse_cpair(ColorShout, appData.colorShout) < 0 || + parse_cpair(ColorSShout, appData.colorSShout) < 0 || + parse_cpair(ColorChannel1, appData.colorChannel1) < 0 || + parse_cpair(ColorChannel, appData.colorChannel) < 0 || + parse_cpair(ColorKibitz, appData.colorKibitz) < 0 || + parse_cpair(ColorTell, appData.colorTell) < 0 || + parse_cpair(ColorChallenge, appData.colorChallenge) < 0 || + parse_cpair(ColorRequest, appData.colorRequest) < 0 || + parse_cpair(ColorSeek, appData.colorSeek) < 0 || + parse_cpair(ColorNormal, appData.colorNormal) < 0) + { + if (appData.colorize) { + fprintf(stderr, + _("%s: can't parse color names; disabling colorization\n"), + programName); + } + appData.colorize = FALSE; + } +} + +int MakeColors() +{ // [HGM] taken out of main(), so it can be called from BoardOptions dialog + XrmValue vFrom, vTo; + int forceMono = False; + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.lightSquareColor; + vFrom.size = strlen(appData.lightSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + lightSquareColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.darkSquareColor; + vFrom.size = strlen(appData.darkSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + darkSquareColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.whitePieceColor; + vFrom.size = strlen(appData.whitePieceColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + whitePieceColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.blackPieceColor; + vFrom.size = strlen(appData.blackPieceColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + blackPieceColor = *(Pixel *) vTo.addr; + } + } + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.highlightSquareColor; + vFrom.size = strlen(appData.highlightSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + highlightSquareColor = *(Pixel *) vTo.addr; + } + } + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.premoveHighlightColor; + vFrom.size = strlen(appData.premoveHighlightColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + premoveHighlightColor = *(Pixel *) vTo.addr; + } + } + return forceMono; +} + int main(argc, argv) int argc; @@ -2011,74 +2114,7 @@ XBoard square size (hint): %d\n\ appData.monoMode = True; } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.lightSquareColor; - vFrom.size = strlen(appData.lightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - lightSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.darkSquareColor; - vFrom.size = strlen(appData.darkSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - darkSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.whitePieceColor; - vFrom.size = strlen(appData.whitePieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - whitePieceColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.blackPieceColor; - vFrom.size = strlen(appData.blackPieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - blackPieceColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.highlightSquareColor; - vFrom.size = strlen(appData.highlightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - highlightSquareColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.premoveHighlightColor; - vFrom.size = strlen(appData.premoveHighlightColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - premoveHighlightColor = *(Pixel *) vTo.addr; - } - } + forceMono = MakeColors(); if (forceMono) { fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"), @@ -2105,24 +2141,7 @@ XBoard square size (hint): %d\n\ (unsigned long) XBlackPixel(xDisplay, xScreen)); } - if (parse_cpair(ColorShout, appData.colorShout) < 0 || - parse_cpair(ColorSShout, appData.colorSShout) < 0 || - parse_cpair(ColorChannel1, appData.colorChannel1) < 0 || - parse_cpair(ColorChannel, appData.colorChannel) < 0 || - parse_cpair(ColorKibitz, appData.colorKibitz) < 0 || - parse_cpair(ColorTell, appData.colorTell) < 0 || - parse_cpair(ColorChallenge, appData.colorChallenge) < 0 || - parse_cpair(ColorRequest, appData.colorRequest) < 0 || - parse_cpair(ColorSeek, appData.colorSeek) < 0 || - parse_cpair(ColorNormal, appData.colorNormal) < 0) - { - if (appData.colorize) { - fprintf(stderr, - _("%s: can't parse color names; disabling colorization\n"), - programName); - } - appData.colorize = FALSE; - } + ParseIcsTextColors(); textColors[ColorNone].fg = textColors[ColorNone].bg = -1; textColors[ColorNone].attr = 0; @@ -2509,7 +2528,7 @@ XBoard square size (hint): %d\n\ CatchDeleteWindow(shellWidget, "QuitProc"); - CreateGCs(); + CreateGCs(False); CreateGrid(); #if HAVE_LIBXPM if (appData.bitmapDirectory[0] != NULLCHAR) { @@ -3087,7 +3106,31 @@ FindFont(pattern, targetPxlSize) return p; } -void CreateGCs() +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); + if (appData.monoMode) { + if (DefaultDepth(xDisplay, xScreen) == 1) { + XtReleaseGC(shellWidget, wbPieceGC); + } else { + XtReleaseGC(shellWidget, bwPieceGC); + } + } else { + XtReleaseGC(shellWidget, prelineGC); + XtReleaseGC(shellWidget, jailSquareGC); + XtReleaseGC(shellWidget, wdPieceGC); + XtReleaseGC(shellWidget, wlPieceGC); + XtReleaseGC(shellWidget, wjPieceGC); + XtReleaseGC(shellWidget, bdPieceGC); + XtReleaseGC(shellWidget, blPieceGC); + XtReleaseGC(shellWidget, bjPieceGC); + } +} + +void CreateGCs(int redo) { XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground | GCBackground | GCFunction | GCPlaneMask; @@ -3099,6 +3142,9 @@ void CreateGCs() 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 gc_values.foreground = XBlackPixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); lineGC = XtGetGC(shellWidget, value_mask, &gc_values); @@ -3108,12 +3154,12 @@ void CreateGCs() coordGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, coordGC, coordFontID); - // [HGM] make font for holdings counts (white on black0 + // [HGM] make font for holdings counts (white on black) gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); countGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, countGC, countFontID); - + } if (appData.monoMode) { gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XWhitePixel(xDisplay, xScreen); @@ -3367,12 +3413,24 @@ void CreateXPMBoard(char *s, int kind) { XpmAttributes attr; attr.valuemask = 0; - if(s == NULL || *s == 0 || *s == '*') return; + if(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; @@ -3381,6 +3439,9 @@ void CreateXPMPieces() 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 */ diff --git a/xoptions.c b/xoptions.c index 9ea806a..e29e2dd 100644 --- a/xoptions.c +++ b/xoptions.c @@ -92,6 +92,7 @@ extern Window xBoardWindow; extern Arg layoutArgs[2], formArgs[2]; Pixel timerForegroundPixel, timerBackgroundPixel; extern int searchTime; +extern int lineGap; // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines @@ -1776,6 +1777,10 @@ void SecondSettingsProc(w, event, prms, nprms) typedef void ButtonCallback(int n); static Option *currentOption; +int MakeColors P((void)); +void CreateGCs P((int redo)); +void CreateXPMBoard P((char *s, int kind)); +void CreateXPMPieces P((void)); void GenericReadout(); Option loadOptions[] = { @@ -1797,7 +1802,7 @@ Option saveOptions[] = { { 0, 1, 0, NULL, NULL, "", NULL, EndMark , "" } }; -SetColor(char *colorName, Widget box) +void SetColor(char *colorName, Widget box) { Arg args[5]; Pixel buttonColor; @@ -1818,7 +1823,7 @@ SetColor(char *colorName, Widget box) void AdjustColor(int i) { - int n = currentOption[i].max, col, j, r, g, b, step = 10; + int n = currentOption[i].value, col, j, r, g, b, step = 10; char *s, buf[MSG_SIZ]; // color string Arg args[5]; XtSetArg(args[0], XtNstring, &s); @@ -1841,6 +1846,65 @@ void AdjustColor(int i) XtSetValues(currentOption[i-n-1].handle, args, 1); } +void BoardOptionsOK(int n) +{ + if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; + MakeColors(); CreateGCs(True); + CreateXPMPieces(); + CreateXPMBoard(appData.liteBackTextureFile, 1); + CreateXPMBoard(appData.darkBackTextureFile, 0); + InitDrawingSizes(-1, 0); + DrawPosition(True, NULL); +} + +Option boardOptions[] = { +{ 0, 0, 70, NULL, (void*) &appData.whitePieceColor, "", NULL, TextBox, _("White Piece Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 70, NULL, (void*) &appData.blackPieceColor, "", NULL, TextBox, _("Black Piece Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 70, NULL, (void*) &appData.lightSquareColor, "", NULL, TextBox, _("Light Square Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 70, NULL, (void*) &appData.darkSquareColor, "", NULL, TextBox, _("Dark Square Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 70, NULL, (void*) &appData.highlightSquareColor, "", NULL, TextBox, _("Highlight Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 70, NULL, (void*) &appData.premoveHighlightColor, "", NULL, TextBox, _("Premove Highlight Color:") }, +{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" }, +{ 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" }, +{ 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" }, +{ 0, 0, 0, NULL, (void*) &appData.upsideDown, "", NULL, CheckBox, _("Flip Pieces Shogi Style") }, +{ 0, 0, 0, NULL, (void*) &appData.allWhite, "", NULL, CheckBox, _("Use Outline Pieces for Black") }, +{ 0, 0, 0, NULL, (void*) &appData.monoMode, "", NULL, CheckBox, _("Mono Mode") }, +{ 0,-1, 5, NULL, (void*) &appData.overrideLineGap, "", NULL, Spin, _("Line Gap ( -1 = default for board size):") }, +{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, "", NULL, FileName, _("Light-Squares Texture File:") }, +{ 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, "", NULL, FileName, _("Dark-Squares Texture File:") }, +{ 0, 0, 0, NULL, (void*) &appData.bitmapDirectory, "", NULL, PathName, _("Directory with Bitmap Pieces:") }, +{ 0, 0, 0, NULL, (void*) &appData.pixmapDirectory, "", NULL, PathName, _("Directory with Pixmap Pieces:") }, +{ 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" } +}; + void GenericReadout() { int i, j; @@ -2215,6 +2279,15 @@ void SaveOptionsProc(w, event, prms, nprms) GenericPopUp(saveOptions, _("Save Game Options")); } +void BoardOptionsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + GenericPopUp(boardOptions, _("Board Options")); +} + //---------------------------- Chat Windows ---------------------------------------------- void OutputChatMessage(int partner, char *mess) -- 1.7.0.4