#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
+#include <X11/Xatom.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/List.h>
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;
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
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();
-}
-
//--------------------------- Engine-specific options menu ----------------------------------
-int SettingsUp;
-Widget SettingsShell;
int values[MAX_OPTIONS];
ChessProgramState *currentCps;
+static Option *currentOption;
+extern Widget shells[];
+static Boolean browserUp;
-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)
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
+ browserUp = True;
+ 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);
+ browserUp = 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; i<currentCps->nrOptions; 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
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)
}
}
-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);
+//----------------------------Generic dialog --------------------------------------------
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, popup,
- layoutArgs, XtNumber(layoutArgs));
- for(c=0; c<width; c++) {
- pane[4] = 'A'+c;
- form =
- XtCreateManagedWidget(pane, formWidgetClass, layout,
- formArgs, XtNumber(formArgs));
- j=0;
- XtSetArg(args[j], XtNfromHoriz, leftMargin); j++;
- XtSetValues(form, args, j);
- leftMargin = form;
+// cloned from Engine Settings dialog (and later merged with it)
- last = widest = NULL; anchor = forelast;
- for(h=0; h<height; h++) {
- forelast = last;
- i = h + c*height;
- if(i >= 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;
-
- // 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 CreateAnyPieces 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<height; h++) {
- i = h + c*height;
- if(i >= 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<height; h++) {
- i = h + c*height;
- if(i >= 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;
+ if(browserUp) return; // prevent closing dialog when it has an open file-browse daughter
+ 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 , "" }
+};
-// cloned from Engine Settings dialog
+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 */
+ }
+ }
-typedef void ButtonCallback(int n);
+ GenericReadout(); // make sure ranks and file settings are read
-char *trialSound;
-static Option *currentOption;
-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();
+ 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;
+ 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)
{
XtSetValues(box, args, 1);
}
-void AdjustColor(int i)
+void SetColorText(int n, char *buf)
{
- int n = currentOption[i].value, col, j, r, g, b, step = 10;
+ 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)
+{
+ 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, useImages, useImageSqs;
+ if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap;
+ useImages = useImageSqs = 0;
MakeColors(); CreateGCs(True);
- CreateXPMPieces();
- CreateXPMBoard(appData.liteBackTextureFile, 1);
- CreateXPMBoard(appData.darkBackTextureFile, 0);
+ CreateAnyPieces();
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, " " },
+{ 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") },
-{ 0, 0, 0, NULL, (void*) &appData.allWhite, "", NULL, CheckBox, _("Use Outline Pieces for Black") },
+{ 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):") },
{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, "", NULL, FileName, _("Light-Squares Texture File:") },
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) {
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:
sscanf(val, "%f", &x);
if(x > currentOption[i].max) x = currentOption[i].max;
if(x < currentOption[i].min) x = currentOption[i].min;
- if(currentOption[i].value != x) {
+ if(currentOption[i].type == Fractional)
+ *(float*) currentOption[i].target = x; // engines never have float options!
+ else if(currentOption[i].value != x) {
currentOption[i].value = x;
- if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x;
- else *(float*) currentOption[i].target = x;
+ if(currentCps) {
+ snprintf(buf, MSG_SIZ, "option %s=%.0f\n", currentOption[i].name, x);
+ SendToProgram(buf, currentCps);
+ } else *(int*) currentOption[i].target = x;
}
break;
case CheckBox:
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);
}
default:
printf("GenericReadout: unexpected case in switch.\n");
case Button:
+ case SaveButton:
case Label:
+ case Break:
break;
}
if(currentOption[i].type == EndMark) break;
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 = "<Key>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;
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);
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:
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;
}
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;
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:
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++;
}
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 && ((char*)option[i].choice)[0] == '#' && !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;
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++;
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, "<Message>WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr);
+ XtAugmentTranslations(popup, XtParseTranslationTable(def));
XQueryPointer(xDisplay, xBoardWindow, &root, &child,
&x, &y, &win_x, &win_y, &mask);
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;
}
String *prms;
Cardinal *nprms;
{
- GenericPopUp(icsOptions, _("ICS Options"));
+ GenericPopUp(icsOptions, _("ICS Options"), 0);
}
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)
String *prms;
Cardinal *nprms;
{
- GenericPopUp(saveOptions, _("Save Game Options"));
+ GenericPopUp(saveOptions, _("Save Game Options"), 0);
}
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)
String *prms;
Cardinal *nprms;
{
- GenericPopUp(boardOptions, _("Board Options"));
+ GenericPopUp(boardOptions, _("Board Options"), 0);
}
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)
{
oldCores = appData.smpCores;
oldPonder = appData.ponderNextMove;
- GenericPopUp(commonEngineOptions, _("Common Engine Settings"));
+ 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; j<p-q; j++) textOptions[i].name[j] = *r++;
+ textOptions[i].name[j++] = 0;
+ if(!*p) break;
+ if(*++p == '\n') p++; // optional linefeed after button-text terminating semicolon
+ q = p;
+ textOptions[i].choice = (char**) (r = textOptions[i].name + j);
+ while(*p && (*p != ';' || p[1] != '\n')) textOptions[i].name[j++] = *p++;
+ textOptions[i].name[j++] = 0;
+ if(*p) p += 2;
+ textOptions[i].max = 135;
+ textOptions[i].min = i&1;
+ textOptions[i].handle = NULL;
+ textOptions[i].target = &SendText;
+ textOptions[i].textValue = strstr(r, "$input") ? "#80FF80" : strstr(r, "$name") ? "#FF8080" : "#FFFFFF";
+ textOptions[i].type = Button;
+ } while(++i < 99 && *p);
+ if(i == 0) return;
+ textOptions[i].type = EndMark;
+ textOptions[i].target = NULL;
+ textOptions[i].min = 2;
+ MarkMenu("menuView.ICStex", 3);
+ GenericPopUp(textOptions, _("ICS text menu"), 3);
+}
+
+static char *commentText;
+static int commentIndex;
+void ClearComment P((int n));
+extern char commentTranslations[];
+
+void NewComCallback(int n)
+{
+ ReplaceComment(commentIndex, commentText);
+}
+
+void SaveChanges(int n)
+{
+ Arg args[16];
+ XtSetArg(args[0], XtNstring, &commentText);
+ XtGetValues(currentOption[0].handle, args, 1);
+ ReplaceComment(commentIndex, commentText);
+}
+
+Option commentOptions[] = {
+{ 0xD, 200, 300, NULL, (void*) &commentText, "", NULL, TextBox, "" },
+{ 0, 0, 0, NULL, (void*) &ClearComment, NULL, NULL, Button, "clear" },
+{ 0, 1, 0, NULL, (void*) &SaveChanges, NULL, NULL, Button, "save changes" },
+{ 0, 1, 0, NULL, (void*) &NewComCallback, "", NULL, EndMark , "" }
+};
+
+void ClearComment(int n)
+{
+ XtCallActionProc(commentOptions[0].handle, "select-all", NULL, NULL, 0);
+ XtCallActionProc(commentOptions[0].handle, "kill-selection", NULL, NULL, 0);
+}
+
+void NewCommentPopup(char *title, char *text, int index)
+{
+ Widget edit;
+ Arg args[16];
+
+ if(shells[1]) { // if already exists, alter title and content
+ XtSetArg(args[0], XtNtitle, title);
+ XtSetValues(shells[1], args, 1);
+ XtSetArg(args[0], XtNstring, text);
+ XtSetValues(commentOptions[0].handle, args, 1);
+ }
+ commentText = text;
+ commentIndex = index;
+ MarkMenu("menuView.Show Comments", 1);
+ if(GenericPopUp(commentOptions, title, 1))
+ XtOverrideTranslations(commentOptions[0].handle, XtParseTranslationTable(commentTranslations));
+}
+
+static char *tagsText, *msgText;
+
+void NewTagsCallback(int n)
+{
+ ReplaceTags(tagsText, &gameInfo);
+}
+
+void changeTags(int n)
+{
+ Arg args[16];
+ XtSetArg(args[0], XtNstring, &tagsText);
+ XtGetValues(currentOption[0].handle, args, 1);
+ ReplaceTags(tagsText, &gameInfo);
+}
+
+Option tagsOptions[] = {
+{ 0xD, 200, 250, NULL, (void*) &tagsText, "", NULL, TextBox, "" },
+{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, "" },
+{ 0, 0, 0, NULL, (void*) &changeTags, NULL, NULL, Button, "save changes" },
+{ 0, 1, 0, NULL, (void*) &NewTagsCallback, "", NULL, EndMark , "" }
+};
+
+void NewTagsPopup(char *text, char *msg)
+{
+ Widget edit;
+ Arg args[16];
+
+ if(shells[2]) { // if already exists, alter title and content
+ XtSetArg(args[0], XtNstring, text);
+ XtSetValues(tagsOptions[0].handle, args, 1);
+ }
+ tagsText = text;
+ tagsOptions[1].textValue = msg;
+ MarkMenu("menuView.Show Tags", 2);
+ GenericPopUp(tagsOptions, _("Tags"), 2);
+}
+
+extern char ICSInputTranslations[];
+char *icsText;
+
+Option boxOptions[] = {
+{ 0, 30, 400, NULL, (void*) &icsText, "", NULL, TextBox, "" },
+{ 0, 3, 0, NULL, NULL, "", NULL, EndMark , "" }
+};
+
+void PutText(char *text, int pos)
+{
+ Widget edit;
+ Arg args[16];
+ char buf[MSG_SIZ], *p;
+
+ if(strstr(text, "$add ") == text) {
+ XtSetArg(args[0], XtNstring, &p);
+ XtGetValues(boxOptions[0].handle, args, 1);
+ snprintf(buf, MSG_SIZ, "%s%s", p, text+5); text = buf;
+ pos += strlen(p) - 5;
+ }
+ XtSetArg(args[0], XtNstring, text);
+ XtSetValues(boxOptions[0].handle, args, 1);
+ XtSetArg(args[0], XtNinsertPosition, pos);
+ XtSetValues(boxOptions[0].handle, args, 1);
+// SetFocus(boxOptions[0].handle, shells[4], NULL, False); // No idea why this does not work, and the following is needed:
+ XSetInputFocus(xDisplay, XtWindow(boxOptions[0].handle), RevertToPointerRoot, CurrentTime);
+}
+
+void InputBoxPopup()
+{
+ MarkMenu("menuView.ICS Input Box", 4);
+ if(GenericPopUp(boxOptions, _("ICS input box"), 4))
+ XtOverrideTranslations(boxOptions[0].handle, XtParseTranslationTable(ICSInputTranslations));
+}
+
+void TypeInProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{
+ Arg args[2];
+ String val;
+
+ if(prms[0][0] == '1') {
+ XtSetArg(args[0], XtNstring, &val);
+ XtGetValues(boxOptions[0].handle, args, 1);
+ TypeInDoneEvent((char*)val);
+ }
+ PopDown(0);\r
+}
+
+char moveTypeInTranslations[] =
+ "<Key>Return: TypeInProc(1) \n"
+ "<Key>Escape: TypeInProc(0) \n";
+
+void PopUpMoveDialog(char firstchar)
+{
+ static char buf[2];
+ buf[0] = firstchar; icsText = buf;
+ if(GenericPopUp(boxOptions, _("Type a move"), 0))
+ XtOverrideTranslations(boxOptions[0].handle, XtParseTranslationTable(moveTypeInTranslations));
+}
+
+void MoveTypeInProc(Widget widget, caddr_t unused, XEvent *event)
+{
+ char buf[10], keys[32];
+ KeySym sym;
+ KeyCode metaL, metaR;
+ int n = XLookupString(&(event->xkey), buf, 10, &sym, NULL);
+ XQueryKeymap(xDisplay,keys);
+ metaL = XKeysymToKeycode(xDisplay, XK_Meta_L);
+ metaR = XKeysymToKeycode(xDisplay, XK_Meta_R);
+ if ( n == 1 && *buf > 32 && !(keys[metaL>>3]&1<<(metaL&7)) && !(keys[metaR>>3]&1<<(metaR&7))) // printable, no alt
+ PopUpMoveDialog(*buf);
+
+}
+
+void
+SettingsPopUp(ChessProgramState *cps)
+{
+ currentCps = cps;
+ GenericPopUp(cps->option, _("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 ----------------------------------------------