2 * xoptions.c -- Move list window, part of X front end for XBoard
4 * Copyright 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
5 * ------------------------------------------------------------------------
7 * GNU XBoard is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or (at
10 * your option) any later version.
12 * GNU XBoard is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see http://www.gnu.org/licenses/. *
20 *------------------------------------------------------------------------
21 ** See the file ChangeLog for a revision history. */
23 // [HGM] this file is the counterpart of woptions.c, containing xboard popup menus
24 // similar to those of WinBoard, to set the most common options interactively.
31 #include <sys/types.h>
36 #else /* not STDC_HEADERS */
37 extern char *getenv();
40 # else /* not HAVE_STRING_H */
42 # endif /* not HAVE_STRING_H */
43 #endif /* not STDC_HEADERS */
50 #include <X11/Intrinsic.h>
51 #include <X11/StringDefs.h>
52 #include <X11/Shell.h>
53 #include <X11/Xaw/Dialog.h>
54 #include <X11/Xaw/Form.h>
55 #include <X11/Xaw/List.h>
56 #include <X11/Xaw/Label.h>
57 #include <X11/Xaw/SimpleMenu.h>
58 #include <X11/Xaw/SmeBSB.h>
59 #include <X11/Xaw/SmeLine.h>
60 #include <X11/Xaw/Box.h>
61 #include <X11/Xaw/Paned.h>
62 #include <X11/Xaw/MenuButton.h>
63 #include <X11/cursorfont.h>
64 #include <X11/Xaw/Text.h>
65 #include <X11/Xaw/AsciiText.h>
66 #include <X11/Xaw/Viewport.h>
67 #include <X11/Xaw/Toggle.h>
75 # define _(s) gettext (s)
76 # define N_(s) gettext_noop (s)
82 extern void SendToProgram P((char *message, ChessProgramState *cps));
83 FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
84 char *init_path, char *mode, int (*show_entry)(), char **name_return));
86 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
87 extern Display *xDisplay;
88 extern int squareSize;
89 extern Pixmap xMarkPixmap;
90 extern char *layoutName;
91 extern Window xBoardWindow;
92 extern Arg layoutArgs[2], formArgs[2];
93 Pixel timerForegroundPixel, timerBackgroundPixel;
94 extern int searchTime;
97 // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines
99 static Widget previous = NULL;
101 void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b)
107 XtSetArg(args[0], XtNdisplayCaret, False);
108 XtSetValues(previous, args, 1);
110 XtSetArg(args[0], XtNstring, &s);
111 XtGetValues(w, args, 1);
112 XtSetArg(args[0], XtNdisplayCaret, True);
113 XtSetArg(args[1], XtNinsertPosition, strlen(s));
114 XtSetValues(w, args, 2);
115 XtSetKeyboardFocus((Widget) data, w);
119 //--------------------------- New Shuffle Game --------------------------------------------
120 extern int shuffleOpenings;
121 extern int startedFromPositionFile;
125 void ShufflePopDown()
127 if (!shuffleUp) return;
128 XtPopdown(shuffleShell);
129 XtDestroyWidget(shuffleShell);
134 void ShuffleCallback(w, client_data, call_data)
136 XtPointer client_data, call_data;
143 XtSetArg(args[0], XtNlabel, &name);
144 XtGetValues(w, args, 1);
146 if (strcmp(name, _("cancel")) == 0) {
150 if (strcmp(name, _("off")) == 0) {
152 shuffleOpenings = False; // [HGM] should be moved to New Variant menu, once we have it!
156 if (strcmp(name, _("random")) == 0) {
157 snprintf(buf, MSG_SIZ, "%d", rand());
158 XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value
159 XtSetValues(XtParent(w), args, 1);
162 if (strcmp(name, _("ok")) == 0) {
164 name = XawDialogGetValueString(w2 = XtParent(w));
165 if(sscanf(name ,"%d",&nr) != 1) {
166 snprintf(buf, MSG_SIZ, "%d", appData.defaultFrcPosition);
167 XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value
168 XtSetValues(w2, args, 1);
171 appData.defaultFrcPosition = nr;
172 shuffleOpenings = True;
182 Widget popup, layout, dialog, edit;
190 XtSetArg(args[i], XtNresizable, True); i++;
191 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
192 shuffleShell = popup =
193 XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass,
194 shellWidget, args, i);
197 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
198 layoutArgs, XtNumber(layoutArgs));
200 snprintf(def, MSG_SIZ, "%d\n", appData.defaultFrcPosition);
202 XtSetArg(args[i], XtNlabel, _("Start-position number:")); i++;
203 XtSetArg(args[i], XtNvalue, def); i++;
204 XtSetArg(args[i], XtNborderWidth, 0); i++;
205 dialog = XtCreateManagedWidget(_("Shuffle"), dialogWidgetClass,
208 // XtSetArg(args[0], XtNeditType, XawtextEdit); // [HGM] can't get edit to work decently
209 // XtSetArg(args[1], XtNuseStringInPlace, False);
210 // XtSetValues(dialog, args, 2);
212 XawDialogAddButton(dialog, _("ok"), ShuffleCallback, (XtPointer) dialog);
213 XawDialogAddButton(dialog, _("cancel"), ShuffleCallback, (XtPointer) dialog);
214 XawDialogAddButton(dialog, _("random"), ShuffleCallback, (XtPointer) dialog);
215 XawDialogAddButton(dialog, _("off"), ShuffleCallback, (XtPointer) dialog);
217 XtRealizeWidget(popup);
218 CatchDeleteWindow(popup, "ShufflePopDown");
220 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
221 &x, &y, &win_x, &win_y, &mask);
223 XtSetArg(args[0], XtNx, x - 10);
224 XtSetArg(args[1], XtNy, y - 30);
225 XtSetValues(popup, args, 2);
227 XtPopup(popup, XtGrabExclusive);
230 edit = XtNameToWidget(dialog, "*value");
232 XtSetKeyboardFocus(popup, edit);
235 void ShuffleMenuProc(w, event, prms, nprms)
241 // if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
242 // Reset(FALSE, TRUE);
247 //--------------------------- Time-Control Menu Popup ----------------------------------
249 Widget TimeControlShell;
251 Widget tcMess1, tcMess2, tcData, tcTime, tcOdds1, tcOdds2;
252 int tcIncrement, tcMoves;
254 void TimeControlPopDown()
256 if (!TimeControlUp) return;
258 XtPopdown(TimeControlShell);
259 XtDestroyWidget(TimeControlShell);
260 TimeControlUp = False;
264 void TimeControlCallback(w, client_data, call_data)
266 XtPointer client_data, call_data;
273 XtSetArg(args[0], XtNlabel, &name);
274 XtGetValues(w, args, 1);
276 if (strcmp(name, _("classical")) == 0) {
277 if(tcInc == 0) return;
279 XtSetArg(args[j], XtNlabel, _("minutes for each")); j++;
280 XtSetValues(tcMess1, args, j);
282 XtSetArg(args[j], XtNlabel, _("moves")); j++;
283 XtSetValues(tcMess2, args, j);
286 XtSetArg(args[j], XtNstring, &name); j++;
287 XtGetValues(tcData, args, j);
288 tcIncrement = 0; sscanf(name, "%d", &tcIncrement);
290 snprintf(buf, MSG_SIZ, "%d", tcMoves);
292 XtSetArg(args[j], XtNstring, buf); j++;
293 XtSetValues(tcData, args, j);
297 if (strcmp(name, _("incremental")) == 0) {
298 if(tcInc == 1) return;
300 XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++;
301 XtSetValues(tcMess1, args, j);
303 XtSetArg(args[j], XtNlabel, _("sec/move")); j++;
304 XtSetValues(tcMess2, args, j);
307 XtSetArg(args[j], XtNstring, &name); j++;
308 XtGetValues(tcData, args, j);
309 tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves);
311 snprintf(buf, MSG_SIZ, "%d", tcIncrement);
313 XtSetArg(args[j], XtNstring, buf); j++;
314 XtSetValues(tcData, args, j);
318 if (strcmp(name, _("fixed time")) == 0) {
319 if(tcInc == 2) return;
321 XtSetArg(args[j], XtNlabel, _("sec/move (max)")); j++;
322 XtSetValues(tcMess1, args, j);
324 XtSetArg(args[j], XtNlabel, _("")); j++;
325 XtSetValues(tcMess2, args, j);
327 XtSetArg(args[j], XtNstring, ""); j++;
328 XtSetValues(tcData, args, j);
332 if (strcmp(name, _(" OK ")) == 0) {
334 XtSetArg(args[0], XtNstring, &txt);
335 XtGetValues(tcData, args, 1);
338 ok = sscanf(txt, "%d", &inc); mps = 0;
339 if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero
343 ok = sscanf(txt, "%d", &mps); inc = -1;
347 ok = 1; inc = -1; mps = 40;
350 XtSetArg(args[0], XtNstring, ""); // erase any offending input
351 XtSetValues(tcData, args, 1);
354 XtSetArg(args[0], XtNstring, &txt);
355 XtGetValues(tcTime, args, 1);
357 if(sscanf(txt, "%d", &inc) != 1) {
358 XtSetArg(args[0], XtNstring, ""); // erase any offending input
359 XtSetValues(tcTime, args, 1);
360 DisplayError(_("Bad Time-Control String"), 0);
365 if(!ParseTimeControl(txt, inc, mps)) {
366 XtSetArg(args[0], XtNstring, ""); // erase any offending input
367 XtSetValues(tcTime, args, 1);
368 DisplayError(_("Bad Time-Control String"), 0);
372 appData.movesPerSession = mps;
373 appData.timeIncrement = inc;
374 appData.timeControl = strdup(txt);
376 XtSetArg(args[0], XtNstring, &txt);
377 XtGetValues(tcOdds1, args, 1);
378 appData.firstTimeOdds = first.timeOdds
379 = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;
380 XtGetValues(tcOdds2, args, 1);
381 appData.secondTimeOdds = second.timeOdds
382 = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;
385 TimeControlPopDown();
390 void TimeControlPopUp()
393 Widget popup, layout, form, b_ok, b_cancel, b_clas, b_inc, mess;
400 tcInc = searchTime > 0 ? 2 : (appData.timeIncrement >= 0);
401 tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;
402 if(!tcInc) tcIncrement = 0;
403 snprintf(def, MSG_SIZ, "%d", tcInc ? tcIncrement : tcMoves);
406 XtSetArg(args[i], XtNresizable, True); i++;
407 // XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
408 TimeControlShell = popup =
409 XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass,
410 shellWidget, args, i);
413 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
414 layoutArgs, XtNumber(layoutArgs));
417 XtCreateManagedWidget(layoutName, formWidgetClass, layout,
418 formArgs, XtNumber(formArgs));
421 // XtSetArg(args[j], XtNwidth, (XtArgVal) 300); j++;
422 // XtSetArg(args[j], XtNheight, (XtArgVal) 85); j++;
423 XtSetValues(popup, args, j);
426 XtSetArg(args[j], XtNborderWidth, 1); j++;
427 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
428 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
429 XtSetArg(args[j], XtNstring, appData.timeControl); j++;
430 XtSetArg(args[j], XtNdisplayCaret, False); j++;
431 XtSetArg(args[j], XtNtop, XtChainTop); j++;
432 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
433 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
434 XtSetArg(args[j], XtNright, XtChainRight); j++;
435 XtSetArg(args[j], XtNresizable, True); j++;
436 XtSetArg(args[j], XtNwidth, 85); j++;
437 XtSetArg(args[j], XtNinsertPosition, 9999); j++;
438 tcTime = XtCreateManagedWidget("TC", asciiTextWidgetClass, form, args, j);
439 XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup);
442 XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("sec/move (max) ") : _(" minutes, plus ") : _("minutes for each")); j++;
443 XtSetArg(args[j], XtNborderWidth, 0); j++;
444 XtSetArg(args[j], XtNfromHoriz, tcTime); j++;
445 XtSetArg(args[j], XtNtop, XtChainTop); j++;
446 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
447 XtSetArg(args[j], XtNleft, XtChainRight); j++;
448 XtSetArg(args[j], XtNright, XtChainRight); j++;
449 // XtSetArg(args[j], XtNwidth, 100); j++;
450 // XtSetArg(args[j], XtNheight, 20); j++;
451 tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);
454 XtSetArg(args[j], XtNborderWidth, 1); j++;
455 XtSetArg(args[j], XtNfromHoriz, tcMess1); j++;
456 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
457 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
458 XtSetArg(args[j], XtNstring, def); j++;
459 XtSetArg(args[j], XtNdisplayCaret, False); j++;
460 XtSetArg(args[j], XtNtop, XtChainTop); j++;
461 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
462 XtSetArg(args[j], XtNleft, XtChainRight); j++;
463 XtSetArg(args[j], XtNright, XtChainRight); j++;
464 XtSetArg(args[j], XtNresizable, True); j++;
465 XtSetArg(args[j], XtNwidth, 40); j++;
466 // XtSetArg(args[j], XtNheight, 20); j++;
467 tcData = XtCreateManagedWidget("MPS", asciiTextWidgetClass, form, args, j);
468 XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup);
471 XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _(" ") : _("sec/move") : _("moves ")); j++;
472 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
473 XtSetArg(args[j], XtNborderWidth, 0); j++;
474 XtSetArg(args[j], XtNfromHoriz, tcData); j++;
475 XtSetArg(args[j], XtNtop, XtChainTop); j++;
476 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
477 XtSetArg(args[j], XtNleft, XtChainRight); j++;
478 XtSetArg(args[j], XtNright, XtChainRight); j++;
479 // XtSetArg(args[j], XtNwidth, 80); j++;
480 // XtSetArg(args[j], XtNheight, 20); j++;
481 tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass,
485 XtSetArg(args[j], XtNborderWidth, 1); j++;
486 XtSetArg(args[j], XtNfromVert, tcTime); j++;
487 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
488 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
489 XtSetArg(args[j], XtNstring, "1"); j++;
490 XtSetArg(args[j], XtNdisplayCaret, False); j++;
491 XtSetArg(args[j], XtNtop, XtChainTop); j++;
492 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
493 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
494 XtSetArg(args[j], XtNright, XtChainLeft); j++;
495 XtSetArg(args[j], XtNresizable, True); j++;
496 XtSetArg(args[j], XtNwidth, 40); j++;
497 // XtSetArg(args[j], XtNheight, 20); j++;
498 tcOdds1 = XtCreateManagedWidget("Odds1", asciiTextWidgetClass, form, args, j);
499 XtAddEventHandler(tcOdds1, ButtonPressMask, False, SetFocus, (XtPointer) popup);
502 XtSetArg(args[j], XtNborderWidth, 1); j++;
503 XtSetArg(args[j], XtNfromVert, tcTime); j++;
504 XtSetArg(args[j], XtNfromHoriz, tcOdds1); j++;
505 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
506 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
507 XtSetArg(args[j], XtNstring, "1"); j++;
508 XtSetArg(args[j], XtNdisplayCaret, False); j++;
509 XtSetArg(args[j], XtNtop, XtChainTop); j++;
510 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
511 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
512 XtSetArg(args[j], XtNright, XtChainLeft); j++;
513 XtSetArg(args[j], XtNresizable, True); j++;
514 XtSetArg(args[j], XtNwidth, 40); j++;
515 // XtSetArg(args[j], XtNheight, 20); j++;
516 tcOdds2 = XtCreateManagedWidget("Odds2", asciiTextWidgetClass, form, args, j);
517 XtAddEventHandler(tcOdds2, ButtonPressMask, False, SetFocus, (XtPointer) popup);
520 XtSetArg(args[j], XtNlabel, _("Engine #1 and #2 Time-Odds Factors")); j++;
521 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
522 XtSetArg(args[j], XtNborderWidth, 0); j++;
523 XtSetArg(args[j], XtNfromVert, tcTime); j++;
524 XtSetArg(args[j], XtNfromHoriz, tcOdds2); j++;
525 XtSetArg(args[j], XtNtop, XtChainTop); j++;
526 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
527 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
528 XtSetArg(args[j], XtNright, XtChainRight); j++;
529 // XtSetArg(args[j], XtNwidth, 200); j++;
530 // XtSetArg(args[j], XtNheight, 20); j++;
531 mess = XtCreateManagedWidget("Oddstext", labelWidgetClass,
534 XtSetArg(args[j], XtNfromVert, tcOdds1); j++;
535 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
536 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
537 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
538 XtSetArg(args[j], XtNright, XtChainLeft); j++;
539 XtSetArg(args[j], XtNstate, tcInc==0); j++;
540 b_clas= XtCreateManagedWidget(_("classical"), toggleWidgetClass,
542 XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0);
545 XtSetArg(args[j], XtNradioGroup, b_clas); j++;
546 XtSetArg(args[j], XtNfromVert, tcOdds1); j++;
547 XtSetArg(args[j], XtNfromHoriz, b_clas); j++;
548 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
549 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
550 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
551 XtSetArg(args[j], XtNright, XtChainLeft); j++;
552 XtSetArg(args[j], XtNstate, tcInc==1); j++;
553 b_inc = XtCreateManagedWidget(_("incremental"), toggleWidgetClass,
555 XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
558 XtSetArg(args[j], XtNradioGroup, b_inc); j++;
559 XtSetArg(args[j], XtNfromVert, tcOdds1); j++;
560 XtSetArg(args[j], XtNfromHoriz, b_inc); j++;
561 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
562 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
563 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
564 XtSetArg(args[j], XtNright, XtChainLeft); j++;
565 XtSetArg(args[j], XtNstate, tcInc==2); j++;
566 b_inc = XtCreateManagedWidget(_("fixed time"), toggleWidgetClass,
568 XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
571 XtSetArg(args[j], XtNfromVert, tcOdds1); j++;
572 XtSetArg(args[j], XtNfromHoriz, tcData); j++;
573 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
574 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
575 XtSetArg(args[j], XtNleft, XtChainRight); j++;
576 XtSetArg(args[j], XtNright, XtChainRight); j++;
577 b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass,
579 XtAddCallback(b_ok, XtNcallback, TimeControlCallback, (XtPointer) 0);
582 XtSetArg(args[j], XtNfromVert, tcOdds1); j++;
583 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
584 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
585 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
586 XtSetArg(args[j], XtNleft, XtChainRight); j++;
587 XtSetArg(args[j], XtNright, XtChainRight); j++;
588 b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass,
590 XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0);
592 XtRealizeWidget(popup);
593 CatchDeleteWindow(popup, "TimeControlPopDown");
595 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
596 &x, &y, &win_x, &win_y, &mask);
598 XtSetArg(args[0], XtNx, x - 10);
599 XtSetArg(args[1], XtNy, y - 30);
600 XtSetValues(popup, args, 2);
602 XtPopup(popup, XtGrabExclusive);
603 TimeControlUp = True;
606 SetFocus(tcTime, popup, (XEvent*) NULL, False);
607 // XtSetKeyboardFocus(popup, tcTime);
610 void TimeControlProc(w, event, prms, nprms)
619 //--------------------------- Engine-Options Menu Popup ----------------------------------
622 extern int adjudicateLossThreshold;
624 Widget engDrawMoves, engThreshold, engRule, engRepeat;
628 if (!EngineUp) return;
630 XtPopdown(EngineShell);
631 XtDestroyWidget(EngineShell);
636 int ReadToggle(Widget w)
638 Arg args; Boolean res;
640 XtSetArg(args, XtNstate, &res);
641 XtGetValues(w, &args, 1);
646 Widget w1, w2, w3, w4, w5, w6, w7, w8;
648 void EngineCallback(w, client_data, call_data)
650 XtPointer client_data, call_data;
656 XtSetArg(args[0], XtNlabel, &name);
657 XtGetValues(w, args, 1);
659 if (strcmp(name, _("OK")) == 0) {
661 appData.periodicUpdates = ReadToggle(w1);
662 // appData.hideThinkingFromHuman = ReadToggle(w2);
663 first.scoreIsAbsolute = appData.firstScoreIsAbsolute = ReadToggle(w3);
664 second.scoreIsAbsolute = appData.secondScoreIsAbsolute = ReadToggle(w4);
665 appData.testClaims = ReadToggle(w5);
666 appData.checkMates = ReadToggle(w6);
667 appData.materialDraws = ReadToggle(w7);
668 appData.trivialDraws = ReadToggle(w8);
670 // adjust setting in other menu for duplicates
671 // (perhaps duplicates should be removed from general Option Menu?)
672 // XtSetArg(args[0], XtNleftBitmap, appData.showThinking ? xMarkPixmap : None);
673 // XtSetValues(XtNameToWidget(menuBarWidget,
674 // "menuOptions.Show Thinking"), args, 1);
676 // read out numeric controls, simply ignore bad formats for now
677 XtSetArg(args[0], XtNstring, &name);
678 XtGetValues(engDrawMoves, args, 1);
679 if(sscanf(name, "%d", &j) == 1) appData.adjudicateDrawMoves = j;
680 XtGetValues(engThreshold, args, 1);
681 if(sscanf(name, "%d", &j) == 1)
682 adjudicateLossThreshold = appData.adjudicateLossThreshold = -j; // inverted!
683 XtGetValues(engRule, args, 1);
684 if(sscanf(name, "%d", &j) == 1) appData.ruleMoves = j;
685 XtGetValues(engRepeat, args, 1);
686 if(sscanf(name, "%d", &j) == 1) appData.drawRepeats = j;
689 ShowThinkingEvent(); // [HGM] thinking: score adjudication might need thinking output
697 Widget popup, layout, form, b_ok, b_cancel, s1;
699 int x, y, i, j, width;
704 tcInc = (appData.timeIncrement >= 0);
705 tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;
706 if(!tcInc) tcIncrement = 0;
707 snprintf(def, MSG_SIZ, "%d", tcInc ? tcIncrement : tcMoves);
710 XtSetArg(args[i], XtNresizable, True); i++;
711 // XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
712 EngineShell = popup =
713 XtCreatePopupShell(_("Adjudications"), transientShellWidgetClass,
714 shellWidget, args, i);
717 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
718 layoutArgs, XtNumber(layoutArgs));
721 XtCreateManagedWidget(layoutName, formWidgetClass, layout,
722 formArgs, XtNumber(formArgs));
725 // XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++;
726 // XtSetArg(args[j], XtNheight, (XtArgVal) 400); j++;
727 // XtSetValues(popup, args, j);
730 // XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++;
731 // XtSetArg(args[j], XtNheight, (XtArgVal) 20); j++;
732 XtSetArg(args[j], XtNleft, (XtArgVal) XtChainLeft); j++;
733 XtSetArg(args[j], XtNright, (XtArgVal) XtChainRight); j++;
734 XtSetArg(args[j], XtNstate, appData.periodicUpdates); j++;
735 // XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++;
736 w1 = XtCreateManagedWidget(_("Periodic Updates (Analysis Mode)"), toggleWidgetClass, form, args, j);
738 XtSetArg(args[j], XtNwidth, (XtArgVal) &width);
739 XtGetValues(w1, &args[j], 1);
741 // XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w1);
742 // XtSetArg(args[j-3], XtNstate, appData.hideThinkingFromHuman);
743 // w2 = XtCreateManagedWidget(_("Hide Thinking from Human"), toggleWidgetClass, form, args, j);
745 XtSetArg(args[j], XtNwidth, (XtArgVal) width); j++;
746 XtSetArg(args[j-2], XtNstate, appData.firstScoreIsAbsolute);
747 XtSetArg(args[j], XtNfromVert, (XtArgVal) w1); j++;
748 w3 = XtCreateManagedWidget(_("Engine #1 Score is Absolute"), toggleWidgetClass, form, args, j);
750 XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w3);
751 XtSetArg(args[j-3], XtNstate, appData.secondScoreIsAbsolute);
752 w4 = XtCreateManagedWidget(_("Engine #2 Score is Absolute"), toggleWidgetClass, form, args, j);
754 s1 = XtCreateManagedWidget(_("\nAdjudications in non-ICS games:"), labelWidgetClass, form, args, 3);
756 XtSetArg(args[j-1], XtNfromVert, (XtArgVal) s1);
757 XtSetArg(args[j-3], XtNstate, appData.testClaims);
758 w5 = XtCreateManagedWidget(_("Verify Engine Result Claims"), toggleWidgetClass, form, args, j);
760 XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w5);
761 XtSetArg(args[j-3], XtNstate, appData.checkMates);
762 w6 = XtCreateManagedWidget(_("Detect All Mates"), toggleWidgetClass, form, args, j);
764 XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w6);
765 XtSetArg(args[j-3], XtNstate, appData.materialDraws);
766 w7 = XtCreateManagedWidget(_("Draw when Insuff. Mating Material"), toggleWidgetClass, form, args, j);
768 XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w7);
769 XtSetArg(args[j-3], XtNstate, appData.trivialDraws);
770 w8 = XtCreateManagedWidget(_("Adjudicate Trivial Draws"), toggleWidgetClass, form, args, j);
772 XtSetArg(args[0], XtNfromVert, (XtArgVal) w4);
773 XtSetArg(args[1], XtNborderWidth, (XtArgVal) 0);
774 XtSetValues(s1, args, 2);
776 snprintf(def, MSG_SIZ, "%d", appData.adjudicateDrawMoves);
778 XtSetArg(args[j], XtNborderWidth, 1); j++;
779 XtSetArg(args[j], XtNfromVert, w8); j++;
780 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
781 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
782 XtSetArg(args[j], XtNstring, def); j++;
783 XtSetArg(args[j], XtNdisplayCaret, False); j++;
784 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
785 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
786 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
787 XtSetArg(args[j], XtNright, XtChainLeft); j++;
788 XtSetArg(args[j], XtNresizable, True); j++;
789 XtSetArg(args[j], XtNwidth, 60); j++;
790 // XtSetArg(args[j], XtNheight, 20); j++;
791 engDrawMoves = XtCreateManagedWidget("Length", asciiTextWidgetClass, form, args, j);
792 XtAddEventHandler(engDrawMoves, ButtonPressMask, False, SetFocus, (XtPointer) popup);
795 XtSetArg(args[j], XtNlabel, _(" moves maximum, then draw")); j++;
796 XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++;
797 XtSetArg(args[j], XtNborderWidth, 0); j++;
798 XtSetArg(args[j], XtNfromVert, w8); j++;
799 XtSetArg(args[j], XtNfromHoriz, engDrawMoves); j++;
800 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
801 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
802 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
803 XtSetArg(args[j], XtNright, XtChainLeft); j++;
804 // XtSetArg(args[j], XtNwidth, 170); j++;
805 // XtSetArg(args[j], XtNheight, 20); j++;
806 tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);
808 snprintf(def, MSG_SIZ, "%d", -appData.adjudicateLossThreshold); // inverted!
810 XtSetArg(args[j], XtNborderWidth, 1); j++;
811 XtSetArg(args[j], XtNfromVert, engDrawMoves); j++;
812 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
813 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
814 XtSetArg(args[j], XtNstring, def); j++;
815 XtSetArg(args[j], XtNdisplayCaret, False); j++;
816 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
817 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
818 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
819 XtSetArg(args[j], XtNright, XtChainLeft); j++;
820 XtSetArg(args[j], XtNresizable, True); j++;
821 XtSetArg(args[j], XtNwidth, 60); j++;
822 XtSetArg(args[j], XtNinsertPosition, 9999); j++;
823 engThreshold = XtCreateManagedWidget("Threshold", asciiTextWidgetClass, form, args, j);
824 XtAddEventHandler(engThreshold, ButtonPressMask, False, SetFocus, (XtPointer) popup);
827 XtSetArg(args[j], XtNlabel, _("-centiPawn lead is win")); j++;
828 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
829 XtSetArg(args[j], XtNborderWidth, 0); j++;
830 XtSetArg(args[j], XtNfromVert, engDrawMoves); j++;
831 XtSetArg(args[j], XtNfromHoriz, engThreshold); j++;
832 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
833 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
834 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
835 XtSetArg(args[j], XtNright, XtChainLeft); j++;
836 // XtSetArg(args[j], XtNwidth, 150); j++;
837 // XtSetArg(args[j], XtNheight, 20); j++;
838 tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j);
840 snprintf(def, MSG_SIZ, "%d", appData.ruleMoves);
842 XtSetArg(args[j], XtNborderWidth, 1); j++;
843 XtSetArg(args[j], XtNfromVert, engThreshold); j++;
844 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
845 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
846 XtSetArg(args[j], XtNstring, def); j++;
847 XtSetArg(args[j], XtNdisplayCaret, False); j++;
848 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
849 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
850 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
851 XtSetArg(args[j], XtNright, XtChainLeft); j++;
852 XtSetArg(args[j], XtNresizable, True); j++;
853 XtSetArg(args[j], XtNwidth, 30); j++;
854 // XtSetArg(args[j], XtNheight, 20); j++;
855 engRule = XtCreateManagedWidget("Rule", asciiTextWidgetClass, form, args, j);
856 XtAddEventHandler(engRule, ButtonPressMask, False, SetFocus, (XtPointer) popup);
859 XtSetArg(args[j], XtNlabel, _("-move rule applied")); j++;
860 XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++;
861 XtSetArg(args[j], XtNborderWidth, 0); j++;
862 XtSetArg(args[j], XtNfromVert, engThreshold); j++;
863 XtSetArg(args[j], XtNfromHoriz, engRule); j++;
864 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
865 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
866 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
867 XtSetArg(args[j], XtNright, XtChainLeft); j++;
868 // XtSetArg(args[j], XtNwidth, 130); j++;
869 // XtSetArg(args[j], XtNheight, 20); j++;
870 tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);
872 snprintf(def, MSG_SIZ, "%d", appData.drawRepeats);
874 XtSetArg(args[j], XtNborderWidth, 1); j++;
875 XtSetArg(args[j], XtNfromVert, engRule); j++;
876 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
877 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
878 XtSetArg(args[j], XtNstring, def); j++;
879 XtSetArg(args[j], XtNdisplayCaret, False); j++;
880 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
881 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
882 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
883 XtSetArg(args[j], XtNright, XtChainLeft); j++;
884 XtSetArg(args[j], XtNresizable, True); j++;
885 XtSetArg(args[j], XtNwidth, 30); j++;
886 // XtSetArg(args[j], XtNheight, 20); j++;
887 engRepeat = XtCreateManagedWidget("Repeats", asciiTextWidgetClass, form, args, j);
888 XtAddEventHandler(engRepeat, ButtonPressMask, False, SetFocus, (XtPointer) popup);
891 XtSetArg(args[j], XtNlabel, _("-fold repeat is draw")); j++;
892 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
893 XtSetArg(args[j], XtNborderWidth, 0); j++;
894 XtSetArg(args[j], XtNfromVert, engRule); j++;
895 XtSetArg(args[j], XtNfromHoriz, engRepeat); j++;
896 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
897 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
898 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
899 XtSetArg(args[j], XtNright, XtChainLeft); j++;
900 // XtSetArg(args[j], XtNwidth, 130); j++;
901 // XtSetArg(args[j], XtNheight, 20); j++;
902 tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j);
905 XtSetArg(args[j], XtNfromVert, engRepeat); j++;
906 XtSetArg(args[j], XtNfromHoriz, tcMess2); j++;
907 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
908 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
909 XtSetArg(args[j], XtNleft, XtChainRight); j++;
910 XtSetArg(args[j], XtNright, XtChainRight); j++;
911 b_ok= XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j);
912 XtAddCallback(b_ok, XtNcallback, EngineCallback, (XtPointer) 0);
915 XtSetArg(args[j], XtNfromVert, engRepeat); j++;
916 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
917 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
918 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
919 XtSetArg(args[j], XtNleft, XtChainRight); j++;
920 XtSetArg(args[j], XtNright, XtChainRight); j++;
921 b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass,
923 XtAddCallback(b_cancel, XtNcallback, EnginePopDown, (XtPointer) 0);
925 XtRealizeWidget(popup);
926 CatchDeleteWindow(popup, "EnginePopDown");
928 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
929 &x, &y, &win_x, &win_y, &mask);
931 XtSetArg(args[0], XtNx, x - 10);
932 XtSetArg(args[1], XtNy, y - 30);
933 XtSetValues(popup, args, 2);
935 XtPopup(popup, XtGrabExclusive);
939 SetFocus(engThreshold, popup, (XEvent*) NULL, False);
942 void EngineMenuProc(w, event, prms, nprms)
951 //--------------------------- New-Variant Menu PopUp -----------------------------------
952 struct NewVarButton {
956 VariantClass variant;
959 struct NewVarButton buttonDesc[] = {
960 {N_("normal"), "#FFFFFF", 0, VariantNormal},
961 {N_("FRC"), "#FFFFFF", 0, VariantFischeRandom},
962 {N_("wild castle"), "#FFFFFF", 0, VariantWildCastle},
963 {N_("no castle"), "#FFFFFF", 0, VariantNoCastle},
964 {N_("knightmate"), "#FFFFFF", 0, VariantKnightmate},
965 {N_("berolina"), "#FFFFFF", 0, VariantBerolina},
966 {N_("cylinder"), "#FFFFFF", 0, VariantCylinder},
967 {N_("shatranj"), "#FFFFFF", 0, VariantShatranj},
968 {N_("makruk"), "#FFFFFF", 0, VariantMakruk},
969 {N_("atomic"), "#FFFFFF", 0, VariantAtomic},
970 {N_("two kings"), "#FFFFFF", 0, VariantTwoKings},
971 {N_("3-checks"), "#FFFFFF", 0, Variant3Check},
972 {N_("suicide"), "#FFFFBF", 0, VariantSuicide},
973 {N_("give-away"), "#FFFFBF", 0, VariantGiveaway},
974 {N_("losers"), "#FFFFBF", 0, VariantLosers},
975 {N_("fairy"), "#BFBFBF", 0, VariantFairy},
976 {N_("Seirawan"), "#FFBFBF", 0, VariantSChess},
977 {N_("Superchess"), "#FFBFBF", 0, VariantSuper},
978 {N_("crazyhouse"), "#FFBFBF", 0, VariantCrazyhouse},
979 {N_("bughouse"), "#FFBFBF", 0, VariantBughouse},
980 {N_("shogi (9x9)"), "#BFFFFF", 0, VariantShogi},
981 {N_("xiangqi (9x10)"), "#BFFFFF", 0, VariantXiangqi},
982 {N_("courier (12x8)"), "#BFFFBF", 0, VariantCourier},
983 {N_("Capablanca (10x8)"), "#BFBFFF", 0, VariantCapablanca},
985 {N_("Gothic (10x8)"), "#BFBFFF", 0, VariantGothic},
987 {N_("janus (10x8)"), "#BFBFFF", 0, VariantJanus},
988 {N_("CRC (10x8)"), "#BFBFFF", 0, VariantCapaRandom},
990 {N_("Falcon (10x8)"), "#BFBFFF", 0, VariantFalcon},
992 {N_("Spartan"), "#FF0000", 0, VariantSpartan},
993 {NULL, 0, 0, (VariantClass) 0}
997 Widget NewVariantShell;
999 void NewVariantPopDown()
1001 if (!NewVariantUp) return;
1002 XtPopdown(NewVariantShell);
1003 XtDestroyWidget(NewVariantShell);
1004 NewVariantUp = False;
1008 void NewVariantCallback(w, client_data, call_data)
1010 XtPointer client_data, call_data;
1016 XtSetArg(args[0], XtNlabel, &name);
1017 XtGetValues(w, args, 1);
1019 if (strcmp(name, _(" OK ")) == 0) {
1020 int nr = (intptr_t) XawToggleGetCurrent(buttonDesc[0].handle) - 1;
1022 v = buttonDesc[nr].variant;
1023 if(!appData.noChessProgram) {
1024 char *name = VariantName(v), buf[MSG_SIZ];
1025 if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {
1026 /* [HGM] in protocol 2 we check if variant is suported by engine */
1027 snprintf(buf, MSG_SIZ, _("Variant %s not supported by %s"), name, first.tidy);
1028 DisplayError(buf, 0);
1029 // NewVariantPopDown();
1030 return; /* ignore OK if first engine does not support it */
1032 if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {
1033 snprintf(buf, MSG_SIZ, _("Warning: second engine (%s) does not support this!"), second.tidy);
1034 DisplayError(buf, 0); /* use of second engine is optional; only warn user */
1038 gameInfo.variant = v;
1039 appData.variant = VariantName(v);
1041 shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */
1042 startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */
1043 appData.pieceToCharTable = NULL;
1045 NewVariantPopDown();
1050 void NewVariantPopUp()
1053 Widget popup, layout, form, last = NULL, b_ok, b_cancel;
1058 XrmValue vFrom, vTo;
1061 XtSetArg(args[i], XtNresizable, True); i++;
1062 // XtSetArg(args[i], XtNwidth, 250); i++;
1063 // XtSetArg(args[i], XtNheight, 300); i++;
1064 NewVariantShell = popup =
1065 XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass,
1066 shellWidget, args, i);
1069 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
1070 layoutArgs, XtNumber(layoutArgs));
1073 XtCreateManagedWidget("form", formWidgetClass, layout,
1074 formArgs, XtNumber(formArgs));
1076 for(i = 0; buttonDesc[i].name != NULL; i++) {
1078 if (!appData.monoMode) {
1079 vFrom.addr = (caddr_t) buttonDesc[i].color;
1080 vFrom.size = strlen(buttonDesc[i].color);
1081 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
1082 if (vTo.addr == NULL) {
1083 buttonColor = (Pixel) -1;
1085 buttonColor = *(Pixel *) vTo.addr;
1090 XtSetArg(args[j], XtNradioGroup, last); j++;
1091 XtSetArg(args[j], XtNwidth, 125); j++;
1092 // XtSetArg(args[j], XtNheight, 16); j++;
1093 XtSetArg(args[j], XtNfromVert, i == 15 ? NULL : last); j++;
1094 XtSetArg(args[j], XtNfromHoriz, i < 15 ? NULL : buttonDesc[i-15].handle); j++;
1095 XtSetArg(args[j], XtNradioData, i+1); j++;
1096 XtSetArg(args[j], XtNbackground, buttonColor); j++;
1097 XtSetArg(args[j], XtNstate, gameInfo.variant == buttonDesc[i].variant); j++;
1098 XtSetArg(args[j], XtNsensitive, appData.noChessProgram || strstr(first.variants, VariantName(buttonDesc[i].variant))); j++;
1099 buttonDesc[i].handle = last =
1100 XtCreateManagedWidget(buttonDesc[i].name, toggleWidgetClass, form, args, j);
1104 XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++;
1105 XtSetArg(args[j], XtNfromHoriz, buttonDesc[12].handle); j++;
1106 XtSetArg(args[j], XtNheight, 35); j++;
1107 // XtSetArg(args[j], XtNwidth, 60); j++;
1108 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
1109 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
1110 XtSetArg(args[j], XtNleft, XtChainRight); j++;
1111 XtSetArg(args[j], XtNright, XtChainRight); j++;
1112 b_cancel= XtCreateManagedWidget(_("CANCEL"), commandWidgetClass, form, args, j);
1113 XtAddCallback(b_cancel, XtNcallback, NewVariantPopDown, (XtPointer) 0);
1116 XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;
1117 XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++;
1118 XtSetArg(args[j], XtNheight, 35); j++;
1119 // XtSetArg(args[j], XtNwidth, 60); j++;
1120 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
1121 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
1122 XtSetArg(args[j], XtNleft, XtChainRight); j++;
1123 XtSetArg(args[j], XtNright, XtChainRight); j++;
1124 b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, form, args, j);
1125 XtAddCallback(b_ok, XtNcallback, NewVariantCallback, (XtPointer) 0);
1128 XtSetArg(args[j], XtNfromVert, buttonDesc[14].handle); j++;
1129 // XtSetArg(args[j], XtNheight, 70); j++;
1130 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
1131 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
1132 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
1133 XtSetArg(args[j], XtNright, XtChainRight); j++;
1134 XtSetArg(args[j], XtNlabel, _("WARNING: variants with un-orthodox\n"
1135 "pieces only have built-in bitmaps\n"
1136 "for -boardSize middling, bulky and\n"
1137 "petite, and substitute king or amazon\n"
1138 "for missing bitmaps. (See manual.)")); j++;
1139 XtCreateManagedWidget("warning", labelWidgetClass, form, args, j);
1141 XtRealizeWidget(popup);
1142 CatchDeleteWindow(popup, "NewVariantPopDown");
1144 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
1145 &x, &y, &win_x, &win_y, &mask);
1147 XtSetArg(args[0], XtNx, x - 10);
1148 XtSetArg(args[1], XtNy, y - 30);
1149 XtSetValues(popup, args, 2);
1151 XtPopup(popup, XtGrabExclusive);
1152 NewVariantUp = True;
1155 void NewVariantProc(w, event, prms, nprms)
1164 //--------------------------- UCI Menu Popup ------------------------------------------
1174 struct UciControl controlDesc[] = {
1175 {N_("maximum nr of CPUs:"), 0, &appData.smpCores},
1176 {N_("Polyglot Directory:"), 0, &appData.polyglotDir},
1177 {N_("Hash Size (MB):"), 0, &appData.defaultHashSize},
1178 {N_("EGTB Path:"), 0, &appData.defaultPathEGTB},
1179 {N_("EGTB Cache (MB):"), 0, &appData.defaultCacheSizeEGTB},
1180 {N_("Polyglot Book:"), 0, &appData.polyglotBook},
1188 XtPopdown(UciShell);
1189 XtDestroyWidget(UciShell);
1194 void UciCallback(w, client_data, call_data)
1196 XtPointer client_data, call_data;
1200 int oldCores = appData.smpCores, ponder = 0;
1202 XtSetArg(args[0], XtNlabel, &name);
1203 XtGetValues(w, args, 1);
1205 if (strcmp(name, _("OK")) == 0) {
1206 int i, j; String name;
1207 for(i=0; i<6; i++) {
1208 XtSetArg(args[0], XtNstring, &name);
1209 XtGetValues(controlDesc[i].handle, args, 1);
1212 *(char**) controlDesc[i].ptr = strdup(name);
1214 if(sscanf(name, "%d", &j) == 1)
1215 *(int*) controlDesc[i].ptr = j;
1218 XtSetArg(args[0], XtNstate, &appData.usePolyglotBook);
1219 XtGetValues(w1, args, 1);
1220 XtSetArg(args[0], XtNstate, &appData.firstHasOwnBookUCI);
1221 XtGetValues(w2, args, 1);
1222 XtSetArg(args[0], XtNstate, &appData.secondHasOwnBookUCI);
1223 XtGetValues(w3, args, 1);
1224 XtSetArg(args[0], XtNstate, &ponder);
1225 XtGetValues(w4, args, 1);
1227 // adjust setting in other menu for duplicates
1228 // (perhaps duplicates should be removed from general Option Menu?)
1229 XtSetArg(args[0], XtNleftBitmap, ponder ? xMarkPixmap : None);
1230 XtSetValues(XtNameToWidget(menuBarWidget,
1231 "menuOptions.Ponder Next Move"), args, 1);
1233 // make sure changes are sent to first engine by re-initializing it
1234 // if it was already started pre-emptively at end of previous game
1235 if(gameMode == BeginningOfGame) Reset(True, True); else {
1236 // Some changed setting need immediate sending always.
1237 PonderNextMoveEvent(ponder);
1238 if(oldCores != appData.smpCores)
1239 NewSettingEvent(False, &(first.maxCores), "cores", appData.smpCores);
1249 Widget popup, layout, form, b_ok, b_cancel, last = NULL, new, upperLeft;
1257 XtSetArg(args[i], XtNresizable, True); i++;
1258 // XtSetArg(args[i], XtNwidth, 300); i++;
1260 XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass,
1261 shellWidget, args, i);
1264 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
1265 layoutArgs, XtNumber(layoutArgs));
1269 XtCreateManagedWidget("form", formWidgetClass, layout,
1270 formArgs, XtNumber(formArgs));
1273 XtSetArg(args[j], XtNtop, XtChainTop); j++;
1274 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
1275 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
1276 // XtSetArg(args[j], XtNheight, 20); j++;
1277 for(i = 0; controlDesc[i].name != NULL; i++) {
1279 XtSetArg(args[j], XtNfromVert, last); j++;
1280 // XtSetArg(args[j], XtNwidth, 130); j++;
1281 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
1282 XtSetArg(args[j], XtNright, XtChainLeft); j++;
1283 XtSetArg(args[j], XtNborderWidth, 0); j++;
1284 new = XtCreateManagedWidget(controlDesc[i].name, labelWidgetClass, form, args, j);
1285 if(i==0) upperLeft = new;
1288 XtSetArg(args[j], XtNborderWidth, 1); j++;
1289 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
1290 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
1291 XtSetArg(args[j], XtNdisplayCaret, False); j++;
1292 XtSetArg(args[j], XtNright, XtChainRight); j++;
1293 XtSetArg(args[j], XtNresizable, True); j++;
1294 XtSetArg(args[j], XtNwidth, i&1 ? 245 : 50); j++;
1295 XtSetArg(args[j], XtNinsertPosition, 9999); j++;
1297 XtSetArg(args[j], XtNstring, * (char**) controlDesc[i].ptr ?
1298 * (char**) controlDesc[i].ptr : ""); j++;
1300 snprintf(def, MSG_SIZ, "%d", * (int*) controlDesc[i].ptr);
1301 XtSetArg(args[j], XtNstring, def); j++;
1303 XtSetArg(args[j], XtNfromHoriz, upperLeft); j++;
1304 controlDesc[i].handle = last =
1305 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
1306 XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup);
1310 XtSetArg(args[j], XtNfromHoriz, controlDesc[0].handle); j++;
1311 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
1312 XtSetArg(args[j], XtNtop, XtChainTop); j++;
1313 XtSetArg(args[j], XtNleft, XtChainRight); j++;
1314 XtSetArg(args[j], XtNright, XtChainRight); j++;
1315 XtSetArg(args[j], XtNstate, appData.ponderNextMove); j++;
1316 w4 = XtCreateManagedWidget(_("Ponder"), toggleWidgetClass, form, args, j);
1319 XtSetArg(args[j], XtNfromVert, last); j++;
1320 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
1321 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
1322 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
1323 XtSetArg(args[j], XtNright, XtChainLeft); j++;
1324 b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j);
1325 XtAddCallback(b_ok, XtNcallback, UciCallback, (XtPointer) 0);
1327 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
1328 b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
1329 XtAddCallback(b_cancel, XtNcallback, UciPopDown, (XtPointer) 0);
1332 XtSetArg(args[j], XtNfromHoriz, upperLeft); j++;
1333 XtSetArg(args[j], XtNstate, appData.usePolyglotBook); j++;
1334 w1 = XtCreateManagedWidget(_(" use book "), toggleWidgetClass, form, args, j);
1335 // XtAddCallback(w1, XtNcallback, UciCallback, (XtPointer) 0);
1338 XtSetArg(args[j], XtNfromHoriz, w1); j++;
1339 XtSetArg(args[j], XtNstate, appData.firstHasOwnBookUCI); j++;
1340 w2 = XtCreateManagedWidget(_("own book 1"), toggleWidgetClass, form, args, j);
1341 // XtAddCallback(w2, XtNcallback, UciCallback, (XtPointer) 0);
1344 XtSetArg(args[j], XtNfromHoriz, w2); j++;
1345 XtSetArg(args[j], XtNstate, appData.secondHasOwnBookUCI); j++;
1346 w3 = XtCreateManagedWidget(_("own book 2"), toggleWidgetClass, form, args, j);
1347 // XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0);
1349 XtRealizeWidget(popup);
1350 CatchDeleteWindow(popup, "UciPopDown");
1352 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
1353 &x, &y, &win_x, &win_y, &mask);
1355 XtSetArg(args[0], XtNx, x - 10);
1356 XtSetArg(args[1], XtNy, y - 30);
1357 XtSetValues(popup, args, 2);
1359 XtPopup(popup, XtGrabExclusive);
1363 SetFocus(controlDesc[2].handle, popup, (XEvent*) NULL, False);
1364 // XtSetKeyboardFocus(popup, controlDesc[1].handle);
1367 void UciMenuProc(w, event, prms, nprms)
1376 //--------------------------- Engine-specific options menu ----------------------------------
1379 Widget SettingsShell;
1380 int values[MAX_OPTIONS];
1381 ChessProgramState *currentCps;
1383 void SettingsPopDown()
1385 if (!SettingsUp) return;
1387 XtPopdown(SettingsShell);
1388 XtDestroyWidget(SettingsShell);
1393 void SpinCallback(w, client_data, call_data)
1395 XtPointer client_data, call_data;
1399 char buf[MSG_SIZ], *p;
1401 int data = (intptr_t) client_data;
1403 XtSetArg(args[0], XtNlabel, &name);
1404 XtGetValues(w, args, 1);
1407 XtSetArg(args[0], XtNstring, &val);
1408 XtGetValues(currentCps->option[data].handle, args, 1);
1409 sscanf(val, "%d", &j);
1410 if (strcmp(name, "browse") == 0) {
1411 if(XsraSelFile(SettingsShell, currentCps->option[data].name, NULL, NULL, "", "",
1412 currentCps->option[data].type == PathName ? "p" : "f", NULL, &p)) {
1413 int len = strlen(p);
1414 if(len && p[len-1] == '/') p[len-1] = NULLCHAR;
1415 XtSetArg(args[0], XtNstring, p);
1416 XtSetValues(currentCps->option[data].handle, args, 1);
1418 SetFocus(currentCps->option[data].handle, SettingsShell, (XEvent*) NULL, False);
1421 if (strcmp(name, "+") == 0) {
1422 if(++j > currentCps->option[data].max) return;
1424 if (strcmp(name, "-") == 0) {
1425 if(--j < currentCps->option[data].min) return;
1427 snprintf(buf, MSG_SIZ, "%d", j);
1428 XtSetArg(args[0], XtNstring, buf);
1429 XtSetValues(currentCps->option[data].handle, args, 1);
1432 void SettingsCallback(w, client_data, call_data)
1434 XtPointer client_data, call_data;
1440 int data = (intptr_t) client_data;
1442 XtSetArg(args[0], XtNlabel, &name);
1443 XtGetValues(w, args, 1);
1445 if (strcmp(name, _("cancel")) == 0) {
1449 if (strcmp(name, _("OK")) == 0 || data) { // save buttons imply OK
1450 for(i=0; i<currentCps->nrOptions; i++) { // send all options that had to be OK-ed to engine
1451 switch(currentCps->option[i].type) {
1453 XtSetArg(args[0], XtNstring, &val);
1454 XtGetValues(currentCps->option[i].handle, args, 1);
1455 if(strcmp(currentCps->option[i].textValue, val)) {
1456 safeStrCpy(currentCps->option[i].textValue, val, MSG_SIZ - (currentCps->option[i].textValue - currentCps->option[i].name) );
1457 snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name, val);
1458 SendToProgram(buf, currentCps);
1462 XtSetArg(args[0], XtNstring, &val);
1463 XtGetValues(currentCps->option[i].handle, args, 1);
1464 sscanf(val, "%d", &j);
1465 if(j > currentCps->option[i].max) j = currentCps->option[i].max;
1466 if(j < currentCps->option[i].min) j = currentCps->option[i].min;
1467 if(currentCps->option[i].value != j) {
1468 currentCps->option[i].value = j;
1469 snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j);
1470 SendToProgram(buf, currentCps);
1475 XtSetArg(args[0], XtNstate, &j);
1476 XtGetValues(currentCps->option[i].handle, args, 1);
1477 if(currentCps->option[i].value != j) {
1478 currentCps->option[i].value = j;
1479 snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j);
1480 SendToProgram(buf, currentCps);
1484 if(currentCps->option[i].value != values[i]) {
1485 currentCps->option[i].value = values[i];
1486 snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name,
1487 ((char**)currentCps->option[i].textValue)[values[i]]);
1488 SendToProgram(buf, currentCps);
1492 if( appData.debugMode )
1493 fprintf(debugFP, "SettingsPopUp: unexpected case in switch.\n");
1497 if(data) { // send save-button command to engine
1498 snprintf(buf, MSG_SIZ, "option %s\n", name);
1499 SendToProgram(buf, currentCps);
1504 snprintf(buf, MSG_SIZ, "option %s\n", name);
1505 SendToProgram(buf, currentCps);
1508 void ComboSelect(w, addr, index) // callback for all combo items
1514 int i = ((intptr_t)addr)>>8;
1515 int j = 255 & (intptr_t) addr;
1517 values[i] = j; // store in temporary, for transfer at OK
1518 XtSetArg(args[0], XtNlabel, ((char**)currentCps->option[i].textValue)[j]);
1519 XtSetValues(currentCps->option[i].handle, args, 1);
1522 void CreateComboPopup(parent, name, n, mb)
1532 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
1535 XtSetArg(args[j], XtNwidth, 100); j++;
1536 // XtSetArg(args[j], XtNright, XtChainRight); j++;
1537 while (mb[i] != NULL) {
1538 entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass,
1540 XtAddCallback(entry, XtNcallback,
1541 (XtCallbackProc) ComboSelect,
1542 (caddr_t)(intptr_t) (256*n+i));
1548 SettingsPopUp(ChessProgramState *cps)
1551 Widget popup, layout, dialog, edit=NULL, form, last, b_ok, b_cancel, leftMargin = NULL, textField = NULL;
1553 int x, y, i, j, height, width, h, c;
1554 int win_x, win_y, maxWidth, maxTextWidth;
1557 static char pane[6] = "paneX";
1558 Widget texts[100], forelast = NULL, anchor, widest;
1560 // to do: start up second engine if needed
1561 if(!cps->initDone || !cps->nrOptions) return; // nothing to be done
1564 if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1;
1565 height = cps->nrOptions / width + 1;
1567 XtSetArg(args[i], XtNresizable, True); i++;
1568 SettingsShell = popup =
1569 XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass,
1570 shellWidget, args, i);
1573 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
1574 layoutArgs, XtNumber(layoutArgs));
1575 for(c=0; c<width; c++) {
1578 XtCreateManagedWidget(pane, formWidgetClass, layout,
1579 formArgs, XtNumber(formArgs));
1581 XtSetArg(args[j], XtNfromHoriz, leftMargin); j++;
1582 XtSetValues(form, args, j);
1585 last = widest = NULL; anchor = forelast;
1586 for(h=0; h<height; h++) {
1589 if(i >= cps->nrOptions) break;
1590 switch(cps->option[i].type) {
1592 snprintf(def, MSG_SIZ, "%d", cps->option[i].value);
1595 XtSetArg(args[j], XtNfromVert, last); j++;
1596 XtSetArg(args[j], XtNborderWidth, 0); j++;
1597 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
1599 dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j);
1601 XtSetArg(args[j], XtNfromVert, last); j++;
1602 XtSetArg(args[j], XtNfromHoriz, dialog); j++;
1603 XtSetArg(args[j], XtNborderWidth, 1); j++;
1604 XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 175); j++;
1605 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
1606 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
1607 XtSetArg(args[j], XtNdisplayCaret, False); j++;
1608 XtSetArg(args[j], XtNright, XtChainRight); j++;
1609 XtSetArg(args[j], XtNresizable, True); j++;
1610 XtSetArg(args[j], XtNstring, cps->option[i].type==Spin ? def : cps->option[i].textValue); j++;
1611 XtSetArg(args[j], XtNinsertPosition, 9999); j++;
1613 cps->option[i].handle = (void*)
1614 (textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j));
1615 XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup);
1616 if(cps->option[i].type == TextBox) break;
1618 // add increment and decrement controls for spin
1620 XtSetArg(args[j], XtNfromVert, edit); j++;
1621 XtSetArg(args[j], XtNfromHoriz, last); j++;
1622 XtSetArg(args[j], XtNheight, 10); j++;
1623 XtSetArg(args[j], XtNwidth, 20); j++;
1624 edit = XtCreateManagedWidget("+", commandWidgetClass, form, args, j);
1625 XtAddCallback(edit, XtNcallback, SpinCallback,
1626 (XtPointer)(intptr_t) i);
1629 XtSetArg(args[j], XtNfromVert, edit); j++;
1630 XtSetArg(args[j], XtNfromHoriz, last); j++;
1631 XtSetArg(args[j], XtNheight, 10); j++;
1632 XtSetArg(args[j], XtNwidth, 20); j++;
1633 last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j);
1634 XtAddCallback(last, XtNcallback, SpinCallback,
1635 (XtPointer)(intptr_t) i);
1639 XtSetArg(args[j], XtNfromVert, last); j++;
1640 XtSetArg(args[j], XtNwidth, 10); j++;
1641 XtSetArg(args[j], XtNheight, 10); j++;
1642 XtSetArg(args[j], XtNstate, cps->option[i].value); j++;
1643 cps->option[i].handle = (void*)
1644 (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j));
1646 XtSetArg(args[j], XtNfromVert, last); j++;
1647 XtSetArg(args[j], XtNfromHoriz, dialog); j++;
1648 XtSetArg(args[j], XtNborderWidth, 0); j++;
1649 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
1650 last = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j);
1655 XtSetArg(args[j], XtNfromVert, last); j++;
1656 XtSetArg(args[j], XtNstate, cps->option[i].value); j++;
1657 cps->option[i].handle = (void*)
1658 (dialog = last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j));
1659 XtAddCallback(last, XtNcallback, SettingsCallback,
1660 (XtPointer)(intptr_t) (cps->option[i].type == SaveButton));
1664 XtSetArg(args[j], XtNfromVert, last); j++;
1665 XtSetArg(args[j], XtNborderWidth, 0); j++;
1666 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
1667 dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j);
1670 XtSetArg(args[j], XtNfromVert, last); j++;
1671 XtSetArg(args[j], XtNfromHoriz, dialog); j++;
1672 XtSetArg(args[j], XtNwidth, 100); j++;
1673 XtSetArg(args[j], XtNmenuName, XtNewString(cps->option[i].name)); j++;
1674 XtSetArg(args[j], XtNlabel, ((char**)cps->option[i].textValue)[cps->option[i].value]); j++;
1675 cps->option[i].handle = (void*)
1676 (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j));
1677 CreateComboPopup(last, cps->option[i].name, i, (char **) cps->option[i].textValue);
1678 values[i] = cps->option[i].value;
1681 if( appData.debugMode )
1682 fprintf(debugFP, "SettingsPopUp: unexpected case in switch.\n");
1687 // make an attempt to align all spins and textbox controls
1688 maxWidth = maxTextWidth = 0;
1689 for(h=0; h<height; h++) {
1691 if(i >= cps->nrOptions) break;
1692 if(cps->option[i].type == Spin || cps->option[i].type == TextBox) {
1695 XtSetArg(args[j], XtNwidth, &w); j++;
1696 XtGetValues(texts[h], args, j);
1697 if(cps->option[i].type == Spin) {
1698 if(w > maxWidth) maxWidth = w;
1701 if(w > maxTextWidth) maxTextWidth = w;
1702 if(!widest) widest = texts[h];
1706 if(maxTextWidth + 110 < maxWidth)
1707 maxTextWidth = maxWidth - 110;
1708 else maxWidth = maxTextWidth + 110;
1709 for(h=0; h<height; h++) {
1711 if(i >= cps->nrOptions) break;
1713 if(cps->option[i].type == Spin) {
1714 XtSetArg(args[j], XtNwidth, maxWidth); j++;
1715 XtSetValues(texts[h], args, j);
1717 if(cps->option[i].type == TextBox) {
1718 XtSetArg(args[j], XtNwidth, maxTextWidth); j++;
1719 XtSetValues(texts[h], args, j);
1724 XtSetArg(args[j], XtNfromVert, anchor ? anchor : last); j++;
1725 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
1726 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
1727 XtSetArg(args[j], XtNleft, XtChainRight); j++;
1728 XtSetArg(args[j], XtNright, XtChainRight); j++;
1729 XtSetArg(args[j], XtNfromHoriz, widest ? widest : dialog); j++;
1730 b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j);
1731 XtAddCallback(b_ok, XtNcallback, SettingsCallback, (XtPointer) 0);
1733 XtSetArg(args[j-1], XtNfromHoriz, b_ok);
1734 b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
1735 XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0);
1737 XtRealizeWidget(popup);
1738 CatchDeleteWindow(popup, "SettingsPopDown");
1740 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
1741 &x, &y, &win_x, &win_y, &mask);
1743 XtSetArg(args[0], XtNx, x - 10);
1744 XtSetArg(args[1], XtNy, y - 30);
1745 XtSetValues(popup, args, 2);
1747 XtPopup(popup, XtGrabExclusive);
1751 if(textField)SetFocus(textField, popup, (XEvent*) NULL, False);
1754 void FirstSettingsProc(w, event, prms, nprms)
1760 SettingsPopUp(&first);
1763 void SecondSettingsProc(w, event, prms, nprms)
1769 if(WaitForSecond(SettingsMenuIfReady)) return;
1770 SettingsPopUp(&second);
1773 //----------------------------Generic dialog --------------------------------------------
1775 // cloned from Engine Settings dialog
1777 typedef void ButtonCallback(int n);
1779 static Option *currentOption;
1780 int MakeColors P((void));
1781 void CreateGCs P((int redo));
1782 void CreateXPMBoard P((char *s, int kind));
1783 void CreateXPMPieces P((void));
1784 void GenericReadout();
1786 Option loadOptions[] = {
1787 { 0, 0, 0, NULL, (void*) &appData.autoDisplayTags, "", NULL, CheckBox, _("Auto-Display Tags") },
1788 { 0, 0, 0, NULL, (void*) &appData.autoDisplayComment, "", NULL, CheckBox, _("Auto-Display Comment") },
1789 { 0, 0, 0, NULL, NULL, NULL, NULL, Label, _("Auto-Play speed of loaded games\n(0 = instant, -1 = off):") },
1790 { 0, -1, 10000000, NULL, (void*) &appData.timeDelay, "", NULL, Fractional, _("Seconds per Move:") },
1791 { 0, 0, 0, NULL, NULL, "", NULL, EndMark , "" }
1794 Option saveOptions[] = {
1795 { 0, 0, 0, NULL, (void*) &appData.autoSaveGames, "", NULL, CheckBox, _("Auto-Save Games") },
1796 { 0, 0, 0, NULL, (void*) &appData.saveGameFile, "", NULL, FileName, _("Save Games on File:") },
1797 { 0, 0, 0, NULL, (void*) &appData.savePositionFile, "", NULL, FileName, _("Save Final Positions on File:") },
1798 { 0, 0, 0, NULL, (void*) &appData.pgnEventHeader, "", NULL, TextBox, _("PGN Event Header:") },
1799 { 0, 0, 0, NULL, (void*) &appData.oldSaveStyle, "", NULL, CheckBox, _("Old Save Style (as opposed to PGN)") },
1800 { 0, 0, 0, NULL, (void*) &appData.saveExtendedInfoInPGN, "", NULL, CheckBox, _("Save Score/Depth Info in PGN") },
1801 { 0, 0, 0, NULL, (void*) &appData.saveOutOfBookInfo, "", NULL, CheckBox, _("Save Out-of-Book Info in PGN ") },
1802 { 0, 1, 0, NULL, NULL, "", NULL, EndMark , "" }
1805 void SetColor(char *colorName, Widget box)
1809 XrmValue vFrom, vTo;
1810 if (!appData.monoMode) {
1811 vFrom.addr = (caddr_t) colorName;
1812 vFrom.size = strlen(colorName);
1813 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
1814 if (vTo.addr == NULL) {
1815 buttonColor = (Pixel) -1;
1817 buttonColor = *(Pixel *) vTo.addr;
1820 XtSetArg(args[0], XtNbackground, buttonColor);;
1821 XtSetValues(box, args, 1);
1824 void AdjustColor(int i)
1826 int n = currentOption[i].value, col, j, r, g, b, step = 10;
1827 char *s, buf[MSG_SIZ]; // color string
1829 XtSetArg(args[0], XtNstring, &s);
1830 XtGetValues(currentOption[i-n-1].handle, args, 1);
1831 if(sscanf(s, "#%x", &col) != 1) return; // malformed
1832 b = col & 0xFF; g = col & 0xFF00; r = col & 0xFF0000;
1834 case 1: g -= 0x100*step; b -= step; break;
1835 case 2: r -= 0x10000*step; b -= step; break;
1836 case 3: g -= 0x100*step; r -= 0x10000*step; break;
1837 case 4: r += 0x10000*step; g += 0x100*step; b += step; break;
1839 if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0;
1840 if(r > 0xFF0000) r = 0xFF0000; if(g > 0xFF00) g = 0xFF00; if(b > 0xFF) b = 0xFF;
1842 snprintf(buf, MSG_SIZ, "#%06x", col);
1843 for(j=1; j<7; j++) if(buf[j] >= 'a') buf[j] -= 32; // capitalize
1844 SetColor(buf, currentOption[i-n].handle);
1845 XtSetArg(args[0], XtNstring, buf);
1846 XtSetValues(currentOption[i-n-1].handle, args, 1);
1849 void BoardOptionsOK(int n)
1851 if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
1852 MakeColors(); CreateGCs(True);
1854 CreateXPMBoard(appData.liteBackTextureFile, 1);
1855 CreateXPMBoard(appData.darkBackTextureFile, 0);
1856 InitDrawingSizes(-1, 0);
1857 DrawPosition(True, NULL);
1860 Option boardOptions[] = {
1861 { 0, 0, 70, NULL, (void*) &appData.whitePieceColor, "", NULL, TextBox, _("White Piece Color:") },
1862 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1863 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1864 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1865 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1866 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1867 { 0, 0, 70, NULL, (void*) &appData.blackPieceColor, "", NULL, TextBox, _("Black Piece Color:") },
1868 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1869 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1870 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1871 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1872 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1873 { 0, 0, 70, NULL, (void*) &appData.lightSquareColor, "", NULL, TextBox, _("Light Square Color:") },
1874 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1875 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1876 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1877 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1878 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1879 { 0, 0, 70, NULL, (void*) &appData.darkSquareColor, "", NULL, TextBox, _("Dark Square Color:") },
1880 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1881 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1882 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1883 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1884 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1885 { 0, 0, 70, NULL, (void*) &appData.highlightSquareColor, "", NULL, TextBox, _("Highlight Color:") },
1886 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1887 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1888 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1889 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1890 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1891 { 0, 0, 70, NULL, (void*) &appData.premoveHighlightColor, "", NULL, TextBox, _("Premove Highlight Color:") },
1892 { 1000, 1, 0, NULL, NULL, NULL, NULL, Button, " " },
1893 { 1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1894 { 2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1895 { 3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1896 { 4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "W" },
1897 { 0, 0, 0, NULL, (void*) &appData.upsideDown, "", NULL, CheckBox, _("Flip Pieces Shogi Style") },
1898 { 0, 0, 0, NULL, (void*) &appData.allWhite, "", NULL, CheckBox, _("Use Outline Pieces for Black") },
1899 { 0, 0, 0, NULL, (void*) &appData.monoMode, "", NULL, CheckBox, _("Mono Mode") },
1900 { 0,-1, 5, NULL, (void*) &appData.overrideLineGap, "", NULL, Spin, _("Line Gap ( -1 = default for board size):") },
1901 { 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, "", NULL, FileName, _("Light-Squares Texture File:") },
1902 { 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, "", NULL, FileName, _("Dark-Squares Texture File:") },
1903 { 0, 0, 0, NULL, (void*) &appData.bitmapDirectory, "", NULL, PathName, _("Directory with Bitmap Pieces:") },
1904 { 0, 0, 0, NULL, (void*) &appData.pixmapDirectory, "", NULL, PathName, _("Directory with Pixmap Pieces:") },
1905 { 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" }
1908 void GenericReadout()
1915 for(i=0; ; i++) { // send all options that had to be OK-ed to engine
1916 switch(currentOption[i].type) {
1920 XtSetArg(args[0], XtNstring, &val);
1921 XtGetValues(currentOption[i].handle, args, 1);
1922 if(*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val)) {
1923 safeStrCpy(currentOption[i].name + 100, val, MSG_SIZ-100); // text value kept in pivate storage for each option
1924 *(char**) currentOption[i].target = currentOption[i].name + 100; // option gets to point to that
1929 XtSetArg(args[0], XtNstring, &val);
1930 XtGetValues(currentOption[i].handle, args, 1);
1931 sscanf(val, "%f", &x);
1932 if(x > currentOption[i].max) x = currentOption[i].max;
1933 if(x < currentOption[i].min) x = currentOption[i].min;
1934 if(currentOption[i].value != x) {
1935 currentOption[i].value = x;
1936 if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x;
1937 else *(float*) currentOption[i].target = x;
1942 XtSetArg(args[0], XtNstate, &j);
1943 XtGetValues(currentOption[i].handle, args, 1);
1944 if(currentOption[i].value != j) {
1945 currentOption[i].value = j;
1946 *(Boolean*) currentOption[i].target = j;
1950 val = ((char**)currentOption[i].choice)[values[i]];
1951 if(val && (*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val))) {
1952 if(*(char**) currentOption[i].target) free(*(char**) currentOption[i].target);
1953 *(char**) currentOption[i].target = strdup(val);
1957 if(currentOption[i].target) // callback for implementing necessary actions on OK (like redraw)
1958 ((ButtonCallback*) currentOption[i].target)(i);
1961 printf("GenericReadout: unexpected case in switch.\n");
1966 if(currentOption[i].type == EndMark) break;
1970 void GenericCallback(w, client_data, call_data)
1972 XtPointer client_data, call_data;
1978 int data = (intptr_t) client_data;
1980 XtSetArg(args[0], XtNlabel, &name);
1981 XtGetValues(w, args, 1);
1983 if (strcmp(name, _("cancel")) == 0) {
1987 if (strcmp(name, _("OK")) == 0) { // save buttons imply OK
1992 ((ButtonCallback*) currentOption[data].target)(data);
1996 GenericPopUp(Option *option, char *title)
1999 Widget popup, layout, dialog, edit=NULL, form, last, b_ok, b_cancel, leftMargin = NULL, textField = NULL;
2001 int x, y, i, j, height=999, width=1, h, c, w;
2002 int win_x, win_y, maxWidth, maxTextWidth;
2004 char def[MSG_SIZ], *msg;
2005 static char pane[6] = "paneX";
2006 Widget texts[100], forelast = NULL, anchor, widest, lastrow = NULL;
2008 currentOption = option; // make available to callback
2009 // kludge: fake address of a ChessProgramState struct that contains the options, so Spin and Combo callbacks work on it
2010 currentCps = (ChessProgramState *) ((char *) option - ((char *)&first.option - (char *)&first));
2012 // if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1;
2013 // height = cps->nrOptions / width + 1;
2015 XtSetArg(args[i], XtNresizable, True); i++;
2016 SettingsShell = popup =
2017 XtCreatePopupShell(title, transientShellWidgetClass,
2018 shellWidget, args, i);
2021 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
2022 layoutArgs, XtNumber(layoutArgs));
2023 for(c=0; c<width; c++) {
2026 XtCreateManagedWidget(pane, formWidgetClass, layout,
2027 formArgs, XtNumber(formArgs));
2029 XtSetArg(args[j], XtNfromHoriz, leftMargin); j++;
2030 XtSetValues(form, args, j);
2033 last = widest = NULL; anchor = lastrow;
2034 for(h=0; h<height; h++) {
2036 if(option[i].type == EndMark) break;
2039 switch(option[i].type) {
2041 snprintf(def, MSG_SIZ, "%.2f", *(float*)option[i].target);
2042 option[i].value = *(float*)option[i].target;
2045 snprintf(def, MSG_SIZ, "%d", option[i].value = *(int*)option[i].target);
2050 if(option[i].name[0]) {
2052 XtSetArg(args[j], XtNfromVert, last); j++;
2053 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2054 XtSetArg(args[j], XtNright, XtChainLeft); j++;
2055 XtSetArg(args[j], XtNborderWidth, 0); j++;
2056 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
2058 dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
2059 } else texts[h] = dialog = NULL;
2060 w = option[i].type == Spin || option[i].type == Fractional ? 70 : option[i].max ? option[i].max : 205;
2061 if(option[i].type == FileName || option[i].type == PathName) w -= 55;
2063 XtSetArg(args[j], XtNfromVert, last); j++;
2064 XtSetArg(args[j], XtNfromHoriz, dialog); j++;
2065 XtSetArg(args[j], XtNborderWidth, 1); j++;
2066 XtSetArg(args[j], XtNwidth, w); j++;
2067 if(option[i].type == TextBox && option[i].min) XtSetArg(args[j], XtNheight, option[i].min); j++;
2068 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2069 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
2070 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
2071 XtSetArg(args[j], XtNdisplayCaret, False); j++;
2072 XtSetArg(args[j], XtNright, XtChainRight); j++;
2073 XtSetArg(args[j], XtNresizable, True); j++;
2074 XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def : *(char**)option[i].target); j++;
2075 XtSetArg(args[j], XtNinsertPosition, 9999); j++;
2077 option[i].handle = (void*)
2078 (textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j));
2079 XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup);
2081 if(option[i].type == TextBox || option[i].type == Fractional) break;
2083 // add increment and decrement controls for spin
2085 XtSetArg(args[j], XtNfromVert, edit); j++;
2086 XtSetArg(args[j], XtNfromHoriz, last); j++;
2087 XtSetArg(args[j], XtNleft, XtChainRight); j++;
2088 XtSetArg(args[j], XtNright, XtChainRight); j++;
2089 if(option[i].type == FileName || option[i].type == PathName) {
2090 w = 50; msg = "browse";
2092 XtSetArg(args[j], XtNheight, 10); j++;
2095 XtSetArg(args[j], XtNwidth, w); j++;
2096 edit = XtCreateManagedWidget(msg, commandWidgetClass, form, args, j);
2097 XtAddCallback(edit, XtNcallback, SpinCallback,
2098 (XtPointer)(intptr_t) i);
2100 if(option[i].type != Spin) break;
2103 XtSetArg(args[j], XtNfromVert, edit); j++;
2104 XtSetArg(args[j], XtNfromHoriz, last); j++;
2105 XtSetArg(args[j], XtNheight, 10); j++;
2106 XtSetArg(args[j], XtNwidth, 20); j++;
2107 XtSetArg(args[j], XtNleft, XtChainRight); j++;
2108 XtSetArg(args[j], XtNright, XtChainRight); j++;
2109 last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j);
2110 XtAddCallback(last, XtNcallback, SpinCallback,
2111 (XtPointer)(intptr_t) i);
2115 XtSetArg(args[j], XtNfromVert, last); j++;
2116 XtSetArg(args[j], XtNwidth, 10); j++;
2117 XtSetArg(args[j], XtNheight, 10); j++;
2118 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2119 XtSetArg(args[j], XtNright, XtChainLeft); j++;
2120 XtSetArg(args[j], XtNstate, option[i].value = *(Boolean*)option[i].target); j++;
2121 option[i].handle = (void*)
2122 (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j));
2124 msg = option[i].name;
2125 if(*msg == NULLCHAR) msg = option[i].textValue;
2128 XtSetArg(args[j], XtNfromVert, last); j++;
2129 XtSetArg(args[j], XtNfromHoriz, option[i].type != Label ? dialog : NULL); j++;
2130 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2131 XtSetArg(args[j], XtNborderWidth, 0); j++;
2132 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
2133 last = XtCreateManagedWidget(msg, labelWidgetClass, form, args, j);
2137 XtSetArg(args[j], XtNfromVert, option[i].min & 1 ? lastrow : last); j++;
2138 if(option[i].min & 1) { XtSetArg(args[j], XtNfromHoriz, last); j++; }
2139 else { XtSetArg(args[j], XtNfromHoriz, NULL); j++; lastrow = forelast; }
2140 if(option[i].max) XtSetArg(args[j], XtNwidth, option[i].max); j++;
2141 if(option[i].textValue) { // special for buttons of New Variant dialog
2142 XtSetArg(args[j], XtNsensitive, appData.noChessProgram || option[i].value < 0
2143 || strstr(first.variants, VariantName(option[i].value))); j++;
2144 XtSetArg(args[j], XtNborderWidth, (gameInfo.variant == option[i].value)+1); j++;
2146 option[i].handle = (void*)
2147 (dialog = last = XtCreateManagedWidget(option[i].name, commandWidgetClass, form, args, j));
2148 if(option[i].target == NULL) SetColor( *(char**) option[i-1].target, last); else
2149 XtAddCallback(last, XtNcallback, GenericCallback,
2150 (XtPointer)(intptr_t) i);
2151 if(option[i].textValue) SetColor( option[i].textValue, last);
2152 forelast = lastrow; // next button can go on same row
2156 XtSetArg(args[j], XtNfromVert, last); j++;
2157 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2158 XtSetArg(args[j], XtNright, XtChainLeft); j++;
2159 XtSetArg(args[j], XtNborderWidth, 0); j++;
2160 XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
2161 texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
2163 for(j=0; option[i].choice[j]; j++)
2164 if(*(char**)option[i].target && !strcmp(*(char**)option[i].target, option[i].choice[j])) break;
2165 option[i].value = j + (option[i].choice[j] == NULL);
2168 XtSetArg(args[j], XtNfromVert, last); j++;
2169 XtSetArg(args[j], XtNfromHoriz, dialog); j++;
2170 XtSetArg(args[j], XtNwidth, option[i].max ? option[i].max : 100); j++;
2171 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
2172 XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++;
2173 XtSetArg(args[j], XtNlabel, ((char**)option[i].textValue)[option[i].value]); j++;
2174 option[i].handle = (void*)
2175 (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j));
2176 CreateComboPopup(last, option[i].name, i, (char **) option[i].textValue);
2177 values[i] = option[i].value;
2184 printf("GenericPopUp: unexpected case in switch.\n");
2189 // make an attempt to align all spins and textbox controls
2190 maxWidth = maxTextWidth = 0;
2191 for(h=0; h<height; h++) {
2193 if(option[i].type == EndMark) break;
2194 if(option[i].type == Spin || option[i].type == TextBox || option[i].type == ComboBox
2195 || option[i].type == PathName || option[i].type == FileName) {
2197 if(!texts[h]) continue;
2199 XtSetArg(args[j], XtNwidth, &w); j++;
2200 XtGetValues(texts[h], args, j);
2201 if(option[i].type == Spin) {
2202 if(w > maxWidth) maxWidth = w;
2205 if(w > maxTextWidth) maxTextWidth = w;
2206 if(!widest) widest = texts[h];
2210 if(maxTextWidth + 110 < maxWidth)
2211 maxTextWidth = maxWidth - 110;
2212 else maxWidth = maxTextWidth + 110;
2213 for(h=0; h<height; h++) {
2215 if(option[i].type == EndMark) break;
2216 if(!texts[h]) continue;
2218 if(option[i].type == Spin) {
2219 XtSetArg(args[j], XtNwidth, maxWidth); j++;
2220 XtSetValues(texts[h], args, j);
2222 if(option[i].type == TextBox || option[i].type == ComboBox || option[i].type == PathName || option[i].type == FileName) {
2223 XtSetArg(args[j], XtNwidth, maxTextWidth); j++;
2224 XtSetValues(texts[h], args, j);
2229 if(!(option[i].min & 2)) {
2231 if(option[i].min & 1) { XtSetArg(args[j], XtNfromHoriz, last); last = forelast; } else
2232 XtSetArg(args[j], XtNfromHoriz, widest ? widest : dialog); j++;
2233 XtSetArg(args[j], XtNfromVert, anchor ? anchor : last); j++;
2234 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
2235 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
2236 XtSetArg(args[j], XtNleft, XtChainRight); j++;
2237 XtSetArg(args[j], XtNright, XtChainRight); j++;
2238 b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j);
2239 XtAddCallback(b_ok, XtNcallback, GenericCallback, (XtPointer) 0);
2241 XtSetArg(args[0], XtNfromHoriz, b_ok);
2242 b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
2243 XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0);
2246 XtRealizeWidget(popup);
2247 CatchDeleteWindow(popup, "SettingsPopDown");
2249 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
2250 &x, &y, &win_x, &win_y, &mask);
2252 XtSetArg(args[0], XtNx, x - 10);
2253 XtSetArg(args[1], XtNy, y - 30);
2254 XtSetValues(popup, args, 2);
2256 XtPopup(popup, XtGrabExclusive);
2260 if(textField)SetFocus(textField, popup, (XEvent*) NULL, False);
2264 void LoadOptionsProc(w, event, prms, nprms)
2270 GenericPopUp(loadOptions, _("Load Game Options"));
2273 void SaveOptionsProc(w, event, prms, nprms)
2279 GenericPopUp(saveOptions, _("Save Game Options"));
2282 void BoardOptionsProc(w, event, prms, nprms)
2288 GenericPopUp(boardOptions, _("Board Options"));
2291 //---------------------------- Chat Windows ----------------------------------------------
2293 void OutputChatMessage(int partner, char *mess)