changes from H.G. Muller; version 4.3.15
[xboard.git] / xoptions.c
1 /*\r
2  * xoptions.c -- Move list window, part of X front end for XBoard\r
3  *\r
4  * Copyright 2000 Free Software Foundation, Inc.\r
5  *\r
6  * The following terms apply to the enhanced version of XBoard distributed\r
7  * by the Free Software Foundation:\r
8  * ------------------------------------------------------------------------\r
9  * This program is free software; you can redistribute it and/or modify\r
10  * it under the terms of the GNU General Public License as published by\r
11  * the Free Software Foundation; either version 2 of the License, or\r
12  * (at your option) any later version.\r
13  *\r
14  * This program is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU General Public License for more details.\r
18  *\r
19  * You should have received a copy of the GNU General Public License\r
20  * along with this program; if not, write to the Free Software\r
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22  * ------------------------------------------------------------------------\r
23  *\r
24  * See the file ChangeLog for a revision history.\r
25  */\r
26 \r
27 // [HGM] this file is the counterpart of woptions.c, containing xboard popup menus\r
28 // similar to those of WinBoard, to set the most common options interactively.\r
29 \r
30 #include "config.h"\r
31 \r
32 #include <stdio.h>\r
33 #include <ctype.h>\r
34 #include <errno.h>\r
35 #include <sys/types.h>\r
36 \r
37 #if STDC_HEADERS\r
38 # include <stdlib.h>\r
39 # include <string.h>\r
40 #else /* not STDC_HEADERS */\r
41 extern char *getenv();\r
42 # if HAVE_STRING_H\r
43 #  include <string.h>\r
44 # else /* not HAVE_STRING_H */\r
45 #  include <strings.h>\r
46 # endif /* not HAVE_STRING_H */\r
47 #endif /* not STDC_HEADERS */\r
48 \r
49 #if HAVE_UNISTD_H\r
50 # include <unistd.h>\r
51 #endif\r
52 \r
53 #include <X11/Intrinsic.h>\r
54 #include <X11/StringDefs.h>\r
55 #include <X11/Shell.h>\r
56 #include <X11/Xaw/Dialog.h>\r
57 #include <X11/Xaw/Form.h>\r
58 #include <X11/Xaw/List.h>\r
59 #include <X11/Xaw/Label.h>\r
60 #include <X11/Xaw/SimpleMenu.h>\r
61 #include <X11/Xaw/SmeBSB.h>\r
62 #include <X11/Xaw/SmeLine.h>\r
63 #include <X11/Xaw/Box.h>\r
64 #include <X11/Xaw/Paned.h>\r
65 #include <X11/Xaw/MenuButton.h>\r
66 #include <X11/cursorfont.h>\r
67 #include <X11/Xaw/Text.h>\r
68 #include <X11/Xaw/AsciiText.h>\r
69 #include <X11/Xaw/Viewport.h>\r
70 #include <X11/Xaw/Toggle.h>\r
71 \r
72 #include "common.h"\r
73 #include "backend.h"\r
74 #include "xboard.h"\r
75 \r
76 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;\r
77 extern Display *xDisplay;\r
78 extern int squareSize;\r
79 extern Pixmap xMarkPixmap;\r
80 extern char *layoutName;\r
81 extern Window xBoardWindow;\r
82 extern Arg layoutArgs[2], formArgs[2];\r
83 Pixel timerForegroundPixel, timerBackgroundPixel;\r
84 \r
85 // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines\r
86 \r
87 static Widget previous = NULL;\r
88 \r
89 void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b)\r
90 {\r
91     Arg args;\r
92 \r
93     if(previous) {\r
94         XtSetArg(args, XtNdisplayCaret, False);\r
95         XtSetValues(previous, &args, 1);\r
96     }\r
97     XtSetArg(args, XtNdisplayCaret, True);\r
98     XtSetValues(w, &args, 1);\r
99     XtSetKeyboardFocus((Widget) data, w);\r
100     previous = w;\r
101 }\r
102 \r
103 //--------------------------- New Shuffle Game --------------------------------------------\r
104 extern int shuffleOpenings;\r
105 extern int startedFromPositionFile;\r
106 int shuffleUp;\r
107 Widget shuffleShell;\r
108 \r
109 void ShufflePopDown()\r
110 {\r
111     if (!shuffleUp) return;\r
112     XtPopdown(shuffleShell);\r
113     XtDestroyWidget(shuffleShell);\r
114     shuffleUp = False;\r
115     ModeHighlight();\r
116 }\r
117 \r
118 void ShuffleCallback(w, client_data, call_data)\r
119      Widget w;\r
120      XtPointer client_data, call_data;\r
121 {\r
122     String name;\r
123     Widget w2;\r
124     Arg args[16];\r
125     char buf[80];\r
126     \r
127     XtSetArg(args[0], XtNlabel, &name);\r
128     XtGetValues(w, args, 1);\r
129     \r
130     if (strcmp(name, "cancel") == 0) {\r
131         ShufflePopDown();\r
132         return;\r
133     }\r
134     if (strcmp(name, "off") == 0) {\r
135         ShufflePopDown();\r
136         shuffleOpenings = False; // [HGM] should be moved to New Variant menu, once we have it!\r
137         ResetGameEvent();\r
138         AnalysisPopDown();\r
139         return;\r
140     }\r
141     if (strcmp(name, "random") == 0) {\r
142         sprintf(buf, "%d", rand());\r
143         XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value\r
144         XtSetValues(XtParent(w), args, 1);\r
145         return;\r
146     }\r
147     if (strcmp(name, "ok") == 0) {\r
148         int nr; String name;\r
149         name = XawDialogGetValueString(w2 = XtParent(w));\r
150         if(sscanf(name ,"%d",&nr) != 1) {\r
151             sprintf(buf, "%d", appData.defaultFrcPosition);\r
152             XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value\r
153             XtSetValues(w2, args, 1);\r
154             return;\r
155         }\r
156         appData.defaultFrcPosition = nr;\r
157         shuffleOpenings = True;\r
158         ShufflePopDown();\r
159         ResetGameEvent();\r
160         AnalysisPopDown();\r
161         return;\r
162     }\r
163 }\r
164 \r
165 void ShufflePopUp()\r
166 {\r
167     Arg args[16];\r
168     Widget popup, layout, dialog, edit;\r
169     Window root, child;\r
170     int x, y, i;\r
171     int win_x, win_y;\r
172     unsigned int mask;\r
173     char def[80];\r
174     \r
175     i = 0;\r
176     XtSetArg(args[i], XtNresizable, True); i++;\r
177     XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
178     shuffleShell = popup =\r
179       XtCreatePopupShell("New Shuffle Game", transientShellWidgetClass,\r
180                          shellWidget, args, i);\r
181     \r
182     layout =\r
183       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
184                             layoutArgs, XtNumber(layoutArgs));\r
185   \r
186     sprintf(def, "%d\n", appData.defaultFrcPosition);\r
187     i = 0;\r
188     XtSetArg(args[i], XtNlabel, "Start-position number:"); i++;\r
189     XtSetArg(args[i], XtNvalue, def); i++;\r
190     XtSetArg(args[i], XtNborderWidth, 0); i++;\r
191     dialog = XtCreateManagedWidget("Shuffle", dialogWidgetClass,\r
192                                    layout, args, i);\r
193     \r
194 //    XtSetArg(args[0], XtNeditType, XawtextEdit);  // [HGM] can't get edit to work decently\r
195 //    XtSetArg(args[1], XtNuseStringInPlace, False);\r
196 //    XtSetValues(dialog, args, 2);\r
197 \r
198     XawDialogAddButton(dialog, "ok", ShuffleCallback, (XtPointer) dialog);\r
199     XawDialogAddButton(dialog, "cancel", ShuffleCallback, (XtPointer) dialog);\r
200     XawDialogAddButton(dialog, "random", ShuffleCallback, (XtPointer) dialog);\r
201     XawDialogAddButton(dialog, "off", ShuffleCallback, (XtPointer) dialog);\r
202     \r
203     XtRealizeWidget(popup);\r
204     CatchDeleteWindow(popup, "ShufflePopDown");\r
205     \r
206     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
207                   &x, &y, &win_x, &win_y, &mask);\r
208     \r
209     XtSetArg(args[0], XtNx, x - 10);\r
210     XtSetArg(args[1], XtNy, y - 30);\r
211     XtSetValues(popup, args, 2);\r
212     \r
213     XtPopup(popup, XtGrabExclusive);\r
214     shuffleUp = True;\r
215     \r
216     edit = XtNameToWidget(dialog, "*value");\r
217 \r
218     XtSetKeyboardFocus(popup, edit);\r
219 }\r
220 \r
221 void ShuffleMenuProc(w, event, prms, nprms)\r
222      Widget w;\r
223      XEvent *event;\r
224      String *prms;\r
225      Cardinal *nprms;\r
226 {\r
227 //    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {\r
228 //      Reset(FALSE, TRUE);\r
229 //    }\r
230     ShufflePopUp();\r
231 }\r
232 \r
233 //--------------------------- Time-Control Menu Popup ----------------------------------\r
234 int TimeControlUp;\r
235 Widget TimeControlShell;\r
236 int tcInc;\r
237 Widget tcMess1, tcMess2, tcData, tcTime, tcOdds1, tcOdds2;\r
238 int tcIncrement, tcMoves;\r
239 \r
240 void TimeControlPopDown()\r
241 {\r
242     if (!TimeControlUp) return;\r
243     XtPopdown(TimeControlShell);\r
244     XtDestroyWidget(TimeControlShell);\r
245     TimeControlUp = False;\r
246     ModeHighlight();\r
247 }\r
248 \r
249 void TimeControlCallback(w, client_data, call_data)\r
250      Widget w;\r
251      XtPointer client_data, call_data;\r
252 {\r
253     String name, txt;\r
254     Widget w2;\r
255     Arg args[16];\r
256     char buf[80];\r
257     int j;\r
258 \r
259     XtSetArg(args[0], XtNlabel, &name);\r
260     XtGetValues(w, args, 1);\r
261     \r
262     if (strcmp(name, "classical") == 0) {\r
263         if(!tcInc) return;\r
264         j=0;\r
265         XtSetArg(args[j], XtNlabel, "minutes for each"); j++;\r
266         XtSetValues(tcMess1, args, j);\r
267         j=0;\r
268         XtSetArg(args[j], XtNlabel, "moves"); j++;\r
269         XtSetValues(tcMess2, args, j);\r
270         j=0;\r
271         XtSetArg(args[j], XtNstring, &name); j++;\r
272         XtGetValues(tcData, args, j);\r
273         tcIncrement = 0; sscanf(name, "%d", &tcIncrement);\r
274         sprintf(buf, "%d", tcMoves);\r
275         j=0;\r
276         XtSetArg(args[j], XtNstring, buf); j++;\r
277         XtSetValues(tcData, args, j);\r
278         tcInc = False;\r
279         return;\r
280     }\r
281     if (strcmp(name, "incremental") == 0) {\r
282         if(tcInc) return;\r
283         j=0;\r
284         XtSetArg(args[j], XtNlabel, "minutes, plus"); j++;\r
285         XtSetValues(tcMess1, args, j);\r
286         j=0;\r
287         XtSetArg(args[j], XtNlabel, "sec/move"); j++;\r
288         XtSetValues(tcMess2, args, j);\r
289         j=0;\r
290         XtSetArg(args[j], XtNstring, &name); j++;\r
291         XtGetValues(tcData, args, j);\r
292         tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves);\r
293         sprintf(buf, "%d", tcIncrement);\r
294         j=0;\r
295         XtSetArg(args[j], XtNstring, buf); j++;\r
296         XtSetValues(tcData, args, j);\r
297         tcInc = True;\r
298         return;\r
299     }\r
300     if (strcmp(name, " OK ") == 0) {\r
301         int inc, mps, tc, ok;\r
302         XtSetArg(args[0], XtNstring, &txt);\r
303         XtGetValues(tcData, args, 1);\r
304         if(tcInc) {\r
305             ok = sscanf(txt, "%d", &inc); mps = 0;\r
306             if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero\r
307             ok &= (inc >= 0);\r
308         } else {\r
309             ok = sscanf(txt, "%d", &mps); inc = -1;\r
310             ok &= (mps > 0);\r
311         }\r
312         if(ok != 1) {\r
313             XtSetArg(args[0], XtNstring, ""); // erase any offending input\r
314             XtSetValues(tcData, args, 1);\r
315             return;\r
316         }\r
317         XtSetArg(args[0], XtNstring, &txt);\r
318         XtGetValues(tcTime, args, 1);\r
319         if(!ParseTimeControl(txt, inc, mps)) {\r
320             XtSetArg(args[0], XtNstring, ""); // erase any offending input\r
321             XtSetValues(tcTime, args, 1);\r
322             DisplayError("Bad Time-Control String", 0);\r
323             return;\r
324         }\r
325         appData.movesPerSession = mps;\r
326         appData.timeIncrement = inc;\r
327         appData.timeControl = strdup(txt);\r
328         XtSetArg(args[0], XtNstring, &txt);\r
329         XtGetValues(tcOdds1, args, 1);\r
330         appData.firstTimeOdds = first.timeOdds \r
331                 = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;\r
332         XtGetValues(tcOdds2, args, 1);\r
333         appData.secondTimeOdds = second.timeOdds \r
334                 = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;\r
335 \r
336         Reset(True, True);\r
337         TimeControlPopDown();\r
338         return;\r
339     }\r
340 }\r
341 \r
342 void TimeControlPopUp()\r
343 {\r
344     Arg args[16];\r
345     Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, mess;\r
346     Window root, child;\r
347     int x, y, i, j;\r
348     int win_x, win_y;\r
349     unsigned int mask;\r
350     char def[80];\r
351     \r
352     tcInc = (appData.timeIncrement >= 0);\r
353     tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;\r
354     if(!tcInc) tcIncrement = 0;\r
355     sprintf(def, "%d", tcInc ? tcIncrement : tcMoves);\r
356 \r
357     i = 0;\r
358     XtSetArg(args[i], XtNresizable, True); i++;\r
359 //    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
360     TimeControlShell = popup =\r
361       XtCreatePopupShell("TimeControl Menu", transientShellWidgetClass,\r
362                          shellWidget, args, i);\r
363     \r
364     layout =\r
365       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
366                             layoutArgs, XtNumber(layoutArgs));\r
367   \r
368     form =\r
369       XtCreateManagedWidget(layoutName, formWidgetClass, layout,\r
370                             formArgs, XtNumber(formArgs));\r
371   \r
372     j = 0;\r
373 //    XtSetArg(args[j], XtNwidth,     (XtArgVal) 300); j++;\r
374 //    XtSetArg(args[j], XtNheight,    (XtArgVal) 85); j++;\r
375     XtSetValues(popup, args, j);\r
376 \r
377     j= 0;\r
378     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
379     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
380     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
381     XtSetArg(args[j], XtNstring, appData.timeControl);  j++;\r
382     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
383     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
384     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
385     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
386     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
387     XtSetArg(args[j], XtNresizable, True);  j++;\r
388     XtSetArg(args[j], XtNwidth,  85);  j++;\r
389 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
390     tcTime = XtCreateManagedWidget("TC", asciiTextWidgetClass, form, args, j);\r
391     XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
392 \r
393     j= 0;\r
394     XtSetArg(args[j], XtNlabel, tcInc ? "   minutes, plus   " : "minutes for each"); j++;\r
395     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
396     XtSetArg(args[j], XtNfromHoriz, tcTime); j++;\r
397     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
398     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
399     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
400     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
401   //  XtSetArg(args[j], XtNwidth,  100);  j++;\r
402   //  XtSetArg(args[j], XtNheight, 20);  j++;\r
403     tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);\r
404 \r
405     j= 0;\r
406     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
407     XtSetArg(args[j], XtNfromHoriz, tcMess1); j++;\r
408     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
409     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
410     XtSetArg(args[j], XtNstring, def);  j++;\r
411     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
412     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
413     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
414     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
415     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
416     XtSetArg(args[j], XtNresizable, True);  j++;\r
417     XtSetArg(args[j], XtNwidth,  40);  j++;\r
418 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
419     tcData = XtCreateManagedWidget("MPS", asciiTextWidgetClass, form, args, j);\r
420     XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
421 \r
422     j= 0;\r
423     XtSetArg(args[j], XtNlabel, tcInc ? "sec/move" : "moves     "); j++;\r
424     XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;\r
425     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
426     XtSetArg(args[j], XtNfromHoriz, tcData); j++;\r
427     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
428     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
429     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
430     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
431 //    XtSetArg(args[j], XtNwidth,  80);  j++;\r
432 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
433     tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass,\r
434                                    form, args, j);\r
435 \r
436     j= 0;\r
437     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
438     XtSetArg(args[j], XtNfromVert, tcTime); j++;\r
439     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
440     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
441     XtSetArg(args[j], XtNstring, "1");  j++;\r
442     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
443     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
444     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
445     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
446     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
447     XtSetArg(args[j], XtNresizable, True);  j++;\r
448     XtSetArg(args[j], XtNwidth,  40);  j++;\r
449 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
450     tcOdds1 = XtCreateManagedWidget("Odds1", asciiTextWidgetClass, form, args, j);\r
451     XtAddEventHandler(tcOdds1, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
452 \r
453     j= 0;\r
454     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
455     XtSetArg(args[j], XtNfromVert, tcTime); j++;\r
456     XtSetArg(args[j], XtNfromHoriz, tcOdds1); j++;\r
457     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
458     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
459     XtSetArg(args[j], XtNstring, "1");  j++;\r
460     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
461     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
462     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
463     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
464     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
465     XtSetArg(args[j], XtNresizable, True);  j++;\r
466     XtSetArg(args[j], XtNwidth,  40);  j++;\r
467 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
468     tcOdds2 = XtCreateManagedWidget("Odds2", asciiTextWidgetClass, form, args, j);\r
469     XtAddEventHandler(tcOdds2, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
470 \r
471     j= 0;\r
472     XtSetArg(args[j], XtNlabel, "Engine #1 and #2 Time-Odds Factors"); j++;\r
473     XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;\r
474     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
475     XtSetArg(args[j], XtNfromVert, tcTime); j++;\r
476     XtSetArg(args[j], XtNfromHoriz, tcOdds2); j++;\r
477     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
478     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
479     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
480     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
481 //    XtSetArg(args[j], XtNwidth,  200);  j++;\r
482 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
483     mess = XtCreateManagedWidget("Oddstext", labelWidgetClass,\r
484                                    form, args, j);\r
485     j=0;\r
486     XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;\r
487     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
488     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
489     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
490     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
491     b_clas= XtCreateManagedWidget("classical", commandWidgetClass,\r
492                                    form, args, j);   \r
493     XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0);\r
494 \r
495     j=0;\r
496     XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;\r
497     XtSetArg(args[j], XtNfromHoriz, b_clas);  j++;\r
498     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
499     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
500     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
501     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
502     b_inc = XtCreateManagedWidget("incremental", commandWidgetClass,\r
503                                    form, args, j);   \r
504     XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);\r
505 \r
506     j=0;\r
507     XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;\r
508     XtSetArg(args[j], XtNfromHoriz, tcData);  j++;\r
509     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
510     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
511     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
512     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
513     b_ok= XtCreateManagedWidget(" OK ", commandWidgetClass,\r
514                                    form, args, j);   \r
515     XtAddCallback(b_ok, XtNcallback, TimeControlCallback, (XtPointer) 0);\r
516 \r
517     j=0;\r
518     XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;\r
519     XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;\r
520     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
521     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
522     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
523     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
524     b_cancel= XtCreateManagedWidget("cancel", commandWidgetClass,\r
525                                    form, args, j);   \r
526     XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0);\r
527 \r
528     XtRealizeWidget(popup);\r
529     CatchDeleteWindow(popup, "TimeControlPopDown");\r
530     \r
531     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
532                   &x, &y, &win_x, &win_y, &mask);\r
533     \r
534     XtSetArg(args[0], XtNx, x - 10);\r
535     XtSetArg(args[1], XtNy, y - 30);\r
536     XtSetValues(popup, args, 2);\r
537     \r
538     XtPopup(popup, XtGrabExclusive);\r
539     TimeControlUp = True;\r
540     \r
541     previous = NULL;\r
542     SetFocus(tcTime, popup, (XEvent*) NULL, False);\r
543 //    XtSetKeyboardFocus(popup, tcTime);\r
544 }\r
545 \r
546 void TimeControlProc(w, event, prms, nprms)\r
547      Widget w;\r
548      XEvent *event;\r
549      String *prms;\r
550      Cardinal *nprms;\r
551 {\r
552    TimeControlPopUp();\r
553 }\r
554 \r
555 //--------------------------- Engine-Options Menu Popup ----------------------------------\r
556 int EngineUp;\r
557 Widget EngineShell;\r
558 extern int adjudicateLossThreshold;\r
559 \r
560 Widget engDrawMoves, engThreshold, engRule, engRepeat;\r
561 \r
562 void EnginePopDown()\r
563 {\r
564     if (!EngineUp) return;\r
565     XtPopdown(EngineShell);\r
566     XtDestroyWidget(EngineShell);\r
567     EngineUp = False;\r
568     ModeHighlight();\r
569 }\r
570 \r
571 int ReadToggle(Widget w)\r
572 {\r
573     Arg args; Boolean res;\r
574 \r
575     XtSetArg(args, XtNstate, &res);\r
576     XtGetValues(w, &args, 1);\r
577 \r
578     return res;\r
579 }\r
580 \r
581 Widget w1, w2, w3, w4, w5, w6, w7, w8;\r
582 \r
583 void EngineCallback(w, client_data, call_data)\r
584      Widget w;\r
585      XtPointer client_data, call_data;\r
586 {\r
587     String name;\r
588     Widget s2;\r
589     Arg args[16];\r
590     char buf[80];\r
591     int j;\r
592     \r
593     XtSetArg(args[0], XtNlabel, &name);\r
594     XtGetValues(w, args, 1);\r
595     \r
596     if (strcmp(name, "OK") == 0) {\r
597         // read all switches\r
598         appData.periodicUpdates = ReadToggle(w1);\r
599 //      appData.hideThinkingFromHuman = ReadToggle(w2);\r
600         appData.firstScoreIsAbsolute  = ReadToggle(w3);\r
601         appData.secondScoreIsAbsolute = ReadToggle(w4);\r
602         appData.testClaims    = ReadToggle(w5);\r
603         appData.checkMates    = ReadToggle(w6);\r
604         appData.materialDraws = ReadToggle(w7);\r
605         appData.trivialDraws  = ReadToggle(w8);\r
606 \r
607         // adjust setting in other menu for duplicates \r
608         // (perhaps duplicates should be removed from general Option Menu?)\r
609 //      XtSetArg(args[0], XtNleftBitmap, appData.showThinking ? xMarkPixmap : None);\r
610 //      XtSetValues(XtNameToWidget(menuBarWidget,\r
611 //                                 "menuOptions.Show Thinking"), args, 1);\r
612 \r
613         // read out numeric controls, simply ignore bad formats for now\r
614         XtSetArg(args[0], XtNstring, &name);\r
615         XtGetValues(engDrawMoves, args, 1);\r
616         if(sscanf(name, "%d", &j) == 1) appData.adjudicateDrawMoves = j;\r
617         XtGetValues(engThreshold, args, 1);\r
618         if(sscanf(name, "%d", &j) == 1) \r
619                 adjudicateLossThreshold = appData.adjudicateLossThreshold = -j; // inverted!\r
620         XtGetValues(engRule, args, 1);\r
621         if(sscanf(name, "%d", &j) == 1) appData.ruleMoves = j;\r
622         XtGetValues(engRepeat, args, 1);\r
623         if(sscanf(name, "%d", &j) == 1) appData.drawRepeats = j;\r
624 \r
625         EnginePopDown();\r
626         ShowThinkingEvent(); // [HGM] thinking: score adjudication might need thinking output\r
627         return;\r
628     }\r
629 }\r
630 \r
631 void EnginePopUp()\r
632 {\r
633     Arg args[16];\r
634     Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, s1; \r
635     Window root, child;\r
636     int x, y, i, j, width;\r
637     int win_x, win_y;\r
638     unsigned int mask;\r
639     char def[80];\r
640     \r
641     tcInc = (appData.timeIncrement >= 0);\r
642     tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;\r
643     if(!tcInc) tcIncrement = 0;\r
644     sprintf(def, "%d", tcInc ? tcIncrement : tcMoves);\r
645 \r
646     i = 0;\r
647     XtSetArg(args[i], XtNresizable, True); i++;\r
648 //    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
649     EngineShell = popup =\r
650       XtCreatePopupShell("Adjudications", transientShellWidgetClass,\r
651                          shellWidget, args, i);\r
652     \r
653     layout =\r
654       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
655                             layoutArgs, XtNumber(layoutArgs));\r
656   \r
657     form =\r
658       XtCreateManagedWidget(layoutName, formWidgetClass, layout,\r
659                             formArgs, XtNumber(formArgs));\r
660   \r
661     j = 0;\r
662 //    XtSetArg(args[j], XtNwidth,     (XtArgVal) 250); j++;\r
663 //    XtSetArg(args[j], XtNheight,    (XtArgVal) 400); j++;\r
664 //    XtSetValues(popup, args, j);\r
665 \r
666     j = 0;\r
667 //    XtSetArg(args[j], XtNwidth,       (XtArgVal) 250); j++;\r
668 //    XtSetArg(args[j], XtNheight,      (XtArgVal) 20); j++;\r
669     XtSetArg(args[j], XtNleft,        (XtArgVal) XtChainLeft); j++;\r
670     XtSetArg(args[j], XtNright,       (XtArgVal) XtChainRight); j++;\r
671     XtSetArg(args[j], XtNstate,       appData.periodicUpdates); j++;\r
672 //    XtSetArg(args[j], XtNjustify,     (XtArgVal) XtJustifyLeft); j++;\r
673     w1 = XtCreateManagedWidget("Periodic Updates (Analysis Mode)", toggleWidgetClass, form, args, j);\r
674 \r
675     XtSetArg(args[j], XtNwidth,       (XtArgVal) &width);\r
676     XtGetValues(w1, &args[j], 1);\r
677 \r
678 //    XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) w1);\r
679 //    XtSetArg(args[j-3], XtNstate,       appData.hideThinkingFromHuman);\r
680 //    w2 = XtCreateManagedWidget("Hide Thinking from Human", toggleWidgetClass, form, args, j);\r
681 \r
682     XtSetArg(args[j], XtNwidth,       (XtArgVal) width); j++;\r
683     XtSetArg(args[j-2], XtNstate,     appData.firstScoreIsAbsolute);\r
684     XtSetArg(args[j], XtNfromVert,    (XtArgVal) w1); j++;\r
685     w3 = XtCreateManagedWidget("Engine #1 Score is Absolute", toggleWidgetClass, form, args, j);\r
686 \r
687     XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) w3);\r
688     XtSetArg(args[j-3], XtNstate,       appData.secondScoreIsAbsolute);\r
689     w4 = XtCreateManagedWidget("Engine #2 Score is Absolute", toggleWidgetClass, form, args, j);\r
690 \r
691     s1 = XtCreateManagedWidget("\nEngine-Engine Adjudications:", labelWidgetClass, form, args, 3);\r
692 \r
693     XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) s1);\r
694     XtSetArg(args[j-3], XtNstate,       appData.testClaims);\r
695     w5 = XtCreateManagedWidget("Verify Engine Result Claims", toggleWidgetClass, form, args, j);\r
696 \r
697     XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) w5);\r
698     XtSetArg(args[j-3], XtNstate,       appData.checkMates);\r
699     w6 = XtCreateManagedWidget("Detect All Mates", toggleWidgetClass, form, args, j);\r
700 \r
701     XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) w6);\r
702     XtSetArg(args[j-3], XtNstate,       appData.materialDraws);\r
703     w7 = XtCreateManagedWidget("Draw when Insuff. Mating Material", toggleWidgetClass, form, args, j);\r
704 \r
705     XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) w7);\r
706     XtSetArg(args[j-3], XtNstate,       appData.trivialDraws);\r
707     w8 = XtCreateManagedWidget("Adjudicate Trivial Draws", toggleWidgetClass, form, args, j);\r
708 \r
709     XtSetArg(args[0], XtNfromVert,  (XtArgVal) w4);\r
710     XtSetArg(args[1], XtNborderWidth, (XtArgVal) 0);\r
711     XtSetValues(s1, args, 2);\r
712 \r
713     sprintf(def, "%d", appData.adjudicateDrawMoves);\r
714     j= 0;\r
715     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
716     XtSetArg(args[j], XtNfromVert, w8); j++;\r
717     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
718     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
719     XtSetArg(args[j], XtNstring, def);  j++;\r
720     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
721     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
722     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
723     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
724     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
725     XtSetArg(args[j], XtNresizable, True);  j++;\r
726     XtSetArg(args[j], XtNwidth,  60);  j++;\r
727 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
728     engDrawMoves = XtCreateManagedWidget("Length", asciiTextWidgetClass, form, args, j);\r
729     XtAddEventHandler(engDrawMoves, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
730 \r
731     j= 0;\r
732     XtSetArg(args[j], XtNlabel, " moves maximum, then draw"); j++;\r
733     XtSetArg(args[j], XtNjustify,     (XtArgVal) XtJustifyLeft); j++;\r
734     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
735     XtSetArg(args[j], XtNfromVert, w8); j++;\r
736     XtSetArg(args[j], XtNfromHoriz, engDrawMoves); j++;\r
737     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
738     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
739     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
740     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
741 //    XtSetArg(args[j], XtNwidth,  170);  j++;\r
742 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
743     tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);\r
744 \r
745     sprintf(def, "%d", -appData.adjudicateLossThreshold); // inverted!\r
746     j= 0;\r
747     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
748     XtSetArg(args[j], XtNfromVert, engDrawMoves); j++;\r
749     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
750     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
751     XtSetArg(args[j], XtNstring, def);  j++;\r
752     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
753     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
754     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
755     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
756     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
757     XtSetArg(args[j], XtNresizable, True);  j++;\r
758     XtSetArg(args[j], XtNwidth,  60);  j++;\r
759 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
760     engThreshold = XtCreateManagedWidget("Threshold", asciiTextWidgetClass, form, args, j);\r
761     XtAddEventHandler(engThreshold, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
762 \r
763     j= 0;\r
764     XtSetArg(args[j], XtNlabel, "-centiPawn lead is win"); j++;\r
765     XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;\r
766     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
767     XtSetArg(args[j], XtNfromVert, engDrawMoves); j++;\r
768     XtSetArg(args[j], XtNfromHoriz, engThreshold); j++;\r
769     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
770     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
771     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
772     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
773 //    XtSetArg(args[j], XtNwidth,  150);  j++;\r
774 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
775     tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j);\r
776 \r
777     sprintf(def, "%d", appData.ruleMoves);\r
778     j= 0;\r
779     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
780     XtSetArg(args[j], XtNfromVert, engThreshold); j++;\r
781     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
782     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
783     XtSetArg(args[j], XtNstring, def);  j++;\r
784     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
785     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
786     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
787     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
788     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
789     XtSetArg(args[j], XtNresizable, True);  j++;\r
790     XtSetArg(args[j], XtNwidth,  30);  j++;\r
791 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
792     engRule = XtCreateManagedWidget("Rule", asciiTextWidgetClass, form, args, j);\r
793     XtAddEventHandler(engRule, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
794 \r
795     j= 0;\r
796     XtSetArg(args[j], XtNlabel, "-move rule applied"); j++;\r
797     XtSetArg(args[j], XtNjustify,     (XtArgVal) XtJustifyLeft); j++;\r
798     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
799     XtSetArg(args[j], XtNfromVert, engThreshold); j++;\r
800     XtSetArg(args[j], XtNfromHoriz, engRule); j++;\r
801     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
802     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
803     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
804     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
805 //    XtSetArg(args[j], XtNwidth,  130);  j++;\r
806 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
807     tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);\r
808 \r
809     sprintf(def, "%d", appData.drawRepeats);\r
810     j= 0;\r
811     XtSetArg(args[j], XtNborderWidth, 1); j++;\r
812     XtSetArg(args[j], XtNfromVert, engRule); j++;\r
813     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
814     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
815     XtSetArg(args[j], XtNstring, def);  j++;\r
816     XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
817     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
818     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
819     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
820     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
821     XtSetArg(args[j], XtNresizable, True);  j++;\r
822     XtSetArg(args[j], XtNwidth,  30);  j++;\r
823 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
824     engRepeat = XtCreateManagedWidget("Repeats", asciiTextWidgetClass, form, args, j);\r
825     XtAddEventHandler(engRepeat, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
826 \r
827     j= 0;\r
828     XtSetArg(args[j], XtNlabel, "-fold repeat is draw"); j++;\r
829     XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;\r
830     XtSetArg(args[j], XtNborderWidth, 0); j++;\r
831     XtSetArg(args[j], XtNfromVert, engRule); j++;\r
832     XtSetArg(args[j], XtNfromHoriz, engRepeat); j++;\r
833     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
834     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
835     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
836     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
837 //    XtSetArg(args[j], XtNwidth,  130);  j++;\r
838 //    XtSetArg(args[j], XtNheight, 20);  j++;\r
839     tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j);\r
840 \r
841     j=0;\r
842     XtSetArg(args[j], XtNfromVert, engRepeat);  j++;\r
843     XtSetArg(args[j], XtNfromHoriz, tcMess2);  j++;\r
844     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
845     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
846     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
847     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
848     b_ok= XtCreateManagedWidget("OK", commandWidgetClass, form, args, j);   \r
849     XtAddCallback(b_ok, XtNcallback, EngineCallback, (XtPointer) 0);\r
850 \r
851     j=0;\r
852     XtSetArg(args[j], XtNfromVert, engRepeat);  j++;\r
853     XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;\r
854     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
855     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
856     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
857     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
858     b_cancel= XtCreateManagedWidget("cancel", commandWidgetClass,\r
859                                    form, args, j);   \r
860     XtAddCallback(b_cancel, XtNcallback, EnginePopDown, (XtPointer) 0);\r
861 \r
862     XtRealizeWidget(popup);\r
863     CatchDeleteWindow(popup, "EnginePopDown");\r
864     \r
865     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
866                   &x, &y, &win_x, &win_y, &mask);\r
867     \r
868     XtSetArg(args[0], XtNx, x - 10);\r
869     XtSetArg(args[1], XtNy, y - 30);\r
870     XtSetValues(popup, args, 2);\r
871     \r
872     XtPopup(popup, XtGrabExclusive);\r
873     EngineUp = True;\r
874     \r
875     previous = NULL;\r
876     SetFocus(engThreshold, popup, (XEvent*) NULL, False);\r
877 }\r
878 \r
879 void EngineMenuProc(w, event, prms, nprms)\r
880      Widget w;\r
881      XEvent *event;\r
882      String *prms;\r
883      Cardinal *nprms;\r
884 {\r
885    EnginePopUp();\r
886 }\r
887 \r
888 //--------------------------- New-Variant Menu PopUp -----------------------------------\r
889 struct NewVarButton {\r
890   char   *name;\r
891   char *color;\r
892   Widget handle;\r
893   VariantClass variant;\r
894 };\r
895 \r
896 struct NewVarButton buttonDesc[] = {\r
897     {"normal",            "#FFFFFF", 0, VariantNormal},\r
898     {"FRC",               "#FFFFFF", 0, VariantFischeRandom},\r
899     {"wild castle",       "#FFFFFF", 0, VariantWildCastle},\r
900     {"no castle",         "#FFFFFF", 0, VariantNoCastle},\r
901     {"knightmate",        "#FFFFFF", 0, VariantKnightmate},\r
902     {"berolina",          "#FFFFFF", 0, VariantBerolina},\r
903     {"cylinder",          "#FFFFFF", 0, VariantCylinder},\r
904     {"shatranj",          "#FFFFFF", 0, VariantShatranj},\r
905     {"atomic",            "#FFFFFF", 0, VariantAtomic},\r
906     {"two kings",         "#FFFFFF", 0, VariantTwoKings},\r
907     {"3-checks",          "#FFFFFF", 0, Variant3Check},\r
908     {"suicide",           "#FFFFBF", 0, VariantSuicide},\r
909     {"give-away",         "#FFFFBF", 0, VariantGiveaway},\r
910     {"losers",            "#FFFFBF", 0, VariantLosers},\r
911     {"fairy",             "#BFBFBF", 0, VariantFairy},\r
912     {"Superchess",        "#FFBFBF", 0, VariantSuper},\r
913     {"crazyhouse",        "#FFBFBF", 0, VariantCrazyhouse},\r
914     {"bughouse",          "#FFBFBF", 0, VariantBughouse},\r
915     {"shogi (9x9)",       "#BFFFFF", 0, VariantShogi},\r
916     {"xiangqi (9x10)",    "#BFFFFF", 0, VariantXiangqi},\r
917     {"courier (12x8)",    "#BFFFBF", 0, VariantCourier},\r
918     {"janus (10x8)",      "#BFBFFF", 0, VariantJanus},\r
919     {"Capablanca (10x8)", "#BFBFFF", 0, VariantCapablanca},\r
920     {"CRC (10x8)",        "#BFBFFF", 0, VariantCapaRandom},\r
921 #ifdef GOTHIC\r
922     {"Gothic (10x8)",     "#BFBFFF", 0, VariantGothic},\r
923 #endif\r
924 #ifdef FALCON\r
925     {"Falcon (10x8)",     "#BFBFFF", 0, VariantFalcon},\r
926 #endif\r
927     {NULL,                0, 0, (VariantClass) 0}\r
928 };\r
929 \r
930 int NewVariantUp;\r
931 Widget NewVariantShell;\r
932 \r
933 void NewVariantPopDown()\r
934 {\r
935     if (!NewVariantUp) return;\r
936     XtPopdown(NewVariantShell);\r
937     XtDestroyWidget(NewVariantShell);\r
938     NewVariantUp = False;\r
939     ModeHighlight();\r
940 }\r
941 \r
942 void NewVariantCallback(w, client_data, call_data)\r
943      Widget w;\r
944      XtPointer client_data, call_data;\r
945 {\r
946     String name;\r
947     Widget w2;\r
948     Arg args[16];\r
949     char buf[80];\r
950     VariantClass v;\r
951     \r
952     XtSetArg(args[0], XtNlabel, &name);\r
953     XtGetValues(w, args, 1);\r
954     \r
955     if (strcmp(name, "  OK  ") == 0) {\r
956         int nr = (int) XawToggleGetCurrent(buttonDesc[0].handle) - 1;\r
957         if(nr < 0) return;\r
958         v = buttonDesc[nr].variant;\r
959         if(!appData.noChessProgram) { \r
960             char *name = VariantName(v), buf[MSG_SIZ];\r
961             if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {\r
962                 /* [HGM] in protocol 2 we check if variant is suported by engine */\r
963                 sprintf(buf, "Variant %s not supported by %s", name, first.tidy);\r
964                 DisplayError(buf, 0);\r
965 //              NewVariantPopDown();\r
966                 return; /* ignore OK if first engine does not support it */\r
967             } else\r
968             if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {\r
969                 sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);\r
970                 DisplayError(buf, 0);   /* use of second engine is optional; only warn user */\r
971             }\r
972         }\r
973 \r
974         gameInfo.variant = v;\r
975         appData.variant = VariantName(v);\r
976 \r
977         shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
978         startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
979         appData.pieceToCharTable = NULL;\r
980         Reset(True, True);\r
981         NewVariantPopDown();\r
982         return;\r
983     }\r
984 }\r
985 \r
986 void NewVariantPopUp()\r
987 {\r
988     Arg args[16];\r
989     Widget popup, layout, dialog, edit, form, last = NULL, b_ok, b_cancel;\r
990     Window root, child;\r
991     int x, y, i, j;\r
992     int win_x, win_y;\r
993     unsigned int mask;\r
994     char def[80];\r
995     XrmValue vFrom, vTo;\r
996 \r
997     i = 0;\r
998     XtSetArg(args[i], XtNresizable, True); i++;\r
999 //    XtSetArg(args[i], XtNwidth, 250); i++;\r
1000 //    XtSetArg(args[i], XtNheight, 300); i++;\r
1001     NewVariantShell = popup =\r
1002       XtCreatePopupShell("NewVariant Menu", transientShellWidgetClass,\r
1003                          shellWidget, args, i);\r
1004     \r
1005     layout =\r
1006       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
1007                             layoutArgs, XtNumber(layoutArgs));\r
1008   \r
1009     form =\r
1010       XtCreateManagedWidget("form", formWidgetClass, layout,\r
1011                             formArgs, XtNumber(formArgs));\r
1012   \r
1013     for(i = 0; buttonDesc[i].name != NULL; i++) {\r
1014         Pixel buttonColor;\r
1015         if (!appData.monoMode) {\r
1016             vFrom.addr = (caddr_t) buttonDesc[i].color;\r
1017             vFrom.size = strlen(buttonDesc[i].color);\r
1018             XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
1019             if (vTo.addr == NULL) {\r
1020                 buttonColor = (Pixel) -1;\r
1021             } else {\r
1022                 buttonColor = *(Pixel *) vTo.addr;\r
1023             }\r
1024         }\r
1025     \r
1026         j = 0;\r
1027         XtSetArg(args[j], XtNradioGroup, last); j++;\r
1028         XtSetArg(args[j], XtNwidth, 125); j++;\r
1029 //      XtSetArg(args[j], XtNheight, 16); j++;\r
1030         XtSetArg(args[j], XtNfromVert, i == 15 ? NULL : last); j++;\r
1031         XtSetArg(args[j], XtNfromHoriz, i < 15 ? NULL : buttonDesc[i-15].handle); j++;\r
1032         XtSetArg(args[j], XtNradioData, i+1); j++;\r
1033         XtSetArg(args[j], XtNbackground, buttonColor); j++;\r
1034         XtSetArg(args[j], XtNstate, gameInfo.variant == buttonDesc[i].variant); j++;\r
1035         buttonDesc[i].handle = last =\r
1036             XtCreateManagedWidget(buttonDesc[i].name, toggleWidgetClass, form, args, j);\r
1037     }\r
1038 \r
1039     j=0;\r
1040     XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle);  j++;\r
1041     XtSetArg(args[j], XtNfromHoriz, buttonDesc[12].handle);  j++;\r
1042     XtSetArg(args[j], XtNheight, 35); j++;\r
1043 //    XtSetArg(args[j], XtNwidth, 60); j++;\r
1044     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
1045     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
1046     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
1047     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
1048     b_cancel= XtCreateManagedWidget("CANCEL", commandWidgetClass, form, args, j);   \r
1049     XtAddCallback(b_cancel, XtNcallback, NewVariantPopDown, (XtPointer) 0);\r
1050 \r
1051     j=0;\r
1052     XtSetArg(args[j], XtNfromHoriz, b_cancel);  j++;\r
1053     XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle);  j++;\r
1054     XtSetArg(args[j], XtNheight, 35); j++;\r
1055 //    XtSetArg(args[j], XtNwidth, 60); j++;\r
1056     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
1057     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
1058     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
1059     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
1060     b_ok= XtCreateManagedWidget("  OK  ", commandWidgetClass, form, args, j);   \r
1061     XtAddCallback(b_ok, XtNcallback, NewVariantCallback, (XtPointer) 0);\r
1062 \r
1063     XtRealizeWidget(popup);\r
1064     CatchDeleteWindow(popup, "NewVariantPopDown");\r
1065     \r
1066     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
1067                   &x, &y, &win_x, &win_y, &mask);\r
1068     \r
1069     XtSetArg(args[0], XtNx, x - 10);\r
1070     XtSetArg(args[1], XtNy, y - 30);\r
1071     XtSetValues(popup, args, 2);\r
1072     \r
1073     XtPopup(popup, XtGrabExclusive);\r
1074     NewVariantUp = True;\r
1075 }\r
1076 \r
1077 void NewVariantProc(w, event, prms, nprms)\r
1078      Widget w;\r
1079      XEvent *event;\r
1080      String *prms;\r
1081      Cardinal *nprms;\r
1082 {\r
1083    NewVariantPopUp();\r
1084 }\r
1085 \r
1086 //--------------------------- UCI Menu Popup ------------------------------------------\r
1087 int UciUp;\r
1088 Widget UciShell;\r
1089 \r
1090 struct UciControl {\r
1091   char *name;\r
1092   Widget handle;\r
1093   void *ptr;\r
1094 };\r
1095 \r
1096 struct UciControl controlDesc[] = {\r
1097   {"maximum nr of CPUs:", 0, &appData.smpCores},\r
1098   {"Polyglot Directory:", 0, &appData.polyglotDir},\r
1099   {"Hash Size (MB):",     0, &appData.defaultHashSize},\r
1100   {"EGTB Path:",          0, &appData.defaultPathEGTB},\r
1101   {"EGTB Cache (MB):",    0, &appData.defaultCacheSizeEGTB},\r
1102   {"Polyglot Book:",      0, &appData.polyglotBook},\r
1103   {NULL, 0, NULL},\r
1104 };\r
1105 \r
1106 void UciPopDown()\r
1107 {\r
1108     if (!UciUp) return;\r
1109     XtPopdown(UciShell);\r
1110     XtDestroyWidget(UciShell);\r
1111     UciUp = False;\r
1112     ModeHighlight();\r
1113 }\r
1114 \r
1115 void UciCallback(w, client_data, call_data)\r
1116      Widget w;\r
1117      XtPointer client_data, call_data;\r
1118 {\r
1119     String name;\r
1120     Arg args[16];\r
1121     char buf[80];\r
1122     int oldCores = appData.smpCores, ponder = 0;\r
1123     \r
1124     XtSetArg(args[0], XtNlabel, &name);\r
1125     XtGetValues(w, args, 1);\r
1126     \r
1127     if (strcmp(name, "OK") == 0) {\r
1128         int nr, i, j; String name;\r
1129         for(i=0; i<6; i++) {\r
1130             XtSetArg(args[0], XtNstring, &name);\r
1131             XtGetValues(controlDesc[i].handle, args, 1);\r
1132             if(i&1) {\r
1133                 if(name)\r
1134                     *(char**) controlDesc[i].ptr = strdup(name);\r
1135             } else {\r
1136                 if(sscanf(name, "%d", &j) == 1) \r
1137                     *(int*) controlDesc[i].ptr = j;\r
1138             }\r
1139         }\r
1140         XtSetArg(args[0], XtNstate, &appData.usePolyglotBook);\r
1141         XtGetValues(w1, args, 1);\r
1142         XtSetArg(args[0], XtNstate, &appData.firstHasOwnBookUCI);\r
1143         XtGetValues(w2, args, 1);\r
1144         XtSetArg(args[0], XtNstate, &appData.secondHasOwnBookUCI);\r
1145         XtGetValues(w3, args, 1);\r
1146         XtSetArg(args[0], XtNstate, &ponder);\r
1147         XtGetValues(w4, args, 1);\r
1148 \r
1149         // adjust setting in other menu for duplicates \r
1150         // (perhaps duplicates should be removed from general Option Menu?)\r
1151         XtSetArg(args[0], XtNleftBitmap, ponder ? xMarkPixmap : None);\r
1152         XtSetValues(XtNameToWidget(menuBarWidget,\r
1153                                    "menuOptions.Ponder Next Move"), args, 1);\r
1154 \r
1155         // make sure changes are sent to first engine by re-initializing it\r
1156         // if it was already started pre-emptively at end of previous game\r
1157         if(gameMode == BeginningOfGame) Reset(True, True); else {\r
1158             // Some changed setting need immediate sending always.\r
1159             PonderNextMoveEvent(ponder);\r
1160             if(oldCores != appData.smpCores)\r
1161                 NewSettingEvent(False, "cores", appData.smpCores);\r
1162       }\r
1163       UciPopDown();\r
1164       return;\r
1165     }\r
1166 }\r
1167 \r
1168 void UciPopUp()\r
1169 {\r
1170     Arg args[16];\r
1171     Widget popup, layout, dialog, edit, form, b_ok, b_cancel, last = NULL, new, upperLeft;\r
1172     Window root, child;\r
1173     int x, y, i, j;\r
1174     int win_x, win_y;\r
1175     unsigned int mask;\r
1176     char def[80];\r
1177     \r
1178     i = 0;\r
1179     XtSetArg(args[i], XtNresizable, True); i++;\r
1180 //    XtSetArg(args[i], XtNwidth, 300); i++;\r
1181     UciShell = popup =\r
1182       XtCreatePopupShell("Engine Settings", transientShellWidgetClass,\r
1183                          shellWidget, args, i);\r
1184     \r
1185     layout =\r
1186       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
1187                             layoutArgs, XtNumber(layoutArgs));\r
1188   \r
1189     \r
1190     form =\r
1191       XtCreateManagedWidget("form", formWidgetClass, layout,\r
1192                             formArgs, XtNumber(formArgs));\r
1193   \r
1194     j = 0;\r
1195     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
1196     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
1197     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
1198 //    XtSetArg(args[j], XtNheight, 20); j++;\r
1199     for(i = 0; controlDesc[i].name != NULL; i++) {\r
1200         j = 3;\r
1201         XtSetArg(args[j], XtNfromVert, last); j++;\r
1202 //      XtSetArg(args[j], XtNwidth, 130); j++;\r
1203         XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;\r
1204         XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
1205         XtSetArg(args[j], XtNborderWidth, 0); j++;\r
1206         new = XtCreateManagedWidget(controlDesc[i].name, labelWidgetClass, form, args, j);\r
1207         if(i==0) upperLeft = new;\r
1208 \r
1209         j = 4;\r
1210         XtSetArg(args[j], XtNborderWidth, 1); j++;\r
1211         XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;\r
1212         XtSetArg(args[j], XtNuseStringInPlace, False);  j++;\r
1213         XtSetArg(args[j], XtNdisplayCaret, False);  j++;\r
1214         XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
1215         XtSetArg(args[j], XtNresizable, True);  j++;\r
1216         XtSetArg(args[j], XtNwidth, i&1 ? 245 : 50); j++;\r
1217         if(i&1) {\r
1218             XtSetArg(args[j], XtNstring, * (char**) controlDesc[i].ptr ? \r
1219                                          * (char**) controlDesc[i].ptr : ""); j++;\r
1220         } else {\r
1221             sprintf(def, "%d", * (int*) controlDesc[i].ptr);\r
1222             XtSetArg(args[j], XtNstring, def); j++;\r
1223         }\r
1224         XtSetArg(args[j], XtNfromHoriz, upperLeft); j++;\r
1225         controlDesc[i].handle = last =\r
1226             XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);\r
1227         XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup);\r
1228     }\r
1229 \r
1230     j=0;\r
1231     XtSetArg(args[j], XtNfromHoriz, controlDesc[0].handle);  j++;\r
1232     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;\r
1233     XtSetArg(args[j], XtNtop, XtChainTop);  j++;\r
1234     XtSetArg(args[j], XtNleft, XtChainRight);  j++;\r
1235     XtSetArg(args[j], XtNright, XtChainRight);  j++;\r
1236     XtSetArg(args[j], XtNstate, appData.ponderNextMove);  j++;\r
1237     w4 = XtCreateManagedWidget("Ponder", toggleWidgetClass, form, args, j);   \r
1238 \r
1239     j=0;\r
1240     XtSetArg(args[j], XtNfromVert, last);  j++;\r
1241     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;\r
1242     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;\r
1243     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;\r
1244     XtSetArg(args[j], XtNright, XtChainLeft);  j++;\r
1245     b_ok = XtCreateManagedWidget("OK", commandWidgetClass, form, args, j);   \r
1246     XtAddCallback(b_ok, XtNcallback, UciCallback, (XtPointer) 0);\r
1247 \r
1248     XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;\r
1249     b_cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);   \r
1250     XtAddCallback(b_cancel, XtNcallback, UciPopDown, (XtPointer) 0);\r
1251 \r
1252     j = 5;\r
1253     XtSetArg(args[j], XtNfromHoriz, upperLeft);  j++;\r
1254     XtSetArg(args[j], XtNstate, appData.usePolyglotBook);  j++;\r
1255     w1 = XtCreateManagedWidget(" use book ", toggleWidgetClass, form, args, j);   \r
1256 //    XtAddCallback(w1, XtNcallback, UciCallback, (XtPointer) 0);\r
1257 \r
1258     j = 5;\r
1259     XtSetArg(args[j], XtNfromHoriz, w1);  j++;\r
1260     XtSetArg(args[j], XtNstate, appData.firstHasOwnBookUCI);  j++;\r
1261     w2 = XtCreateManagedWidget("own book 1", toggleWidgetClass, form, args, j);   \r
1262 //    XtAddCallback(w2, XtNcallback, UciCallback, (XtPointer) 0);\r
1263 \r
1264     j = 5;\r
1265     XtSetArg(args[j], XtNfromHoriz, w2);  j++;\r
1266     XtSetArg(args[j], XtNstate, appData.secondHasOwnBookUCI);  j++;\r
1267     w3 = XtCreateManagedWidget("own book 2", toggleWidgetClass, form, args, j);   \r
1268 //    XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0);\r
1269 \r
1270     XtRealizeWidget(popup);\r
1271     CatchDeleteWindow(popup, "UciPopDown");\r
1272     \r
1273     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
1274                   &x, &y, &win_x, &win_y, &mask);\r
1275     \r
1276     XtSetArg(args[0], XtNx, x - 10);\r
1277     XtSetArg(args[1], XtNy, y - 30);\r
1278     XtSetValues(popup, args, 2);\r
1279     \r
1280     XtPopup(popup, XtGrabExclusive);\r
1281     UciUp = True;\r
1282 \r
1283     previous = NULL;\r
1284     SetFocus(controlDesc[2].handle, popup, (XEvent*) NULL, False);\r
1285 //    XtSetKeyboardFocus(popup, controlDesc[1].handle);\r
1286 }\r
1287 \r
1288 void UciMenuProc(w, event, prms, nprms)\r
1289      Widget w;\r
1290      XEvent *event;\r
1291      String *prms;\r
1292      Cardinal *nprms;\r
1293 {\r
1294    UciPopUp();\r
1295 }\r
1296 \r
1297 //--------------------------- General Popup for Cloning ----------------------------------\r
1298 #if 0\r
1299 int XXXUp;\r
1300 Widget XXXShell;\r
1301 \r
1302 void XXXPopDown()\r
1303 {\r
1304     if (!XXXUp) return;\r
1305     XtPopdown(XXXShell);\r
1306     XtDestroyWidget(XXXShell);\r
1307     XXXUp = False;\r
1308     ModeHighlight();\r
1309 }\r
1310 \r
1311 void XXXCallback(w, client_data, call_data)\r
1312      Widget w;\r
1313      XtPointer client_data, call_data;\r
1314 {\r
1315     String name;\r
1316     Widget w2;\r
1317     Arg args[16];\r
1318     char buf[80];\r
1319     \r
1320     XtSetArg(args[0], XtNlabel, &name);\r
1321     XtGetValues(w, args, 1);\r
1322     \r
1323     if (strcmp(name, "cancel") == 0) {\r
1324         XXXPopDown();\r
1325         return;\r
1326     }\r
1327     if (strcmp(name, "ok") == 0) {\r
1328         int nr; String name;\r
1329         name = XawDialogGetValueString(w2 = XtParent(w));\r
1330         if(sscanf(name ,"%d",&nr) != 1) {\r
1331             sprintf(buf, "%d", appData.defaultFrcPosition);\r
1332             XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value\r
1333             XtSetValues(w2, args, 1);\r
1334             return;\r
1335         }\r
1336         XXXPopDown();\r
1337         return;\r
1338     }\r
1339 }\r
1340 \r
1341 void XXXPopUp()\r
1342 {\r
1343     Arg args[16];\r
1344     Widget popup, layout, dialog, edit;\r
1345     Window root, child;\r
1346     int x, y, i;\r
1347     int win_x, win_y;\r
1348     unsigned int mask;\r
1349     char def[80];\r
1350     \r
1351     i = 0;\r
1352     XtSetArg(args[i], XtNresizable, True); i++;\r
1353     XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
1354     XXXShell = popup =\r
1355       XtCreatePopupShell("XXX Menu", transientShellWidgetClass,\r
1356                          shellWidget, args, i);\r
1357     \r
1358     layout =\r
1359       XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
1360                             layoutArgs, XtNumber(layoutArgs));\r
1361   \r
1362     sprintf(def, "%d\n", appData.defaultFrcPosition);\r
1363     i = 0;\r
1364     XtSetArg(args[i], XtNlabel, ""); i++;\r
1365     XtSetArg(args[i], XtNvalue, def); i++;\r
1366     XtSetArg(args[i], XtNborderWidth, 0); i++;\r
1367     dialog = XtCreateManagedWidget("XXX", dialogWidgetClass,\r
1368                                    layout, args, i);\r
1369     \r
1370     XawDialogAddButton(dialog, "ok", XXXCallback, (XtPointer) dialog);\r
1371     XawDialogAddButton(dialog, "cancel", XXXCallback, (XtPointer) dialog);\r
1372     \r
1373     XtRealizeWidget(popup);\r
1374     CatchDeleteWindow(popup, "XXXPopDown");\r
1375     \r
1376     XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
1377                   &x, &y, &win_x, &win_y, &mask);\r
1378     \r
1379     XtSetArg(args[0], XtNx, x - 10);\r
1380     XtSetArg(args[1], XtNy, y - 30);\r
1381     XtSetValues(popup, args, 2);\r
1382     \r
1383     XtPopup(popup, XtGrabExclusive);\r
1384     XXXUp = True;\r
1385     \r
1386     edit = XtNameToWidget(dialog, "*value");\r
1387 \r
1388     previous = NULL;\r
1389     SetFocus(engThreshold, popup, (XEvent*) NULL, False);\r
1390 }\r
1391 \r
1392 void XXXMenuProc(w, event, prms, nprms)\r
1393      Widget w;\r
1394      XEvent *event;\r
1395      String *prms;\r
1396      Cardinal *nprms;\r
1397 {\r
1398    XXXPopUp();\r
1399 }\r
1400 #endif\r
1401 \r