X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=f29eb15f6a9386dcee119f2c4785c80b82021a63;hb=e70077aab0199817f37aef9ed0bdba1bbca93b45;hp=9923bd29608b07d04a4d47d47c27886d238eaf44;hpb=fb1fe1e685ae5b35d0230cd33c2c0c795d6db24b;p=xboard.git diff --git a/xboard.c b/xboard.c index 9923bd2..f29eb15 100644 --- a/xboard.c +++ b/xboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -142,6 +142,10 @@ extern char *getenv(); # endif #endif +#if ENABLE_NLS +#include +#endif + #include #include #include @@ -234,6 +238,8 @@ typedef struct { String name; String ref; MenuItem *mi; + int textWidth; + Widget subMenu; } Menu; int main P((int argc, char **argv)); @@ -243,14 +249,20 @@ RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); RETSIGTYPE TermSizeSigHandler P((int sig)); void CreateGCs P((int redo)); +void CreateAnyPieces P((void)); void CreateXIMPieces P((void)); void CreateXPMPieces P((void)); void CreateXPMBoard P((char *s, int n)); void CreatePieces P((void)); void CreatePieceMenus P((void)); -Widget CreateMenuBar P((Menu *mb)); +Widget CreateMenuBar P((Menu *mb, int boardWidth)); Widget CreateButtonBar P ((MenuItem *mi)); +#if ENABLE_NLS +char *InsertPxlSize P((char *pattern, int targetPxlSize)); +XFontSet CreateFontSet P((char *base_fnt_lst)); +#else char *FindFont P((char *pattern, int targetPxlSize)); +#endif void PieceMenuPopup P((Widget w, XEvent *event, String *params, Cardinal *num_params)); static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk)); @@ -261,6 +273,7 @@ void CreateGrid P((void)); int EventToSquare P((int x, int limit)); void DrawSquare P((int row, int column, ChessSquare piece, int do_flash)); void EventProc P((Widget widget, caddr_t unused, XEvent *event)); +void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event)); void HandleUserMove P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AnimateUserMove P((Widget w, XEvent * event, @@ -322,6 +335,7 @@ void CopyPositionProc P((Widget w, XEvent *event, String *prms, void PastePositionProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void CopyGameListProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SavePositionProc P((Widget w, XEvent *event, @@ -364,6 +378,7 @@ void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void TypeInProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void UpKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void DownKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -374,6 +389,9 @@ void StopExaminingProc P((Widget w, XEvent *event, String *prms, void UploadProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void TempBackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void TempForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +Boolean TempBackwardActive = False; void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -431,7 +449,6 @@ void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void DisplayMove P((int moveNumber)); void DisplayTitle P((char *title)); void ICSInitScript P((void)); @@ -450,6 +467,7 @@ void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)) void OptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void IcsTextProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void LoadEngineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -458,9 +476,9 @@ void SoundOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms) void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void EditBookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void SelectMove P((Widget w, XEvent * event, String * params, Cardinal * nParams)); void GameListOptionsPopDown P(()); -void ShufflePopDown P(()); -void TimeControlPopDown P(()); void GenericPopDown P(()); void update_ics_width P(()); int get_term_width P(()); @@ -493,8 +511,14 @@ int hOffset; // [HGM] dual XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6]; -Font clockFontID, coordFontID, countFontID; -XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct; +#if ENABLE_NLS +XFontSet fontSet, clockFontSet; +#else +Font clockFontID; +XFontStruct *clockFontStruct; +#endif +Font coordFontID, countFontID; +XFontStruct *coordFontStruct, *countFontStruct; XtAppContext appContext; char *layoutName; char *oldICSInteractionTitle; @@ -537,6 +561,9 @@ WindowPlacement wpEngineOutput; WindowPlacement wpGameList; WindowPlacement wpTags; +extern Widget shells[]; +extern Boolean shellUp[]; + #define SOLID 0 #define OUTLINE 1 Pixmap pieceBitmap[2][(int)BlackPawn]; @@ -615,6 +642,7 @@ MenuItem fileMenu[] = { MenuItem editMenu[] = { {N_("Copy Game Ctrl+C"), "Copy Game", CopyGameProc}, {N_("Copy Position Ctrl+Shift+C"), "Copy Position", CopyPositionProc}, + {N_("Copy Game List"), "Copy Game List", CopyGameListProc}, {"----", NULL, NothingProc}, {N_("Paste Game Ctrl+V"), "Paste Game", PasteGameProc}, {N_("Paste Position Ctrl+Shift+V"), "Paste Position", PastePositionProc}, @@ -623,6 +651,7 @@ MenuItem editMenu[] = { {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, {N_("Edit Tags"), "Edit Tags", EditTagsProc}, {N_("Edit Comment"), "Edit Comment", EditCommentProc}, + {N_("Edit Book"), "Edit Book", EditBookProc}, {"----", NULL, NothingProc}, {N_("Revert Home"), "Revert", RevertProc}, {N_("Annotate"), "Annotate", AnnotateProc}, @@ -658,7 +687,7 @@ MenuItem modeMenu[] = { {N_("Machine Black Ctrl+B"), "Machine Black", MachineBlackProc}, {N_("Two Machines Ctrl+T"), "Two Machines", TwoMachinesProc}, {N_("Analysis Mode Ctrl+A"), "Analysis Mode", AnalyzeModeProc}, - {N_("Analyze File Ctrl+F"), "Analyze File", AnalyzeFileProc }, + {N_("Analyze Game Ctrl+G"), "Analyze File", AnalyzeFileProc }, {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc}, {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, {N_("Training"), "Training", TrainingProc}, @@ -691,6 +720,8 @@ MenuItem actionMenu[] = { }; MenuItem engineMenu[] = { + {N_("Load New Engine ..."), "Load Engine", LoadEngineProc}, + {"----", NULL, NothingProc}, {N_("Engine #1 Settings ..."), "Engine #1 Settings", FirstSettingsProc}, {N_("Engine #2 Settings ..."), "Engine #2 Settings", SecondSettingsProc}, {"----", NULL, NothingProc}, @@ -773,7 +804,7 @@ Menu menuBar[] = { MenuItem buttonBar[] = { {"<<", "<<", ToStartProc}, {"<", "<", BackwardProc}, - {PAUSE_BUTTON, PAUSE_BUTTON, PauseProc}, + {N_(PAUSE_BUTTON), PAUSE_BUTTON, PauseProc}, {">", ">", ForwardProc}, {">>", ">>", ToEndProc}, {NULL, NULL, NULL} @@ -790,7 +821,7 @@ String pieceMenuStrings[2][PIECE_MENU_SIZE] = { N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), N_("Empty square"), N_("Clear board") } }; -/* must be in same order as PieceMenuStrings! */ +/* must be in same order as pieceMenuStrings! */ ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = { { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil, @@ -806,7 +837,7 @@ ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = { String dropMenuStrings[DROP_MENU_SIZE] = { "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen") }; -/* must be in same order as PieceMenuStrings! */ +/* must be in same order as dropMenuStrings! */ ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = { (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen @@ -894,7 +925,6 @@ XtActionsRec boardActions[] = { { "PieceMenuPopup", PieceMenuPopup }, { "WhiteClock", WhiteClock }, { "BlackClock", BlackClock }, - { "Iconify", Iconify }, { "ResetProc", ResetProc }, { "NewVariantProc", NewVariantProc }, { "LoadGameProc", LoadGameProc }, @@ -910,6 +940,7 @@ XtActionsRec boardActions[] = { { "CopyPositionProc", CopyPositionProc }, { "PastePositionProc", PastePositionProc }, { "CopyGameProc", CopyGameProc }, + { "CopyGameListProc", CopyGameListProc }, { "PasteGameProc", PasteGameProc }, { "SaveGameProc", SaveGameProc }, { "SavePositionProc", SavePositionProc }, @@ -930,6 +961,7 @@ XtActionsRec boardActions[] = { { "ShowGameListProc", ShowGameListProc }, { "ShowMoveListProc", HistoryShowProc}, { "EditTagsProc", EditCommentProc }, + { "EditBookProc", EditBookProc }, { "EditCommentProc", EditCommentProc }, { "IcsInputBoxProc", IcsInputBoxProc }, { "PauseProc", PauseProc }, @@ -944,6 +976,7 @@ XtActionsRec boardActions[] = { { "AdjuWhiteProc", AdjuWhiteProc }, { "AdjuBlackProc", AdjuBlackProc }, { "AdjuDrawProc", AdjuDrawProc }, + { "TypeInProc", TypeInProc }, { "EnterKeyProc", EnterKeyProc }, { "UpKeyProc", UpKeyProc }, { "DownKeyProc", DownKeyProc }, @@ -952,6 +985,8 @@ XtActionsRec boardActions[] = { { "UploadProc", UploadProc }, { "BackwardProc", BackwardProc }, { "ForwardProc", ForwardProc }, + { "TempBackwardProc", TempBackwardProc }, + { "TempForwardProc", TempForwardProc }, { "ToStartProc", ToStartProc }, { "ToEndProc", ToEndProc }, { "RevertProc", RevertProc }, @@ -1007,13 +1042,11 @@ XtActionsRec boardActions[] = { { "GameListPopDown", (XtActionProc) GameListPopDown }, { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown }, { "PromotionPopDown", (XtActionProc) PromotionPopDown }, - { "HistoryPopDown", (XtActionProc) HistoryPopDown }, { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown }, { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown }, - { "ShufflePopDown", (XtActionProc) ShufflePopDown }, - { "TimeControlPopDown", (XtActionProc) TimeControlPopDown }, { "GenericPopDown", (XtActionProc) GenericPopDown }, { "CopyMemoProc", (XtActionProc) CopyMemoProc }, + { "SelectMove", (XtActionProc) SelectMove }, }; char globalTranslations[] = @@ -1023,6 +1056,8 @@ char globalTranslations[] = :Ctrlo: LoadGameProc() \n \ :MetaNext: LoadNextGameProc() \n \ :MetaPrior: LoadPrevGameProc() \n \ + :CtrlDown: LoadSelectedProc(3) \n \ + :CtrlUp: LoadSelectedProc(-3) \n \ :Ctrls: SaveGameProc() \n \ :Ctrlc: CopyGameProc() \n \ :Ctrlv: PasteGameProc() \n \ @@ -1037,7 +1072,7 @@ char globalTranslations[] = :Ctrlb: MachineBlackProc() \n \ :Ctrlt: TwoMachinesProc() \n \ :Ctrla: AnalysisModeProc() \n \ - :Ctrlf: AnalyzeFileProc() \n \ + :Ctrlg: AnalyzeFileProc() \n \ :Ctrle: EditGameProc() \n \ :CtrlE: EditPositionProc() \n \ :MetaO: EngineOutputProc() \n \ @@ -1059,6 +1094,8 @@ char globalTranslations[] = :MetaRight: ForwardProc() \n \ :MetaHome: ToStartProc() \n \ :MetaLeft: BackwardProc() \n \ + :Left: BackwardProc() \n \ + :Right: ForwardProc() \n \ :Home: RevertProc() \n \ :End: TruncateGameProc() \n \ :Ctrlm: MoveNowProc() \n \ @@ -1076,14 +1113,13 @@ char globalTranslations[] = :CtrlH: HideThinkingProc() \n " #endif "\ - :-: Iconify() \n \ :F1: ManProc() \n \ :F2: FlipViewProc() \n \ - .: BackwardProc() \n \ - .: ForwardProc() \n \ - Shift1: AskQuestionProc(\"Direct command\",\ + :Return: TempBackwardProc() \n \ + :Return: TempForwardProc() \n \ + :Ctrl1: AskQuestionProc(\"Direct command\",\ \"Send to chess program:\",,1) \n \ - Shift2: AskQuestionProc(\"Direct command\",\ + :Ctrl2: AskQuestionProc(\"Direct command\",\ \"Send to second chess program:\",,2) \n"; char boardTranslations[] = @@ -1102,8 +1138,12 @@ char boardTranslations[] = Any: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \ PieceMenuPopup(menuB) \n"; -char whiteTranslations[] = ": WhiteClock()\n"; -char blackTranslations[] = ": BlackClock()\n"; +char whiteTranslations[] = + "Shift: WhiteClock(1)\n \ + : WhiteClock(0)\n"; +char blackTranslations[] = + "Shift: BlackClock(1)\n \ + : BlackClock(0)\n"; char ICSInputTranslations[] = "Up: UpKeyProc() \n " @@ -1253,8 +1293,8 @@ xpm_closest_to(dirname, size, ext) fprintf(stderr, _("\ Warning: No DIR structure found on this system --\n\ Unable to autosize for XPM/XIM pieces.\n\ - Please report this error to frankm@hiwaay.net.\n\ - Include system type & operating system in message.\n")); + Please report this error to %s.\n\ + Include system type & operating system in message.\n"), PACKAGE_BUGREPORT);); return size; } #endif /* HAVE_DIR_STRUCT */ @@ -1401,7 +1441,7 @@ colorVariable[] = { // [HGM] font: keep a font for each square size, even non-stndard ones #define NUM_SIZES 18 #define MAX_SIZE 130 -Boolean fontSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE]; +Boolean fontIsSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE]; char *fontTable[NUM_FONTS][MAX_SIZE]; void @@ -1430,7 +1470,7 @@ ParseFont(char *name, int number) default: return; } - fontSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file) + fontIsSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file) } void @@ -1500,7 +1540,7 @@ SaveFontArg(FILE *f, ArgDescriptor *ad) break; } for(i=0; iargName, i, fontTable[n][i]); + fprintf(f, OPTCHAR "%s" SEPCHAR "\"size%d:%s\"\n", ad->argName, i, fontTable[n][i]); } void @@ -1533,7 +1573,7 @@ ParseCommPortSettings(char *s) } extern Widget engineOutputShell; -extern Widget tagsShell, editTagsShell; + void GetActualPlacement(Widget wg, WindowPlacement *wp) { @@ -1561,14 +1601,12 @@ GetWindowCoords() { // wrapper to shield use of window handles from back-end (make addressible by number?) // In XBoard this will have to wait until awareness of window parameters is implemented GetActualPlacement(shellWidget, &wpMain); - if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput); else - if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory); + if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput); + if(MoveHistoryIsUp()) GetActualPlacement(shells[7], &wpMoveHistory); if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph); if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList); - if(commentShell) GetActualPlacement(commentShell, &wpComment); - else GetActualPlacement(editShell, &wpComment); - if(tagsShell) GetActualPlacement(tagsShell, &wpTags); - else GetActualPlacement(editTagsShell, &wpTags); + if(shellUp[1]) GetActualPlacement(shells[1], &wpComment); + if(shellUp[2]) GetActualPlacement(shells[2], &wpTags); } void @@ -1622,7 +1660,7 @@ ConvertToLine(int argc, char **argv) line[0] = NULLCHAR; for(i=1; i= 0) lineGap = appData.overrideLineGap; + boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); + boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); + + if(boardWidth != oldWidth || boardHeight != oldHeight || oldDual != twoBoards) { // do resizing stuff only if size actually changed /* * Enable shell resizing. */ @@ -1665,9 +1711,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags) XtSetArg(args[0], XtNdefaultDistance, &sep); XtGetValues(formWidget, args, 1); - if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; - boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); - boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); + oldWidth = boardWidth; oldHeight = boardHeight; oldDual = twoBoards; CreateGrid(); hOffset = boardWidth + 10; for(i=0; i BOARD_FILES || appData.NrRanks > BOARD_RANKS ) @@ -2055,11 +2134,11 @@ main(argc, argv) tinyLayout = szd->tinyLayout; // [HGM] font: use defaults from settings file if available and not overruled } - if(!fontSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize]) + if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize]) appData.clockFont = fontTable[CLOCK_FONT][squareSize]; - if(!fontSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize]) + if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize]) appData.font = fontTable[MESSAGE_FONT][squareSize]; - if(!fontSet[COORD_FONT] && fontValid[COORD_FONT][squareSize]) + if(!fontIsSet[COORD_FONT] && fontValid[COORD_FONT][squareSize]) appData.coordFont = fontTable[COORD_FONT][squareSize]; /* Now, using squareSize as a hint, find a good XPM/XIM set size */ @@ -2105,19 +2184,42 @@ XBoard square size (hint): %d\n\ /* * Determine what fonts to use. */ +#if ENABLE_NLS + appData.font = InsertPxlSize(appData.font, fontPxlSize); + appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize); + appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize); + fontSet = CreateFontSet(appData.font); + clockFontSet = CreateFontSet(appData.clockFont); + { + /* For the coordFont, use the 0th font of the fontset. */ + XFontSet coordFontSet = CreateFontSet(appData.coordFont); + XFontStruct **font_struct_list; + char **font_name_list; + XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list); + coordFontID = XLoadFont(xDisplay, font_name_list[0]); + coordFontStruct = XQueryFont(xDisplay, coordFontID); + } +#else + appData.font = FindFont(appData.font, fontPxlSize); appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize); + appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize); clockFontID = XLoadFont(xDisplay, appData.clockFont); clockFontStruct = XQueryFont(xDisplay, clockFontID); - appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize); coordFontID = XLoadFont(xDisplay, appData.coordFont); coordFontStruct = XQueryFont(xDisplay, coordFontID); - appData.font = FindFont(appData.font, fontPxlSize); - countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings - countFontStruct = XQueryFont(xDisplay, countFontID); -// appData.font = FindFont(appData.font, fontPxlSize); +#endif + countFontID = coordFontID; // [HGM] holdings + countFontStruct = coordFontStruct; xdb = XtDatabase(xDisplay); +#if ENABLE_NLS + XrmPutLineResource(&xdb, "*international: True"); + vTo.size = sizeof(XFontSet); + vTo.addr = (XtPointer) &fontSet; + XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo); +#else XrmPutStringResource(&xdb, "*font", appData.font); +#endif /* * Detect if there are not enough colors available and adapt. @@ -2131,10 +2233,7 @@ XBoard square size (hint): %d\n\ if (forceMono) { fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"), programName); - - if (appData.bitmapDirectory == NULL || - appData.bitmapDirectory[0] == NULLCHAR) - appData.bitmapDirectory = DEF_BITMAP_DIR; + appData.monoMode = True; } if (appData.lowTimeWarning && !appData.monoMode) { @@ -2181,7 +2280,7 @@ XBoard square size (hint): %d\n\ XtGetValues(formWidget, args, 1); j = 0; - widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar); + widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar, boardWidth); XtSetArg(args[0], XtNtop, XtChainTop); XtSetArg(args[1], XtNbottom, XtChainTop); XtSetArg(args[2], XtNright, XtChainLeft); @@ -2190,7 +2289,11 @@ XBoard square size (hint): %d\n\ widgetList[j++] = whiteTimerWidget = XtCreateWidget("whiteTime", labelWidgetClass, formWidget, timerArgs, XtNumber(timerArgs)); +#if ENABLE_NLS + XtSetArg(args[0], XtNfontSet, clockFontSet); +#else XtSetArg(args[0], XtNfont, clockFontStruct); +#endif XtSetArg(args[1], XtNtop, XtChainTop); XtSetArg(args[2], XtNbottom, XtChainTop); XtSetValues(whiteTimerWidget, args, 3); @@ -2198,7 +2301,11 @@ XBoard square size (hint): %d\n\ widgetList[j++] = blackTimerWidget = XtCreateWidget("blackTime", labelWidgetClass, formWidget, timerArgs, XtNumber(timerArgs)); +#if ENABLE_NLS + XtSetArg(args[0], XtNfontSet, clockFontSet); +#else XtSetArg(args[0], XtNfont, clockFontStruct); +#endif XtSetArg(args[1], XtNtop, XtChainTop); XtSetArg(args[2], XtNbottom, XtChainTop); XtSetValues(blackTimerWidget, args, 3); @@ -2544,19 +2651,7 @@ XBoard square size (hint): %d\n\ CreateGCs(False); CreateGrid(); -#if HAVE_LIBXPM - if (appData.bitmapDirectory[0] != NULLCHAR) { - CreatePieces(); - } else { - CreateXPMPieces(); - CreateXPMBoard(appData.liteBackTextureFile, 1); - CreateXPMBoard(appData.darkBackTextureFile, 0); - } -#else - CreateXIMPieces(); - /* Create regular pieces */ - if (!useImages) CreatePieces(); -#endif + CreateAnyPieces(); CreatePieceMenus(); @@ -2577,6 +2672,8 @@ XBoard square size (hint): %d\n\ XtAddEventHandler(boardWidget, ExposureMask|PointerMotionMask, False, (XtEventHandler) EventProc, NULL); /* end why */ + XtAddEventHandler(formWidget, KeyPressMask, False, + (XtEventHandler) MoveTypeInProc, NULL); /* [AS] Restore layout */ if( wpMoveHistory.visible ) { @@ -2613,13 +2710,16 @@ XBoard square size (hint): %d\n\ } gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes() InitPosition(TRUE); - XtSetKeyboardFocus(shellWidget, formWidget); +// XtSetKeyboardFocus(shellWidget, formWidget); + XSetInputFocus(xDisplay, XtWindow(formWidget), RevertToPointerRoot, CurrentTime); XtAppMainLoop(appContext); if (appData.debugMode) fclose(debugFP); // [DM] debug return 0; } +static Boolean noEcho; + void ShutDownFrontEnd() { @@ -2629,6 +2729,7 @@ ShutDownFrontEnd() if (saveSettingsOnExit) SaveSettings(settingsFileName); unlink(gameCopyFilename); unlink(gamePasteFilename); + if(noEcho) EchoOn(); } RETSIGTYPE TermSizeSigHandler(int sig) @@ -2772,10 +2873,12 @@ Enables icsEnables[] = { { "menuOptions.Hide Thinking", False }, { "menuOptions.Ponder Next Move", False }, #endif - { "menuEngine.Engine #1 Settings", False }, #endif + { "menuEngine.Engine #1 Settings", False }, { "menuEngine.Engine #2 Settings", False }, + { "menuEngine.Load Engine", False }, { "menuEdit.Annotate", False }, + { "menuOptions.Match", False }, { NULL, False } }; @@ -2834,6 +2937,20 @@ Enables gnuEnables[] = { { "menuFile.Mail Move", False }, { "menuFile.Reload CMail Message", False }, + // [HGM] The following have been added to make a switch from ncp to GNU mode possible + { "menuMode.Machine White", True }, + { "menuMode.Machine Black", True }, + { "menuMode.Analysis Mode", True }, + { "menuMode.Analyze File", True }, + { "menuMode.Two Machines", True }, + { "menuMode.Machine Match", True }, + { "menuEngine.Engine #1 Settings", True }, + { "menuEngine.Engine #2 Settings", True }, + { "menuEngine.Hint", True }, + { "menuEngine.Book", True }, + { "menuEngine.Move Now", True }, + { "menuEngine.Retract Move", True }, + { "Action", True }, { NULL, False } }; @@ -2888,7 +3005,7 @@ Enables machineThinkingEnables[] = { { "menuMode.Machine White", False }, { "menuMode.Machine Black", False }, { "menuMode.Two Machines", False }, - { "menuMode.Machine Match", False }, +// { "menuMode.Machine Match", False }, { "menuEngine.Retract Move", False }, { NULL, False } }; @@ -2907,7 +3024,7 @@ Enables userThinkingEnables[] = { { "menuMode.Machine White", True }, { "menuMode.Machine Black", True }, { "menuMode.Two Machines", True }, - { "menuMode.Machine Match", True }, +// { "menuMode.Machine Match", True }, { "menuEngine.Retract Move", True }, { NULL, False } }; @@ -2917,8 +3034,10 @@ void SetICSMode() SetMenuEnables(icsEnables); #if ZIPPY - if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */ + if (appData.zippyPlay && !appData.noChessProgram) { /* [DM] icsEngineAnalyze */ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True); + XtSetSensitive(XtNameToWidget(menuBarWidget, "menuEngine.Engine #1 Settings"), True); + } #endif } @@ -3030,6 +3149,96 @@ NextInHistory() #define Abs(n) ((n)<0 ? -(n) : (n)) +#ifdef ENABLE_NLS +char * +InsertPxlSize(pattern, targetPxlSize) + char *pattern; + int targetPxlSize; +{ + char *base_fnt_lst, strInt[12], *p, *q; + int alternatives, i, len, strIntLen; + + /* + * Replace the "*" (if present) in the pixel-size slot of each + * alternative with the targetPxlSize. + */ + p = pattern; + alternatives = 1; + while ((p = strchr(p, ',')) != NULL) { + alternatives++; + p++; + } + snprintf(strInt, sizeof(strInt), "%d", targetPxlSize); + strIntLen = strlen(strInt); + base_fnt_lst = calloc(1, strlen(pattern) + strIntLen * alternatives + 1); + + p = pattern; + q = base_fnt_lst; + while (alternatives--) { + char *comma = strchr(p, ','); + for (i=0; i<14; i++) { + char *hyphen = strchr(p, '-'); + if (!hyphen) break; + if (comma && hyphen > comma) break; + len = hyphen + 1 - p; + if (i == 7 && *p == '*' && len == 2) { + p += len; + memcpy(q, strInt, strIntLen); + q += strIntLen; + *q++ = '-'; + } else { + memcpy(q, p, len); + p += len; + q += len; + } + } + if (!comma) break; + len = comma + 1 - p; + memcpy(q, p, len); + p += len; + q += len; + } + strcpy(q, p); + + return base_fnt_lst; +} + +XFontSet +CreateFontSet(base_fnt_lst) + char *base_fnt_lst; +{ + XFontSet fntSet; + char **missing_list; + int missing_count; + char *def_string; + + fntSet = XCreateFontSet(xDisplay, base_fnt_lst, + &missing_list, &missing_count, &def_string); + if (appData.debugMode) { + int i, count; + XFontStruct **font_struct_list; + char **font_name_list; + fprintf(debugFP, "Requested font set for list %s\n", base_fnt_lst); + if (fntSet) { + fprintf(debugFP, " got list %s, locale %s\n", + XBaseFontNameListOfFontSet(fntSet), + XLocaleOfFontSet(fntSet)); + count = XFontsOfFontSet(fntSet, &font_struct_list, &font_name_list); + for (i = 0; i < count; i++) { + fprintf(debugFP, " got charset %s\n", font_name_list[i]); + } + } + for (i = 0; i < missing_count; i++) { + fprintf(debugFP, " missing charset %s\n", missing_list[i]); + } + } + if (fntSet == NULL) { + fprintf(stderr, _("Unable to create font set for %s.\n"), base_fnt_lst); + exit(2); + } + return fntSet; +} +#else // not ENABLE_NLS /* * Find a font that matches "pattern" that is as close as * possible to the targetPxlSize. Prefer fonts that are k @@ -3047,39 +3256,12 @@ FindFont(pattern, targetPxlSize) char **fonts, *p, *best, *scalable, *scalableTail; int i, j, nfonts, minerr, err, pxlSize; -#ifdef ENABLE_NLS - char **missing_list; - int missing_count; - char *def_string, *base_fnt_lst, strInt[3]; - XFontSet fntSet; - XFontStruct **fnt_list; - - base_fnt_lst = calloc(1, strlen(pattern) + 3); - snprintf(strInt, sizeof(strInt)/sizeof(strInt[0]), "%d", targetPxlSize); - p = strstr(pattern, "--"); - strncpy(base_fnt_lst, pattern, p - pattern + 2); - strcat(base_fnt_lst, strInt); - strcat(base_fnt_lst, strchr(p + 2, '-')); - - if ((fntSet = XCreateFontSet(xDisplay, - base_fnt_lst, - &missing_list, - &missing_count, - &def_string)) == NULL) { - - fprintf(stderr, _("Unable to create font set.\n")); - exit (2); - } - - nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts); -#else fonts = XListFonts(xDisplay, pattern, 999999, &nfonts); if (nfonts < 1) { fprintf(stderr, _("%s: no fonts match pattern %s\n"), programName, pattern); exit(2); } -#endif best = fonts[0]; scalable = NULL; @@ -3121,15 +3303,10 @@ FindFont(pattern, targetPxlSize) fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"), pattern, targetPxlSize, p); } -#ifdef ENABLE_NLS - if (missing_count > 0) - XFreeStringList(missing_list); - XFreeFontSet(xDisplay, fntSet); -#else - XFreeFontNames(fonts); -#endif + XFreeFontNames(fonts); return p; } +#endif void DeleteGCs() { // [HGM] deletes GCs that are to be remade, to prevent resource leak; @@ -3441,7 +3618,7 @@ void CreateXPMBoard(char *s, int kind) { XpmAttributes attr; attr.valuemask = 0; - if(s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; } + if(!appData.useBitmaps || s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; } if (XpmReadFileToPixmap(xDisplay, xBoardWindow, s, &(xpmBoardBitmap[kind]), NULL, &attr) == 0) { useTexture |= kind + 1; textureW[kind] = attr.width; textureH[kind] = attr.height; } @@ -3760,10 +3937,10 @@ void CreateMenuBarPopup(parent, name, mb) mi = mb->mi; while (mi->string != NULL) { if (strcmp(mi->string, "----") == 0) { - entry = XtCreateManagedWidget(mi->string, smeLineObjectClass, + entry = XtCreateManagedWidget(_(mi->string), smeLineObjectClass, menu, args, j); } else { - XtSetArg(args[j], XtNlabel, XtNewString(mi->string)); + XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); entry = XtCreateManagedWidget(mi->ref, smeBSBObjectClass, menu, args, j+1); XtAddCallback(entry, XtNcallback, @@ -3774,13 +3951,16 @@ void CreateMenuBarPopup(parent, name, mb) } } -Widget CreateMenuBar(mb) +Widget CreateMenuBar(mb, boardWidth) Menu *mb; + int boardWidth; { - int j; - Widget anchor, menuBar; + int i, j, nr = 0, wtot = 0, widths[10]; + Widget menuBar; Arg args[16]; char menuName[MSG_SIZ]; + Dimension w; + Menu *ma = mb; j = 0; XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++; @@ -3794,22 +3974,28 @@ Widget CreateMenuBar(mb) strncat(menuName, mb->ref, MSG_SIZ - strlen(menuName) - 1); j = 0; XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++; - if (tinyLayout) { - char shortName[2]; - shortName[0] = mb->name[0]; - shortName[1] = NULLCHAR; - XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++; - } - else { - XtSetArg(args[j], XtNlabel, XtNewString(mb->name)); j++; - } - + XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++; XtSetArg(args[j], XtNborderWidth, 0); j++; - anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass, + mb->subMenu = XtCreateManagedWidget(mb->name, menuButtonWidgetClass, menuBar, args, j); CreateMenuBarPopup(menuBar, menuName, mb); + j = 0; + XtSetArg(args[j], XtNwidth, &w); j++; + XtGetValues(mb->subMenu, args, j); + wtot += mb->textWidth = widths[nr++] = w; mb++; } + while(wtot > boardWidth - 40) { + int wmax=0, imax=0; + for(i=0; i wmax) wmax = widths[imax=i]; + widths[imax]--; + wtot--; + } + for(i=0; itype == ButtonRelease) menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); else if (event->type == ButtonPress) @@ -3988,6 +4175,7 @@ void WhiteClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { + shiftKey = prms[0][0] & 1; ClockClick(0); } @@ -3997,6 +4185,7 @@ void BlackClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { + shiftKey = prms[0][0] & 1; ClockClick(1); } @@ -4464,6 +4653,12 @@ void DrawSquare(row, column, piece, do_flash) } } if(!partnerUp && marker[row][column]) { + if(appData.monoMode) { + XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? darkSquareGC : lightSquareGC, + x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); + XDrawArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? lightSquareGC : darkSquareGC, + x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); + } else XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); } @@ -4764,6 +4959,7 @@ void HandleUserMove(w, event, prms, nprms) void AnimateUserMove (Widget w, XEvent * event, String * params, Cardinal * nParams) { + if(!PromoScroll(event->xmotion.x, event->xmotion.y)) DragPieceMove(event->xmotion.x, event->xmotion.y); } @@ -4839,6 +5035,14 @@ void CommentPopDown() PopDown(1); } +static char *openName; +FILE *openFP; + +void DelayedLoad() +{ + (void) (*fileProc)(openFP, 0, openName); +} + void FileNamePopUp(label, def, filter, proc, openMode) char *label; char *def; @@ -4849,12 +5053,11 @@ void FileNamePopUp(label, def, filter, proc, openMode) fileProc = proc; /* I can't see a way not */ fileOpenMode = openMode; /* to use globals here */ { // [HGM] use file-selector dialog stolen from Ghostview - char *name; int index; // this is not supported yet - FILE *f; - if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ", - (def[0] ? def : NULL), filter, openMode, NULL, &name)) - (void) (*fileProc)(f, index=0, name); + if(openFP = XsraSelFile(shellWidget, label, NULL, NULL, _("could not open: "), + (def[0] ? def : NULL), filter, openMode, NULL, &openName)) + // [HGM] delay to give expose event opportunity to redraw board after browser-dialog popdown before lengthy load starts + ScheduleDelayedEvent(&DelayedLoad, 50); } } @@ -4941,6 +5144,7 @@ void PromotionPopUp() Position x, y; Dimension bw_width, pw_width; int j; + char *PromoChars = "wglcqrbnkac+=\0"; j = 0; XtSetArg(args[j], XtNwidth, &bw_width); j++; @@ -4964,47 +5168,33 @@ void PromotionPopUp() if(gameInfo.variant != VariantShogi) { if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) { - XawDialogAddButton(dialog, _("Warlord"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("General"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Captain"), PromotionCallback, - (XtPointer) dialog); - } else { - XawDialogAddButton(dialog, _("Queen"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Rook"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Bishop"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Knight"), PromotionCallback, - (XtPointer) dialog); + XawDialogAddButton(dialog, _("Warlord"), PromotionCallback, PromoChars + 0); + XawDialogAddButton(dialog, _("General"), PromotionCallback, PromoChars + 1); + XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback, PromoChars + 2); + XawDialogAddButton(dialog, _("Captain"), PromotionCallback, PromoChars + 3); + } else { + XawDialogAddButton(dialog, _("Queen"), PromotionCallback, PromoChars + 4); + XawDialogAddButton(dialog, _("Rook"), PromotionCallback, PromoChars + 5); + XawDialogAddButton(dialog, _("Bishop"), PromotionCallback, PromoChars + 6); + XawDialogAddButton(dialog, _("Knight"), PromotionCallback, PromoChars + 7); } if (!appData.testLegality || gameInfo.variant == VariantSuicide || - gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || + gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || gameInfo.variant == VariantGiveaway) { - XawDialogAddButton(dialog, _("King"), PromotionCallback, - (XtPointer) dialog); + XawDialogAddButton(dialog, _("King"), PromotionCallback, PromoChars + 8); } if(gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantGothic || gameInfo.variant == VariantCapaRandom) { - XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Chancellor"), PromotionCallback, - (XtPointer) dialog); + XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback, PromoChars + 9); + XawDialogAddButton(dialog, _("Chancellor"), PromotionCallback, PromoChars + 10); } } else // [HGM] shogi { - XawDialogAddButton(dialog, _("Promote"), PromotionCallback, - (XtPointer) dialog); - XawDialogAddButton(dialog, _("Defer"), PromotionCallback, - (XtPointer) dialog); + XawDialogAddButton(dialog, _("Promote"), PromotionCallback, PromoChars + 11); + XawDialogAddButton(dialog, _("Defer"), PromotionCallback, PromoChars + 12); } - XawDialogAddButton(dialog, _("cancel"), PromotionCallback, - (XtPointer) dialog); + XawDialogAddButton(dialog, _("cancel"), PromotionCallback, PromoChars + 13); XtRealizeWidget(promotionShell); CatchDeleteWindow(promotionShell, "PromotionPopDown"); @@ -5040,31 +5230,17 @@ void PromotionCallback(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { - String name; - Arg args[16]; - int promoChar; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); + int promoChar = * (const char *) client_data; PromotionPopDown(); if (fromX == -1) return; - if (strcmp(name, _("cancel")) == 0) { + if (! promoChar) { fromX = fromY = -1; ClearHighlights(); return; - } else if (strcmp(name, _("Knight")) == 0) { - promoChar = 'n'; - } else if (strcmp(name, _("Promote")) == 0) { - promoChar = '+'; - } else if (strcmp(name, _("Defer")) == 0) { - promoChar = '='; - } else { - promoChar = ToLower(name[0]); } - UserMoveEvent(fromX, fromY, toX, toY, promoChar); if (!appData.highlightLastMove || gotPremove) ClearHighlights(); @@ -5268,6 +5444,8 @@ void ModeHighlight() XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1); } oldmode = gameMode; + XtSetArg(args[0], XtNleftBitmap, matchMode && matchGame < appData.matchGames ? xMarkPixmap : None); + XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Machine Match"), args, 1); /* Maybe all the enables should be handled here, not just this one */ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"), @@ -5458,11 +5636,19 @@ SendPositionSelection(Widget w, Atom *selection, Atom *target, *value_return = targets_tmp; *type_return = XA_ATOM; *length_return = 2; +#if 0 + // This code leads to a read of value_return out of bounds on 64-bit systems. + // Other code which I have seen always sets *format_return to 32 independent of + // sizeof(Atom) without adjusting *length_return. For instance see TextConvertSelection() + // at http://cgit.freedesktop.org/xorg/lib/libXaw/tree/src/Text.c -- BJ *format_return = 8 * sizeof(Atom); if (*format_return > 32) { *length_return *= *format_return / 32; *format_return = 32; } +#else + *format_return = 32; +#endif return True; } else { return False; @@ -5567,31 +5753,27 @@ SendGameSelection(Widget w, Atom *selection, Atom *target, *value_return = targets_tmp; *type_return = XA_ATOM; *length_return = 2; +#if 0 + // This code leads to a read of value_return out of bounds on 64-bit systems. + // Other code which I have seen always sets *format_return to 32 independent of + // sizeof(Atom) without adjusting *length_return. For instance see TextConvertSelection() + // at http://cgit.freedesktop.org/xorg/lib/libXaw/tree/src/Text.c -- BJ *format_return = 8 * sizeof(Atom); if (*format_return > 32) { *length_return *= *format_return / 32; *format_return = 32; } +#else + *format_return = 32; +#endif return True; } else { return False; } } -/* note: when called from menu all parameters are NULL, so no clue what the - * Widget which was clicked on was, or what the click event was - */ -void CopyGameProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; +void CopySomething() { - int ret; - - ret = SaveGameToFile(gameCopyFilename, FALSE); - if (!ret) return; - /* * Set both PRIMARY (the selection) and CLIPBOARD, since we don't * have a notion of a game that is selected but not copied. @@ -5609,6 +5791,33 @@ void CopyGameProc(w, event, prms, nprms) NULL/* transfer_done_proc */); } +/* note: when called from menu all parameters are NULL, so no clue what the + * Widget which was clicked on was, or what the click event was + */ +void CopyGameProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + int ret; + + ret = SaveGameToFile(gameCopyFilename, FALSE); + if (!ret) return; + + CopySomething(); +} + +void CopyGameListProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + if(!SaveGameListAsText(fopen(gameCopyFilename, "w"))) return; + CopySomething(); +} + /* function called when the data to Paste is ready */ static void PasteGameCB(Widget w, XtPointer client_data, Atom *selection, @@ -5751,13 +5960,13 @@ void AnalyzeFileProc(w, event, prms, nprms) DisplayError(buf, 0); return; } - Reset(FALSE, TRUE); +// Reset(FALSE, TRUE); #ifndef OPTIONSDIALOG if (!appData.showThinking) ShowThinkingProc(w,event,prms,nprms); #endif AnalyzeFileEvent(); - FileNamePopUp(_("File to analyze"), "", ".pgn .game", LoadGamePopUp, "rb"); +// FileNamePopUp(_("File to analyze"), "", ".pgn .game", LoadGamePopUp, "rb"); AnalysisPeriodicEvent(1); } @@ -5776,12 +5985,7 @@ void MatchProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if(gameMode != BeginningOfGame) { DisplayError(_("You can only start a match from the initial position."), 0); return; } - matchMode = 2; // This is back-end, really - appData.matchGames = appData.defaultMatchGames; - matchGame = 1; - first.matchWins = second.matchWins = 0; - TwoMachinesEvent(); + MatchEvent(2); } void IcsClientProc(w, event, prms, nprms) @@ -6051,6 +6255,37 @@ void BackwardProc(w, event, prms, nprms) BackwardEvent(); } +void TempBackwardProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + if (!TempBackwardActive) { + TempBackwardActive = True; + BackwardEvent(); + } +} + +void TempForwardProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + /* Check to see if triggered by a key release event for a repeating key. + * If so the next queued event will be a key press of the same key at the same time */ + if (XEventsQueued(xDisplay, QueuedAfterReading)) { + XEvent next; + XPeekEvent(xDisplay, &next); + if (next.type == KeyPress && next.xkey.time == event->xkey.time && + next.xkey.keycode == event->xkey.keycode) + return; + } + ForwardEvent(); + TempBackwardActive = False; +} + void ToStartProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6635,17 +6870,18 @@ void AboutProc(w, event, prms, nprms) { char buf[MSG_SIZ]; #if ZIPPY - char *zippy = " (with Zippy code)"; + char *zippy = _(" (with Zippy code)"); #else char *zippy = ""; #endif - snprintf(buf, sizeof(buf), "%s%s\n\n%s\n%s\n%s\n\n%s%s\n%s", - programVersion, zippy, - "Copyright 1991 Digital Equipment Corporation", - "Enhancements Copyright 1992-2009 Free Software Foundation", - "Enhancements Copyright 2005 Alessandro Scotti", - PACKAGE, " is free software and carries NO WARRANTY;", - "see the file COPYING for more information."); + snprintf(buf, sizeof(buf), +_("%s%s\n\n" +"Copyright 1991 Digital Equipment Corporation\n" +"Enhancements Copyright 1992-2009 Free Software Foundation\n" +"Enhancements Copyright 2005 Alessandro Scotti\n\n" +"%s is free software and carries NO WARRANTY;" +"see the file COPYING for more information."), + programVersion, zippy, PACKAGE); ErrorPopUp(_("About XBoard"), buf, FALSE); } @@ -6676,19 +6912,6 @@ void NothingProc(w, event, prms, nprms) return; } -void Iconify(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - fromX = fromY = -1; - XtSetArg(args[0], XtNiconic, True); - XtSetValues(shellWidget, args, 1); -} - void DisplayMessage(message, extMessage) char *message, *extMessage; { @@ -6710,6 +6933,8 @@ void DisplayMessage(message, extMessage) }; }; + safeStrCpy(lastMsg, message, MSG_SIZ); // [HGM] make available + /* need to test if messageWidget already exists, since this function can also be called during the startup, if for example a Xresource is not set up correctly */ @@ -6769,6 +6994,7 @@ void DisplayTitle(text) XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++; XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++; XtSetValues(shellWidget, args, i); + XSync(xDisplay, False); } @@ -7014,6 +7240,7 @@ PlaySound(name) } else { char buf[2048]; char *prefix = "", *sep = ""; + if(appData.soundProgram[0] == NULLCHAR) return; if(!strchr(name, '/')) { prefix = appData.soundDirectory; sep = "/"; } snprintf(buf, sizeof(buf), "%s '%s%s%s' &", appData.soundProgram, prefix, sep, name); system(buf); @@ -7057,15 +7284,29 @@ PlayAlarmSound() } void +PlayTellSound() +{ + PlaySound(appData.soundTell); +} + +void EchoOn() { system("stty echo"); + noEcho = False; } void EchoOff() { system("stty -echo"); + noEcho = True; +} + +void +RunCommand(char *buf) +{ + system(buf); } void @@ -7565,50 +7806,40 @@ int OpenTCP(host, port, pr) #if OMIT_SOCKETS DisplayFatalError(_("Socket support is not configured in"), 0, 2); #else /* !OMIT_SOCKETS */ - int s; - struct sockaddr_in sa; - struct hostent *hp; - unsigned short uport; + struct addrinfo hints; + struct addrinfo *ais, *ai; + int error; + int s=0; ChildProc *cp; - if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) { - return errno; - } - - memset((char *) &sa, (int)0, sizeof(struct sockaddr_in)); - sa.sin_family = AF_INET; - sa.sin_addr.s_addr = INADDR_ANY; - uport = (unsigned short) 0; - sa.sin_port = htons(uport); - if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) { - return errno; - } - - memset((char *) &sa, (int)0, sizeof(struct sockaddr_in)); - if (!(hp = gethostbyname(host))) { - int b0, b1, b2, b3; - if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) { - hp = (struct hostent *) calloc(1, sizeof(struct hostent)); - hp->h_addrtype = AF_INET; - hp->h_length = 4; - hp->h_addr_list = (char **) calloc(2, sizeof(char *)); - hp->h_addr_list[0] = (char *) malloc(4); - hp->h_addr_list[0][0] = b0; - hp->h_addr_list[0][1] = b1; - hp->h_addr_list[0][2] = b2; - hp->h_addr_list[0][3] = b3; - } else { - return ENOENT; - } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + error = getaddrinfo(host, port, &hints, &ais); + if (error != 0) { + /* a getaddrinfo error is not an errno, so can't return it */ + fprintf(debugFP, "getaddrinfo(%s, %s): %s\n", + host, port, gai_strerror(error)); + return ENOENT; + } + + for (ai = ais; ai != NULL; ai = ai->ai_next) { + if ((s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { + error = errno; + continue; + } + if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) { + error = errno; + continue; + } + error = 0; + break; } - sa.sin_family = hp->h_addrtype; - uport = (unsigned short) atoi(port); - sa.sin_port = htons(uport); - memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length); + freeaddrinfo(ais); - if (connect(s, (struct sockaddr *) &sa, - sizeof(struct sockaddr_in)) < 0) { - return errno; + if (error != 0) { + return error; } cp = (ChildProc *) calloc(1, sizeof(ChildProc)); @@ -7617,7 +7848,6 @@ int OpenTCP(host, port, pr) cp->fdFrom = s; cp->fdTo = s; *pr = (ProcRef) cp; - #endif /* !OMIT_SOCKETS */ return 0; @@ -7985,8 +8215,7 @@ CreateAnimVars () /* For XPM pieces, we need bitmaps to use as masks. */ if (useImages) - CreateAnimMasks(info.depth); - xpmDone = 1; + CreateAnimMasks(info.depth), xpmDone = 1; } #ifndef HAVE_USLEEP @@ -8037,6 +8266,12 @@ FrameDelay (time) #endif +void +DoSleep(int n) +{ + FrameDelay(n); +} + /* Convert board position to corner of screen rect and color */ static void @@ -8478,8 +8713,8 @@ AnimateMove(board, fromX, fromY, toX, toY) } void -DragPieceBegin(x, y) - int x; int y; +DragPieceBegin(x, y, instantly) + int x; int y; Boolean instantly; { int boardX, boardY, color; XPoint corner; @@ -8531,6 +8766,16 @@ DragPieceBegin(x, y) } } +void +ChangeDragPiece(ChessSquare piece) +{ + Pixmap mask; + player.dragPiece = piece; + /* The piece will be drawn using its own bitmap as a matte */ + SelectGCMask(piece, &player.pieceGC, &player.outlineGC, &mask); + XSetClipMask(xDisplay, player.pieceGC, mask); +} + static void DragPieceMove(x, y) int x; int y; @@ -8672,7 +8917,7 @@ void SquareToPos(int rank, int file, int *x, int *y) /* Draw an arrow between two points using current settings */ void DrawArrowBetweenPoints( int s_x, int s_y, int d_x, int d_y ) { - XPoint arrow[7]; + XPoint arrow[8]; double dx, dy, j, k, x, y; if( d_x == s_x ) { @@ -8769,6 +9014,7 @@ void DrawArrowBetweenPoints( int s_x, int s_y, int d_x, int d_y ) } XFillPolygon(xDisplay, xBoardWindow, highlineGC, arrow, 7, Nonconvex, CoordModeOrigin); + if(appData.monoMode) arrow[7] = arrow[0], XDrawLines(xDisplay, xBoardWindow, darkSquareGC, arrow, 8, CoordModeOrigin); // Polygon( hdc, arrow, 7 ); } @@ -8833,3 +9079,9 @@ void DrawArrowHighlight(int fromX, int fromY, int toX,int toY) if( IsDrawArrowEnabled() && fromX >= 0 && fromY >= 0 && toX >= 0 && toY >= 0) DrawArrowBetweenSquares(fromX, fromY, toX, toY); } + +void UpdateLogos(int displ) +{ + return; // no logos in XBoard yet +} +