X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=dialogs.c;h=35b3aefbe8b7d035ad1f085457d475acd501766b;hb=24eec7ef0db2c98df79453e377a72cefe12b7569;hp=8e3936fdce8b7164aacc64554fc32f713a679cb9;hpb=89ca7bf7ee0c418d1a2cdf2830c9a34c78a715b0;p=xboard.git diff --git a/dialogs.c b/dialogs.c index 8e3936f..35b3aef 100644 --- a/dialogs.c +++ b/dialogs.c @@ -1,7 +1,7 @@ /* * dialogs.c -- platform-independent code for dialogs of XBoard * - * Copyright 2000, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. + * Copyright 2000, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc. * ------------------------------------------------------------------------ * * GNU XBoard is free software: you can redistribute it and/or modify @@ -93,11 +93,13 @@ int SetCurrentComboSelection (Option *opt) { int j; + if(currentCps) ; else if(!opt->textValue) opt->value = *(int*)opt->target; /* numeric */else { for(j=0; opt->choice[j]; j++) // look up actual value in list of possible values, to get selection nr if(*(char**)opt->target && !strcmp(*(char**)opt->target, ((char**)opt->textValue)[j])) break; opt->value = j + (opt->choice[j] == NULL); } + SetComboChoice(opt, opt->value); return opt->value; } @@ -286,11 +288,11 @@ static Option matchOptions[] = { { 0, 0, 0, NULL, (void*) &appData.cycleSync, "", NULL, CheckBox, N_("Sync after cycle") }, { 0, LR, 175, NULL, NULL, NULL, NULL, Label, N_("Tourney participants:") }, { 0, SAME_ROW|RR, 175, NULL, NULL, NULL, NULL, Label, N_("Select Engine:") }, -{ 150, T_VSCRL | T_FILL | T_WRAP, +{ 200, T_VSCRL | T_FILL | T_WRAP, 175, NULL, (void*) &engineName, NULL, NULL, TextBox, "" }, -{ 150, SAME_ROW|RR, +{ 200, SAME_ROW|RR, 175, NULL, (void*) engineMnemonic, (char*) &AddToTourney, NULL, ListBox, "" }, -{ 0, 0, 0, NULL, NULL, NULL, NULL, Break, "" }, // to decouple alignment above and below boxes +{ 0, SAME_ROW, 0, NULL, NULL, NULL, NULL, Break, "" }, // to decouple alignment above and below boxes //{ 0, COMBO_CALLBACK | NO_GETTEXT, // 0, NULL, (void*) &AddToTourney, (char*) (engineMnemonic+1), (engineMnemonic+1), ComboBox, N_("Select Engine:") }, { 0, 0, 10, NULL, (void*) &appData.tourneyType, "", NULL, Spin, N_("Tourney type (0 = round-robin, 1 = gauntlet):") }, @@ -331,8 +333,10 @@ UpgradeParticipant () static void PseudoOK () { + if(matchMode) return; GenericReadout(matchOptions, -2); // read all, but suppress calling of MatchOK ASSIGN(appData.participants, engineName); + ASSIGN(appData.tourneyFile, tfName); PopDown(MasterDlg); // early popdown to prevent FreezeUI called through MatchEvent from causing XtGrab warning } @@ -562,7 +566,6 @@ NewVariantProc () { static int start; int i, last; - char buf[MSG_SIZ]; ranksTmp = filesTmp = sizeTmp = -1; // prefer defaults over actual settings if(appData.noChessProgram) sprintf(warning, _("Only bughouse is not available in viewer mode.")); else sprintf(warning, _("All variants not supported by the first engine\n(currently %s) are disabled."), first.tidy); @@ -586,9 +589,9 @@ NewVariantProc () } variantDescriptors[start-2].type = (last < 0 ? EndMark : Skip); variantDescriptors[start-1].type = (last < 6 ? Skip : Break); - safeStrCpy(buf, engineVariant, MSG_SIZ); *engineVariant = NULLCHAR; // yeghh... + safeStrCpy(engineVariant+100, engineVariant, 100); *engineVariant = NULLCHAR; // yeghh... GenericPopUp(variantDescriptors, _("New Variant"), TransientDlg, BoardWindow, MODAL, 0); - safeStrCpy(engineVariant, buf, MSG_SIZ); // must temporarily clear to avoid enabling all variant buttons + safeStrCpy(engineVariant, engineVariant+100, MSG_SIZ); // must temporarily clear to avoid enabling all variant buttons } //------------------------------------------- Common Engine Options ------------------------------------- @@ -1459,10 +1462,26 @@ SecondSettingsProc () SettingsPopUp(&second); } +void +RefreshSettingsDialog (ChessProgramState *cps, int val) +{ + if(val == 1) { // option values changed + if(shellUp[TransientDlg] && cps == currentCps) { + GenericUpdate(cps->option, -1); // normally update values when dialog is up + } + return; // and be done + } + if(val == 2) { // option list changed + if(!shellUp[TransientDlg] || cps != currentCps) return; // our dialog is not up, so nothing to do + } + PopDown(TransientDlg); // make sure any other dialog closes first + SettingsPopUp(cps); // and popup new one +} + //----------------------------------------------- Load Engine -------------------------------------- char *engineDir, *engineLine, *nickName, *params; -Boolean isUCI, hasBook, storeVariant, v1, addToList, useNick, secondEng; +Boolean isUCI, isUSI, hasBook, storeVariant, v1, addToList, useNick, secondEng; static void EngSel P((int n, int sel)); static int InstallOK P((int n)); @@ -1478,6 +1497,7 @@ static Option installOptions[] = { { 0, 0, 0, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine Command:") }, { 0, LR, 0, NULL, NULL, NULL, NULL, Label, N_("(Directory will be derived from engine path when empty)") }, { 0, 0, 0, NULL, (void*) &isUCI, NULL, NULL, CheckBox, N_("UCI") }, +{ 0, 0, 0, NULL, (void*) &isUSI, NULL, NULL, CheckBox, N_("USI/UCCI (uses specified -uxiAdapter)") }, { 0, 0, 0, NULL, (void*) &v1, NULL, NULL, CheckBox, N_("WB protocol v1 (do not wait for engine features)") }, { 0, 0, 0, NULL, (void*) &hasBook, NULL, NULL, CheckBox, N_("Must not use GUI book") }, { 0, 0, 0, NULL, (void*) &addToList, NULL, NULL, CheckBox, N_("Add this engine to the list") }, @@ -1492,6 +1512,10 @@ InstallOK (int n) ASSIGN(engineLine, engineList[n]); } PopDown(TransientDlg); // early popdown, to allow FreezeUI to instate grab + if(isUSI) { + isUCI = 2; // kludge to pass isUSI to Load() + if(!*appData.ucciAdapter) { ASSIGN(appData.ucciAdapter, "usi2wb -%variant \"%fcp\"\"%fd\""); } // make sure -uxiAdapter is defined + } if(!secondEng) Load(&first, 0); else Load(&second, 1); return FALSE; // no double PopDown! } @@ -1517,7 +1541,7 @@ EngSel (int n, int sel) static void LoadEngineProc (int engineNr, char *title) { - isUCI = storeVariant = v1 = useNick = False; addToList = hasBook = True; // defaults + isUCI = isUSI = storeVariant = v1 = useNick = False; addToList = hasBook = True; // defaults secondEng = engineNr; if(engineLine) free(engineLine); engineLine = strdup(""); if(engineDir) free(engineDir); engineDir = strdup("."); @@ -1665,6 +1689,10 @@ SetTcType (int n) void TimeControlProc () { + if(gameMode != BeginningOfGame) { + DisplayError(_("Changing time control during a game is not implemented"), 0); + return; + } tmpMoves = appData.movesPerSession; tmpInc = appData.timeIncrement; if(tmpInc < 0) tmpInc = 0; tmpOdds1 = tmpOdds2 = 1; tcType = 0; @@ -1767,7 +1795,7 @@ PromotionPopUp (char choice) { // choice depends on variant: prepare dialog acordingly count = 8; SetPromo(_("Cancel"), --count, -1); // Beware: GenericPopUp cannot handle user buttons named "cancel" (lowe case)! - if(choice != '+') { + if(choice != '+' && !IS_SHOGI(gameInfo.variant)) { if (!appData.testLegality || gameInfo.variant == VariantSuicide || gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || gameInfo.variant == VariantGiveaway) { @@ -1896,7 +1924,14 @@ IcsHist (int n, Option *opt, DialogClass dlg) if(opt != &chatOptions[CHAT_IN] && !(opt == &chatOptions[CHAT_PARTNER] && n == 33)) return 0; switch(n) { + case 5: + if(!hidden) ClearChat(); + break; + case 8: + if(!hidden) PaneSwitch(); + break; case 33: // + if(1) BoardToTop(); else if(hidden) BoardToTop(); else PaneSwitch(); break; @@ -1912,7 +1947,7 @@ IcsHist (int n, Option *opt, DialogClass dlg) while(!dirty[chat = (chat + 1)%MAX_CHAT]) if(chat == start) break; if(!dirty[chat]) while(!chatPartner[chat = (chat + 1)%MAX_CHAT][0]) if(chat == start) break; - if(chat == start && hidden) chat = 0; // if all unused, start left + if(!chatPartner[chat][0]) break; // if all unused, ignore ChatSwitch(chat + 1); break; case 1: @@ -1933,6 +1968,7 @@ OutputChatMessage (int partner, char *mess) char *p = texts[partner]; int len = strlen(mess) + 1; + if(!DialogExists(ChatDlg)) return; if(p) len += strlen(p); texts[partner] = (char*) malloc(len); snprintf(texts[partner], len, "%s%s", p ? p : "", mess); @@ -1951,11 +1987,12 @@ ChatOK (int n) { // can only be called through in chat-partner text-edit, as there is no OK button char buf[MSG_SIZ]; - if(!hidden && (!partner || strcmp(partner, chatPartner[activePartner]))) { + if(!hidden && (!partner || strcmp(partner, chatPartner[activePartner]) || !*partner)) { safeStrCpy(chatPartner[activePartner], partner, MSG_SIZ); SetWidgetText(&chatOptions[CHAT_OUT], "", -1); // clear text if we alter partner SetWidgetText(&chatOptions[CHAT_IN], "", ChatDlg); // clear text if we alter partner SetWidgetLabel(&chatOptions[activePartner+1], chatPartner[activePartner][0] ? chatPartner[activePartner] : _("New Chat")); + if(!*partner) PaneSwitch(); HardSetFocus(&chatOptions[CHAT_IN], 0); } if(line[0] || hidden) { // something was typed (for ICS commands we also allow empty line!) @@ -1968,6 +2005,10 @@ ChatOK (int n) snprintf(buf, MSG_SIZ, "whisper %s\n", line); // WHISPER box uses "whisper" to send else if(!strcmp("shouts", chatPartner[activePartner])) snprintf(buf, MSG_SIZ, "shout %s\n", line); // SHOUT box uses "shout" to send + else if(!strcmp("c-shouts", chatPartner[activePartner])) + snprintf(buf, MSG_SIZ, "cshout %s\n", line); // C-SHOUT box uses "cshout" to send + else if(!strcmp("kibitzes", chatPartner[activePartner])) + snprintf(buf, MSG_SIZ, "kibitz %s\n", line); // KIBITZ box uses "kibitz" to send else { if(!atoi(chatPartner[activePartner])) { snprintf(buf, MSG_SIZ, "> %s\n", line); // echo only tells to handle, not channel @@ -2090,6 +2131,7 @@ ChatProc () void ConsoleAutoPopUp (char *buf) { + if(*buf == 27) { if(appData.icsActive && DialogExists(ChatDlg)) HardSetFocus (&chatOptions[CHAT_IN], ChatDlg); return; } if(!appData.autoBox) return; if(appData.icsActive) { // text typed to board in ICS mode: divert to ICS input box if(DialogExists(ChatDlg)) { // box already exists: append to current contents @@ -2150,6 +2192,7 @@ GLT_OK (int n) { GLT_ParseList(); appData.gameListTags = strdup(lpUserGLT); + GameListUpdate(); return 1; } @@ -2243,8 +2286,8 @@ ErrorPopUp (char *title, char *label, int modal) { errorUp = True; errorOptions[1].name = label; - if(dialogError = shellUp[TransientDlg]) - GenericPopUp(errorOptions+1, title, FatalDlg, TransientDlg, MODAL, 0); // pop up as daughter of the transient dialog + if(dialogError = shellUp[MasterDlg]) + GenericPopUp(errorOptions+1, title, FatalDlg, MasterDlg, MODAL, 0); // pop up as daughter of the transient dialog else GenericPopUp(errorOptions+modal, title, modal ? FatalDlg: ErrorDlg, BoardWindow, modal, 0); // kludge: option start address indicates modality } @@ -2414,7 +2457,8 @@ DisplayLogos (Option *w1, Option *w2) { void *whiteLogo = first.programLogo, *blackLogo = second.programLogo; if(appData.autoLogo) { - if(appData.noChessProgram) whiteLogo = blackLogo = NULL; else + if(appData.noChessProgram) whiteLogo = blackLogo = NULL; + if(appData.icsActive) whiteLogo = blackLogo = second.programLogo; switch(gameMode) { // pick logos based on game mode case IcsObserving: whiteLogo = second.programLogo; // ICS logo @@ -2470,14 +2514,14 @@ CCB (int n) Option mainOptions[] = { // description of main window in terms of generic dialog creator { 0, 0xCA, 0, NULL, NULL, "", NULL, BarBegin, "" }, // menu bar - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("File") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Edit") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("View") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Mode") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Action") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Engine") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Options") }, - { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Help") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_File") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_Edit") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_View") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_Mode") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_Action") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("E_ngine") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_Options") }, + { 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("_Help") }, { 0, 0, 0, NULL, (void*)&SizeKludge, "", NULL, BarEnd, "" }, { 0, LR|T2T|BORDER|SAME_ROW, 0, NULL, NULL, NULL, NULL, Label, "1" }, // optional title in window { 50, LL|TT, 100, NULL, (void*) &LogoW, NULL, NULL, Skip, "" }, // white logo @@ -2535,11 +2579,18 @@ MenuCallback (int n) static Option * Exp (int n, int x, int y) { - static int but1, but3, oldW, oldH; + static int but1, but3, oldW, oldH, oldX, oldY; int menuNr = -3, sizing, f, r; TimeMark now; + extern Boolean right; + + if(right) { // kludgy way to let button 1 double as button 3 when back-end requests this + if(but1 && n == 0) but1 = 0, but3 = 1; + else if(n == -1) n = -3, right = FALSE; + } if(n == 0) { // motion + oldX = x; oldY = y; if(SeekGraphClick(Press, x, y, 1)) return NULL; if((but1 || dragging == 2) && !PromoScroll(x, y)) DragPieceMove(x, y); if(but3) MovePV(x, y, lineGap + BOARD_HEIGHT * (squareSize + lineGap)); @@ -2562,8 +2613,8 @@ Exp (int n, int x, int y) case 3: menuNr = RightClick(Press, x, y, &pmFromX, &pmFromY), but3 = 1; break; case -2: shiftKey = !shiftKey; case -3: menuNr = RightClick(Release, x, y, &pmFromX, &pmFromY), but3 = 0; break; - case 4: BackwardEvent(); break; - case 5: ForwardEvent(); break; + case 4: Wheel(-1, oldX, oldY); break; + case 5: Wheel(1, oldX, oldY); break; case 10: sizing = (oldW != x || oldH != y); oldW = x; oldH = y; @@ -2589,13 +2640,14 @@ Option * BoardPopUp (int squareSize, int lineGap, void *clockFontThingy) { int i, size = BOARD_WIDTH*(squareSize + lineGap) + lineGap, logo = appData.logoSize; + int f = 2*appData.fixedSize; // width fudge, needed for unknown reasons to not clip board mainOptions[W_WHITE].choice = (char**) clockFontThingy; mainOptions[W_BLACK].choice = (char**) clockFontThingy; mainOptions[W_BOARD].value = BOARD_HEIGHT*(squareSize + lineGap) + lineGap; mainOptions[W_BOARD].max = mainOptions[W_SMALL].max = size; // board size mainOptions[W_SMALL].max = size - 2; // board title (subtract border!) mainOptions[W_BLACK].max = mainOptions[W_WHITE].max = size/2-3; // clock width - mainOptions[W_MESSG].max = appData.showButtonBar ? size-135 : size-2; // message + mainOptions[W_MESSG].max = appData.showButtonBar ? size-135+f : size-2+f; // message mainOptions[W_MENU].max = size-40; // menu bar mainOptions[W_TITLE].type = appData.titleInWindow ? Label : Skip ; if(logo && logo <= size/4) { // Activate logos @@ -2717,6 +2769,7 @@ DisplayMessage (char *message, char *extMessage) #define MAXFILES 1000 +static DialogClass savDlg; static ChessProgramState *savCps; static FILE **savFP; static char *fileName, *extFilter, *savMode, **namePtr; @@ -2799,7 +2852,7 @@ BrowseOK (int n) snprintf(title, MSG_SIZ, "%s", fileName); else snprintf(title, MSG_SIZ, "%s/%s", curDir, fileName); - SetWidgetText((Option*) savFP, title, TransientDlg); + SetWidgetText((Option*) savFP, title, savDlg); currentCps = savCps; // could return to Engine Settings dialog! return TRUE; } @@ -2953,10 +3006,38 @@ DirSelProc (int n, int sel) } void +StartDir (char *filter, char *newName) +{ + static char *gamesDir, *trnDir, *imgDir, *bookDir; + static char curDir[MSG_SIZ]; + char **res = NULL; + if(!filter || !*filter) return; + if(strstr(filter, "pgn")) res = &gamesDir; else + if(strstr(filter, "bin")) res = &bookDir; else + if(strstr(filter, "png")) res = &imgDir; else + if(strstr(filter, "trn")) res = &trnDir; else + if(strstr(filter, "fen")) res = &appData.positionDir; + if(res) { + if(newName) { + char *p, *q; + if(*newName) { + ASSIGN(*res, newName); + for(p=*res; q=strchr(p, '/');) p = q + 1; *p = NULLCHAR; + } + if(*curDir) chdir(curDir); + *curDir = NULLCHAR; + } else { + getcwd(curDir, MSG_SIZ); + if(*res && **res) chdir(*res); + } + } +} + +void Browse (DialogClass dlg, char *label, char *proposed, char *ext, Boolean pathFlag, char *mode, char **name, FILE **fp) { int j=0; - savFP = fp; savMode = mode, namePtr = name, savCps = currentCps, oldVal = values[9]; // save params, for use in callback + savFP = fp; savMode = mode, namePtr = name, savCps = currentCps, oldVal = values[9], savDlg = dlg; // save params, for use in callback ASSIGN(extFilter, ext); ASSIGN(fileName, proposed ? proposed : ""); for(j=0; Extensions[j]; j++) // look up actual value in list of possible values, to get selection nr