PageRenderTime 268ms CodeModel.GetById 69ms app.highlight 176ms RepoModel.GetById 1ms app.codeStats 1ms

/xboard-4.5.2a/xoptions.c

#
C | 1873 lines | 1653 code | 158 blank | 62 comment | 301 complexity | 7b4439034da70a23c3519959c048c411 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * xoptions.c -- Move list window, part of X front end for XBoard
   3 *
   4 * Copyright 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
   5 * ------------------------------------------------------------------------
   6 *
   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.
  11 *
  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.
  16 *
  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/.  *
  19 *
  20 *------------------------------------------------------------------------
  21 ** See the file ChangeLog for a revision history.  */
  22
  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.
  25
  26#include "config.h"
  27
  28#include <stdio.h>
  29#include <ctype.h>
  30#include <errno.h>
  31#include <sys/types.h>
  32
  33#if STDC_HEADERS
  34# include <stdlib.h>
  35# include <string.h>
  36#else /* not STDC_HEADERS */
  37extern char *getenv();
  38# if HAVE_STRING_H
  39#  include <string.h>
  40# else /* not HAVE_STRING_H */
  41#  include <strings.h>
  42# endif /* not HAVE_STRING_H */
  43#endif /* not STDC_HEADERS */
  44
  45#if HAVE_UNISTD_H
  46# include <unistd.h>
  47#endif
  48#include <stdint.h>
  49
  50#include <X11/Intrinsic.h>
  51#include <X11/StringDefs.h>
  52#include <X11/Shell.h>
  53#include <X11/Xatom.h>
  54#include <X11/Xaw/Dialog.h>
  55#include <X11/Xaw/Form.h>
  56#include <X11/Xaw/List.h>
  57#include <X11/Xaw/Label.h>
  58#include <X11/Xaw/SimpleMenu.h>
  59#include <X11/Xaw/SmeBSB.h>
  60#include <X11/Xaw/SmeLine.h>
  61#include <X11/Xaw/Box.h>
  62#include <X11/Xaw/Paned.h>
  63#include <X11/Xaw/MenuButton.h>
  64#include <X11/cursorfont.h>
  65#include <X11/Xaw/Text.h>
  66#include <X11/Xaw/AsciiText.h>
  67#include <X11/Xaw/Viewport.h>
  68#include <X11/Xaw/Toggle.h>
  69
  70#include "common.h"
  71#include "backend.h"
  72#include "xboard.h"
  73#include "gettext.h"
  74
  75#ifdef ENABLE_NLS
  76# define  _(s) gettext (s)
  77# define N_(s) gettext_noop (s)
  78#else
  79# define  _(s) (s)
  80# define N_(s)  s
  81#endif
  82
  83extern void SendToProgram P((char *message, ChessProgramState *cps));
  84FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
  85		char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return));
  86
  87extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
  88extern Display *xDisplay;
  89extern int squareSize;
  90extern Pixmap xMarkPixmap;
  91extern char *layoutName;
  92extern Window xBoardWindow;
  93extern Arg layoutArgs[2], formArgs[2];
  94Pixel timerForegroundPixel, timerBackgroundPixel;
  95extern int searchTime;
  96extern Atom wm_delete_window;
  97extern int lineGap;
  98
  99// [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines
 100
 101static Widget previous = NULL;
 102
 103void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b)
 104{
 105    Arg args[2];
 106    char *s;
 107
 108    if(previous) {
 109	XtSetArg(args[0], XtNdisplayCaret, False);
 110	XtSetValues(previous, args, 1);
 111    }
 112    XtSetArg(args[0], XtNstring, &s);
 113    XtGetValues(w, args, 1);
 114    XtSetArg(args[0], XtNdisplayCaret, True);
 115    XtSetArg(args[1], XtNinsertPosition, strlen(s));
 116    XtSetValues(w, args, 2);
 117    XtSetKeyboardFocus((Widget) data, w);
 118    previous = w;
 119}
 120
 121//--------------------------- New Shuffle Game --------------------------------------------
 122extern int shuffleOpenings;
 123extern int startedFromPositionFile;
 124int shuffleUp;
 125Widget shuffleShell;
 126
 127void ShufflePopDown()
 128{
 129    if (!shuffleUp) return;
 130    XtPopdown(shuffleShell);
 131    XtDestroyWidget(shuffleShell);
 132    shuffleUp = False;
 133    ModeHighlight();
 134}
 135
 136void ShuffleCallback(w, client_data, call_data)
 137     Widget w;
 138     XtPointer client_data, call_data;
 139{
 140    String name;
 141    Widget w2;
 142    Arg args[16];
 143    char buf[MSG_SIZ];
 144
 145    XtSetArg(args[0], XtNlabel, &name);
 146    XtGetValues(w, args, 1);
 147
 148    if (strcmp(name, _("cancel")) == 0) {
 149        ShufflePopDown();
 150        return;
 151    }
 152    if (strcmp(name, _("off")) == 0) {
 153        ShufflePopDown();
 154	shuffleOpenings = False; // [HGM] should be moved to New Variant menu, once we have it!
 155	ResetGameEvent();
 156        return;
 157    }
 158    if (strcmp(name, _("random")) == 0) {
 159      snprintf(buf, MSG_SIZ,  "%d", rand());
 160	XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value
 161	XtSetValues(XtParent(w), args, 1);
 162        return;
 163    }
 164    if (strcmp(name, _("ok")) == 0) {
 165	int nr; String name;
 166        name = XawDialogGetValueString(w2 = XtParent(w));
 167	if(sscanf(name ,"%d",&nr) != 1) {
 168	  snprintf(buf, MSG_SIZ,  "%d", appData.defaultFrcPosition);
 169	    XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value
 170	    XtSetValues(w2, args, 1);
 171	    return;
 172	}
 173	appData.defaultFrcPosition = nr;
 174	shuffleOpenings = True;
 175        ShufflePopDown();
 176	ResetGameEvent();
 177        return;
 178    }
 179}
 180
 181void ShufflePopUp()
 182{
 183    Arg args[16];
 184    Widget popup, layout, dialog, edit;
 185    Window root, child;
 186    int x, y, i;
 187    int win_x, win_y;
 188    unsigned int mask;
 189    char def[MSG_SIZ];
 190
 191    i = 0;
 192    XtSetArg(args[i], XtNresizable, True); i++;
 193    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 194    shuffleShell = popup =
 195      XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass,
 196			 shellWidget, args, i);
 197
 198    layout =
 199      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 200			    layoutArgs, XtNumber(layoutArgs));
 201
 202    snprintf(def, MSG_SIZ,  "%d\n", appData.defaultFrcPosition);
 203    i = 0;
 204    XtSetArg(args[i], XtNlabel, _("Start-position number:")); i++;
 205    XtSetArg(args[i], XtNvalue, def); i++;
 206    XtSetArg(args[i], XtNborderWidth, 0); i++;
 207    dialog = XtCreateManagedWidget(_("Shuffle"), dialogWidgetClass,
 208				   layout, args, i);
 209
 210//    XtSetArg(args[0], XtNeditType, XawtextEdit);  // [HGM] can't get edit to work decently
 211//    XtSetArg(args[1], XtNuseStringInPlace, False);
 212//    XtSetValues(dialog, args, 2);
 213
 214    XawDialogAddButton(dialog, _("ok"), ShuffleCallback, (XtPointer) dialog);
 215    XawDialogAddButton(dialog, _("cancel"), ShuffleCallback, (XtPointer) dialog);
 216    XawDialogAddButton(dialog, _("random"), ShuffleCallback, (XtPointer) dialog);
 217    XawDialogAddButton(dialog, _("off"), ShuffleCallback, (XtPointer) dialog);
 218
 219    XtRealizeWidget(popup);
 220    CatchDeleteWindow(popup, "ShufflePopDown");
 221
 222    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 223		  &x, &y, &win_x, &win_y, &mask);
 224
 225    XtSetArg(args[0], XtNx, x - 10);
 226    XtSetArg(args[1], XtNy, y - 30);
 227    XtSetValues(popup, args, 2);
 228
 229    XtPopup(popup, XtGrabExclusive);
 230    shuffleUp = True;
 231
 232    edit = XtNameToWidget(dialog, "*value");
 233
 234    XtSetKeyboardFocus(popup, edit);
 235}
 236
 237void ShuffleMenuProc(w, event, prms, nprms)
 238     Widget w;
 239     XEvent *event;
 240     String *prms;
 241     Cardinal *nprms;
 242{
 243//    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
 244//	Reset(FALSE, TRUE);
 245//    }
 246    ShufflePopUp();
 247}
 248
 249//--------------------------- Time-Control Menu Popup ----------------------------------
 250int TimeControlUp;
 251Widget TimeControlShell;
 252int tcInc;
 253Widget tcMess1, tcMess2, tcData, tcTime, tcOdds1, tcOdds2;
 254int tcIncrement, tcMoves;
 255
 256void TimeControlPopDown()
 257{
 258    if (!TimeControlUp) return;
 259    previous = NULL;
 260    XtPopdown(TimeControlShell);
 261    XtDestroyWidget(TimeControlShell);
 262    TimeControlUp = False;
 263    ModeHighlight();
 264}
 265
 266void TimeControlCallback(w, client_data, call_data)
 267     Widget w;
 268     XtPointer client_data, call_data;
 269{
 270    String name, txt;
 271    Arg args[16];
 272    char buf[MSG_SIZ];
 273    int j;
 274
 275    XtSetArg(args[0], XtNlabel, &name);
 276    XtGetValues(w, args, 1);
 277
 278    if (strcmp(name, _("classical")) == 0) {
 279	if(tcInc == 0) return;
 280	j=0;
 281	XtSetArg(args[j], XtNlabel, _("minutes for each")); j++;
 282	XtSetValues(tcMess1, args, j);
 283	j=0;
 284	XtSetArg(args[j], XtNlabel, _("moves")); j++;
 285	XtSetValues(tcMess2, args, j);
 286	if(tcInc == 1) {
 287	    j=0;
 288	    XtSetArg(args[j], XtNstring, &name); j++;
 289	    XtGetValues(tcData, args, j);
 290	    tcIncrement = 0; sscanf(name, "%d", &tcIncrement);
 291	}
 292	snprintf(buf, MSG_SIZ,  "%d", tcMoves);
 293	j=0;
 294	XtSetArg(args[j], XtNstring, buf); j++;
 295	XtSetValues(tcData, args, j);
 296	tcInc = 0;
 297        return;
 298    }
 299    if (strcmp(name, _("incremental")) == 0) {
 300	if(tcInc == 1) return;
 301	j=0;
 302	XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++;
 303	XtSetValues(tcMess1, args, j);
 304	j=0;
 305	XtSetArg(args[j], XtNlabel, _("sec/move")); j++;
 306	XtSetValues(tcMess2, args, j);
 307	if(tcInc == 0) {
 308	    j=0;
 309	    XtSetArg(args[j], XtNstring, &name); j++;
 310	    XtGetValues(tcData, args, j);
 311	    tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves);
 312	}
 313	snprintf(buf, MSG_SIZ,  "%d", tcIncrement);
 314	j=0;
 315	XtSetArg(args[j], XtNstring, buf); j++;
 316	XtSetValues(tcData, args, j);
 317	tcInc = 1;
 318        return;
 319    }
 320    if (strcmp(name, _("fixed time")) == 0) {
 321	if(tcInc == 2) return;
 322	j=0;
 323	XtSetArg(args[j], XtNlabel, _("sec/move (max)")); j++;
 324	XtSetValues(tcMess1, args, j);
 325	j=0;
 326	XtSetArg(args[j], XtNlabel, _("")); j++;
 327	XtSetValues(tcMess2, args, j);
 328	j=0;
 329	XtSetArg(args[j], XtNstring, ""); j++;
 330	XtSetValues(tcData, args, j);
 331	tcInc = 2;
 332        return;
 333    }
 334    if (strcmp(name, _(" OK ")) == 0) {
 335	int inc, mps, ok;
 336	XtSetArg(args[0], XtNstring, &txt);
 337	XtGetValues(tcData, args, 1);
 338	switch(tcInc) {
 339	  case 1:
 340	    ok = sscanf(txt, "%d", &inc); mps = 0;
 341	    if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero
 342	    ok &= (inc >= 0);
 343	    break;
 344	  case 0:
 345	    ok = sscanf(txt, "%d", &mps); inc = -1;
 346	    ok &= (mps > 0);
 347	    break;
 348	  case 2:
 349	    ok = 1; inc = -1; mps = 40;
 350	}
 351	if(ok != 1) {
 352	    XtSetArg(args[0], XtNstring, ""); // erase any offending input
 353	    XtSetValues(tcData, args, 1);
 354	    return;
 355	}
 356	XtSetArg(args[0], XtNstring, &txt);
 357	XtGetValues(tcTime, args, 1);
 358	if(tcInc == 2) {
 359	    if(sscanf(txt, "%d", &inc) != 1) {
 360		XtSetArg(args[0], XtNstring, ""); // erase any offending input
 361		XtSetValues(tcTime, args, 1);
 362		DisplayError(_("Bad Time-Control String"), 0);
 363		return;
 364	    }
 365	    searchTime = inc;
 366	} else {
 367	    if(!ParseTimeControl(txt, inc, mps)) {
 368		XtSetArg(args[0], XtNstring, ""); // erase any offending input
 369		XtSetValues(tcTime, args, 1);
 370		DisplayError(_("Bad Time-Control String"), 0);
 371		return;
 372	    }
 373	    searchTime = 0;
 374	    appData.movesPerSession = mps;
 375	    appData.timeIncrement = inc;
 376	    appData.timeControl = strdup(txt);
 377	}
 378	XtSetArg(args[0], XtNstring, &txt);
 379	XtGetValues(tcOdds1, args, 1);
 380	appData.firstTimeOdds = first.timeOdds
 381		= (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;
 382	XtGetValues(tcOdds2, args, 1);
 383	appData.secondTimeOdds = second.timeOdds
 384		= (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1;
 385
 386	Reset(True, True);
 387        TimeControlPopDown();
 388        return;
 389    }
 390}
 391
 392void TimeControlPopUp()
 393{
 394    Arg args[16];
 395    Widget popup, layout, form,  b_ok, b_cancel, b_clas, b_inc, mess;
 396    Window root, child;
 397    int x, y, i, j;
 398    int win_x, win_y;
 399    unsigned int mask;
 400    char def[MSG_SIZ];
 401
 402    tcInc = searchTime > 0 ? 2 : (appData.timeIncrement >= 0);
 403    tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;
 404    if(!tcInc) tcIncrement = 0;
 405    snprintf(def, MSG_SIZ,  "%d", tcInc ? tcIncrement : tcMoves);
 406
 407    i = 0;
 408    XtSetArg(args[i], XtNresizable, True); i++;
 409//    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 410    TimeControlShell = popup =
 411      XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass,
 412			 shellWidget, args, i);
 413
 414    layout =
 415      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 416			    layoutArgs, XtNumber(layoutArgs));
 417
 418    form =
 419      XtCreateManagedWidget(layoutName, formWidgetClass, layout,
 420			    formArgs, XtNumber(formArgs));
 421
 422    j = 0;
 423//    XtSetArg(args[j], XtNwidth,     (XtArgVal) 300); j++;
 424//    XtSetArg(args[j], XtNheight,    (XtArgVal) 85); j++;
 425    XtSetValues(popup, args, j);
 426
 427    j= 0;
 428    XtSetArg(args[j], XtNborderWidth, 1); j++;
 429    XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
 430    XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
 431    XtSetArg(args[j], XtNstring, appData.timeControl);  j++;
 432    XtSetArg(args[j], XtNdisplayCaret, False);  j++;
 433    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 434    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 435    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 436    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 437    XtSetArg(args[j], XtNresizable, True);  j++;
 438    XtSetArg(args[j], XtNwidth,  85);  j++;
 439    XtSetArg(args[j], XtNinsertPosition, 9999);  j++;
 440    tcTime = XtCreateManagedWidget("TC", asciiTextWidgetClass, form, args, j);
 441    XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup);
 442
 443    j= 0;
 444    XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("sec/move (max)   ") : _("   minutes, plus   ") : _("minutes for each")); j++;
 445    XtSetArg(args[j], XtNborderWidth, 0); j++;
 446    XtSetArg(args[j], XtNfromHoriz, tcTime); j++;
 447    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 448    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 449    XtSetArg(args[j], XtNleft, XtChainRight);  j++;
 450    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 451  //  XtSetArg(args[j], XtNwidth,  100);  j++;
 452  //  XtSetArg(args[j], XtNheight, 20);  j++;
 453    tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j);
 454
 455    j= 0;
 456    XtSetArg(args[j], XtNborderWidth, 1); j++;
 457    XtSetArg(args[j], XtNfromHoriz, tcMess1); j++;
 458    XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
 459    XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
 460    XtSetArg(args[j], XtNstring, def);  j++;
 461    XtSetArg(args[j], XtNdisplayCaret, False);  j++;
 462    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 463    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 464    XtSetArg(args[j], XtNleft, XtChainRight);  j++;
 465    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 466    XtSetArg(args[j], XtNresizable, True);  j++;
 467    XtSetArg(args[j], XtNwidth,  40);  j++;
 468//    XtSetArg(args[j], XtNheight, 20);  j++;
 469    tcData = XtCreateManagedWidget("MPS", asciiTextWidgetClass, form, args, j);
 470    XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup);
 471
 472    j= 0;
 473    XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("             ") : _("sec/move") : _("moves     ")); j++;
 474    XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
 475    XtSetArg(args[j], XtNborderWidth, 0); j++;
 476    XtSetArg(args[j], XtNfromHoriz, tcData); j++;
 477    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 478    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 479    XtSetArg(args[j], XtNleft, XtChainRight);  j++;
 480    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 481//    XtSetArg(args[j], XtNwidth,  80);  j++;
 482//    XtSetArg(args[j], XtNheight, 20);  j++;
 483    tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass,
 484				   form, args, j);
 485
 486    j= 0;
 487    XtSetArg(args[j], XtNborderWidth, 1); j++;
 488    XtSetArg(args[j], XtNfromVert, tcTime); j++;
 489    XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
 490    XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
 491    XtSetArg(args[j], XtNstring, "1");  j++;
 492    XtSetArg(args[j], XtNdisplayCaret, False);  j++;
 493    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 494    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 495    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 496    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
 497    XtSetArg(args[j], XtNresizable, True);  j++;
 498    XtSetArg(args[j], XtNwidth,  40);  j++;
 499//    XtSetArg(args[j], XtNheight, 20);  j++;
 500    tcOdds1 = XtCreateManagedWidget("Odds1", asciiTextWidgetClass, form, args, j);
 501    XtAddEventHandler(tcOdds1, ButtonPressMask, False, SetFocus, (XtPointer) popup);
 502
 503    j= 0;
 504    XtSetArg(args[j], XtNborderWidth, 1); j++;
 505    XtSetArg(args[j], XtNfromVert, tcTime); j++;
 506    XtSetArg(args[j], XtNfromHoriz, tcOdds1); j++;
 507    XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
 508    XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
 509    XtSetArg(args[j], XtNstring, "1");  j++;
 510    XtSetArg(args[j], XtNdisplayCaret, False);  j++;
 511    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 512    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 513    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 514    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
 515    XtSetArg(args[j], XtNresizable, True);  j++;
 516    XtSetArg(args[j], XtNwidth,  40);  j++;
 517//    XtSetArg(args[j], XtNheight, 20);  j++;
 518    tcOdds2 = XtCreateManagedWidget("Odds2", asciiTextWidgetClass, form, args, j);
 519    XtAddEventHandler(tcOdds2, ButtonPressMask, False, SetFocus, (XtPointer) popup);
 520
 521    j= 0;
 522    XtSetArg(args[j], XtNlabel, _("Engine #1 and #2 Time-Odds Factors")); j++;
 523    XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
 524    XtSetArg(args[j], XtNborderWidth, 0); j++;
 525    XtSetArg(args[j], XtNfromVert, tcTime); j++;
 526    XtSetArg(args[j], XtNfromHoriz, tcOdds2); j++;
 527    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
 528    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
 529    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 530    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 531//    XtSetArg(args[j], XtNwidth,  200);  j++;
 532//    XtSetArg(args[j], XtNheight, 20);  j++;
 533    mess = XtCreateManagedWidget("Oddstext", labelWidgetClass,
 534				   form, args, j);
 535    j=0;
 536    XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
 537    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
 538    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
 539    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 540    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
 541    XtSetArg(args[j], XtNstate, tcInc==0); j++;
 542    b_clas= XtCreateManagedWidget(_("classical"), toggleWidgetClass,
 543				   form, args, j);
 544    XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0);
 545
 546    j=0;
 547    XtSetArg(args[j], XtNradioGroup, b_clas); j++;
 548    XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
 549    XtSetArg(args[j], XtNfromHoriz, b_clas);  j++;
 550    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
 551    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
 552    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 553    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
 554    XtSetArg(args[j], XtNstate, tcInc==1); j++;
 555    b_inc = XtCreateManagedWidget(_("incremental"), toggleWidgetClass,
 556				   form, args, j);
 557    XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
 558
 559    j=0;
 560    XtSetArg(args[j], XtNradioGroup, b_inc); j++;
 561    XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
 562    XtSetArg(args[j], XtNfromHoriz, b_inc);  j++;
 563    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
 564    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
 565    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
 566    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
 567    XtSetArg(args[j], XtNstate, tcInc==2); j++;
 568    b_inc = XtCreateManagedWidget(_("fixed time"), toggleWidgetClass,
 569				   form, args, j);
 570    XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
 571
 572    j=0;
 573    XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
 574    XtSetArg(args[j], XtNfromHoriz, tcData);  j++;
 575    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
 576    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
 577    XtSetArg(args[j], XtNleft, XtChainRight);  j++;
 578    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 579    b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass,
 580				   form, args, j);
 581    XtAddCallback(b_ok, XtNcallback, TimeControlCallback, (XtPointer) 0);
 582
 583    j=0;
 584    XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
 585    XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;
 586    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
 587    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
 588    XtSetArg(args[j], XtNleft, XtChainRight);  j++;
 589    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 590    b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass,
 591				   form, args, j);
 592    XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0);
 593
 594    XtRealizeWidget(popup);
 595    CatchDeleteWindow(popup, "TimeControlPopDown");
 596
 597    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 598		  &x, &y, &win_x, &win_y, &mask);
 599
 600    XtSetArg(args[0], XtNx, x - 10);
 601    XtSetArg(args[1], XtNy, y - 30);
 602    XtSetValues(popup, args, 2);
 603
 604    XtPopup(popup, XtGrabExclusive);
 605    TimeControlUp = True;
 606
 607    previous = NULL;
 608    SetFocus(tcTime, popup, (XEvent*) NULL, False);
 609//    XtSetKeyboardFocus(popup, tcTime);
 610}
 611
 612void TimeControlProc(w, event, prms, nprms)
 613     Widget w;
 614     XEvent *event;
 615     String *prms;
 616     Cardinal *nprms;
 617{
 618   TimeControlPopUp();
 619}
 620
 621//--------------------------- Engine-specific options menu ----------------------------------
 622
 623int values[MAX_OPTIONS];
 624ChessProgramState *currentCps;
 625static Option *currentOption;
 626extern Widget shells[];
 627static Boolean browserUp;
 628
 629void CheckCallback(Widget ww, XtPointer data, XEvent *event, Boolean *b)
 630{
 631    Widget w = currentOption[(int)(intptr_t)data].handle;
 632    Boolean s;
 633    Arg args[16];
 634
 635    XtSetArg(args[0], XtNstate, &s);
 636    XtGetValues(w, args, 1);
 637    XtSetArg(args[0], XtNstate, !s);
 638    XtSetValues(w, args, 1);
 639}
 640
 641void SpinCallback(w, client_data, call_data)
 642     Widget w;
 643     XtPointer client_data, call_data;
 644{
 645    String name, val;
 646    Arg args[16];
 647    char buf[MSG_SIZ], *p;
 648    int j;
 649    int data = (intptr_t) client_data;
 650
 651    XtSetArg(args[0], XtNlabel, &name);
 652    XtGetValues(w, args, 1);
 653
 654    j = 0;
 655    XtSetArg(args[0], XtNstring, &val);
 656    XtGetValues(currentOption[data].handle, args, 1);
 657    sscanf(val, "%d", &j);
 658    if (strcmp(name, "browse") == 0) {
 659	char *q, *r;
 660	XtSetArg(args[0], XtNstring, &q);
 661	XtGetValues(currentOption[data].handle, args, 1);
 662	for(r = ""; *q; q++) if(*q == '.') r = q; else if(*q == '/') r = ""; // last dot after last slash
 663	browserUp = True;
 664	if(XsraSelFile(shells[0], currentOption[data].name, NULL, NULL, "", "", r,
 665			 	  currentOption[data].type == PathName ? "p" : "f", NULL, &p)) {
 666		int len = strlen(p);
 667		if(len && p[len-1] == '/') p[len-1] = NULLCHAR;
 668		XtSetArg(args[0], XtNstring, p);
 669		XtSetValues(currentOption[data].handle, args, 1);
 670	}
 671	browserUp = False;
 672	SetFocus(currentOption[data].handle, shells[0], (XEvent*) NULL, False);
 673	return;
 674    } else
 675    if (strcmp(name, "+") == 0) {
 676	if(++j > currentOption[data].max) return;
 677    } else
 678    if (strcmp(name, "-") == 0) {
 679	if(--j < currentOption[data].min) return;
 680    } else return;
 681    snprintf(buf, MSG_SIZ,  "%d", j);
 682    XtSetArg(args[0], XtNstring, buf);
 683    XtSetValues(currentOption[data].handle, args, 1);
 684    SetFocus(currentOption[data].handle, shells[0], NULL, False);
 685}
 686
 687void ComboSelect(w, addr, index) // callback for all combo items
 688     Widget w;
 689     caddr_t addr;
 690     caddr_t index;
 691{
 692    Arg args[16];
 693    int i = ((intptr_t)addr)>>8;
 694    int j = 255 & (intptr_t) addr;
 695
 696    values[i] = j; // store in temporary, for transfer at OK
 697    XtSetArg(args[0], XtNlabel, ((char**)currentOption[i].textValue)[j]);
 698    XtSetValues(currentOption[i].handle, args, 1);
 699}
 700
 701void CreateComboPopup(parent, name, n, mb)
 702     Widget parent;
 703     String name;
 704     int n;
 705     char *mb[];
 706{
 707    int i=0, j;
 708    Widget menu, entry;
 709    Arg args[16];
 710
 711    menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
 712			      parent, NULL, 0);
 713    j = 0;
 714    XtSetArg(args[j], XtNwidth, 100);  j++;
 715//    XtSetArg(args[j], XtNright, XtChainRight);  j++;
 716    while (mb[i] != NULL) {
 717	    entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass,
 718					  menu, args, j);
 719	    XtAddCallback(entry, XtNcallback,
 720			  (XtCallbackProc) ComboSelect,
 721			  (caddr_t)(intptr_t) (256*n+i));
 722	i++;
 723    }
 724}
 725
 726
 727//----------------------------Generic dialog --------------------------------------------
 728
 729// cloned from Engine Settings dialog (and later merged with it)
 730
 731typedef void ButtonCallback(int n);
 732
 733char *trialSound;
 734static int oldCores, oldPonder;
 735int MakeColors P((void));
 736void CreateGCs P((int redo));
 737void CreateAnyPieces P((void));
 738void GenericReadout P((int selected));
 739Widget shells[10];
 740Widget marked[10];
 741Boolean shellUp[10];
 742WindowPlacement *wp[10];
 743Option *dialogOptions[10];
 744
 745void MarkMenu(char *item, int dlgNr)
 746{
 747    Arg args[2];
 748    XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 749    XtSetValues(marked[dlgNr] = XtNameToWidget(menuBarWidget, item), args, 1);
 750}
 751
 752int PopDown(int n)
 753{
 754    int j;
 755    Arg args[10];
 756    Dimension windowH, windowW; Position windowX, windowY;
 757    if (!shellUp[n]) return 0;
 758    if(n && wp[n]) { // remember position
 759	j = 0;
 760	XtSetArg(args[j], XtNx, &windowX); j++;
 761	XtSetArg(args[j], XtNy, &windowY); j++;
 762	XtSetArg(args[j], XtNheight, &windowH); j++;
 763	XtSetArg(args[j], XtNwidth, &windowW); j++;
 764	XtGetValues(shells[n], args, j);
 765	wp[n]->x = windowX;
 766	wp[n]->x = windowY;
 767	wp[n]->width  = windowW;
 768	wp[n]->height = windowH;
 769    }
 770    previous = NULL;
 771    XtPopdown(shells[n]);
 772    if(n == 0) XtDestroyWidget(shells[n]);
 773    shellUp[n] = False;
 774    if(marked[n]) {
 775	XtSetArg(args[0], XtNleftBitmap, None);
 776	XtSetValues(marked[n], args, 1);
 777    }
 778    if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now
 779    return 1;
 780}
 781
 782void GenericPopDown(w, event, prms, nprms)
 783     Widget w;
 784     XEvent *event;
 785     String *prms;
 786     Cardinal *nprms;
 787{
 788    int n;
 789    if(browserUp) return; // prevent closing dialog when it has an open file-browse daughter
 790    PopDown(prms[0][0] - '0');
 791}
 792
 793Option matchOptions[] = {
 794{ 0,  2, 1000000000, NULL, (void*) &appData.defaultMatchGames, "", NULL, Spin, N_("Default Number of Games in Match:") },
 795{ 0,  0, 1000000000, NULL, (void*) &appData.matchPause, "", NULL, Spin, N_("Pause between Match Games (msec):") },
 796{ 0,  0,          0, NULL, (void*) &appData.loadGameFile, "", NULL, FileName, N_("Game File with Opening Lines:") },
 797{ 0, -2, 1000000000, NULL, (void*) &appData.loadGameIndex, "", NULL, Spin, N_("Game Number (-1 or -2 = Auto-Increment):") },
 798{ 0,  0,          0, NULL, (void*) &appData.loadPositionFile, "", NULL, FileName, N_("File with Start Positions:") },
 799{ 0, -2, 1000000000, NULL, (void*) &appData.loadPositionIndex, "", NULL, Spin, N_("Position Number (-1 or -2 = Auto-Increment):") },
 800{ 0,  0, 1000000000, NULL, (void*) &appData.rewindIndex, "", NULL, Spin, N_("Rewind Index after this many Games (0 = never):") },
 801{ 0, 0, 0, NULL, NULL, "", NULL, EndMark , "" }
 802};
 803
 804void GeneralOptionsOK(int n)
 805{
 806	int newPonder = appData.ponderNextMove;
 807	appData.ponderNextMove = oldPonder;
 808	PonderNextMoveEvent(newPonder);
 809}
 810
 811Option generalOptions[] = {
 812{ 0,  0, 0, NULL, (void*) &appData.alwaysPromoteToQueen, "", NULL, CheckBox, N_("Always Queen") },
 813{ 0,  0, 0, NULL, (void*) &appData.animateDragging, "", NULL, CheckBox, N_("Animate Dragging") },
 814{ 0,  0, 0, NULL, (void*) &appData.animate, "", NULL, CheckBox, N_("Animate Moving") },
 815{ 0,  0, 0, NULL, (void*) &appData.autoCallFlag, "", NULL, CheckBox, N_("Auto Flag") },
 816{ 0,  0, 0, NULL, (void*) &appData.autoFlipView, "", NULL, CheckBox, N_("Auto Flip View") },
 817{ 0,  0, 0, NULL, (void*) &appData.blindfold, "", NULL, CheckBox, N_("Blindfold") },
 818{ 0,  0, 0, NULL, (void*) &appData.dropMenu, "", NULL, CheckBox, N_("Drop Menu") },
 819{ 0,  0, 0, NULL, (void*) &appData.highlightDragging, "", NULL, CheckBox, N_("Highlight Dragging (Show Move Targets)") },
 820{ 0,  0, 0, NULL, (void*) &appData.highlightLastMove, "", NULL, CheckBox, N_("Highlight Last Move") },
 821{ 0,  0, 0, NULL, (void*) &appData.highlightMoveWithArrow, "", NULL, CheckBox, N_("Highlight with Arrow") },
 822{ 0,  0, 0, NULL, (void*) &appData.ringBellAfterMoves, "", NULL, CheckBox, N_("Move Sound") },
 823{ 0,  0, 0, NULL, (void*) &appData.oneClick, "", NULL, CheckBox, N_("One-Click Moving") },
 824{ 0,  0, 0, NULL, (void*) &appData.periodicUpdates, "", NULL, CheckBox, N_("Periodic Updates (in Analysis Mode)") },
 825{ 0,  0, 0, NULL, (void*) &appData.ponderNextMove, "", NULL, CheckBox, N_("Ponder Next Move") },
 826{ 0,  0, 0, NULL, (void*) &appData.popupExitMessage, "", NULL, CheckBox, N_("Popup Exit Messages") },
 827{ 0,  0, 0, NULL, (void*) &appData.popupMoveErrors, "", NULL, CheckBox, N_("Popup Move Errors") },
 828{ 0,  0, 0, NULL, (void*) &appData.showCoords, "", NULL, CheckBox, N_("Show Coordinates") },
 829{ 0,  0, 0, NULL, (void*) &appData.markers, "", NULL, CheckBox, N_("Show Target Squares") },
 830{ 0,  0, 0, NULL, (void*) &appData.hideThinkingFromHuman, "", NULL, CheckBox, N_("Hide Thinking from Human") },
 831{ 0,  0, 0, NULL, (void*) &appData.testLegality, "", NULL, CheckBox, N_("Test Legality") },
 832{ 0, 0, 10, NULL, (void*) &appData.flashCount, "", NULL, Spin, N_("Flash Moves (0 = no flashing):") },
 833{ 0, 1, 10, NULL, (void*) &appData.flashRate, "", NULL, Spin, N_("Flash Rate (high = fast):") },
 834{ 0, 5, 100,NULL, (void*) &appData.animSpeed, "", NULL, Spin, N_("Animation Speed (high = slow):") },
 835{ 0,  0, 0, NULL, (void*) &GeneralOptionsOK, "", NULL, EndMark , "" }
 836};
 837
 838void Pick(int n)
 839{
 840	VariantClass v = currentOption[n].value;
 841	if(!appData.noChessProgram) {
 842	    char *name = VariantName(v), buf[MSG_SIZ];
 843	    if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {
 844		/* [HGM] in protocol 2 we check if variant is suported by engine */
 845	      snprintf(buf, MSG_SIZ,  _("Variant %s not supported by %s"), name, first.tidy);
 846		DisplayError(buf, 0);
 847		return; /* ignore OK if first engine does not support it */
 848	    } else
 849	    if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {
 850	      snprintf(buf, MSG_SIZ,  _("Warning: second engine (%s) does not support this!"), second.tidy);
 851		DisplayError(buf, 0);   /* use of second engine is optional; only warn user */
 852	    }
 853	}
 854
 855	GenericReadout(-1); // make sure ranks and file settings are read
 856
 857	gameInfo.variant = v;
 858	appData.variant = VariantName(v);
 859
 860	shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */
 861	startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */
 862	appData.pieceToCharTable = NULL;
 863	appData.pieceNickNames = "";
 864	appData.colorNickNames = "";
 865	Reset(True, True);
 866        PopDown(0);
 867        return;
 868}
 869
 870Option variantDescriptors[] = {
 871{ VariantNormal, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("normal")},
 872{ VariantFairy, 1, 135, NULL, (void*) &Pick, "#BFBFBF", NULL, Button, N_("fairy")},
 873{ VariantFischeRandom, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("FRC")},
 874{ VariantSChess, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("Seirawan")},
 875{ VariantWildCastle, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("wild castle")},
 876{ VariantSuper, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("Superchess")},
 877{ VariantNoCastle, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("no castle")},
 878{ VariantCrazyhouse, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("crazyhouse")},
 879{ VariantKnightmate, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("knightmate")},
 880{ VariantBughouse, 1, 135, NULL, (void*) &Pick, "#FFBFBF", NULL, Button, N_("bughouse")},
 881{ VariantBerolina, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("berolina")},
 882{ VariantShogi, 1, 135, NULL, (void*) &Pick, "#BFFFFF", NULL, Button, N_("shogi (9x9)")},
 883{ VariantCylinder, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("cylinder")},
 884{ VariantXiangqi, 1, 135, NULL, (void*) &Pick, "#BFFFFF", NULL, Button, N_("xiangqi (9x10)")},
 885{ VariantShatranj, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("shatranj")},
 886{ VariantCourier, 1, 135, NULL, (void*) &Pick, "#BFFFBF", NULL, Button, N_("courier (12x8)")},
 887{ VariantMakruk, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("makruk")},
 888{ VariantGreat, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Great Shatranj (10x8)")},
 889{ VariantAtomic, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("atomic")},
 890{ VariantCapablanca, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Capablanca (10x8)")},
 891{ VariantTwoKings, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("two kings")},
 892{ VariantGothic, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("Gothic (10x8)")},
 893{ Variant3Check, 0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("3-checks")},
 894{ VariantJanus, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("janus (10x8)")},
 895{ VariantSuicide, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("suicide")},
 896{ VariantCapaRandom, 1, 135, NULL, (void*) &Pick, "#BFBFFF", NULL, Button, N_("CRC (10x8)")},
 897{ VariantGiveaway, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("give-away")},
 898{ VariantSpartan, 1, 135, NULL, (void*) &Pick, "#FF0000", NULL, Button, N_("Spartan")},
 899{ VariantLosers, 0, 135, NULL, (void*) &Pick, "#FFFFBF", NULL, Button, N_("losers")},
 900{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, N_("Board size ( -1 = default for selected variant):")},
 901{ 0, -1, BOARD_RANKS-1, NULL, (void*) &appData.NrRanks, "", NULL, Spin, N_("Number of Board Ranks:") },
 902{ 0, -1, BOARD_FILES, NULL, (void*) &appData.NrFiles, "", NULL, Spin, N_("Number of Board Files:") },
 903{ 0, -1, BOARD_RANKS-1, NULL, (void*) &appData.holdingsSize, "", NULL, Spin, N_("Holdings Size:") },
 904{ 0, 0, 0, NULL, NULL, NULL, NULL, Label,
 905				N_("WARNING: variants with un-orthodox\n"
 906				  "pieces only have built-in bitmaps\n"
 907				  "for -boardSize middling, bulky and\n"
 908				  "petite, and substitute king or amazon\n"
 909				  "for missing bitmaps. (See manual.)")},
 910{ 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" }
 911};
 912
 913void CommonOptionsOK(int n)
 914{
 915	int newPonder = appData.ponderNextMove;
 916	// make sure changes are sent to first engine by re-initializing it
 917	// if it was already started pre-emptively at end of previous game
 918	if(gameMode == BeginningOfGame) Reset(True, True); else {
 919	    // Some changed setting need immediate sending always.
 920	    if(oldCores != appData.smpCores)
 921		NewSettingEvent(False, &(first.maxCores), "cores", appData.smpCores);
 922	    appData.ponderNextMove = oldPonder;
 923	    PonderNextMoveEvent(newPonder);
 924	}
 925}
 926
 927Option commonEngineOptions[] = {
 928{ 0,     0, 0, NULL, (void*) &appData.ponderNextMove, "", NULL, CheckBox, N_("Ponder Next Move") },
 929{ 0,  0, 1000, NULL, (void*) &appData.smpCores, "", NULL, Spin, N_("Maximum Number of CPUs per Engine:") },
 930{ 0,     0, 0, NULL, (void*) &appData.polyglotDir, "", NULL, PathName, N_("Polygot Directory:") },
 931{ 0, 0, 16000, NULL, (void*) &appData.defaultHashSize, "", NULL, Spin, N_("Hash-Table Size (MB):") },
 932{ 0,     0, 0, NULL, (void*) &appData.defaultPathEGTB, "", NULL, PathName, N_("Nalimov EGTB Path:") },
 933{ 0,  0, 1000, NULL, (void*) &appData.defaultCacheSizeEGTB, "", NULL, Spin, N_("EGTB Cache Size (MB):") },
 934{ 0,     0, 0, NULL, (void*) &appData.usePolyglotBook, "", NULL, CheckBox, N_("Use GUI Book") },
 935{ 0,     0, 0, NULL, (void*) &appData.polyglotBook, "", NULL, FileName, N_("Opening-Book Filename:") },
 936{ 0,   0, 100, NULL, (void*) &appData.bookDepth, "", NULL, Spin, N_("Book Depth (moves):") },
 937{ 0,   0, 100, NULL, (void*) &appData.bookStrength, "", NULL, Spin, N_("Book Variety (0) vs. Strength (100):") },
 938{ 0,     0, 0, NULL, (void*) &appData.firstHasOwnBookUCI, "", NULL, CheckBox, N_("Engine #1 Has Own Book") },
 939{ 0,     0, 0, NULL, (void*) &appData.secondHasOwnBookUCI, "", NULL, CheckBox, N_("Engine #2 Has Own Book          ") },
 940{ 0,     1, 0, NULL, (void*) &CommonOptionsOK, "", NULL, EndMark , "" }
 941};
 942
 943Option adjudicationOptions[] = {
 944{ 0, 0,    0, NULL, (void*) &appData.checkMates, "", NULL, CheckBox, N_("Detect all Mates") },
 945{ 0, 0,    0, NULL, (void*) &appData.testClaims, "", NULL, CheckBox, N_("Verify Engine Result Claims") },
 946{ 0, 0,    0, NULL, (void*) &appData.materialDraws, "", NULL, CheckBox, N_("Draw if Insufficient Mating Material") },
 947{ 0, 0,    0, NULL, (void*) &appData.trivialDraws, "", NULL, CheckBox, N_("Adjudicate Trivial Draws (3-Move Delay)") },
 948{ 0, 0,  100, NULL, (void*) &appData.ruleMoves, "", NULL, Spin, N_("N-Move Rule:") },
 949{ 0, 0,    6, NULL, (void*) &appData.drawRepeats, "", NULL, Spin, N_("N-fold Repeats:") },
 950{ 0, 0, 1000, NULL, (void*) &appData.adjudicateDrawMoves, "", NULL, Spin, N_("Draw after N Moves Total:") },
 951{ 0,-5000, 0, NULL, (void*) &appData.adjudicateLossThreshold, "", NULL, Spin, N_("Win / Loss Threshold:") },
 952{ 0, 0,    0, NULL, (void*) &first.scoreIsAbsolute, "", NULL, CheckBox, N_("Negate Score of Engine #1") },
 953{ 0, 0,    0, NULL, (void*) &second.scoreIsAbsolute, "", NULL, CheckBox, N_("Negate Score of Engine #2") },
 954{ 0, 1,    0, NULL, NULL, "", NULL, EndMark , "" }
 955};
 956
 957void IcsOptionsOK(int n)
 958{
 959    ParseIcsTextColors();
 960}
 961
 962Option icsOptions[] = {
 963{ 0, 0, 0, NULL, (void*) &appData.autoKibitz, "",  NULL, CheckBox, N_("Auto-Kibitz") },
 964{ 0, 0, 0, NULL, (void*) &appData.autoComment, "", NULL, CheckBox, N_("Auto-Comment") },
 965{ 0, 0, 0, NULL, (void*) &appData.autoObserve, "", NULL, CheckBox, N_("Auto-Observe") },
 966{ 0, 0, 0, NULL, (void*) &appData.autoRaiseBoard, "", NULL, CheckBox, N_("Auto-Raise Board") },
 967{ 0, 0, 0, NULL, (void*) &appData.bgObserve, "",   NULL, CheckBox, N_("Background Observe while Playing") },
 968{ 0, 0, 0, NULL, (void*) &appData.dualBoard, "",   NULL, CheckBox, N_("Dual Board for Background-Observed Game") },
 969{ 0, 0, 0, NULL, (void*) &appData.getMoveList, "", NULL, CheckBox, N_("Get Move List") },
 970{ 0, 0, 0, NULL, (void*) &appData.quietPlay, "",   NULL, CheckBox, N_("Quiet Play") },
 971{ 0, 0, 0, NULL, (void*) &appData.seekGraph, "",   NULL, CheckBox, N_("Seek Graph") },
 972{ 0, 0, 0, NULL, (void*) &appData.autoRefresh, "", NULL, CheckBox, N_("Auto-Refresh Seek Graph") },
 973{ 0, 0, 0, NULL, (void*) &appData.premove, "",     NULL, CheckBox, N_("Premove") },
 974{ 0, 0, 0, NULL, (void*) &appData.premoveWhite, "", NULL, CheckBox, N_("Premove for White") },
 975{ 0, 0, 0, NULL, (void*) &appData.premoveWhiteText, "", NULL, TextBox, N_("First White Move:") },
 976{ 0, 0, 0, NULL, (void*) &appData.premoveBlack, "", NULL, CheckBox, N_("Premove for Black") },
 977{ 0, 0, 0, NULL, (void*) &appData.premoveBlackText, "", NULL, TextBox, N_("First Black Move:") },
 978{ 0, 0, 0, NULL, NULL, NULL, NULL, Break, "" },
 979{ 0, 0, 0, NULL, (void*) &appData.icsAlarm, "", NULL, CheckBox, N_("Alarm") },
 980{ 0, 0, 100000000, NULL, (void*) &appData.icsAlarmTime, "", NULL, Spin, N_("Alarm Time (msec):") },
 981//{ 0, 0, 0, NULL, (void*) &appData.chatBoxes, "", NULL, TextBox, N_("Startup Chat Boxes:") },
 982{ 0, 0, 0, NULL, (void*) &appData.colorize, "", NULL, CheckBox, N_("Colorize Messages") },
 983{ 0, 0, 0, NULL, (void*) &appData.colorShout, "", NULL, TextBox, N_("Shout Text Colors:") },
 984{ 0, 0, 0, NULL, (void*) &appData.colorSShout, "", NULL, TextBox, N_("S-Shout Text Colors:") },
 985{ 0, 0, 0, NULL, (void*) &appData.colorChannel1, "", NULL, TextBox, N_("Channel #1 Text Colors:") },
 986{ 0, 0, 0, NULL, (void*) &appData.colorChannel, "", NULL, TextBox, N_("Other Channel Text Colors:") },
 987{ 0, 0, 0, NULL, (void*) &appData.colorKibitz, "", NULL, TextBox, N_("Kibitz Text Colors:") },
 988{ 0, 0, 0, NULL, (void*) &appData.colorTell, "", NULL, TextBox, N_("Tell Text Colors:") },
 989{ 0, 0, 0, NULL, (void*) &appData.colorChallenge, "", NULL, TextBox, N_("Challenge Text Colors:") },
 990{ 0, 0, 0, NULL, (void*) &appData.colorRequest, "", NULL, TextBox, N_("Request Text Colors:") },
 991{ 0, 0, 0, NULL, (void*) &appData.colorSeek, "", NULL, TextBox, N_("Seek Text Colors:") },
 992{ 0, 0, 0, NULL, (void*) &IcsOptionsOK, "", NULL, EndMark , "" }
 993};
 994
 995Option loadOptions[] = {
 996{ 0, 0, 0, NULL, (void*) &appData.autoDisplayTags, "", NULL, CheckBox, N_("Auto-Display Tags") },
 997{ 0, 0, 0, NULL, (void*) &appData.autoDisplayComment, "", NULL, CheckBox, N_("Auto-Display Comment") },
 998{ 0, 0, 0, NULL, NULL, NULL, NULL, Label, N_("Auto-Play speed of loaded games\n(0 = instant, -1 = off):") },
 999{ 0, -1, 10000000, NULL, (void*) &appData.timeDelay, "", NULL, Fractional, N_("Seconds per Move:") },
1000{ 0,  0, 0, NULL, NULL, "", NULL, EndMark , "" }
1001};
1002
1003Option saveOptions[] = {
1004{ 0, 0, 0, NULL, (void*) &appData.autoSaveGames, "", NULL, CheckBox, N_("Auto-Save Games") },
1005{ 0, 0, 0, NULL, (void*) &appData.saveGameFile, "", NULL, FileName,  N_("Save Games on File:") },
1006{ 0, 0, 0, NULL, (void*) &appData.savePositionFile, "", NULL, FileName,  N_("Save Final Positions on File:") },
1007{ 0, 0, 0, NULL, (void*) &appData.pgnEventHeader, "", NULL, TextBox,  N_("PGN Event Header:") },
1008{ 0, 0, 0, NULL, (void*) &appData.oldSaveStyle, "", NULL, CheckBox, N_("Old Save Style (as opposed to PGN)") },
1009{ 0, 0, 0, NULL, (void*) &appData.saveExtendedInfoInPGN, "", NULL, CheckBox, N_("Save Score/Depth Info in PGN") },
1010{ 0, 0, 0, NULL, (void*) &appData.saveOutOfBookInfo, "", NULL, CheckBox, N_("Save Out-of-Book Info in PGN           ") },
1011{ 0, 1, 0, NULL, NULL, "", NULL, EndMark , "" }
1012};
1013
1014char *soundNames[] = {
1015	N_("No Sound"),
1016	N_("Default Beep"),
1017	N_("Above WAV File"),
1018	N_("Car Horn"),
1019	N_("Cymbal"),
1020	N_("Ding"),
1021	N_("Gong"),
1022	N_("Laser"),
1023	N_("Penalty"),
1024	N_("Phone"),
1025	N_("Pop"),
1026	N_("Slap"),
1027	N_("Wood Thunk"),
1028	NULL,
1029	N_("User File")
1030};
1031
1032char *soundFiles[] = { // sound files corresponding to above names
1033	"",
1034	"$",
1035	"*", // kludge alert: as first thing in the dialog readout this is replaced with the user-given .WAV filename
1036	"honkhonk.wav",
1037	"cymbal.wav",
1038	"ding1.wav",
1039	"gong.wav",
1040	"laser.wav",
1041	"penalty.wav",
1042	"phone.wav",
1043	"pop2.wav",
1044	"slap.wav",
1045	"woodthunk.wav",
1046	NULL,
1047	NULL
1048};
1049
1050void Test(int n)
1051{
1052    GenericReadout(2);
1053    if(soundFiles[values[3]]) PlaySound(soundFiles[values[3]]);
1054}
1055
1056Option soundOptions[] = {
1057{ 0, 0, 0, NULL, (void*) &appData.soundProgram, "", NULL, TextBox, N_("Sound Program:") },
1058{ 0, 0, 0, NULL, (void*) &appData.soundDirectory, "", NULL, PathName, N_("Sounds Directory:") },
1059{ 0, 0, 0, NULL, (void*) (soundFiles+2) /* kludge! */, "", NULL, FileName, N_("User WAV File:") },
1060{ 0, 0, 0, NULL, (void*) &trialSound, (char*) soundNames, soundFiles, ComboBox, N_("Try-Out Sound:") },
1061{ 0, 1, 0, NULL, (void*) &Test, NULL, NULL, Button, N_("Play") },
1062{ 0, 0, 0, NULL, (void*) &appData.soundMove, (char*) soundNames, soundFiles, ComboBox, N_("Move:") },
1063{ 0, 0, 0, NULL, (void*) &appData.soundIcsWin, (char*) soundNames, soundFiles, ComboBox, N_("Win:") },
1064{ 0, 0, 0, NULL, (void*) &appData.soundIcsLoss, (char*) soundNames, soundFiles, ComboBox, N_("Lose:") },
1065{ 0, 0, 0, NULL, (void*) &appData.soundIcsDraw, (char*) soundNames, soundFiles, ComboBox, N_("Draw:") },
1066{ 0, 0, 0, NULL, (void*) &appData.soundIcsUnfinished, (char*) soundNames, soundFiles, ComboBox, N_("Unfinished:") },
1067{ 0, 0, 0, NULL, (void*) &appData.soundIcsAlarm, (char*) soundNames, soundFiles, ComboBox, N_("Alarm:") },
1068{ 0, 0, 0, NULL, (void*) &appData.soundShout, (char*) soundNames, soundFiles, ComboBox, N_("Shout:") },
1069{ 0, 0, 0, NULL, (void*) &appData.soundSShout, (char*) soundNames, soundFiles, ComboBox, N_("S-Shout:") },
1070{ 0, 0, 0, NULL, (void*) &appData.soundChannel, (char*) soundNames, soundFiles, ComboBox, N_("Channel:") },
1071{ 0, 0, 0, NULL, (void*) &appData.soundChannel1, (char*) soundNames, soundFiles, ComboBox, N_("Channel 1:") },
1072{ 0, 0, 0, NULL, (void*) &appData.soundTell, (char*) soundNames, soundFiles, ComboBox, N_("Tell:") },
1073{ 0, 0, 0, NULL, (void*) &appData.soundKibitz, (char*) soundNames, soundFiles, ComboBox, N_("Kibitz:") },
1074{ 0, 0, 0, NULL, (void*) &appData.soundChallenge, (char*) soundNames, soundFiles, ComboBox, N_("Challenge:") },
1075{ 0, 0, 0, NULL, (void*) &appData.soundRequest, (char*) soundNames, soundFiles, ComboBox, N_("Request:") },
1076{ 0, 0, 0, NULL, (void*) &appData.soundSeek, (char*) soundNames, soundFiles, ComboBox, N_("Seek:") },
1077{ 0, 1, 0, NULL, NULL, "", NULL, EndMark , "" }
1078};
1079
1080void SetColor(char *colorName, Widget box)
1081{
1082	Arg args[5];
1083	Pixel buttonColor;
1084	XrmValue vFrom, vTo;
1085	if (!appData.monoMode) {
1086	    vFrom.addr = (caddr_t) colorName;
1087	    vFrom.size = strlen(colorName);
1088	    XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
1089	    if (vTo.addr == NULL) {
1090	  	buttonColor = (Pixel) -1;
1091	    } else {
1092		buttonColor = *(Pixel *) vTo.addr;
1093	    }
1094	}
1095	XtSetArg(args[0], XtNbackground, buttonColor);;
1096	XtSetValues(box, args, 1);
1097}
1098
1099void SetColorText(int n, char *buf)
1100{
1101    Arg args[5];
1102    XtSetArg(args[0], XtNstring, buf);
1103    XtSetValues(currentOption[n-1].handle, args, 1);
1104    SetFocus(currentOption[n-1].handle, shells[0], NULL, False);
1105    SetColor(buf, currentOption[n].handle);
1106}
1107
1108void DefColor(int n)
1109{
1110    SetColorText(n, (char*) currentOption[n].choice);
1111}
1112
1113void RefreshColor(int source, int n)
1114{
1115    int col, j, r, g, b, step = 10;
1116    char *s, buf[MSG_SIZ]; // color string
1117    Arg args[5];
1118    XtSetArg(args[0], XtNstring, &s);
1119    XtGetValues(currentOption[source].handle, args, 1);
1120    if(sscanf(s, "#%x", &col) != 1) return;   // malformed
1121    b = col & 0xFF; g = col & 0xFF00; r = col & 0xFF0000;
1122    switch(n) {
1123	case 1: r += 0x10000*step;break;
1124	case 2: g += 0x100*step;  break;
1125	case 3: b += step;        break;
1126	case 4: r -= 0x10000*step; g -= 0x100*step; b -= step; break;
1127    }
1128    if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0;
1129    if(r > 0xFF0000) r = 0xFF0000; if(g > 0xFF00) g = 0xFF00; if(b > 0xFF) b = 0xFF;
1130    col = r | g | b;
1131    snprintf(buf, MSG_SIZ, "#%06x", col);
1132    for(j=1; j<7; j++) if(buf[j] >= 'a') buf[j] -= 32; // capitalize
1133    SetColorText(source+1, buf);
1134}
1135
1136void ColorChanged(Widget w, XtPointer data, XEvent *event, Boolean *b)
1137{
1138    char buf[10];
1139    if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && *buf == '\r' )
1140	RefreshColor((int)(intptr_t) data, 0);
1141}
1142
1143void AdjustColor(int i)
1144{
1145    int n = currentOption[i].value;
1146    RefreshColor(i-n-1, n);
1147}
1148
1149void BoardOptionsOK(int n)
1150{
1151    extern int defaultLineGap, useImages, useImageSqs;
1152    if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap;
1153    useImages = useImageSqs = 0;
1154    MakeColors(); CreateGCs(True);
1155    CreateAnyPieces();
1156    InitDrawingSizes(-1, 0);
1157    DrawPosition(True, NULL);
1158}
1159
1160Option boardOptions[] = {
1161{ 0,   0, 70, NULL, (void*) &appData.whitePieceColor, "", NULL, TextBox, N_("White Piece Color:") },
1162{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FFFFCC", Button, "      " },
1163{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1164{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1165{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1166{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1167{ 0,   0, 70, NULL, (void*) &appData.blackPieceColor, "", NULL, TextBox, N_("Black Piece Color:") },
1168{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#202020", Button, "      " },
1169{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1170{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1171{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1172{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1173{ 0,   0, 70, NULL, (void*) &appData.lightSquareColor, "", NULL, TextBox, N_("Light Square Color:") },
1174{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#C8C365", Button, "      " },
1175{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1176{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1177{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1178{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1179{ 0,   0, 70, NULL, (void*) &appData.darkSquareColor, "", NULL, TextBox, N_("Dark Square Color:") },
1180{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#77A26D", Button, "      " },
1181{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1182{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1183{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1184{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1185{ 0,   0, 70, NULL, (void*) &appData.highlightSquareColor, "", NULL, TextBox, N_("Highlight Color:") },
1186{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FFFF00", Button, "      " },
1187{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1188{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1189{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1190{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1191{ 0,   0, 70, NULL, (void*) &appData.premoveHighlightColor, "", NULL, TextBox, N_("Premove Highlight Color:") },
1192{ 1000, 1, 0, NULL, (void*) &DefColor, NULL, (char**) "#FF0000", Button, "      " },
1193{    1, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "R" },
1194{    2, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "G" },
1195{    3, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "B" },
1196{    4, 1, 0, NULL, (void*) &AdjustColor, NULL, NULL, Button, "D" },
1197{ 0, 0, 0, NULL, (void*) &appData.upsideDown, "", NULL, CheckBox, N_("Flip Pieces Shogi Style        (Colored buttons restore default)") },
1198//{ 0, 0, 0, NULL, (void*) &appData.allWhite, "", NULL, CheckBox, N_("Use Outline Pieces for Black") },
1199{ 0, 0, 0, NULL, (void*) &appData.monoMode, "", NULL, CheckBox, N_("Mono Mode") },
1200{ 0,-1, 5, NULL, (void*) &appData.overrideLineGap, "", NULL, Spin, N_("Line Gap ( -1 = default for board size):") },
1201{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, "", NULL, FileName, N_("Light-Squares Texture File:") },
1202{ 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, "", NULL, FileName, N_("Dark-Squares Texture File:") },
1203{ 0, 0, 0, NULL, (void*) &appData.bitmapDirectory, "", NULL, PathName, N_("Directory with Bitmap Pieces:") },
1204{ 0, 0, 0, NULL, (void*) &appData.pixmapDirectory, "", NULL, PathName, N_("Directory with Pixmap Pieces:") },
1205{ 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" }
1206};
1207
1208void GenericReadout(int selected)
1209{
1210    int i, j;
1211    String name, val;
1212    Arg args[16];
1213    char buf[MSG_SIZ], **dest;
1214    float x;
1215	for(i=0; ; i++) { // send all options that had to be OK-ed to engine
1216	    if(selected >= 0) { if(i < selected) continue; else if(i > selected) break; }
1217	    switch(currentOption[i].type) {
1218		case TextBox:
1219		case FileName:
1220		case PathName:
1221		    XtSetArg(args[0], XtNstring, &val);
1222		    XtGetValues(currentOpt

Large files files are truncated, but you can click here to view the full file