Widget SettingsShell;
int values[MAX_OPTIONS];
ChessProgramState *currentCps;
+static Option *currentOption;
void SettingsPopDown()
{
j = 0;
XtSetArg(args[0], XtNstring, &val);
- XtGetValues(currentCps->option[data].handle, args, 1);
+ XtGetValues(currentOption[data].handle, args, 1);
sscanf(val, "%d", &j);
if (strcmp(name, "browse") == 0) {
- if(XsraSelFile(SettingsShell, currentCps->option[data].name, NULL, NULL, "", "",
- currentCps->option[data].type == PathName ? "p" : "f", NULL, &p)) {
+ if(XsraSelFile(SettingsShell, currentOption[data].name, NULL, NULL, "", "",
+ currentOption[data].type == PathName ? "p" : "f", NULL, &p)) {
int len = strlen(p);
if(len && p[len-1] == '/') p[len-1] = NULLCHAR;
XtSetArg(args[0], XtNstring, p);
- XtSetValues(currentCps->option[data].handle, args, 1);
+ XtSetValues(currentOption[data].handle, args, 1);
}
- SetFocus(currentCps->option[data].handle, SettingsShell, (XEvent*) NULL, False);
+ SetFocus(currentOption[data].handle, SettingsShell, (XEvent*) NULL, False);
return;
} else
if (strcmp(name, "+") == 0) {
- if(++j > currentCps->option[data].max) return;
+ if(++j > currentOption[data].max) return;
} else
if (strcmp(name, "-") == 0) {
- if(--j < currentCps->option[data].min) return;
+ if(--j < currentOption[data].min) return;
} else return;
snprintf(buf, MSG_SIZ, "%d", j);
XtSetArg(args[0], XtNstring, buf);
- XtSetValues(currentCps->option[data].handle, args, 1);
+ XtSetValues(currentOption[data].handle, args, 1);
}
void SettingsCallback(w, client_data, call_data)
}
if (strcmp(name, _("OK")) == 0 || data) { // save buttons imply OK
for(i=0; i<currentCps->nrOptions; i++) { // send all options that had to be OK-ed to engine
- switch(currentCps->option[i].type) {
+ switch(currentOption[i].type) {
case TextBox:
XtSetArg(args[0], XtNstring, &val);
- XtGetValues(currentCps->option[i].handle, args, 1);
- if(strcmp(currentCps->option[i].textValue, val)) {
- safeStrCpy(currentCps->option[i].textValue, val, MSG_SIZ - (currentCps->option[i].textValue - currentCps->option[i].name) );
- snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name, val);
+ XtGetValues(currentOption[i].handle, args, 1);
+ if(strcmp(currentOption[i].textValue, val)) {
+ safeStrCpy(currentOption[i].textValue, val, MSG_SIZ - (currentOption[i].textValue - currentOption[i].name) );
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name, val);
SendToProgram(buf, currentCps);
}
break;
case Spin:
XtSetArg(args[0], XtNstring, &val);
- XtGetValues(currentCps->option[i].handle, args, 1);
+ XtGetValues(currentOption[i].handle, args, 1);
sscanf(val, "%d", &j);
- if(j > currentCps->option[i].max) j = currentCps->option[i].max;
- if(j < currentCps->option[i].min) j = currentCps->option[i].min;
- if(currentCps->option[i].value != j) {
- currentCps->option[i].value = j;
- snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j);
+ if(j > currentOption[i].max) j = currentOption[i].max;
+ if(j < currentOption[i].min) j = currentOption[i].min;
+ if(currentOption[i].value != j) {
+ currentOption[i].value = j;
+ snprintf(buf, MSG_SIZ, "option %s=%d\n", currentOption[i].name, j);
SendToProgram(buf, currentCps);
}
break;
case CheckBox:
j = 0;
XtSetArg(args[0], XtNstate, &j);
- XtGetValues(currentCps->option[i].handle, args, 1);
- if(currentCps->option[i].value != j) {
- currentCps->option[i].value = j;
- snprintf(buf, MSG_SIZ, "option %s=%d\n", currentCps->option[i].name, j);
+ XtGetValues(currentOption[i].handle, args, 1);
+ if(currentOption[i].value != j) {
+ currentOption[i].value = j;
+ snprintf(buf, MSG_SIZ, "option %s=%d\n", currentOption[i].name, j);
SendToProgram(buf, currentCps);
}
break;
case ComboBox:
- if(currentCps->option[i].value != values[i]) {
- currentCps->option[i].value = values[i];
- snprintf(buf, MSG_SIZ, "option %s=%s\n", currentCps->option[i].name,
- ((char**)currentCps->option[i].textValue)[values[i]]);
+ if(currentOption[i].value != values[i]) {
+ currentOption[i].value = values[i];
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name,
+ ((char**)currentOption[i].textValue)[values[i]]);
SendToProgram(buf, currentCps);
}
break;
int j = 255 & (intptr_t) addr;
values[i] = j; // store in temporary, for transfer at OK
- XtSetArg(args[0], XtNlabel, ((char**)currentCps->option[i].textValue)[j]);
- XtSetValues(currentCps->option[i].handle, args, 1);
+ XtSetArg(args[0], XtNlabel, ((char**)currentOption[i].textValue)[j]);
+ XtSetValues(currentOption[i].handle, args, 1);
}
void CreateComboPopup(parent, name, n, mb)
// to do: start up second engine if needed
if(!cps->initDone || !cps->nrOptions) return; // nothing to be done
- currentCps = cps;
+ currentCps = cps; currentOption = cps->option;
if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1;
height = cps->nrOptions / width + 1;
typedef void ButtonCallback(int n);
char *trialSound;
-static Option *currentOption;
static int oldCores, oldPonder;
int MakeColors P((void));
void CreateGCs P((int redo));
XtSetArg(args[0], XtNleftBitmap, None);
XtSetValues(marked[n], args, 1);
}
+ if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now
return 1;
}
int i, j;
String name, val;
Arg args[16];
- char buf[MSG_SIZ];
+ char buf[MSG_SIZ], **dest;
float x;
for(i=0; ; i++) { // send all options that had to be OK-ed to engine
switch(currentOption[i].type) {
case PathName:
XtSetArg(args[0], XtNstring, &val);
XtGetValues(currentOption[i].handle, args, 1);
- if(*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val)) {
- safeStrCpy(currentOption[i].name + 100, val, MSG_SIZ-100); // text value kept in pivate storage for each option
- *(char**) currentOption[i].target = currentOption[i].name + 100; // option gets to point to that
+ dest = currentCps ? &(currentOption[i].textValue) : (char**) currentOption[i].target;
+ if(*dest == NULL || strcmp(*dest, val)) {
+ if(currentCps) {
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name, val);
+ SendToProgram(buf, currentCps);
+ } else *dest = currentOption[i].name + 100; // option gets to point to private storage;
+ safeStrCpy(*dest, val, MSG_SIZ - (*dest - currentOption[i].name)); // copy text there
}
break;
case Spin:
if(x < currentOption[i].min) x = currentOption[i].min;
if(currentOption[i].value != x) {
currentOption[i].value = x;
- if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x;
+ if(currentCps) { // engines never have float options, so no decimals!
+ snprintf(buf, MSG_SIZ, "option %s=%.0f\n", currentOption[i].name, x);
+ SendToProgram(buf, currentCps);
+ } else if(currentOption[i].type == Spin) *(int*) currentOption[i].target = x;
else *(float*) currentOption[i].target = x;
}
break;
XtGetValues(currentOption[i].handle, args, 1);
if(currentOption[i].value != j) {
currentOption[i].value = j;
- *(Boolean*) currentOption[i].target = j;
+ if(currentCps) {
+ snprintf(buf, MSG_SIZ, "option %s=%d\n", currentOption[i].name, j);
+ SendToProgram(buf, currentCps);
+ } else *(Boolean*) currentOption[i].target = j;
}
break;
case ComboBox:
val = ((char**)currentOption[i].choice)[values[i]];
- if(val && (*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val))) {
+ if(currentCps) {
+ if(currentOption[i].value == values[i]) break; // not changed
+ currentOption[i].value = values[i];
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", currentOption[i].name,
+ ((char**)currentOption[i].textValue)[values[i]]);
+ SendToProgram(buf, currentCps);
+ } else if(val && (*(char**) currentOption[i].target == NULL || strcmp(*(char**) currentOption[i].target, val))) {
if(*(char**) currentOption[i].target) free(*(char**) currentOption[i].target);
*(char**) currentOption[i].target = strdup(val);
}
default:
printf("GenericReadout: unexpected case in switch.\n");
case Button:
+ case SaveButton:
case Label:
break;
}
PopDown(data);
return;
}
- if(currentOption[data].textValue);
- ((ButtonCallback*) currentOption[data].target)(data);
+ if(currentCps) {
+ if(currentOption[data].type == SaveButton) GenericReadout();
+ snprintf(buf, MSG_SIZ, "option %s\n", name);
+ SendToProgram(buf, currentCps);
+ } else ((ButtonCallback*) currentOption[data].target)(data);
}
int
}
dialogOptions[dlgNr] = option; // make available to callback
- // kludge: fake address of a ChessProgramState struct that contains the options, so Spin and Combo callbacks work on it
+ // post currentOption globally, so Spin and Combo callbacks can already use it
// WARNING: this kludge does not work for persistent dialogs, so that these cannot have spin or combo controls!
- currentCps = (ChessProgramState *) ((char *) option - ((char *)&first.option - (char *)&first));
-
-// if(cps->nrOptions > 50) width = 4; else if(cps->nrOptions>24) width = 2; else width = 1;
-// height = cps->nrOptions / width + 1;
+ currentOption = option;
+
+ if(currentCps) { // Settings popup for engine: format through heuristic
+ int n = currentCps->nrOptions;
+ if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
+ height = n / width + 1;
+ if(currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton) currentOption[n].min = 1; // OK on same line
+ currentOption[n].type = EndMark; currentOption[n].target = NULL; // delimit list by callback-less end mark
+ }
i = 0;
XtSetArg(args[i], XtNresizable, True); i++;
popup = shells[dlgNr] =
option[i].value = *(float*)option[i].target;
goto tBox;
case Spin:
- snprintf(def, MSG_SIZ, "%d", option[i].value = *(int*)option[i].target);
+ if(!currentCps) option[i].value = *(int*)option[i].target;
+ snprintf(def, MSG_SIZ, "%d", option[i].value);
case TextBox:
case FileName:
case PathName:
XtSetArg(args[j], XtNdisplayCaret, False); j++;
XtSetArg(args[j], XtNright, XtChainRight); j++;
XtSetArg(args[j], XtNresizable, True); j++;
- XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def : *(char**)option[i].target); j++;
XtSetArg(args[j], XtNinsertPosition, 9999); j++;
+ XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def :
+ currentCps ? option[i].textValue : *(char**)option[i].target); j++;
edit = last;
option[i].handle = (void*)
(textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j));
(XtPointer)(intptr_t) i);
break;
case CheckBox:
+ if(!currentCps) option[i].value = *(Boolean*)option[i].target;
j=0;
XtSetArg(args[j], XtNfromVert, last); j++;
XtSetArg(args[j], XtNwidth, 10); j++;
XtSetArg(args[j], XtNheight, 10); j++;
XtSetArg(args[j], XtNleft, XtChainLeft); j++;
XtSetArg(args[j], XtNright, XtChainLeft); j++;
- XtSetArg(args[j], XtNstate, option[i].value = *(Boolean*)option[i].target); j++;
+ XtSetArg(args[j], XtNstate, option[i].value); j++;
option[i].handle = (void*)
(dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j));
case Label:
XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
last = XtCreateManagedWidget(msg, labelWidgetClass, form, args, j);
break;
+ case SaveButton:
case Button:
j=0;
XtSetArg(args[j], XtNfromVert, option[i].min & 1 ? lastrow : last); j++;
}
option[i].handle = (void*)
(dialog = last = XtCreateManagedWidget(option[i].name, commandWidgetClass, form, args, j));
- if(option[i].target == NULL) SetColor( *(char**) option[i-1].target, last); else
+ if(option[i].target == NULL && !currentCps) SetColor( *(char**) option[i-1].target, last); else
XtAddCallback(last, XtNcallback, GenericCallback,
(XtPointer)(intptr_t) i + (dlgNr<<16));
if(option[i].textValue) SetColor( option[i].textValue, last);
XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
- for(j=0; option[i].choice[j]; j++)
+ if(currentCps) option[i].choice = (char**) option[i].textValue; else {
+ for(j=0; option[i].choice[j]; j++)
if(*(char**)option[i].target && !strcmp(*(char**)option[i].target, option[i].choice[j])) break;
- option[i].value = j + (option[i].choice[j] == NULL);
+ option[i].value = j + (option[i].choice[j] == NULL);
+ }
j=0;
XtSetArg(args[j], XtNfromVert, last); j++;