Fix crash on empty Engine Settings dialog
[xboard.git] / xoptions.c
index 14ab5d7..8841dca 100644 (file)
@@ -80,22 +80,6 @@ extern char *getenv();
 # define N_(s)  s
 #endif
 
-extern void SendToProgram P((char *message, ChessProgramState *cps));
-FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
-               char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return));
-
-extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
-extern Display *xDisplay;
-extern int squareSize;
-extern Pixmap xMarkPixmap;
-extern char *layoutName;
-extern Window xBoardWindow;
-extern Arg layoutArgs[2], formArgs[2];
-Pixel timerForegroundPixel, timerBackgroundPixel;
-extern int searchTime;
-extern Atom wm_delete_window;
-extern int lineGap;
-
 // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines
 
 static Widget previous = NULL;
@@ -119,8 +103,6 @@ void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b)
 }
 
 //--------------------------- New Shuffle Game --------------------------------------------
-extern int shuffleOpenings;
-extern int startedFromPositionFile;
 int shuffleUp;
 Widget shuffleShell;
 
@@ -332,7 +314,7 @@ void TimeControlCallback(w, client_data, call_data)
         return;
     }
     if (strcmp(name, _(" OK ")) == 0) {
-       int inc, mps, ok;
+       int inc, mps, ok=0;
        XtSetArg(args[0], XtNstring, &txt);
        XtGetValues(tcData, args, 1);
        switch(tcInc) {
@@ -620,11 +602,13 @@ void TimeControlProc(w, event, prms, nprms)
 
 //--------------------------- Engine-specific options menu ----------------------------------
 
+typedef void ButtonCallback(int n);
+
 int values[MAX_OPTIONS];
 ChessProgramState *currentCps;
 static Option *currentOption;
-extern Widget shells[];
 static Boolean browserUp;
+ButtonCallback *comboCallback;
 
 void CheckCallback(Widget ww, XtPointer data, XEvent *event, Boolean *b)
 {
@@ -694,8 +678,10 @@ void ComboSelect(w, addr, index) // callback for all combo items
     int j = 255 & (intptr_t) addr;
 
     values[i] = j; // store in temporary, for transfer at OK
-    XtSetArg(args[0], XtNlabel, ((char**)currentOption[i].textValue)[j]);
+    XtSetArg(args[0], XtNlabel, _(((char**)currentOption[i].textValue)[j]));
     XtSetValues(currentOption[i].handle, args, 1);
+
+    if(currentOption[i].min & 1 && !currentCps && comboCallback) (comboCallback)(i);
 }
 
 void CreateComboPopup(parent, name, n, mb)
@@ -712,6 +698,7 @@ void CreateComboPopup(parent, name, n, mb)
                              parent, NULL, 0);
     j = 0;
     XtSetArg(args[j], XtNwidth, 100);  j++;
+    XtSetArg(args[j], XtNlabel, _(mb[i]));  j++;
 //    XtSetArg(args[j], XtNright, XtChainRight);  j++;
     while (mb[i] != NULL) {
            entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass,
@@ -728,8 +715,6 @@ void CreateComboPopup(parent, name, n, mb)
 
 // cloned from Engine Settings dialog (and later merged with it)
 
-typedef void ButtonCallback(int n);
-
 extern WindowPlacement wpComment, wpTags;
 char *trialSound;
 static int oldCores, oldPonder;
@@ -786,7 +771,6 @@ void GenericPopDown(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    int n;
     if(browserUp) return; // prevent closing dialog when it has an open file-browse daughter
     PopDown(prms[0][0] - '0');
 }
@@ -1092,7 +1076,7 @@ void SetColor(char *colorName, Widget box)
            } else {
                buttonColor = *(Pixel *) vTo.addr;
            }
-       }
+       } else buttonColor = (Pixel) 0;
        XtSetArg(args[0], XtNbackground, buttonColor);;
        XtSetValues(box, args, 1);
 }
