X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xoptions.c;h=f3e8f67a376f2a7f2cbeaf87b7766325435eb34e;hb=407cd1126c6c24d890359f1fe1686f6d90c0ad61;hp=b8b1ee8e71fef9dce662cea958a140abe9acb47e;hpb=9e70e37cd4cd1e80a00391a188b1da16eb46589b;p=xboard.git diff --git a/xoptions.c b/xoptions.c index b8b1ee8..f3e8f67 100644 --- a/xoptions.c +++ b/xoptions.c @@ -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; @@ -104,6 +88,7 @@ void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b) { Arg args[2]; char *s; + int j; if(previous) { XtSetArg(args[0], XtNdisplayCaret, False); @@ -111,16 +96,15 @@ void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b) } XtSetArg(args[0], XtNstring, &s); XtGetValues(w, args, 1); + j = 1; XtSetArg(args[0], XtNdisplayCaret, True); - XtSetArg(args[1], XtNinsertPosition, strlen(s)); - XtSetValues(w, args, 2); + if(!strchr(s, '\n')) XtSetArg(args[1], XtNinsertPosition, strlen(s)), j++; + XtSetValues(w, args, j); XtSetKeyboardFocus((Widget) data, w); previous = w; } //--------------------------- New Shuffle Game -------------------------------------------- -extern int shuffleOpenings; -extern int startedFromPositionFile; int shuffleUp; Widget shuffleShell; @@ -323,7 +307,7 @@ void TimeControlCallback(w, client_data, call_data) XtSetArg(args[j], XtNlabel, _("sec/move (max)")); j++; XtSetValues(tcMess1, args, j); j=0; - XtSetArg(args[j], XtNlabel, _("")); j++; + XtSetArg(args[j], XtNlabel, ""); j++; XtSetValues(tcMess2, args, j); j=0; XtSetArg(args[j], XtNstring, ""); j++; @@ -332,7 +316,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 +604,14 @@ void TimeControlProc(w, event, prms, nprms) //--------------------------- Engine-specific options menu ---------------------------------- +typedef void ButtonCallback(int n); +typedef int OKCallback(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) { @@ -660,6 +647,8 @@ void SpinCallback(w, client_data, call_data) XtSetArg(args[0], XtNstring, &q); XtGetValues(currentOption[data].handle, args, 1); for(r = ""; *q; q++) if(*q == '.') r = q; else if(*q == '/') r = ""; // last dot after last slash + if(!strcmp(r, "") && !currentCps && currentOption[data].type == FileName && currentOption[data].textValue) + r = currentOption[data].textValue; browserUp = True; if(XsraSelFile(shells[0], currentOption[data].name, NULL, NULL, "", "", r, currentOption[data].type == PathName ? "p" : "f", NULL, &p)) { @@ -696,6 +685,8 @@ void ComboSelect(w, addr, index) // callback for all combo items values[i] = j; // store in temporary, for transfer at OK 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,11 +703,11 @@ 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) { + XtSetArg(args[j], XtNlabel, _(mb[i])); entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass, - menu, args, j); + menu, args, j+1); XtAddCallback(entry, XtNcallback, (XtCallbackProc) ComboSelect, (caddr_t)(intptr_t) (256*n+i)); @@ -729,15 +720,13 @@ 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; int MakeColors P((void)); void CreateGCs P((int redo)); void CreateAnyPieces P((void)); -void GenericReadout P((int selected)); +int GenericReadout P((int selected)); Widget shells[10]; Widget marked[10]; Boolean shellUp[10]; @@ -787,27 +776,64 @@ 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'); } +char *engineName, *engineDir, *engineChoice, *engineLine, *nickName, *params, *tfName; +Boolean isUCI, hasBook, storeVariant, v1, addToList, useNick; +extern Option installOptions[], matchOptions[]; +char *engineNr[] = { N_("First Engine"), N_("Second Engine"), NULL }; +char *engineList[100] = {" "}, *engineMnemonic[100] = {""}; + +void AddToTourney(int n) +{ + Arg args[2]; + char *p, *val, buf[10000]; + XawTextBlock t; + + GenericReadout(4); // selected engine + t.ptr = engineChoice; t.firstPos = 0; t.length = strlen(engineChoice); t.format = XawFmt8Bit; + XawTextReplace(matchOptions[3].handle, 9999, 9999, &t); + t.ptr = "\n"; t.length = 1; + XawTextReplace(matchOptions[3].handle, 9999, 9999, &t); +} + +int MatchOK(int n) +{ + if(appData.participants && appData.participants[0]) free(appData.participants); + appData.participants = strdup(engineName); + if(!CreateTourney(tfName)) return !appData.participants[0]; + PopDown(0); // early popdown to prevent FreezeUI called through MatchEvent from causing XtGrab warning + MatchEvent(2); // start tourney + return 1; +} + Option matchOptions[] = { -{ 0, 2, 1000000000, NULL, (void*) &appData.defaultMatchGames, "", NULL, Spin, N_("Default Number of Games in Match:") }, +{ 0, 0, 0, NULL, (void*) &tfName, ".trn", NULL, FileName, N_("Tournament file:") }, +{ 0, 0, 0, NULL, (void*) &appData.roundSync, "", NULL, CheckBox, N_("Sync after round (for concurrent playing of a single") }, +{ 0, 0, 0, NULL, (void*) &appData.cycleSync, "", NULL, CheckBox, N_("Sync after cycle tourney with multiple XBoards)") }, +{ 0xD, 150, 0, NULL, (void*) &engineName, "", NULL, TextBox, "Tourney participants:" }, +{ 0, 1, 0, NULL, (void*) &engineChoice, (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):") }, +{ 0, 1, 1000000000, NULL, (void*) &appData.tourneyCycles, "", NULL, Spin, N_("Number of tourney cycles (or Swiss rounds):") }, +{ 0, 1, 1000000000, NULL, (void*) &appData.defaultMatchGames, "", NULL, Spin, N_("Default Number of Games in Match (or Pairing):") }, { 0, 0, 1000000000, NULL, (void*) &appData.matchPause, "", NULL, Spin, N_("Pause between Match Games (msec):") }, -{ 0, 0, 0, NULL, (void*) &appData.loadGameFile, "", NULL, FileName, N_("Game File with Opening Lines:") }, +{ 0, 0, 0, NULL, (void*) &appData.saveGameFile, ".pgn", NULL, FileName, N_("Save Tourney Games on:") }, +{ 0, 0, 0, NULL, (void*) &appData.loadGameFile, ".pgn", NULL, FileName, N_("Game File with Opening Lines:") }, { 0, -2, 1000000000, NULL, (void*) &appData.loadGameIndex, "", NULL, Spin, N_("Game Number (-1 or -2 = Auto-Increment):") }, -{ 0, 0, 0, NULL, (void*) &appData.loadPositionFile, "", NULL, FileName, N_("File with Start Positions:") }, +{ 0, 0, 0, NULL, (void*) &appData.loadPositionFile, ".fen", NULL, FileName, N_("File with Start Positions:") }, { 0, -2, 1000000000, NULL, (void*) &appData.loadPositionIndex, "", NULL, Spin, N_("Position Number (-1 or -2 = Auto-Increment):") }, { 0, 0, 1000000000, NULL, (void*) &appData.rewindIndex, "", NULL, Spin, N_("Rewind Index after this many Games (0 = never):") }, -{ 0, 0, 0, NULL, NULL, "", NULL, EndMark , "" } +{ 0, 0, 0, NULL, (void*) &MatchOK, "", NULL, EndMark , "" } }; -void GeneralOptionsOK(int n) +int GeneralOptionsOK(int n) { int newPonder = appData.ponderNextMove; appData.ponderNextMove = oldPonder; PonderNextMoveEvent(newPonder); + return 1; } Option generalOptions[] = { @@ -818,6 +844,7 @@ Option generalOptions[] = { { 0, 0, 0, NULL, (void*) &appData.autoFlipView, "", NULL, CheckBox, N_("Auto Flip View") }, { 0, 0, 0, NULL, (void*) &appData.blindfold, "", NULL, CheckBox, N_("Blindfold") }, { 0, 0, 0, NULL, (void*) &appData.dropMenu, "", NULL, CheckBox, N_("Drop Menu") }, +{ 0, 0, 0, NULL, (void*) &appData.hideThinkingFromHuman, "", NULL, CheckBox, N_("Hide Thinking from Human") }, { 0, 0, 0, NULL, (void*) &appData.highlightDragging, "", NULL, CheckBox, N_("Highlight Dragging (Show Move Targets)") }, { 0, 0, 0, NULL, (void*) &appData.highlightLastMove, "", NULL, CheckBox, N_("Highlight Last Move") }, { 0, 0, 0, NULL, (void*) &appData.highlightMoveWithArrow, "", NULL, CheckBox, N_("Highlight with Arrow") }, @@ -829,7 +856,6 @@ Option generalOptions[] = { { 0, 0, 0, NULL, (void*) &appData.popupMoveErrors, "", NULL, CheckBox, N_("Popup Move Errors") }, { 0, 0, 0, NULL, (void*) &appData.showCoords, "", NULL, CheckBox, N_("Show Coordinates") }, { 0, 0, 0, NULL, (void*) &appData.markers, "", NULL, CheckBox, N_("Show Target Squares") }, -{ 0, 0, 0, NULL, (void*) &appData.hideThinkingFromHuman, "", NULL, CheckBox, N_("Hide Thinking from Human") }, { 0, 0, 0, NULL, (void*) &appData.testLegality, "", NULL, CheckBox, N_("Test Legality") }, { 0, 0, 10, NULL, (void*) &appData.flashCount, "", NULL, Spin, N_("Flash Moves (0 = no flashing):") }, { 0, 1, 10, NULL, (void*) &appData.flashRate, "", NULL, Spin, N_("Flash Rate (high = fast):") }, @@ -912,7 +938,7 @@ Option variantDescriptors[] = { { 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" } }; -void CommonOptionsOK(int n) +int CommonOptionsOK(int n) { int newPonder = appData.ponderNextMove; // make sure changes are sent to first engine by re-initializing it @@ -924,6 +950,7 @@ void CommonOptionsOK(int n) appData.ponderNextMove = oldPonder; PonderNextMoveEvent(newPonder); } + return 1; } Option commonEngineOptions[] = { @@ -934,7 +961,7 @@ Option commonEngineOptions[] = { { 0, 0, 0, NULL, (void*) &appData.defaultPathEGTB, "", NULL, PathName, N_("Nalimov EGTB Path:") }, { 0, 0, 1000, NULL, (void*) &appData.defaultCacheSizeEGTB, "", NULL, Spin, N_("EGTB Cache Size (MB):") }, { 0, 0, 0, NULL, (void*) &appData.usePolyglotBook, "", NULL, CheckBox, N_("Use GUI Book") }, -{ 0, 0, 0, NULL, (void*) &appData.polyglotBook, "", NULL, FileName, N_("Opening-Book Filename:") }, +{ 0, 0, 0, NULL, (void*) &appData.polyglotBook, ".bin", NULL, FileName, N_("Opening-Book Filename:") }, { 0, 0, 100, NULL, (void*) &appData.bookDepth, "", NULL, Spin, N_("Book Depth (moves):") }, { 0, 0, 100, NULL, (void*) &appData.bookStrength, "", NULL, Spin, N_("Book Variety (0) vs. Strength (100):") }, { 0, 0, 0, NULL, (void*) &appData.firstHasOwnBookUCI, "", NULL, CheckBox, N_("Engine #1 Has Own Book") }, @@ -956,9 +983,10 @@ Option adjudicationOptions[] = { { 0, 1, 0, NULL, NULL, "", NULL, EndMark , "" } }; -void IcsOptionsOK(int n) +int IcsOptionsOK(int n) { ParseIcsTextColors(); + return 1; } Option icsOptions[] = { @@ -1004,8 +1032,8 @@ Option loadOptions[] = { Option saveOptions[] = { { 0, 0, 0, NULL, (void*) &appData.autoSaveGames, "", NULL, CheckBox, N_("Auto-Save Games") }, -{ 0, 0, 0, NULL, (void*) &appData.saveGameFile, "", NULL, FileName, N_("Save Games on File:") }, -{ 0, 0, 0, NULL, (void*) &appData.savePositionFile, "", NULL, FileName, N_("Save Final Positions on File:") }, +{ 0, 0, 0, NULL, (void*) &appData.saveGameFile, ".pgn", NULL, FileName, N_("Save Games on File:") }, +{ 0, 0, 0, NULL, (void*) &appData.savePositionFile, ".fen", NULL, FileName, N_("Save Final Positions on File:") }, { 0, 0, 0, NULL, (void*) &appData.pgnEventHeader, "", NULL, TextBox, N_("PGN Event Header:") }, { 0, 0, 0, NULL, (void*) &appData.oldSaveStyle, "", NULL, CheckBox, N_("Old Save Style (as opposed to PGN)") }, { 0, 0, 0, NULL, (void*) &appData.saveExtendedInfoInPGN, "", NULL, CheckBox, N_("Save Score/Depth Info in PGN") }, @@ -1058,7 +1086,7 @@ void Test(int n) Option soundOptions[] = { { 0, 0, 0, NULL, (void*) &appData.soundProgram, "", NULL, TextBox, N_("Sound Program:") }, { 0, 0, 0, NULL, (void*) &appData.soundDirectory, "", NULL, PathName, N_("Sounds Directory:") }, -{ 0, 0, 0, NULL, (void*) (soundFiles+2) /* kludge! */, "", NULL, FileName, N_("User WAV File:") }, +{ 0, 0, 0, NULL, (void*) (soundFiles+2) /* kludge! */, ".wav", NULL, FileName, N_("User WAV File:") }, { 0, 0, 0, NULL, (void*) &trialSound, (char*) soundNames, soundFiles, ComboBox, N_("Try-Out Sound:") }, { 0, 1, 0, NULL, (void*) &Test, NULL, NULL, Button, N_("Play") }, { 0, 0, 0, NULL, (void*) &appData.soundMove, (char*) soundNames, soundFiles, ComboBox, N_("Move:") }, @@ -1093,7 +1121,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); } @@ -1148,15 +1176,15 @@ void AdjustColor(int i) RefreshColor(i-n-1, n); } -void BoardOptionsOK(int n) +int BoardOptionsOK(int n) { - extern int defaultLineGap, useImages, useImageSqs; if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap; useImages = useImageSqs = 0; MakeColors(); CreateGCs(True); CreateAnyPieces(); InitDrawingSizes(-1, 0); DrawPosition(True, NULL); + return 1; } Option boardOptions[] = { @@ -1200,17 +1228,17 @@ Option boardOptions[] = { //{ 0, 0, 0, NULL, (void*) &appData.allWhite, "", NULL, CheckBox, N_("Use Outline Pieces for Black") }, { 0, 0, 0, NULL, (void*) &appData.monoMode, "", NULL, CheckBox, N_("Mono Mode") }, { 0,-1, 5, NULL, (void*) &appData.overrideLineGap, "", NULL, Spin, N_("Line Gap ( -1 = default for board size):") }, -{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, "", NULL, FileName, N_("Light-Squares Texture File:") }, -{ 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, "", NULL, FileName, N_("Dark-Squares Texture File:") }, +{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, ".xpm", NULL, FileName, N_("Light-Squares Texture File:") }, +{ 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, ".xpm", NULL, FileName, N_("Dark-Squares Texture File:") }, { 0, 0, 0, NULL, (void*) &appData.bitmapDirectory, "", NULL, PathName, N_("Directory with Bitmap Pieces:") }, { 0, 0, 0, NULL, (void*) &appData.pixmapDirectory, "", NULL, PathName, N_("Directory with Pixmap Pieces:") }, { 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" } }; -void GenericReadout(int selected) +int GenericReadout(int selected) { - int i, j; - String name, val; + int i, j, res=1; + String val; Arg args[16]; char buf[MSG_SIZ], **dest; float x; @@ -1227,7 +1255,10 @@ void GenericReadout(int selected) 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; + } else { + if(*dest) free(*dest); + *dest = malloc(strlen(val)+1); + } safeStrCpy(*dest, val, MSG_SIZ - (*dest - currentOption[i].name)); // copy text there } break; @@ -1275,7 +1306,7 @@ void GenericReadout(int selected) break; case EndMark: if(currentOption[i].target) // callback for implementing necessary actions on OK (like redraw) - ((ButtonCallback*) currentOption[i].target)(i); + res = ((OKCallback*) currentOption[i].target)(i); break; default: printf("GenericReadout: unexpected case in switch.\n"); @@ -1287,16 +1318,16 @@ void GenericReadout(int selected) } if(currentOption[i].type == EndMark) break; } + return res; } 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; @@ -1309,8 +1340,7 @@ void GenericCallback(w, client_data, call_data) return; } if (strcmp(name, _("OK")) == 0) { // save buttons imply OK - GenericReadout(-1); - PopDown(data); + if(GenericReadout(-1)) PopDown(data); return; } if(currentCps) { @@ -1326,7 +1356,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; @@ -1349,9 +1379,10 @@ GenericPopUp(Option *option, char *title, int dlgNr) if(currentCps) { // Settings popup for engine: format through heuristic int n = currentCps->nrOptions; + if(!n) { DisplayNote(_("Engine has no options")); return 0; } 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; @@ -1495,7 +1526,7 @@ GenericPopUp(Option *option, char *title, int dlgNr) 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++; + if(option[i].max) { XtSetArg(args[j], XtNwidth, option[i].max); j++; } if(option[i].textValue) { // special for buttons of New Variant dialog XtSetArg(args[j], XtNsensitive, appData.noChessProgram || option[i].value < 0 || strstr(first.variants, VariantName(option[i].value))); j++; @@ -1737,14 +1768,17 @@ void MatchOptionsProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { + NamesToList(firstChessProgramNames, engineList, engineMnemonic); + comboCallback = &AddToTourney; + matchOptions[5].min = -(appData.pairingEngine[0] != NULLCHAR); // with pairing engine, allow Swiss + ASSIGN(tfName, appData.tourneyFile[0] ? appData.tourneyFile : MakeName(appData.defName)); GenericPopUp(matchOptions, _("Match Options"), 0); } 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")) { @@ -1826,9 +1860,10 @@ static int commentIndex; void ClearComment P((int n)); extern char commentTranslations[]; -void NewComCallback(int n) +int NewComCallback(int n) { ReplaceComment(commentIndex, commentText); + return 1; } void SaveChanges(int n) @@ -1840,9 +1875,9 @@ void SaveChanges(int n) } Option commentOptions[] = { -{ 0xD, 200, 300, NULL, (void*) &commentText, "", NULL, TextBox, "" }, -{ 0, 0, 0, NULL, (void*) &ClearComment, NULL, NULL, Button, "clear" }, -{ 0, 1, 0, NULL, (void*) &SaveChanges, NULL, NULL, Button, "save changes" }, +{ 0xD, 200, 250, NULL, (void*) &commentText, "", NULL, TextBox, "" }, +{ 0, 0, 50, NULL, (void*) &ClearComment, NULL, NULL, Button, "clear" }, +{ 0, 1, 100, NULL, (void*) &SaveChanges, NULL, NULL, Button, "save changes" }, { 0, 1, 0, NULL, (void*) &NewComCallback, "", NULL, EndMark , "" } }; @@ -1863,7 +1898,7 @@ void NewCommentPopup(char *title, char *text, int index) XtSetArg(args[0], XtNstring, text); XtSetValues(commentOptions[0].handle, args, 1); } - commentText = text; + if(commentText) free(commentText); commentText = strdup(text); commentIndex = index; MarkMenu("menuView.Show Comments", 1); if(GenericPopUp(commentOptions, title, 1)) @@ -1872,9 +1907,10 @@ void NewCommentPopup(char *title, char *text, int index) static char *tagsText, *msgText; -void NewTagsCallback(int n) +int NewTagsCallback(int n) { ReplaceTags(tagsText, &gameInfo); + return 1; } void changeTags(int n) @@ -1882,13 +1918,14 @@ void changeTags(int n) Arg args[16]; XtSetArg(args[0], XtNstring, &tagsText); XtGetValues(currentOption[1].handle, args, 1); + if(bookUp) SaveToBook(tagsText); else ReplaceTags(tagsText, &gameInfo); } Option tagsOptions[] = { { 0, 0, 0, NULL, NULL, NULL, NULL, Label, "" }, -{ 0xD, 200, 250, NULL, (void*) &tagsText, "", NULL, TextBox, "" }, -{ 0, 0, 0, NULL, (void*) &changeTags, NULL, NULL, Button, "save changes" }, +{ 0xD, 200, 200, NULL, (void*) &tagsText, "", NULL, TextBox, "" }, +{ 0, 0, 100, NULL, (void*) &changeTags, NULL, NULL, Button, "save changes" }, { 0, 1, 0, NULL, (void*) &NewTagsCallback, "", NULL, EndMark , "" } }; @@ -1896,18 +1933,20 @@ void NewTagsPopup(char *text, char *msg) { Widget edit; Arg args[16]; + char *title = bookUp ? _("Edit book") : _("Tags"); if(shells[2]) { // if already exists, alter title and content XtSetArg(args[0], XtNstring, text); XtSetValues(tagsOptions[1].handle, args, 1); + XtSetArg(args[0], XtNtitle, title); + XtSetValues(shells[2], args, 1); } - tagsText = text; + if(tagsText) free(tagsText); tagsText = strdup(text); tagsOptions[0].textValue = msg; MarkMenu("menuView.Show Tags", 2); - GenericPopUp(tagsOptions, _("Tags"), 2); + GenericPopUp(tagsOptions, title, 2); } -extern char ICSInputTranslations[]; char *icsText; Option boxOptions[] = { @@ -1917,7 +1956,6 @@ Option boxOptions[] = { void PutText(char *text, int pos) { - Widget edit; Arg args[16]; char buf[MSG_SIZ], *p; @@ -2011,106 +2049,18 @@ void SecondSettingsProc(w, event, prms, nprms) SettingsPopUp(&second); } -char *engineName, *engineDir, *engineChoice, *engineLine; -Boolean isUCI, hasBook, storeVariant, v1, addToList; -extern Option installOptions[]; -extern char *firstChessProgramNames; -char *engineNr[] = { N_("First Engine"), N_("Second Engine"), NULL }; -char *engineList[100] = {" "}, *engineMnemonic[100] = {""}; - -void NamesToList(char *names) -{ - char buf[MSG_SIZ], *p, *q; - int i=1; - while(*names) { - p = names; q = buf; - while(*p && *p != '\n') *q++ = *p++; - *q = 0; - if(engineList[i]) free(engineList[i]); - engineList[i] = strdup(buf); - if(*p == '\n') p++; - TidyProgramName(engineList[i], "localhost", buf); - if(engineMnemonic[i]) free(engineMnemonic[i]); - if(q = strstr(engineList[i], " -variant ")) { - strcat(buf, "("); - sscanf(q + 10, "%s", buf + strlen(buf)); - strcat(buf, ")"); - } - engineMnemonic[i] = strdup(buf); - names = p; i++; - } - engineList[i] = NULL; -} - -// following implemented as macro to avoid type limitations -#define SWAP(item, temp) temp = appData.item[0]; appData.item[0] = appData.item[n]; appData.item[n] = temp; - -void SwapEngines(int n) -{ // swap settings for first engine and other engine (so far only some selected options) - int h; - char *p; - if(n == 0) return; - SWAP(directory, p) - SWAP(chessProgram, p) - SWAP(isUCI, h) - SWAP(hasOwnBookUCI, h) - SWAP(protocolVersion, h) - SWAP(reuse, h) - SWAP(scoreIsAbsolute, h) - SWAP(timeOdds, h) -} - -void Load(ChessProgramState *cps, int i) -{ - char *p, *q, buf[MSG_SIZ]; - if(engineLine[0]) { // an engine was selected from the combo box - snprintf(buf, MSG_SIZ, "-fcp %s", engineLine); - SwapEngines(i); // kludge to parse -f* / -first* like it is -s* / -second* - ParseArgsFromString(buf); - SwapEngines(i); - ReplaceEngine(cps, i); - return; - } - p = engineName; - while(q = strchr(p, '/')) p = q+1; - if(*p== NULLCHAR) return; - appData.chessProgram[i] = strdup(p); - if(engineDir[0] != NULLCHAR) - appData.directory[i] = engineDir; - else if(p != engineName) { // derive directory from engine path, when not given - p[-1] = 0; - appData.directory[i] = strdup(engineName); - p[-1] = '/'; - } else appData.directory[i] = "."; - appData.isUCI[i] = isUCI; - appData.protocolVersion[i] = v1 ? 1 : PROTOVER; - appData.hasOwnBookUCI[i] = hasBook; - if(addToList) { - int len; - q = firstChessProgramNames; - snprintf(buf, MSG_SIZ, "\"%s\" -fd \"%s\"%s%s%s%s%s\n", p, appData.directory[i], - v1 ? " -firstProtocolVersion 1" : "", - hasBook ? "" : " -fNoOwnBookUCI", - isUCI ? " -fUCI" : "", - storeVariant ? " -variant " : "", - storeVariant ? VariantName(gameInfo.variant) : ""); -printf("new line: %s", buf); - firstChessProgramNames = malloc(len = strlen(q) + strlen(buf) + 1); - snprintf(firstChessProgramNames, len, "%s%s", q, buf); - if(q) free(q); - } - ReplaceEngine(cps, i); -} - -void InstallOK(int n) +int InstallOK(int n) { PopDown(0); // early popdown, to allow FreezeUI to instate grab if(engineChoice[0] == engineNr[0][0]) Load(&first, 0); else Load(&second, 1); + return 1; } 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*) &useNick, NULL, NULL, CheckBox, N_("Use nickname in PGN player tags of engine-engine games") }, { 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)") }, @@ -2129,14 +2079,25 @@ void LoadEngineProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - isUCI = addToList = storeVariant = v1 = False; hasBook = True; // defaults - engineDir = ""; + isUCI = storeVariant = v1 = useNick = False; addToList = hasBook = True; // defaults if(engineChoice) free(engineChoice); engineChoice = strdup(engineNr[0]); if(engineLine) free(engineLine); engineLine = strdup(""); - NamesToList(firstChessProgramNames); + if(engineDir) free(engineDir); engineDir = strdup(""); + if(nickName) free(nickName); nickName = strdup(""); + if(params) free(params); params = strdup(""); + NamesToList(firstChessProgramNames, engineList, engineMnemonic); GenericPopUp(installOptions, _("Load engine"), 0); } +void EditBookProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + EditBookEvent(); +} + //---------------------------- Chat Windows ---------------------------------------------- void OutputChatMessage(int partner, char *mess)