X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xoptions.c;h=55a3935f39f93ed5dc58a3b87898282eb0681e32;hb=a61f78756889e18aa279dc273bd99b9af60468d7;hp=528ab3ad19012760cd2fa5dccec7c806f03fb551;hpb=24f7a493a2d030011b0a4f883eaeeb6cbf991414;p=xboard.git diff --git a/xoptions.c b/xoptions.c index 528ab3a..55a3935 100644 --- a/xoptions.c +++ b/xoptions.c @@ -127,9 +127,18 @@ BoardFocus () //--------------------------- Engine-specific options menu ---------------------------------- int dialogError; -static Boolean browserUp; Option *dialogOptions[NrOfDialogs]; +static Arg layoutArgs[] = { + { XtNborderWidth, 0 }, + { XtNdefaultDistance, 0 }, +}; + +static Arg formArgs[] = { + { XtNborderWidth, 0 }, + { XtNresizable, (XtArgVal) True }, +}; + void GetWidgetText (Option *opt, char **buf) { @@ -230,12 +239,12 @@ HighlightWithScroll (Option *opt, int sel, int max) float top, bottom, f, g; HighlightListBoxItem(opt, sel); if(!ReadScroll(opt, &top, &bottom)) return; // no scroll bar - bottom = bottom*max - 1.; + bottom = bottom*max - 1.f; f = g = top; top *= max; - if(sel > (top + 3*bottom)/4) f = (sel - 0.75*(bottom-top))/max; else - if(sel < (3*top + bottom)/4) f = (sel - 0.25*(bottom-top))/max; - if(f < 0.) f = 0.; if(f + 1./max > 1.) f = 1. - 1./max; + if(sel > (top + 3*bottom)/4) f = (sel - 0.75f*(bottom-top))/max; else + if(sel < (3*top + bottom)/4) f = (sel - 0.25f*(bottom-top))/max; + if(f < 0.f) f = 0.; if(f + 1.f/max > 1.f) f = 1. - 1./max; if(f != g) SetScroll(opt, f); } @@ -296,16 +305,7 @@ SpinCallback (Widget w, XtPointer client_data, XtPointer call_data) for(r = ""; *q; q++) if(*q == '.') r = q; else if(*q == '/') r = ""; // last dot after last slash if(!strcmp(r, "") && !currentCps && opt->type == FileName && opt->textValue) r = opt->textValue; - browserUp = True; - if(XsraSelFile(shells[TransientDlg], opt->name, NULL, NULL, "", "", r, - opt->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(opt->handle, args, 1); - } - browserUp = False; - SetFocus(opt->handle, shells[TransientDlg], (XEvent*) NULL, False); + Browse(data>>8, opt->name, NULL, r, opt->type == PathName, "", &p, (FILE**) opt); return; } else if (strcmp(name, "+") == 0) { @@ -328,7 +328,7 @@ ComboSelect (Widget w, caddr_t addr, caddr_t index) // callback for all combo it values[i] = j; // store selected value in Option struct, for retrieval at OK - if(opt[i].type == Graph || opt[i].min & COMBO_CALLBACK && !currentCps) { + if(opt[i].type == Graph || opt[i].min & COMBO_CALLBACK && (!currentCps || shellUp[BrowserDlg])) { ((ButtonCallback*) opt[i].target)(i); return; } @@ -359,7 +359,7 @@ CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n) static Widget CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def) { // fromList determines if the item texts are taken from a list of strings, or from a menu table - int i, j; + int i; Widget menu, entry; Arg arg; MenuItem *mb = (MenuItem *) opt->choice; @@ -370,7 +370,7 @@ CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def) for (i=0; 1; i++) { - char *msg = fromList ? list[i] : mb[i].string, *msg2; + char *msg = fromList ? list[i] : mb[i].string; if(!msg) break; entry = CreateMenuItem(menu, opt->min & NO_GETTEXT ? msg : _(msg), (XtCallbackProc) ComboSelect, (n<<16)+i); if(!fromList) mb[i].handle = (void*) entry; // save item ID, for enabling / checkmarking @@ -387,11 +387,12 @@ char moveTypeInTranslations[] = "Escape: TypeInProc(0) \n"; extern char filterTranslations[]; extern char gameListTranslations[]; +extern char memoTranslations[]; -char *translationTable[] = { +char *translationTable[] = { // beware: order is essential! historyTranslations, commentTranslations, moveTypeInTranslations, ICSInputTranslations, - filterTranslations, gameListTranslations, + filterTranslations, gameListTranslations, memoTranslations }; void @@ -407,7 +408,8 @@ AddHandler (Option *opt, int nr) Widget shells[NrOfDialogs]; DialogClass parents[NrOfDialogs]; WindowPlacement *wp[NrOfDialogs] = { // Beware! Order must correspond to DialogClass enum - NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput + NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput, &wpEvalGraph, + NULL, NULL, NULL, NULL, &wpMain }; int @@ -416,6 +418,32 @@ DialogExists (DialogClass n) return shells[n] != NULL; } +void +RaiseWindow (DialogClass dlg) +{ + static XEvent xev; + Window root = RootWindow(xDisplay, DefaultScreen(xDisplay)); + Atom atom = XInternAtom (xDisplay, "_NET_ACTIVE_WINDOW", False); + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = xDisplay; + xev.xclient.window = XtWindow(shells[dlg]); + xev.xclient.message_type = atom; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = CurrentTime; + + XSendEvent (xDisplay, + root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + + XFlush(xDisplay); + XSync(xDisplay, False); +} + int PopDown (DialogClass n) { // pops down any dialog created by GenericPopUp (or returns False if it wasn't up), unmarks any associated marked menu @@ -443,9 +471,10 @@ PopDown (DialogClass n) MarkMenuItem(marked[n], False); marked[n] = NULL; } - if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now + if(!n && n != BrowserDlg) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now currentOption = dialogOptions[TransientDlg]; // just in case a transient dialog was up (to allow its check and combo callbacks to work) - XtSetKeyboardFocus(shells[parents[n]], n == BoardWindow ? formWidget: shells[parents[n]]); + RaiseWindow(parents[n]); + if(parents[n] == BoardWindow) XtSetKeyboardFocus(shellWidget, formWidget); return 1; } @@ -454,7 +483,7 @@ GenericPopDown (Widget w, XEvent *event, String *prms, Cardinal *nprms) { // to cause popdown through a translation (Delete Window button!) int dlg = atoi(prms[0]); Widget sh = shells[dlg]; - if(browserUp || dialogError) return; // prevent closing dialog when it has an open file-browse daughter + if(shellUp[BrowserDlg] && dlg != BrowserDlg || dialogError) return; // prevent closing dialog when it has an open file-browse daughter shells[dlg] = w; PopDown(dlg); shells[dlg] = sh; // restore @@ -564,7 +593,7 @@ GenericCallback (Widget w, XtPointer client_data, XtPointer call_data) if(GenericReadout(currentOption, -1)) PopDown(dlg); // calls OK-proc after full readout, but no popdown if it returns false } else - if(currentCps) { + if(currentCps && dlg != BrowserDlg) { XtSetArg(args[0], XtNlabel, &name); XtGetValues(w, args, 1); if(currentOption[data].type == SaveButton) GenericReadout(currentOption, -1); @@ -599,7 +628,7 @@ WheelProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) int j=0, n = atoi(prms[0]); static char *params[3] = { "", "Continuous", "Proportional" }; Arg args[16]; - float f, h, top; + float h, top; Widget v; if(!n) { // transient dialogs also use this for list-selection callback n = prms[1][0]-'0'; @@ -612,7 +641,7 @@ WheelProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) XtSetArg(args[j], XtNshown, &h); j++; XtSetArg(args[j], XtNtopOfThumb, &top); j++; XtGetValues(v, args, j); - top += 0.1*h*n; if(top < 0.) top = 0.; + top += 0.1f*h*n; if(top < 0.f) top = 0.; XtCallActionProc(v, "StartScroll", event, params+1, 1); XawScrollbarSetThumb(v, top, -1.0); XtCallActionProc(v, "NotifyThumb", event, params, 0); @@ -631,7 +660,7 @@ static char scrollTranslations[] = static void SqueezeIntoBox (Option *opt, int nr, int width) { // size buttons in bar to fit, clipping button names where necessary - int i, j, wtot = 0; + int i, wtot = 0; Dimension widths[20], oldWidths[20]; Arg arg; for(i=1; inrOptions; if(!n) { DisplayNote(_("Engine has no options")); currentCps = NULL; return 0; } if(n > 50) width = 4; else if(n>24) width = 2; else width = 1; @@ -725,6 +754,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent XtSetArg(args[i], XtNresizable, True); i++; shells[BoardWindow] = shellWidget; parents[dlgNr] = parent; + if(dlgNr == BoardWindow) popup = shellWidget; else popup = shells[dlgNr] = XtCreatePopupShell(title, !top || !appData.topLevel ? transientShellWidgetClass : topLevelShellWidgetClass, shells[parent], args, i); @@ -760,7 +790,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent option[i].value = *(float*)option[i].target; goto tBox; case Spin: - if(!currentCps) option[i].value = *(int*)option[i].target; + if(!engineDlg) option[i].value = *(int*)option[i].target; snprintf(def, MSG_SIZ, "%d", option[i].value); case TextBox: case FileName: @@ -790,7 +820,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent XtSetArg(args[j], XtNresizable, True); 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++; + engineDlg ? option[i].textValue : *(char**)option[i].target); j++; edit = last; option[i].handle = (void*) (textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j)); @@ -822,7 +852,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent XtAddCallback(last, XtNcallback, SpinCallback, (XtPointer)(intptr_t) i + 256*dlgNr); break; case CheckBox: - if(!currentCps) option[i].value = *(Boolean*)option[i].target; // where checkbox callback uses it + if(!engineDlg) option[i].value = *(Boolean*)option[i].target; // where checkbox callback uses it j = SetPositionAndSize(args, last, lastrow, 1 /* border */, textHeight/2 /* w */, textHeight/2 /* h */, 0xC0 /* chain both to left edge */); XtSetArg(args[j], XtNvertDistance, (textHeight+2)/4 + 3); j++; @@ -865,7 +895,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent forelast = lastrow; } else chain = 0, shrink = FALSE; j = SetPositionAndSize(args, last, lastrow, 3 /* border */, - option[i].max /* w */, shrink ? textHeight : 0 /* h */, chain /* chain */); + option[i].max /* w */, shrink ? textHeight : 0 /* h */, option[i].min & 0xE | chain /* chain */); XtSetArg(args[j], XtNlabel, _(option[i].name)); j++; if(option[i].textValue) { // special for buttons of New Variant dialog XtSetArg(args[j], XtNsensitive, appData.noChessProgram || option[i].value < 0 @@ -874,7 +904,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent } option[i].handle = (void*) (dialog = last = XtCreateManagedWidget(option[i].name, commandWidgetClass, form, args, j)); - if(option[i].choice && ((char*)option[i].choice)[0] == '#' && !currentCps) { // for the color picker default-reset + if(option[i].choice && ((char*)option[i].choice)[0] == '#' && !engineDlg) { // for the color picker default-reset SetColor( *(char**) option[i-1].target, &option[i]); XtAddEventHandler(option[i-1].handle, KeyReleaseMask, False, ColorChanged, (XtPointer)(intptr_t) i-1); } @@ -889,12 +919,12 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j); if(option[i].min & COMBO_CALLBACK) msg = _(option[i].name); else { - if(!currentCps) SetCurrentComboSelection(option+i); + if(!engineDlg) SetCurrentComboSelection(option+i); msg=_(((char**)option[i].choice)[option[i].value]); } j = SetPositionAndSize(args, dialog, last, (option[i].min & 2) == 0 /* border */, - option[i].max && !currentCps ? option[i].max : 100 /* w */, + option[i].max && !engineDlg ? option[i].max : 100 /* w */, textHeight /* h */, 0x91 /* chain */); // same row as its label! XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++; XtSetArg(args[j], XtNlabel, msg); j++; @@ -932,6 +962,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent (last = XtCreateManagedWidget("graph", widgetClass, form, args, j)); XtAddEventHandler(last, ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, False, (XtEventHandler) GraphEventProc, option[i].target); // mandatory user-supplied expose handler + if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow; break; case PopUp: // note: used only after Graph, so 'last' refers to the Graph widget option[i].handle = (void*) CreateComboPopup(last, option + i, i + 256*dlgNr, TRUE, option[i].value); @@ -1054,16 +1085,17 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent } XtRealizeWidget(popup); - XSetWMProtocols(xDisplay, XtWindow(popup), &wm_delete_window, 1); - snprintf(def, MSG_SIZ, "WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr); - XtAugmentTranslations(popup, XtParseTranslationTable(def)); - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - + if(dlgNr != BoardWindow) { // assign close button, and position w.r.t. pointer, if not main window + XSetWMProtocols(xDisplay, XtWindow(popup), &wm_delete_window, 1); + snprintf(def, MSG_SIZ, "WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr); + XtAugmentTranslations(popup, XtParseTranslationTable(def)); + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + } XtPopup(popup, modal ? XtGrabExclusive : XtGrabNone); shellUp[dlgNr]++; // count rather than flag previous = NULL; @@ -1076,6 +1108,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y)); j++; XtSetValues(popup, args, j); } + RaiseWindow(dlgNr); return 1; // tells caller he must do initialization (e.g. add specific event handlers) }