@@ -1149,7 +1133,6 @@ void AdjustColor(int i)
 
 void BoardOptionsOK(int n)
 {
-    extern int defaultLineGap, useImages, useImageSqs;
     if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap;
     useImages = useImageSqs = 0;
     MakeColors(); CreateGCs(True);
@@ -1209,7 +1192,7 @@ Option boardOptions[] = {
 void GenericReadout(int selected)
 {
     int i, j;
-    String name, val;
+    String val;
     Arg args[16];
     char buf[MSG_SIZ], **dest;
     float x;
@@ -1292,10 +1275,9 @@ void GenericCallback(w, client_data, call_data)
      Widget w;
      XtPointer client_data, call_data;
 {
-    String name, val;
+    String name;
     Arg args[16];
     char buf[MSG_SIZ];
-    int i, j;
     int data = (intptr_t) client_data;
 
     currentOption = dialogOptions[data>>16]; data &= 0xFFFF;
@@ -1325,7 +1307,7 @@ int
 GenericPopUp(Option *option, char *title, int dlgNr)
 {
     Arg args[16];
-    Widget popup, layout, dialog, edit=NULL, form,  last, b_ok, b_cancel, leftMargin = NULL, textField = NULL;
+    Widget popup, layout, dialog=NULL, edit=NULL, form,  last, b_ok, b_cancel, leftMargin = NULL, textField = NULL;
     Window root, child;
     int x, y, i, j, height=999, width=1, h, c, w;
     int win_x, win_y, maxWidth, maxTextWidth;
@@ -1350,7 +1332,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
        int n = currentCps->nrOptions;
        if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
        height = n / width + 1;
-       if(currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton) currentOption[n].min = 1; // OK on same line
+       if(n && (currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton)) currentOption[n].min = 1; // OK on same line
        currentOption[n].type = EndMark; currentOption[n].target = NULL; // delimit list by callback-less end mark
     }
      i = 0;
@@ -1397,6 +1379,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
            XtSetArg(args[j], XtNright, XtChainLeft); j++;
            XtSetArg(args[j], XtNborderWidth, 0);  j++;
            XtSetArg(args[j], XtNjustify, XtJustifyLeft);  j++;
+           XtSetArg(args[j], XtNlabel, _(option[i].name));  j++;
            texts[h] =
            dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
            } else texts[h] = dialog = NULL;
@@ -1439,7 +1422,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
            XtSetArg(args[j], XtNleft, XtChainRight); j++;
            XtSetArg(args[j], XtNright, XtChainRight); j++;
            if(option[i].type == FileName || option[i].type == PathName) {
-               w = 50; msg = "browse";
+               w = 50; msg = _("browse");
            } else {
                XtSetArg(args[j], XtNheight, 10);  j++;
                w = 20; msg = "+";
@@ -1481,6 +1464,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
            XtSetArg(args[j], XtNleft, XtChainLeft); j++;
            XtSetArg(args[j], XtNborderWidth, 0);  j++;
            XtSetArg(args[j], XtNjustify, XtJustifyLeft);  j++;
+           XtSetArg(args[j], XtNlabel, _(msg));  j++;
            last = XtCreateManagedWidget(msg, labelWidgetClass, form, args, j);
            if(option[i].type == CheckBox)
                XtAddEventHandler(last, ButtonPressMask, False, CheckCallback, (XtPointer)(intptr_t) i);
@@ -1489,6 +1473,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
          case Button:
            j=0;
            XtSetArg(args[j], XtNfromVert, option[i].min & 1 ? lastrow : last);  j++;
+           XtSetArg(args[j], XtNlabel, _(option[i].name));  j++;
            if(option[i].min & 1) { XtSetArg(args[j], XtNfromHoriz, last);  j++; }
            else  { XtSetArg(args[j], XtNfromHoriz, NULL);  j++; lastrow = forelast; }
            if(option[i].max) XtSetArg(args[j], XtNwidth, option[i].max);  j++;
@@ -1515,6 +1500,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
            XtSetArg(args[j], XtNright, XtChainLeft); j++;
            XtSetArg(args[j], XtNborderWidth, 0);  j++;
            XtSetArg(args[j], XtNjustify, XtJustifyLeft);  j++;
+           XtSetArg(args[j], XtNlabel, _(option[i].name));  j++;
            texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
 
            if(currentCps) option[i].choice = (char**) option[i].textValue; else {
@@ -1529,7 +1515,7 @@ GenericPopUp(Option *option, char *title, int dlgNr)
            XtSetArg(args[j], XtNwidth, option[i].max && !currentCps ? option[i].max : 100);  j++;
            XtSetArg(args[j], XtNleft, XtChainLeft); j++;
            XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name));  j++;
-           XtSetArg(args[j], XtNlabel, ((char**)option[i].textValue)[option[i].value]);  j++;
+           XtSetArg(args[j], XtNlabel, _(((char**)option[i].textValue)[option[i].value]));  j++;
            option[i].handle = (void*)
                (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j));
            CreateComboPopup(last, option[i].name, i, (char **) option[i].textValue);
@@ -1736,10 +1722,9 @@ void MatchOptionsProc(w, event, prms, nprms)
 }
 
 Option textOptions[100];
-extern char *icsTextMenuString;
 void PutText P((char *text, int pos));
 
-SendString(char *p)
+void SendString(char *p)
 {
     char buf[MSG_SIZ], *q;
     if(q = strstr(p, "$input")) {
@@ -1902,7 +1887,6 @@ void NewTagsPopup(char *text, char *msg)
     GenericPopUp(tagsOptions, _("Tags"), 2);
 }
 
-extern char ICSInputTranslations[];
 char *icsText;
 
 Option boxOptions[] = {
@@ -1912,7 +1896,6 @@ Option boxOptions[] = {
 
 void PutText(char *text, int pos)
 {
-    Widget edit;
     Arg args[16];
     char buf[MSG_SIZ], *p;
 
@@ -2083,7 +2066,8 @@ void Load(ChessProgramState *cps, int i)
     if(addToList) {
        int len;
        q = firstChessProgramNames;
-       snprintf(buf, MSG_SIZ, "\"%s\" -fd \"%s\"%s%s%s%s%s\n", p, appData.directory[i], 
+       if(nickName[0]) snprintf(buf, MSG_SIZ, "\"%s\" -fcp ", nickName); else buf[0] = NULLCHAR;
+       snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), "\"%s\" -fd \"%s\"%s%s%s%s%s\n", p, appData.directory[i], 
                        v1 ? " -firstProtocolVersion 1" : "",
                        hasBook ? "" : " -fNoOwnBookUCI",
                        isUCI ? " -fUCI" : "",
@@ -2106,6 +2090,7 @@ void InstallOK(int n)
 Option installOptions[] = {
 {   0,  0,    0, NULL, (void*) &engineLine, (char*) engineMnemonic, engineList, ComboBox, N_("Select engine from list:") },
 {   0,  0,    0, NULL, NULL, NULL, NULL, Label, N_("or specify one below:") },
+{   0,  0,    0, NULL, (void*) &nickName, NULL, NULL, TextBox, N_("Nickname (optional):") },
 {   0,  0,    0, NULL, (void*) &engineDir, NULL, NULL, PathName, N_("Engine Directory:") },
 {   0,  0,    0, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine Command:") },
 {   0,  0,    0, NULL, NULL, NULL, NULL, Label, N_("(Directory will be derived from engine path when empty)") },
@@ -2125,7 +2110,7 @@ void LoadEngineProc(w, event, prms, nprms)
      Cardinal *nprms;
 {
    isUCI = addToList = storeVariant = v1 = False; hasBook = True; // defaults
-   engineDir = ""; 
+   engineDir = nickName = ""; 
    if(engineChoice) free(engineChoice); engineChoice = strdup(engineNr[0]);
    if(engineLine)   free(engineLine);   engineLine = strdup("");
    NamesToList(firstChessProgramNames);