X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xoptions.c;h=16576f952683fac05304c1e73f579aa442868134;hb=14fa496aee4fc5ff4288ac254937a0cab78c12eb;hp=f2da6c0ea77662c47d7a85574c54d78e1f723eb9;hpb=f79d26770a06d6307a005b456961e9252ed1728e;p=xboard.git diff --git a/xoptions.c b/xoptions.c index f2da6c0..16576f9 100644 --- a/xoptions.c +++ b/xoptions.c @@ -50,6 +50,7 @@ extern char *getenv(); #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ extern char *getenv(); extern void SendToProgram P((char *message, ChessProgramState *cps)); FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed, - char *init_path, char *mode, int (*show_entry)(), char **name_return)); + char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return)); extern Widget formWidget, shellWidget, boardWidget, menuBarWidget; extern Display *xDisplay; @@ -92,6 +93,7 @@ extern Window xBoardWindow; extern Arg layoutArgs[2], formArgs[2]; Pixel timerForegroundPixel, timerBackgroundPixel; extern int searchTime; +extern Atom wm_delete_window; extern int lineGap; // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines @@ -616,448 +618,23 @@ void TimeControlProc(w, event, prms, nprms) TimeControlPopUp(); } -Widget w1, w2, w3, w4, w5, w6, w7, w8; - -//--------------------------- New-Variant Menu PopUp ----------------------------------- -struct NewVarButton { - char *name; - char *color; - Widget handle; - VariantClass variant; -}; - -struct NewVarButton buttonDesc[] = { - {N_("normal"), "#FFFFFF", 0, VariantNormal}, - {N_("FRC"), "#FFFFFF", 0, VariantFischeRandom}, - {N_("wild castle"), "#FFFFFF", 0, VariantWildCastle}, - {N_("no castle"), "#FFFFFF", 0, VariantNoCastle}, - {N_("knightmate"), "#FFFFFF", 0, VariantKnightmate}, - {N_("berolina"), "#FFFFFF", 0, VariantBerolina}, - {N_("cylinder"), "#FFFFFF", 0, VariantCylinder}, - {N_("shatranj"), "#FFFFFF", 0, VariantShatranj}, - {N_("makruk"), "#FFFFFF", 0, VariantMakruk}, - {N_("atomic"), "#FFFFFF", 0, VariantAtomic}, - {N_("two kings"), "#FFFFFF", 0, VariantTwoKings}, - {N_("3-checks"), "#FFFFFF", 0, Variant3Check}, - {N_("suicide"), "#FFFFBF", 0, VariantSuicide}, - {N_("give-away"), "#FFFFBF", 0, VariantGiveaway}, - {N_("losers"), "#FFFFBF", 0, VariantLosers}, - {N_("fairy"), "#BFBFBF", 0, VariantFairy}, - {N_("Seirawan"), "#FFBFBF", 0, VariantSChess}, - {N_("Superchess"), "#FFBFBF", 0, VariantSuper}, - {N_("crazyhouse"), "#FFBFBF", 0, VariantCrazyhouse}, - {N_("bughouse"), "#FFBFBF", 0, VariantBughouse}, - {N_("shogi (9x9)"), "#BFFFFF", 0, VariantShogi}, - {N_("xiangqi (9x10)"), "#BFFFFF", 0, VariantXiangqi}, - {N_("courier (12x8)"), "#BFFFBF", 0, VariantCourier}, - {N_("Capablanca (10x8)"), "#BFBFFF", 0, VariantCapablanca}, -#ifdef GOTHIC - {N_("Gothic (10x8)"), "#BFBFFF", 0, VariantGothic}, -#endif - {N_("janus (10x8)"), "#BFBFFF", 0, VariantJanus}, - {N_("CRC (10x8)"), "#BFBFFF", 0, VariantCapaRandom}, -#ifdef FALCON - {N_("Falcon (10x8)"), "#BFBFFF", 0, VariantFalcon}, -#endif - {N_("Spartan"), "#FF0000", 0, VariantSpartan}, - {NULL, 0, 0, (VariantClass) 0} -}; - -int NewVariantUp; -Widget NewVariantShell; - -void NewVariantPopDown() -{ - if (!NewVariantUp) return; - XtPopdown(NewVariantShell); - XtDestroyWidget(NewVariantShell); - NewVariantUp = False; - ModeHighlight(); -} - -void NewVariantCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Arg args[16]; - VariantClass v; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _(" OK ")) == 0) { - int nr = (intptr_t) XawToggleGetCurrent(buttonDesc[0].handle) - 1; - if(nr < 0) return; - v = buttonDesc[nr].variant; - if(!appData.noChessProgram) { - char *name = VariantName(v), buf[MSG_SIZ]; - if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) { - /* [HGM] in protocol 2 we check if variant is suported by engine */ - snprintf(buf, MSG_SIZ, _("Variant %s not supported by %s"), name, first.tidy); - DisplayError(buf, 0); -// NewVariantPopDown(); - return; /* ignore OK if first engine does not support it */ - } else - if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) { - snprintf(buf, MSG_SIZ, _("Warning: second engine (%s) does not support this!"), second.tidy); - DisplayError(buf, 0); /* use of second engine is optional; only warn user */ - } - } - - gameInfo.variant = v; - appData.variant = VariantName(v); - - shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */ - startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */ - appData.pieceToCharTable = NULL; - Reset(True, True); - NewVariantPopDown(); - return; - } -} - -void NewVariantPopUp() -{ - Arg args[16]; - Widget popup, layout, form, last = NULL, b_ok, b_cancel; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - XrmValue vFrom, vTo; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, 250); i++; -// XtSetArg(args[i], XtNheight, 300); i++; - NewVariantShell = popup = - XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - for(i = 0; buttonDesc[i].name != NULL; i++) { - Pixel buttonColor; - if (!appData.monoMode) { - vFrom.addr = (caddr_t) buttonDesc[i].color; - vFrom.size = strlen(buttonDesc[i].color); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - buttonColor = (Pixel) -1; - } else { - buttonColor = *(Pixel *) vTo.addr; - } - } - - j = 0; - XtSetArg(args[j], XtNradioGroup, last); j++; - XtSetArg(args[j], XtNwidth, 125); j++; -// XtSetArg(args[j], XtNheight, 16); j++; - XtSetArg(args[j], XtNfromVert, i == 15 ? NULL : last); j++; - XtSetArg(args[j], XtNfromHoriz, i < 15 ? NULL : buttonDesc[i-15].handle); j++; - XtSetArg(args[j], XtNradioData, i+1); j++; - XtSetArg(args[j], XtNbackground, buttonColor); j++; - XtSetArg(args[j], XtNstate, gameInfo.variant == buttonDesc[i].variant); j++; - XtSetArg(args[j], XtNsensitive, appData.noChessProgram || strstr(first.variants, VariantName(buttonDesc[i].variant))); j++; - buttonDesc[i].handle = last = - XtCreateManagedWidget(buttonDesc[i].name, toggleWidgetClass, form, args, j); - } - - j=0; - XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNfromHoriz, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNheight, 35); j++; -// XtSetArg(args[j], XtNwidth, 60); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_cancel= XtCreateManagedWidget(_("CANCEL"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, NewVariantPopDown, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromHoriz, b_cancel); j++; - XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNheight, 35); j++; -// XtSetArg(args[j], XtNwidth, 60); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, NewVariantCallback, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromVert, buttonDesc[14].handle); j++; -// XtSetArg(args[j], XtNheight, 70); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNlabel, _("WARNING: variants with un-orthodox\n" - "pieces only have built-in bitmaps\n" - "for -boardSize middling, bulky and\n" - "petite, and substitute king or amazon\n" - "for missing bitmaps. (See manual.)")); j++; - XtCreateManagedWidget("warning", labelWidgetClass, form, args, j); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "NewVariantPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - NewVariantUp = True; -} - -void NewVariantProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - NewVariantPopUp(); -} - -//--------------------------- UCI Menu Popup ------------------------------------------ -int UciUp; -Widget UciShell; - -struct UciControl { - char *name; - Widget handle; - void *ptr; -}; - -struct UciControl controlDesc[] = { - {N_("maximum nr of CPUs:"), 0, &appData.smpCores}, - {N_("Polyglot Directory:"), 0, &appData.polyglotDir}, - {N_("Hash Size (MB):"), 0, &appData.defaultHashSize}, - {N_("EGTB Path:"), 0, &appData.defaultPathEGTB}, - {N_("EGTB Cache (MB):"), 0, &appData.defaultCacheSizeEGTB}, - {N_("Polyglot Book:"), 0, &appData.polyglotBook}, - {NULL, 0, NULL}, -}; - -void UciPopDown() -{ - if (!UciUp) return; - previous = NULL; - XtPopdown(UciShell); - XtDestroyWidget(UciShell); - UciUp = False; - ModeHighlight(); -} - -void UciCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Arg args[16]; - int oldCores = appData.smpCores, ponder = 0; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("OK")) == 0) { - int i, j; String name; - for(i=0; i<6; i++) { - XtSetArg(args[0], XtNstring, &name); - XtGetValues(controlDesc[i].handle, args, 1); - if(i&1) { - if(name) - *(char**) controlDesc[i].ptr = strdup(name); - } else { - if(sscanf(name, "%d", &j) == 1) - *(int*) controlDesc[i].ptr = j; - } - } - XtSetArg(args[0], XtNstate, &appData.usePolyglotBook); - XtGetValues(w1, args, 1); - XtSetArg(args[0], XtNstate, &appData.firstHasOwnBookUCI); - XtGetValues(w2, args, 1); - XtSetArg(args[0], XtNstate, &appData.secondHasOwnBookUCI); - XtGetValues(w3, args, 1); - XtSetArg(args[0], XtNstate, &ponder); - XtGetValues(w4, args, 1); - - // adjust setting in other menu for duplicates - // (perhaps duplicates should be removed from general Option Menu?) - XtSetArg(args[0], XtNleftBitmap, ponder ? xMarkPixmap : None); - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Ponder Next Move"), args, 1); - - // make sure changes are sent to first engine by re-initializing it - // if it was already started pre-emptively at end of previous game - if(gameMode == BeginningOfGame) Reset(True, True); else { - // Some changed setting need immediate sending always. - PonderNextMoveEvent(ponder); - if(oldCores != appData.smpCores) - NewSettingEvent(False, &(first.maxCores), "cores", appData.smpCores); - } - UciPopDown(); - return; - } -} - -void UciPopUp() -{ - Arg args[16]; - Widget popup, layout, form, b_ok, b_cancel, last = NULL, new, upperLeft; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - char def[MSG_SIZ]; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, 300); i++; - UciShell = popup = - XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - j = 0; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - for(i = 0; controlDesc[i].name != NULL; i++) { - j = 3; - XtSetArg(args[j], XtNfromVert, last); j++; -// XtSetArg(args[j], XtNwidth, 130); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - new = XtCreateManagedWidget(controlDesc[i].name, labelWidgetClass, form, args, j); - if(i==0) upperLeft = new; - - j = 4; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, i&1 ? 245 : 50); j++; - XtSetArg(args[j], XtNinsertPosition, 9999); j++; - if(i&1) { - XtSetArg(args[j], XtNstring, * (char**) controlDesc[i].ptr ? - * (char**) controlDesc[i].ptr : ""); j++; - } else { - snprintf(def, MSG_SIZ, "%d", * (int*) controlDesc[i].ptr); - XtSetArg(args[j], XtNstring, def); j++; - } - XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; - controlDesc[i].handle = last = - XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); - } - - j=0; - XtSetArg(args[j], XtNfromHoriz, controlDesc[0].handle); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNstate, appData.ponderNextMove); j++; - w4 = XtCreateManagedWidget(_("Ponder"), toggleWidgetClass, form, args, j); - - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, UciCallback, (XtPointer) 0); - - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; - b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, UciPopDown, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; - XtSetArg(args[j], XtNstate, appData.usePolyglotBook); j++; - w1 = XtCreateManagedWidget(_(" use book "), toggleWidgetClass, form, args, j); -// XtAddCallback(w1, XtNcallback, UciCallback, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, w1); j++; - XtSetArg(args[j], XtNstate, appData.firstHasOwnBookUCI); j++; - w2 = XtCreateManagedWidget(_("own book 1"), toggleWidgetClass, form, args, j); -// XtAddCallback(w2, XtNcallback, UciCallback, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, w2); j++; - XtSetArg(args[j], XtNstate, appData.secondHasOwnBookUCI); j++; - w3 = XtCreateManagedWidget(_("own book 2"), toggleWidgetClass, form, args, j); -// XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "UciPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - UciUp = True; - - previous = NULL; - SetFocus(controlDesc[2].handle, popup, (XEvent*) NULL, False); -// XtSetKeyboardFocus(popup, controlDesc[1].handle); -} - -void UciMenuProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - UciPopUp(); -} - //--------------------------- Engine-specific options menu ---------------------------------- -int SettingsUp; -Widget SettingsShell; int values[MAX_OPTIONS]; ChessProgramState *currentCps; +static Option *currentOption; +extern Widget shells[]; -void SettingsPopDown() +void CheckCallback(Widget ww, XtPointer data, XEvent *event, Boolean *b) { - if (!SettingsUp) return; - previous = NULL; - XtPopdown(SettingsShell); - XtDestroyWidget(SettingsShell); - SettingsUp = False; - ModeHighlight(); + Widget w = currentOption[(int)(intptr_t)data].handle; + Boolean s; + Arg args[16]; + + XtSetArg(args[0], XtNstate, &s); + XtGetValues(w, args, 1); + XtSetArg(args[0], XtNstate, !s); + XtSetValues(w, args, 1); } void SpinCallback(w, client_data, call_data) @@ -1075,104 +652,33 @@ void SpinCallback(w, client_data, call_data) j = 0; XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[data].handle, args, 1); + XtGetValues(currentOption[data].handle, args, 1); sscanf(val, "%d", &j); if (strcmp(name, "browse") == 0) { - if(XsraSelFile(SettingsShell, currentCps->option[data].name, NULL, NULL, "", "", - currentCps->option[data].type == PathName ? "p" : "f", NULL, &p)) { + char *q, *r; + XtSetArg(args[0], XtNstring, &q); + XtGetValues(currentOption[data].handle, args, 1); + for(r = ""; *q; q++) if(*q == '.') r = q; else if(*q == '/') r = ""; // last dot after last slash + if(XsraSelFile(shells[0], currentOption[data].name, NULL, NULL, "", "", r, + currentOption[data].type == PathName ? "p" : "f", NULL, &p)) { int len = strlen(p); if(len && p[len-1] == '/') p[len-1] = NULLCHAR; XtSetArg(args[0], XtNstring, p); - XtSetValues(currentCps->option[data].handle, args, 1); + XtSetValues(currentOption[data].handle, args, 1); } - SetFocus(currentCps->option[data].handle, SettingsShell, (XEvent*) NULL, False); + SetFocus(currentOption[data].handle, shells[0], (XEvent*) NULL, False); return; } else if (strcmp(name, "+") == 0) { - if(++j > currentCps->option[data].max) return; + if(++j > currentOption[data].max) return; } else if (strcmp(name, "-") == 0) { - if(--j < currentCps->option[data].min) return; + if(--j < currentOption[data].min) return; } else return; snprintf(buf, MSG_SIZ, "%d", j); XtSetArg(args[0], XtNstring, buf); - XtSetValues(currentCps->option[data].handle, args, 1); -} - -void SettingsCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name, val; - Arg args[16]; - char buf[MSG_SIZ]; - int i, j; - int data = (intptr_t) client_data; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("cancel")) == 0) { - SettingsPopDown(); - return; - } - if (strcmp(name, _("OK")) == 0 || data) { // save buttons imply OK - for(i=0; inrOptions; i++) { // send all options that had to be OK-ed to engine - switch(currentCps->option[i].type) { - case TextBox: - XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[i].handle, args, 1); - if(strcmp(currentCps->option[i].textValue, val)) { - safeStrCpy(currentCps->option[i].textValue, val, MSG_SIZ - (currentCps->option[i].textValue - currentCps->option[i].name) ); - snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name, val); - SendToProgram(buf, currentCps); - } - break; - case Spin: - XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[i].handle, args, 1); - sscanf(val, "%d", &j); - if(j > currentCps->option[i].max) j = currentCps->option[i].max; - if(j < currentCps->option[i].min) j = currentCps->option[i].min; - if(currentCps->option[i].value != j) { - currentCps->option[i].value = j; - snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j); - SendToProgram(buf, currentCps); - } - break; - case CheckBox: - j = 0; - XtSetArg(args[0], XtNstate, &j); - XtGetValues(currentCps->option[i].handle, args, 1); - if(currentCps->option[i].value != j) { - currentCps->option[i].value = j; - snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j); - SendToProgram(buf, currentCps); - } - break; - case ComboBox: - if(currentCps->option[i].value != values[i]) { - currentCps->option[i].value = values[i]; - snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name, - ((char**)currentCps->option[i].textValue)[values[i]]); - SendToProgram(buf, currentCps); - } - break; - default: - if( appData.debugMode ) - fprintf(debugFP, "SettingsPopUp: unexpected case in switch.\n"); - break; - } - } - if(data) { // send save-button command to engine - snprintf(buf, MSG_SIZ, "option %s\n", name); - SendToProgram(buf, currentCps); - } - SettingsPopDown(); - return; - } - snprintf(buf, MSG_SIZ, "option %s\n", name); - SendToProgram(buf, currentCps); + XtSetValues(currentOption[data].handle, args, 1); + SetFocus(currentOption[data].handle, shells[0], NULL, False); } void ComboSelect(w, addr, index) // callback for all combo items @@ -1185,8 +691,8 @@ void ComboSelect(w, addr, index) // callback for all combo items int j = 255 & (intptr_t) addr; values[i] = j; // store in temporary, for transfer at OK - XtSetArg(args[0], XtNlabel, ((char**)currentCps->option[i].textValue)[j]); - XtSetValues(currentCps->option[i].handle, args, 1); + XtSetArg(args[0], XtNlabel, ((char**)currentOption[i].textValue)[j]); + XtSetValues(currentOption[i].handle, args, 1); } void CreateComboPopup(parent, name, n, mb) @@ -1214,245 +720,223 @@ void CreateComboPopup(parent, name, n, mb) } } -void -SettingsPopUp(ChessProgramState *cps) -{ - Arg args[16]; - Widget popup, layout, dialog, edit=NULL, form, last, b_ok, b_cancel, leftMargin = NULL, textField = NULL; - Window root, child; - int x, y, i, j, height, width, h, c; - int win_x, win_y, maxWidth, maxTextWidth; - unsigned int mask; - char def[MSG_SIZ]; - static char pane[6] = "paneX"; - Widget texts[100], forelast = NULL, anchor, widest; - - // to do: start up second engine if needed - if(!cps->initDone || !cps->nrOptions) return; // nothing to be done - currentCps = cps; - if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1; - height = cps->nrOptions / width + 1; - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - SettingsShell = popup = - XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - for(c=0; c= cps->nrOptions) break; - switch(cps->option[i].type) { - case Spin: - snprintf(def, MSG_SIZ, "%d", cps->option[i].value); - case TextBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - texts[h] = - dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 175); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNstring, cps->option[i].type==Spin ? def : cps->option[i].textValue); j++; - XtSetArg(args[j], XtNinsertPosition, 9999); j++; - edit = last; - cps->option[i].handle = (void*) - (textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j)); - XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); - if(cps->option[i].type == TextBox) break; +// cloned from Engine Settings dialog (and later merged with it) - // add increment and decrement controls for spin - j=0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, last); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNwidth, 20); j++; - edit = XtCreateManagedWidget("+", commandWidgetClass, form, args, j); - XtAddCallback(edit, XtNcallback, SpinCallback, - (XtPointer)(intptr_t) i); +typedef void ButtonCallback(int n); - j=0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, last); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNwidth, 20); j++; - last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j); - XtAddCallback(last, XtNcallback, SpinCallback, - (XtPointer)(intptr_t) i); - break; - case CheckBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNwidth, 10); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNstate, cps->option[i].value); j++; - cps->option[i].handle = (void*) - (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j)); - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - last = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); - break; - case SaveButton: - case Button: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNstate, cps->option[i].value); j++; - cps->option[i].handle = (void*) - (dialog = last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j)); - XtAddCallback(last, XtNcallback, SettingsCallback, - (XtPointer)(intptr_t) (cps->option[i].type == SaveButton)); - break; - case ComboBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); +extern WindowPlacement wpComment, wpTags; +char *trialSound; +static int oldCores, oldPonder; +int MakeColors P((void)); +void CreateGCs P((int redo)); +void CreateXPMBoard P((char *s, int kind)); +void CreateXPMPieces P((void)); +void GenericReadout(); +Widget shells[10]; +Widget marked[10]; +Boolean shellUp[10]; +WindowPlacement *wp[10] = { NULL, &wpComment, &wpTags }; +Option *dialogOptions[10]; - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNwidth, 100); j++; - XtSetArg(args[j], XtNmenuName, XtNewString(cps->option[i].name)); j++; - XtSetArg(args[j], XtNlabel, ((char**)cps->option[i].textValue)[cps->option[i].value]); j++; - cps->option[i].handle = (void*) - (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j)); - CreateComboPopup(last, cps->option[i].name, i, (char **) cps->option[i].textValue); - values[i] = cps->option[i].value; - break; - default: - if( appData.debugMode ) - fprintf(debugFP, "SettingsPopUp: unexpected case in switch.\n"); - break; - } - } +void MarkMenu(char *item, int dlgNr) +{ + Arg args[2]; + XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); + XtSetValues(marked[dlgNr] = XtNameToWidget(menuBarWidget, item), args, 1); +} - // make an attempt to align all spins and textbox controls - maxWidth = maxTextWidth = 0; - for(h=0; h= cps->nrOptions) break; - if(cps->option[i].type == Spin || cps->option[i].type == TextBox) { - Dimension w; - j=0; - XtSetArg(args[j], XtNwidth, &w); j++; - XtGetValues(texts[h], args, j); - if(cps->option[i].type == Spin) { - if(w > maxWidth) maxWidth = w; - widest = texts[h]; - } else { - if(w > maxTextWidth) maxTextWidth = w; - if(!widest) widest = texts[h]; - } - } - } - if(maxTextWidth + 110 < maxWidth) - maxTextWidth = maxWidth - 110; - else maxWidth = maxTextWidth + 110; - for(h=0; h= cps->nrOptions) break; - j=0; - if(cps->option[i].type == Spin) { - XtSetArg(args[j], XtNwidth, maxWidth); j++; - XtSetValues(texts[h], args, j); - } else - if(cps->option[i].type == TextBox) { - XtSetArg(args[j], XtNwidth, maxTextWidth); j++; - XtSetValues(texts[h], args, j); - } +int PopDown(int n) +{ + int j; + Arg args[10]; + Dimension windowH, windowW; Position windowX, windowY; + if (!shellUp[n]) return 0; + if(n && wp[n]) { // remember position + j = 0; + XtSetArg(args[j], XtNx, &windowX); j++; + XtSetArg(args[j], XtNy, &windowY); j++; + XtSetArg(args[j], XtNheight, &windowH); j++; + XtSetArg(args[j], XtNwidth, &windowW); j++; + XtGetValues(shells[n], args, j); + wp[n]->x = windowX; + wp[n]->x = windowY; + wp[n]->width = windowW; + wp[n]->height = windowH; } - } - j=0; - XtSetArg(args[j], XtNfromVert, anchor ? anchor : last); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNfromHoriz, widest ? widest : dialog); j++; - b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, SettingsCallback, (XtPointer) 0); - - XtSetArg(args[j-1], XtNfromHoriz, b_ok); - b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "SettingsPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - SettingsUp = True; - previous = NULL; - if(textField)SetFocus(textField, popup, (XEvent*) NULL, False); + XtPopdown(shells[n]); + if(n == 0) XtDestroyWidget(shells[n]); + shellUp[n] = False; + if(marked[n]) { + XtSetArg(args[0], XtNleftBitmap, None); + XtSetValues(marked[n], args, 1); + } + if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now + return 1; } -void FirstSettingsProc(w, event, prms, nprms) +void GenericPopDown(w, event, prms, nprms) Widget w; XEvent *event; String *prms; Cardinal *nprms; { - SettingsPopUp(&first); + int n; + PopDown(prms[0][0] - '0'); } -void SecondSettingsProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; +Option matchOptions[] = { +{ 0, 2, 1000000000, NULL, (void*) &appData.defaultMatchGames, "", NULL, Spin, _("Default Number of Games in Match:") }, +{ 0, 0, 1000000000, NULL, (void*) &appData.matchPause, "", NULL, Spin, _("Pause between Match Games (msec):") }, +{ 0, 0, 0, NULL, (void*) &appData.loadGameFile, "", NULL, FileName, _("Game File with Opening Lines:") }, +{ 0, -2, 1000000000, NULL, (void*) &appData.loadGameIndex, "", NULL, Spin, _("Game Number (-1 or -2 = Auto-Increment):") }, +{ 0, 0, 0, NULL, (void*) &appData.loadPositionFile, "", NULL, FileName, _("File with Start Positions:") }, +{ 0, -2, 1000000000, NULL, (void*) &appData.loadPositionIndex, "", NULL, Spin, _("Position Number (-1 or -2 = Auto-Increment):") }, +{ 0, 0, 1000000000, NULL, (void*) &appData.rewindIndex, "", NULL, Spin, _("Rewind Index after this many Games (0 = never):") }, +{ 0, 0, 0, NULL, NULL, "", NULL, EndMark , "" } +}; + +void GeneralOptionsOK(int n) { - if(WaitForSecond(SettingsMenuIfReady)) return; - SettingsPopUp(&second); + int newPonder = appData.ponderNextMove; + appData.ponderNextMove = oldPonder; + PonderNextMoveEvent(newPonder); } -//----------------------------Generic dialog -------------------------------------------- +Option generalOptions[] = { +{ 0, 0, 0, NULL, (void*) &appData.sweepSelect, "", NULL, CheckBox, _("Almost Always Queen (Detour Under-Promote)") }, +{ 0, 0, 0, NULL, (void*) &appData.animateDragging, "", NULL, CheckBox, _("Animate Dragging") }, +{ 0, 0, 0, NULL, (void*) &appData.animate, "", NULL, CheckBox, _("Animate Moving") }, +{ 0, 0, 0, NULL, (void*) &appData.autoCallFlag, "", NULL, CheckBox, _("Auto Flag") }, +{ 0, 0, 0, NULL, (void*) &appData.autoFlipView, "", NULL, CheckBox, _("Auto Flip View") }, +{ 0, 0, 0, NULL, (void*) &appData.blindfold, "", NULL, CheckBox, _("Blindfold") }, +{ 0, 0, 0, NULL, (void*) &appData.dropMenu, "", NULL, CheckBox, _("Drop Menu") }, +{ 0, 0, 0, NULL, (void*) &appData.highlightDragging, "", NULL, CheckBox, _("Highlight Dragging (Show Move Targets)") }, +{ 0, 0, 0, NULL, (void*) &appData.highlightLastMove, "", NULL, CheckBox, _("Highlight Last Move") }, +{ 0, 0, 0, NULL, (void*) &appData.highlightMoveWithArrow, "", NULL, CheckBox, _("Highlight with Arrow") }, +{ 0, 0, 0, NULL, (void*) &appData.ringBellAfterMoves, "", NULL, CheckBox, _("Move Sound") }, +{ 0, 0, 0, NULL, (void*) &appData.oneClick, "", NULL, CheckBox, _("One-Click Moving") }, +{ 0, 0, 0, NULL, (void*) &appData.periodicUpdates, "", NULL, CheckBox, _("Periodic Updates (in Analysis Mode)") }, +{ 0, 0, 0, NULL, (void*) &appData.ponderNextMove, "", NULL, CheckBox, _("Ponder Next Move") }, +{ 0, 0, 0, NULL, (void*) &appData.popupExitMessage, "", NULL, CheckBox, _("Popup Exit Messages") }, +{ 0, 0, 0, NULL, (void*) &appData.popupMoveErrors, "", NULL, CheckBox, _("Popup Move Errors") }, +{ 0, 0, 0, NULL, (void*) &appData.showCoords, "", NULL, CheckBox, _("Show Coordinates") }, +{ 0, 0, 0, NULL, (void*) &appData.markers, "", NULL, CheckBox, _("Show Target Squares") }, +{ 0, 0, 0, NULL, (void*) &appData.hideThinkingFromHuman, "", NULL, CheckBox, _("Hide Thinking from Human") }, +{ 0, 0, 0, NULL, (void*) &appData.testLegality, "", NULL, CheckBox, _("Test Legality") }, +{ 0, 0, 10, NULL, (void*) &appData.flashCount, "", NULL, Spin, _("Flash Moves (0 = no flashing):") }, +{ 0, 1, 10, NULL, (void*) &appData.flashRate, "", NULL, Spin, _("Flash Rate (high = fast):") }, +{ 0, 5, 100,NULL, (void*) &appData.animSpeed, "", NULL, Spin, _("Animation Speed (high = slow):") }, +{ 0, 0, 0, NULL, (void*) &GeneralOptionsOK, "", NULL, EndMark , "" } +}; + +void Pick(int n) +{ + VariantClass v = currentOption[n].value; + if(!appData.noChessProgram) { + char *name = VariantName(v), buf[MSG_SIZ]; + if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) { + /* [HGM] in protocol 2 we check if variant is suported by engine */ + snprintf(buf, MSG_SIZ, _("Variant %s not supported by %s"), name, first.tidy); + DisplayError(buf, 0); + return; /* ignore OK if first engine does not support it */ + } else + if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) { + snprintf(buf, MSG_SIZ, _("Warning: second engine (%s) does not support this!"), second.tidy); + DisplayError(buf, 0); /* use of second engine is optional; only warn user */ + } + } -// cloned from Engine Settings dialog + GenericReadout(); // make sure ranks and file settings are read -typedef void ButtonCallback(int n); + gameInfo.variant = v; + appData.variant = VariantName(v); -char *trialSound; -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(); + shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */ + startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */ + appData.pieceToCharTable = NULL; + appData.pieceNickNames = ""; + appData.colorNickNames = ""; + Reset(True, True); + PopDown(0); + return; +} + +Option variantDescriptors[] = { +{ VariantNormal, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("normal")}, +{ VariantFairy, 1, 135, NULL, (void*) &Pick, "#BFBFBF", NULL, Button, N_("fairy")}, +{ VariantFischeRandom, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("FRC")}, +{ VariantSChess, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("Seirawan")}, +{ VariantWildCastle, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("wild castle")}, +{ VariantSuper, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("Superchess")}, +{ VariantNoCastle, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("no castle")}, +{ VariantCrazyhouse, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("crazyhouse")}, +{ VariantKnightmate, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("knightmate")}, +{ VariantBughouse, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("bughouse")}, +{ VariantBerolina, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("berolina")}, +{ VariantShogi, 1, 135, NULL, (void*) &Pick, "#BFFFFF", NULL, Button, N_("shogi (9x9)")}, +{ VariantCylinder, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("cylinder")}, +{ VariantXiangqi, 1, 135, NULL, (void*) &Pick, "#BFFFFF", NULL, Button, N_("xiangqi (9x10)")}, +{ VariantShatranj, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("shatranj")}, +{ VariantCourier, 1, 135, NULL, (void*) &Pick, "#BFFFBF", NULL, Button, N_("courier (12x8)")}, +{ VariantMakruk, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("makruk")}, +{ VariantGreat, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Great Shatranj (10x8)")}, +{ VariantAtomic, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("atomic")}, +{ VariantCapablanca, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Capablanca (10x8)")}, +{ VariantTwoKings, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("two kings")}, +{ VariantGothic, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Gothic (10x8)")}, +{ Variant3Check, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("3-checks")}, +{ VariantJanus, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("janus (10x8)")}, +{ VariantSuicide, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("suicide")}, +{ VariantCapaRandom, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("CRC (10x8)")}, +{ VariantGiveaway, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("give-away")}, +{ VariantSpartan, 1, 135, NULL, (void*) &Pick, "#FF0000", NULL, Button, N_("Spartan")}, +{ VariantLosers, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("losers")}, +{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, _("Board size ( -1 = default for selected variant):")}, +{ 0, -1, BOARD_RANKS-1, NULL, (void*) &appData.NrRanks, "", NULL, Spin, N_("Number of Board Ranks:") }, +{ 0, -1, BOARD_FILES, NULL, (void*) &appData.NrFiles, "", NULL, Spin, N_("Number of Board Files:") }, +{ 0, -1, BOARD_RANKS-1, NULL, (void*) &appData.holdingsSize, "", NULL, Spin, N_("Holdings Size:") }, +{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, + _("WARNING: variants with un-orthodox\n" + "pieces only have built-in bitmaps\n" + "for -boardSize middling, bulky and\n" + "petite, and substitute king or amazon\n" + "for missing bitmaps. (See manual.)")}, +{ 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" } +}; + +void CommonOptionsOK(int n) +{ + int newPonder = appData.ponderNextMove; + // make sure changes are sent to first engine by re-initializing it + // if it was already started pre-emptively at end of previous game + if(gameMode == BeginningOfGame) Reset(True, True); else { + // Some changed setting need immediate sending always. + if(oldCores != appData.smpCores) + NewSettingEvent(False, &(first.maxCores), "cores", appData.smpCores); + appData.ponderNextMove = oldPonder; + PonderNextMoveEvent(newPonder); + } +} + +Option commonEngineOptions[] = { +{ 0, 0, 0, NULL, (void*) &appData.ponderNextMove, "", NULL, CheckBox, _("Ponder Next Move") }, +{ 0, 0, 1000, NULL, (void*) &appData.smpCores, "", NULL, Spin, _("Maximum Number of CPUs per Engine:") }, +{ 0, 0, 0, NULL, (void*) &appData.polyglotDir, "", NULL, PathName, _("Polygot Directory:") }, +{ 0, 0, 16000, NULL, (void*) &appData.defaultHashSize, "", NULL, Spin, _("Hash-Table Size (MB):") }, +{ 0, 0, 0, NULL, (void*) &appData.defaultPathEGTB, "", NULL, PathName, _("Nalimov EGTB Path:") }, +{ 0, 0, 1000, NULL, (void*) &appData.defaultCacheSizeEGTB, "", NULL, Spin, _("EGTB Cache Size (MB):") }, +{ 0, 0, 0, NULL, (void*) &appData.usePolyglotBook, "", NULL, CheckBox, _("Use GUI Book") }, +{ 0, 0, 0, NULL, (void*) &appData.polyglotBook, "", NULL, FileName, _("Opening-Book Filename:") }, +{ 0, 0, 100, NULL, (void*) &appData.bookDepth, "", NULL, Spin, _("Book Depth (moves):") }, +{ 0, 0, 100, NULL, (void*) &appData.bookStrength, "", NULL, Spin, _("Book Variety (0) vs. Strength (100):") }, +{ 0, 0, 0, NULL, (void*) &appData.firstHasOwnBookUCI, "", NULL, CheckBox, _("Engine #1 Has Own Book") }, +{ 0, 0, 0, NULL, (void*) &appData.secondHasOwnBookUCI, "", NULL, CheckBox, _("Engine #2 Has Own Book ") }, +{ 0, 1, 0, NULL, (void*) &CommonOptionsOK, "", NULL, EndMark , "" } +}; Option adjudicationOptions[] = { { 0, 0, 0, NULL, (void*) &appData.checkMates, "", NULL, CheckBox, _("Detect all Mates") }, @@ -1609,34 +1093,60 @@ void SetColor(char *colorName, Widget box) XtSetValues(box, args, 1); } -void AdjustColor(int i) +void SetColorText(int n, char *buf) +{ + Arg args[5]; + XtSetArg(args[0], XtNstring, buf); + XtSetValues(currentOption[n-1].handle, args, 1); + SetFocus(currentOption[n-1].handle, shells[0], NULL, False); + SetColor(buf, currentOption[n].handle); +} + +void DefColor(int n) { - int n = currentOption[i].value, col, j, r, g, b, step = 10; + SetColorText(n, (char*) currentOption[n].choice); +} + +void RefreshColor(int source, int n) +{ + int col, j, r, g, b, step = 10; char *s, buf[MSG_SIZ]; // color string Arg args[5]; XtSetArg(args[0], XtNstring, &s); - XtGetValues(currentOption[i-n-1].handle, args, 1); + XtGetValues(currentOption[source].handle, args, 1); if(sscanf(s, "#%x", &col) != 1) return; // malformed b = col & 0xFF; g = col & 0xFF00; r = col & 0xFF0000; switch(n) { - case 1: g -= 0x100*step; b -= step; break; - case 2: r -= 0x10000*step; b -= step; break; - case 3: g -= 0x100*step; r -= 0x10000*step; break; - case 4: r += 0x10000*step; g += 0x100*step; b += step; break; + case 1: r += 0x10000*step;break; + case 2: g += 0x100*step; break; + case 3: b += step; break; + case 4: r -= 0x10000*step; g -= 0x100*step; b -= step; break; } if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0; if(r > 0xFF0000) r = 0xFF0000; if(g > 0xFF00) g = 0xFF00; if(b > 0xFF) b = 0xFF; col = r | g | b; snprintf(buf, MSG_SIZ, "#%06x", col); for(j=1; j<7; j++) if(buf[j] >= 'a') buf[j] -= 32; // capitalize - SetColor(buf, currentOption[i-n].handle); - XtSetArg(args[0], XtNstring, buf); - XtSetValues(currentOption[i-n-1].handle, args, 1); + SetColorText(source+1, buf); +} + +void ColorChanged(Widget w, XtPointer data, XEvent *event, Boolean *b) +{ + char buf[10]; + if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && *buf == '\r' ) + RefreshColor((int)(intptr_t) data, 0); +} + +void AdjustColor(int i) +{ + int n = currentOption[i].value; + RefreshColor(i-n-1, n); } void BoardOptionsOK(int n) { - if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; + extern int defaultLineGap; + if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap; MakeColors(); CreateGCs(True); CreateXPMPieces(); CreateXPMBoard(appData.liteBackTextureFile, 1); @@ -1647,42 +1157,42 @@ void BoardOptionsOK(int n) Option boardOptions[] = { { 0, 0, 70, NULL, (void*) &appData.whitePieceColor, "", NULL, TextBox, _("White Piece Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FFFFCC", 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" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, { 0, 0, 70, NULL, (void*) &appData.blackPieceColor, "", NULL, TextBox, _("Black Piece Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#202020", 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" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, { 0, 0, 70, NULL, (void*) &appData.lightSquareColor, "", NULL, TextBox, _("Light Square Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#C8C365", 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" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, { 0, 0, 70, NULL, (void*) &appData.darkSquareColor, "", NULL, TextBox, _("Dark Square Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#77A26D", 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" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, { 0, 0, 70, NULL, (void*) &appData.highlightSquareColor, "", NULL, TextBox, _("Highlight Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FFFF00", 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" }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, { 0, 0, 70, NULL, (void*) &appData.premoveHighlightColor, "", NULL, TextBox, _("Premove Highlight Color:") }, -{ 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " }, +{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FF0000", 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") }, +{ 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" }, +{ 0, 0, 0, NULL, (void*) &appData.upsideDown, "", NULL, CheckBox, _("Flip Pieces Shogi Style (Colored buttons restore default)") }, { 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):") }, @@ -1698,7 +1208,7 @@ void GenericReadout() int i, j; String name, val; Arg args[16]; - char buf[MSG_SIZ]; + char buf[MSG_SIZ], **dest; float x; for(i=0; ; i++) { // send all options that had to be OK-ed to engine switch(currentOption[i].type) { @@ -1707,9 +1217,13 @@ void GenericReadout() case PathName: XtSetArg(args[0], XtNstring, &val); XtGetValues(currentOption[i].handle, args, 1); - if(*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val)) { - safeStrCpy(currentOption[i].name + 100, val, MSG_SIZ-100); // text value kept in pivate storage for each option - *(char**) currentOption[i].target = currentOption[i].name + 100; // option gets to point to that + dest = currentCps ? &(currentOption[i].textValue) : (char**) currentOption[i].target; + if(*dest == NULL || strcmp(*dest, val)) { + if(currentCps) { + snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name, val); + SendToProgram(buf, currentCps); + } else *dest = currentOption[i].name + 100; // option gets to point to private storage; + safeStrCpy(*dest, val, MSG_SIZ - (*dest - currentOption[i].name)); // copy text there } break; case Spin: @@ -1721,7 +1235,10 @@ void GenericReadout() if(x < currentOption[i].min) x = currentOption[i].min; if(currentOption[i].value != x) { currentOption[i].value = x; - if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x; + if(currentCps) { // engines never have float options, so no decimals! + snprintf(buf, MSG_SIZ, "option %s=%.0f\n", currentOption[i].name, x); + SendToProgram(buf, currentCps); + } else if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x; else *(float*) currentOption[i].target = x; } break; @@ -1731,12 +1248,21 @@ void GenericReadout() XtGetValues(currentOption[i].handle, args, 1); if(currentOption[i].value != j) { currentOption[i].value = j; - *(Boolean*) currentOption[i].target = j; + if(currentCps) { + snprintf(buf, MSG_SIZ, "option %s=%d\n", currentOption[i].name, j); + SendToProgram(buf, currentCps); + } else *(Boolean*) currentOption[i].target = j; } break; case ComboBox: val = ((char**)currentOption[i].choice)[values[i]]; - if(val && (*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val))) { + if(currentCps) { + if(currentOption[i].value == values[i]) break; // not changed + currentOption[i].value = values[i]; + snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name, + ((char**)currentOption[i].textValue)[values[i]]); + SendToProgram(buf, currentCps); + } else if(val && (*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val))) { if(*(char**) currentOption[i].target) free(*(char**) currentOption[i].target); *(char**) currentOption[i].target = strdup(val); } @@ -1748,6 +1274,7 @@ void GenericReadout() default: printf("GenericReadout: unexpected case in switch.\n"); case Button: + case SaveButton: case Label: break; } @@ -1765,23 +1292,31 @@ void GenericCallback(w, client_data, call_data) int i, j; int data = (intptr_t) client_data; + currentOption = dialogOptions[data>>16]; data &= 0xFFFF; + XtSetArg(args[0], XtNlabel, &name); XtGetValues(w, args, 1); if (strcmp(name, _("cancel")) == 0) { - SettingsPopDown(); + PopDown(data); return; } if (strcmp(name, _("OK")) == 0) { // save buttons imply OK GenericReadout(); - SettingsPopDown(); + PopDown(data); return; } - ((ButtonCallback*) currentOption[data].target)(data); + if(currentCps) { + if(currentOption[data].type == SaveButton) GenericReadout(); + snprintf(buf, MSG_SIZ, "option %s\n", name); + SendToProgram(buf, currentCps); + } else ((ButtonCallback*) currentOption[data].target)(data); } -void -GenericPopUp(Option *option, char *title) +static char *oneLiner = "Return: redraw-display()\n"; + +int +GenericPopUp(Option *option, char *title, int dlgNr) { Arg args[16]; Widget popup, layout, dialog, edit=NULL, form, last, b_ok, b_cancel, leftMargin = NULL, textField = NULL; @@ -1793,15 +1328,28 @@ GenericPopUp(Option *option, char *title) static char pane[6] = "paneX"; Widget texts[100], forelast = NULL, anchor, widest, lastrow = NULL; - currentOption = option; // make available to callback - // kludge: fake address of a ChessProgramState struct that contains the options, so Spin and Combo callbacks work on it - currentCps = (ChessProgramState *) ((char *) option - ((char *)&first.option - (char *)&first)); + if(shellUp[dlgNr]) return 0; // already up + if(dlgNr && shells[dlgNr]) { + XtPopup(shells[dlgNr], XtGrabNone); + shellUp[dlgNr] = True; + return 0; + } -// if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1; -// height = cps->nrOptions / width + 1; + dialogOptions[dlgNr] = option; // make available to callback + // post currentOption globally, so Spin and Combo callbacks can already use it + // WARNING: this kludge does not work for persistent dialogs, so that these cannot have spin or combo controls! + currentOption = option; + + if(currentCps) { // Settings popup for engine: format through heuristic + int n = currentCps->nrOptions; + if(n > 50) width = 4; else if(n>24) width = 2; else width = 1; + height = n / width + 1; + if(currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton) currentOption[n].min = 1; // OK on same line + currentOption[n].type = EndMark; currentOption[n].target = NULL; // delimit list by callback-less end mark + } i = 0; XtSetArg(args[i], XtNresizable, True); i++; - SettingsShell = popup = + popup = shells[dlgNr] = XtCreatePopupShell(title, transientShellWidgetClass, shellWidget, args, i); @@ -1830,7 +1378,8 @@ GenericPopUp(Option *option, char *title) option[i].value = *(float*)option[i].target; goto tBox; case Spin: - snprintf(def, MSG_SIZ, "%d", option[i].value = *(int*)option[i].target); + if(!currentCps) option[i].value = *(int*)option[i].target; + snprintf(def, MSG_SIZ, "%d", option[i].value); case TextBox: case FileName: case PathName: @@ -1852,19 +1401,28 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[j], XtNfromHoriz, dialog); j++; XtSetArg(args[j], XtNborderWidth, 1); j++; XtSetArg(args[j], XtNwidth, w); j++; - if(option[i].type == TextBox && option[i].min) XtSetArg(args[j], XtNheight, option[i].min); j++; + if(option[i].type == TextBox && option[i].min) { + XtSetArg(args[j], XtNheight, option[i].min); j++; + if(option[i].value & 1) { XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; } + if(option[i].value & 2) { XtSetArg(args[j], XtNscrollHorizontal, XawtextScrollAlways); j++; } + if(option[i].value & 4) { XtSetArg(args[j], XtNautoFill, True); j++; } + if(option[i].value & 8) { XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; } + } XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNeditType, XawtextEdit); j++; XtSetArg(args[j], XtNuseStringInPlace, False); j++; XtSetArg(args[j], XtNdisplayCaret, False); j++; XtSetArg(args[j], XtNright, XtChainRight); j++; XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def : *(char**)option[i].target); j++; XtSetArg(args[j], XtNinsertPosition, 9999); j++; + XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def : + currentCps ? option[i].textValue : *(char**)option[i].target); j++; edit = last; option[i].handle = (void*) (textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j)); XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); + if(option[i].min == 0 || option[i].type != TextBox) + XtOverrideTranslations(last, XtParseTranslationTable(oneLiner)); if(option[i].type == TextBox || option[i].type == Fractional) break; @@ -1882,8 +1440,7 @@ GenericPopUp(Option *option, char *title) } XtSetArg(args[j], XtNwidth, w); j++; edit = XtCreateManagedWidget(msg, commandWidgetClass, form, args, j); - XtAddCallback(edit, XtNcallback, SpinCallback, - (XtPointer)(intptr_t) i); + XtAddCallback(edit, XtNcallback, SpinCallback, (XtPointer)(intptr_t) i); if(option[i].type != Spin) break; @@ -1895,17 +1452,17 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[j], XtNleft, XtChainRight); j++; XtSetArg(args[j], XtNright, XtChainRight); j++; last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j); - XtAddCallback(last, XtNcallback, SpinCallback, - (XtPointer)(intptr_t) i); + XtAddCallback(last, XtNcallback, SpinCallback, (XtPointer)(intptr_t) i); break; case CheckBox: + if(!currentCps) option[i].value = *(Boolean*)option[i].target; j=0; XtSetArg(args[j], XtNfromVert, last); j++; XtSetArg(args[j], XtNwidth, 10); j++; XtSetArg(args[j], XtNheight, 10); j++; XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNstate, option[i].value = *(Boolean*)option[i].target); j++; + XtSetArg(args[j], XtNstate, option[i].value); j++; option[i].handle = (void*) (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j)); case Label: @@ -1919,7 +1476,10 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[j], XtNborderWidth, 0); j++; XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; last = XtCreateManagedWidget(msg, labelWidgetClass, form, args, j); + if(option[i].type == CheckBox) + XtAddEventHandler(last, ButtonPressMask, False, CheckCallback, (XtPointer)(intptr_t) i); break; + case SaveButton: case Button: j=0; XtSetArg(args[j], XtNfromVert, option[i].min & 1 ? lastrow : last); j++; @@ -1933,9 +1493,12 @@ GenericPopUp(Option *option, char *title) } option[i].handle = (void*) (dialog = last = XtCreateManagedWidget(option[i].name, commandWidgetClass, form, args, j)); - if(option[i].target == NULL) SetColor( *(char**) option[i-1].target, last); else + if(option[i].choice && !currentCps) { + SetColor( *(char**) option[i-1].target, last); + XtAddEventHandler(option[i-1].handle, KeyReleaseMask, False, ColorChanged, (XtPointer)(intptr_t) i-1); + } XtAddCallback(last, XtNcallback, GenericCallback, - (XtPointer)(intptr_t) i); + (XtPointer)(intptr_t) i + (dlgNr<<16)); if(option[i].textValue) SetColor( option[i].textValue, last); forelast = lastrow; // next button can go on same row break; @@ -1948,14 +1511,16 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j); - for(j=0; option[i].choice[j]; j++) + if(currentCps) option[i].choice = (char**) option[i].textValue; else { + for(j=0; option[i].choice[j]; j++) if(*(char**)option[i].target && !strcmp(*(char**)option[i].target, option[i].choice[j])) break; - option[i].value = j + (option[i].choice[j] == NULL); + option[i].value = j + (option[i].choice[j] == NULL); + } j=0; XtSetArg(args[j], XtNfromVert, last); j++; XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNwidth, option[i].max ? option[i].max : 100); j++; + XtSetArg(args[j], XtNwidth, option[i].max && !currentCps ? option[i].max : 100); j++; XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++; XtSetArg(args[j], XtNlabel, ((char**)option[i].textValue)[option[i].value]); j++; @@ -2024,16 +1589,17 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[j], XtNleft, XtChainRight); j++; XtSetArg(args[j], XtNright, XtChainRight); j++; b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, GenericCallback, (XtPointer) 0); + XtAddCallback(b_ok, XtNcallback, GenericCallback, (XtPointer)(intptr_t) dlgNr + (dlgNr<<16)); XtSetArg(args[0], XtNfromHoriz, b_ok); b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0); + XtAddCallback(b_cancel, XtNcallback, GenericCallback, (XtPointer)(intptr_t) dlgNr); } XtRealizeWidget(popup); - CatchDeleteWindow(popup, "SettingsPopDown"); - + XSetWMProtocols(xDisplay, XtWindow(popup), &wm_delete_window, 1); + snprintf(def, MSG_SIZ, "WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr); + XtAugmentTranslations(popup, XtParseTranslationTable(def)); XQueryPointer(xDisplay, xBoardWindow, &root, &child, &x, &y, &win_x, &win_y, &mask); @@ -2041,11 +1607,19 @@ GenericPopUp(Option *option, char *title) XtSetArg(args[1], XtNy, y - 30); XtSetValues(popup, args, 2); - XtPopup(popup, XtGrabExclusive); - SettingsUp = True; - + XtPopup(popup, dlgNr ? XtGrabNone : XtGrabExclusive); + shellUp[dlgNr] = True; previous = NULL; if(textField)SetFocus(textField, popup, (XEvent*) NULL, False); + if(dlgNr && wp[dlgNr] && wp[dlgNr]->width > 0) { // if persistent window-info available, reposition + j = 0; + XtSetArg(args[j], XtNheight, (Dimension) (wp[dlgNr]->height)); j++; + XtSetArg(args[j], XtNwidth, (Dimension) (wp[dlgNr]->width)); j++; + XtSetArg(args[j], XtNx, (Position) (wp[dlgNr]->x)); j++; + XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y)); j++; + XtSetValues(popup, args, j); + } + return 1; } @@ -2055,7 +1629,7 @@ void IcsOptionsProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - GenericPopUp(icsOptions, _("ICS Options")); + GenericPopUp(icsOptions, _("ICS Options"), 0); } void LoadOptionsProc(w, event, prms, nprms) @@ -2064,7 +1638,7 @@ void LoadOptionsProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - GenericPopUp(loadOptions, _("Load Game Options")); + GenericPopUp(loadOptions, _("Load Game Options"), 0); } void SaveOptionsProc(w, event, prms, nprms) @@ -2073,7 +1647,7 @@ void SaveOptionsProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - GenericPopUp(saveOptions, _("Save Game Options")); + GenericPopUp(saveOptions, _("Save Game Options"), 0); } void SoundOptionsProc(w, event, prms, nprms) @@ -2083,7 +1657,7 @@ void SoundOptionsProc(w, event, prms, nprms) Cardinal *nprms; { soundFiles[2] = "*"; - GenericPopUp(soundOptions, _("Sound Options")); + GenericPopUp(soundOptions, _("Sound Options"), 0); } void BoardOptionsProc(w, event, prms, nprms) @@ -2092,7 +1666,7 @@ void BoardOptionsProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - GenericPopUp(boardOptions, _("Board Options")); + GenericPopUp(boardOptions, _("Board Options"), 0); } void EngineMenuProc(w, event, prms, nprms) @@ -2101,8 +1675,276 @@ void EngineMenuProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - GenericPopUp(adjudicationOptions, "Adjudicate non-ICS Games"); + GenericPopUp(adjudicationOptions, "Adjudicate non-ICS Games", 0); +} + +void UciMenuProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + oldCores = appData.smpCores; + oldPonder = appData.ponderNextMove; + GenericPopUp(commonEngineOptions, _("Common Engine Settings"), 0); +} + +void NewVariantProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + GenericPopUp(variantDescriptors, _("New Variant"), 0); +} + +void OptionsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + oldPonder = appData.ponderNextMove; + GenericPopUp(generalOptions, _("General Options"), 0); +} + +void MatchOptionsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + GenericPopUp(matchOptions, _("Match Options"), 0); +} + +Option textOptions[100]; +extern char *icsTextMenuString; +void PutText P((char *text, int pos)); + +SendString(char *p) +{ + char buf[MSG_SIZ], *q; + if(q = strstr(p, "$input")) { + if(!shellUp[4]) return; + strncpy(buf, p, MSG_SIZ); + strncpy(buf + (q-p), q+6, MSG_SIZ-(q-p)); + PutText(buf, q-p); + return; + } + snprintf(buf, MSG_SIZ, "%s\n", p); + SendToICS(buf); +} + +/* function called when the data to Paste is ready */ +static void +SendTextCB(Widget w, XtPointer client_data, Atom *selection, + Atom *type, XtPointer value, unsigned long *len, int *format) +{ + char buf[MSG_SIZ], *p = (char*) textOptions[(int)(intptr_t) client_data].choice, *name = (char*) value, *q; + if (value==NULL || *len==0) return; /* nothing selected, abort */ + name[*len]='\0'; + strncpy(buf, p, MSG_SIZ); + q = strstr(p, "$name"); + snprintf(buf + (q-p), MSG_SIZ -(q-p), "%s%s", name, q+5); + SendString(buf); + XtFree(value); +} + +void SendText(int n) +{ + char *p = (char*) textOptions[n].choice; + if(strstr(p, "$name")) { + XtGetSelectionValue(menuBarWidget, + XA_PRIMARY, XA_STRING, + /* (XtSelectionCallbackProc) */ SendTextCB, + (XtPointer) (intptr_t) n, /* client_data passed to PastePositionCB */ + CurrentTime + ); + } else SendString(p); +} + +void IcsTextProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + int i=0, j; + char *p, *q, *r; + if((p = icsTextMenuString) == NULL) return; + do { + q = r = p; while(*p && *p != ';') p++; + for(j=0; joption, _("Engine Settings"), 0); +} + +void FirstSettingsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + SettingsPopUp(&first); +} + +void SecondSettingsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + if(WaitForSecond(SettingsMenuIfReady)) return; + SettingsPopUp(&second); } + //---------------------------- Chat Windows ---------------------------------------------- void OutputChatMessage(int partner, char *mess)