X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=85088b838b1dfd52063107258d2db6e7fc7554dc;hb=e70077aab0199817f37aef9ed0bdba1bbca93b45;hp=cbf38fa6412c80971248410f2a2369379bd7006d;hpb=376a6b54e45239d67cb491320e4c965fe610d7a1;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index cbf38fa..85088b8 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -73,6 +73,7 @@ #include #include #include +#include #if __GNUC__ #include @@ -105,7 +106,6 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber); VOID NewVariantPopup(HWND hwnd); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, /*char*/int promoChar)); -void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames); void DisplayMove P((int moveNumber)); Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); void ChatPopUp P((char *s)); @@ -124,9 +124,10 @@ typedef struct { POINT pos; /* window coordinates of current pos */ POINT lastpos; /* window coordinates of last pos - used for clipping */ POINT from; /* board coordinates of the piece's orig pos */ + ChessSquare piece; } DragInfo; -static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1} }; +static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, EmptySquare }; typedef struct { POINT sq[2]; /* board coordinates of from, to squares */ @@ -187,6 +188,7 @@ COLORREF lightSquareColor, darkSquareColor, whitePieceColor, HPALETTE hPal; ColorClass currentColorClass; +static HWND savedHwnd; HWND hCommPort = NULL; /* currently open comm port */ static HWND hwndPause; /* pause button */ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */ @@ -225,6 +227,271 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOA #endif #endif +#define INTERNATIONAL + +#ifdef INTERNATIONAL +# define _(s) T_(s) +# define N_(s) s +#else +# define _(s) s +# define N_(s) s +# define T_(s) s +# define Translate(x, y) +# define LoadLanguageFile(s) +#endif + +#ifdef INTERNATIONAL + +Boolean barbaric; // flag indicating if translation is needed + +// list of item numbers used in each dialog (used to alter language at run time) + +#define ABOUTBOX -1 /* not sure why these are needed */ +#define ABOUTBOX2 -1 + +int dialogItems[][41 ] = { +{ ABOUTBOX, IDOK, OPT_MESS, 400 }, +{ DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, + OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors, IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, +{ DLG_LoadOptions, OPT_Autostep, OPT_AStext1, OPT_Exact, OPT_Subset, OPT_Struct, OPT_Material, OPT_Range, OPT_Difference, + OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds, IDOK, IDCANCEL }, +{ DLG_SaveOptions, OPT_Autosave, OPT_AVPrompt, OPT_AVToFile, OPT_AVBrowse, + 801, OPT_PGN, OPT_Old, OPT_OutOfBookInfo, IDOK, IDCANCEL }, +{ 1536, 1090, IDC_Directories, 1089, 1091, IDOK, IDCANCEL, 1038, IDC_IndexNr, 1037 }, +{ DLG_CommPort, IDOK, IDCANCEL, IDC_Port, IDC_Rate, IDC_Bits, IDC_Parity, + IDC_Stop, IDC_Flow, OPT_SerialHelp }, +{ DLG_EditComment, IDOK, OPT_CancelComment, OPT_ClearComment, OPT_EditComment }, +{ DLG_PromotionKing, PB_Chancellor, PB_Archbishop, PB_Queen, PB_Rook, + PB_Bishop, PB_Knight, PB_King, IDCANCEL, IDC_Yes, IDC_No, IDC_Centaur }, +{ ABOUTBOX2, IDC_ChessBoard }, +{ DLG_GameList, OPT_GameListLoad, OPT_GameListPrev, OPT_GameListNext, + OPT_GameListClose, IDC_GameListDoFilter }, +{ DLG_EditTags, IDOK, OPT_TagsCancel, OPT_EditTags }, +{ DLG_Error, IDOK }, +{ DLG_Colorize, IDOK, IDCANCEL, OPT_ChooseColor, OPT_Bold, OPT_Italic, + OPT_Underline, OPT_Strikeout, OPT_Sample }, +{ DLG_Question, IDOK, IDCANCEL, OPT_QuestionText }, +{ DLG_Startup, IDC_Welcome, OPT_ChessEngine, OPT_ChessServer, OPT_View, + IDC_SPECIFY_ENG_STATIC, IDC_SPECIFY_SERVER_STATIC, OPT_AnyAdditional, + IDOK, IDCANCEL, IDM_HELPCONTENTS }, +{ DLG_IndexNumber, IDC_Index }, +{ DLG_TypeInMove, IDOK, IDCANCEL }, +{ DLG_TypeInName, IDOK, IDCANCEL }, +{ DLG_Sound, IDC_Event, OPT_NoSound, OPT_DefaultBeep, OPT_BuiltInSound, + OPT_WavFile, OPT_BrowseSound, OPT_DefaultSounds, IDOK, IDCANCEL, OPT_PlaySound }, +{ DLG_GeneralOptions, IDOK, IDCANCEL, OPT_AlwaysOnTop, OPT_HighlightLastMove, + OPT_AlwaysQueen, OPT_PeriodicUpdates, OPT_AnimateDragging, OPT_PonderNextMove, + OPT_AnimateMoving, OPT_PopupExitMessage, OPT_AutoFlag, OPT_PopupMoveErrors, + OPT_AutoFlipView, OPT_ShowButtonBar, OPT_AutoRaiseBoard, OPT_ShowCoordinates, + OPT_Blindfold, OPT_ShowThinking, OPT_HighlightDragging, OPT_TestLegality, + OPT_SaveExtPGN, OPT_HideThinkFromHuman, OPT_ExtraInfoInMoveHistory, + OPT_HighlightMoveArrow, OPT_AutoLogo ,OPT_SmartMove }, +{ DLG_IcsOptions, IDOK, IDCANCEL, OPT_AutoComment, OPT_AutoKibitz, OPT_AutoObserve, + OPT_GetMoveList, OPT_LocalLineEditing, OPT_QuietPlay, OPT_SeekGraph, OPT_AutoRefresh, + OPT_BgObserve, OPT_DualBoard, OPT_Premove, OPT_PremoveWhite, OPT_PremoveBlack, + OPT_SmartMove, OPT_IcsAlarm, IDC_Sec, OPT_ChooseShoutColor, OPT_ChooseSShoutColor, + OPT_ChooseChannel1Color, OPT_ChooseChannelColor, OPT_ChooseKibitzColor, + OPT_ChooseTellColor, OPT_ChooseChallengeColor, OPT_ChooseRequestColor, + OPT_ChooseSeekColor, OPT_ChooseNormalColor, OPT_ChooseBackgroundColor, + OPT_DefaultColors, OPT_DontColorize, IDC_Boxes, GPB_Colors, GPB_Premove, + GPB_General, GPB_Alarm }, +{ DLG_BoardOptions, IDOK, IDCANCEL, OPT_SizeTiny, OPT_SizeTeeny, OPT_SizeDinky, + OPT_SizePetite, OPT_SizeSlim, OPT_SizeSmall, OPT_SizeMediocre, OPT_SizeMiddling, + OPT_SizeAverage, OPT_SizeModerate, OPT_SizeMedium, OPT_SizeBulky, OPT_SizeLarge, + OPT_SizeBig, OPT_SizeHuge, OPT_SizeGiant, OPT_SizeColossal, OPT_SizeTitanic, + OPT_ChooseLightSquareColor, OPT_ChooseDarkSquareColor, OPT_ChooseWhitePieceColor, + OPT_ChooseBlackPieceColor, OPT_ChooseHighlightSquareColor, OPT_ChoosePremoveHighlightColor, + OPT_Monochrome, OPT_AllWhite, OPT_UpsideDown, OPT_DefaultBoardColors, GPB_Colors, + IDC_Light, IDC_Dark, IDC_White, IDC_Black, IDC_High, IDC_PreHigh, GPB_Size, OPT_Bitmaps, OPT_PieceFont }, +{ DLG_NewVariant, IDOK, IDCANCEL, OPT_VariantNormal, OPT_VariantFRC, OPT_VariantWildcastle, + OPT_VariantNocastle, OPT_VariantLosers, OPT_VariantGiveaway, OPT_VariantSuicide, + OPT_Variant3Check, OPT_VariantTwoKings, OPT_VariantAtomic, OPT_VariantCrazyhouse, + OPT_VariantBughouse, OPT_VariantTwilight, OPT_VariantShogi, OPT_VariantSuper, + OPT_VariantKnightmate, OPT_VariantBerolina, OPT_VariantCylinder, OPT_VariantFairy, + OPT_VariantMakruk, OPT_VariantGothic, OPT_VariantCapablanca, OPT_VariantJanus, + OPT_VariantCRC, OPT_VariantFalcon, OPT_VariantCourier, OPT_VariantGreat, OPT_VariantSChess, + OPT_VariantShatranj, OPT_VariantXiangqi, GPB_Variant, GPB_Board, IDC_Height, + IDC_Width, IDC_Hand, IDC_Pieces, IDC_Def }, +{ DLG_Fonts, IDOK, IDCANCEL, OPT_ChooseClockFont, OPT_ChooseMessageFont, + OPT_ChooseCoordFont, OPT_ChooseTagFont, OPT_ChooseCommentsFont, OPT_ChooseConsoleFont, OPT_ChooseMoveHistoryFont, OPT_DefaultFonts, + OPT_ClockFont, OPT_MessageFont, OPT_CoordFont, OPT_EditTagsFont, OPT_ChoosePieceFont, OPT_MessageFont8, + OPT_SampleGameListFont, OPT_ChooseGameListFont, OPT_MessageFont7, + OPT_CommentsFont, OPT_MessageFont5, GPB_Current, GPB_All, OPT_MessageFont6 }, +{ DLG_NewGameFRC, IDC_NFG_Label, IDC_NFG_Random, IDOK, IDCANCEL }, +{ DLG_GameListOptions, IDC_GLT, IDC_GLT_Up, IDC_GLT_Down, IDC_GLT_Restore, + IDC_GLT_Default, IDOK, IDCANCEL, IDC_GLT_RestoreTo }, +{ DLG_MoveHistory }, +{ DLG_EvalGraph }, +{ DLG_EngineOutput, IDC_EngineLabel1, IDC_Engine1_NPS, IDC_EngineLabel2, IDC_Engine2_NPS }, +{ DLG_Chat, IDC_Partner, IDC_Clear, IDC_Send, }, +{ DLG_EnginePlayOptions, IDC_EpPonder, IDC_EpShowThinking, IDC_EpHideThinkingHuman, + IDC_EpPeriodicUpdates, GPB_Adjudications, IDC_Draw, IDC_Moves, IDC_Threshold, + IDC_Centi, IDC_TestClaims, IDC_DetectMates, IDC_MaterialDraws, IDC_TrivialDraws, + GPB_Apply, IDC_Rule, IDC_Repeats, IDC_ScoreAbs1, IDC_ScoreAbs2, IDOK, IDCANCEL }, +{ DLG_OptionsUCI, IDC_PolyDir, IDC_BrowseForPolyglotDir, IDC_Hash, IDC_Path, + IDC_BrowseForEGTB, IDC_Cache, IDC_UseBook, IDC_BrowseForBook, IDC_CPU, IDC_OwnBook1, + IDC_OwnBook2, IDC_Depth, IDC_Variation, IDC_DefGames, IDOK, IDCANCEL }, +{ 0 } +}; + +static char languageBuf[70000], *foreign[1000], *english[1000], *languageFile[MSG_SIZ]; +static int lastChecked; +static char oldLanguage[MSG_SIZ], *menuText[10][30]; +extern int tinyLayout; +extern char * menuBarText[][10]; + +void +LoadLanguageFile(char *name) +{ //load the file with translations, and make a list of the strings to be translated, and their translations + FILE *f; + int i=0, j=0, n=0, k; + char buf[MSG_SIZ]; + + if(!name || name[0] == NULLCHAR) return; + snprintf(buf, MSG_SIZ, "%s%s", name, strchr(name, '.') ? "" : ".lng"); // auto-append lng extension + appData.language = oldLanguage; + if(!strcmp(buf, oldLanguage)) { barbaric = 1; return; } // this language already loaded; just switch on + if((f = fopen(buf, "r")) == NULL) return; + while((k = fgetc(f)) != EOF) { + if(i >= sizeof(languageBuf)) { DisplayError("Language file too big", 0); return; } + languageBuf[i] = k; + if(k == '\n') { + if(languageBuf[n] == '"' && languageBuf[i-1] == '"') { + char *p; + if(p = strstr(languageBuf + n + 1, "\" === \"")) { + if(p > languageBuf+n+2 && p+8 < languageBuf+i) { + if(j >= sizeof(english)) { DisplayError("Too many translated strings", 0); return; } + english[j] = languageBuf + n + 1; *p = 0; + foreign[j++] = p + 7; languageBuf[i-1] = 0; +//if(appData.debugMode) fprintf(debugFP, "translation: replace '%s' by '%s'\n", english[j-1], foreign[j-1]); + } + } + } + n = i + 1; + } else if(i > 0 && languageBuf[i-1] == '\\') { + switch(k) { + case 'n': k = '\n'; break; + case 'r': k = '\r'; break; + case 't': k = '\t'; break; + } + languageBuf[--i] = k; + } + i++; + } + fclose(f); + barbaric = (j != 0); + safeStrCpy(oldLanguage, buf, sizeof(oldLanguage)/sizeof(oldLanguage[0]) ); +} + +char * +T_(char *s) +{ // return the translation of the given string + // efficiency can be improved a lot... + int i=0; + static char buf[MSG_SIZ]; +//if(appData.debugMode) fprintf(debugFP, "T_(%s)\n", s); + if(!barbaric) return s; + if(!s) return ""; // sanity + while(english[i]) { + if(!strcmp(s, english[i])) return foreign[i]; + if(english[i][0] == '%' && strstr(s, english[i]+1) == s) { // allow translation of strings with variable ending + snprintf(buf, MSG_SIZ, "%s%s", foreign[i], s + strlen(english[i]+1)); // keep unmatched portion + return buf; + } + i++; + } + return s; +} + +void +Translate(HWND hDlg, int dialogID) +{ // translate all text items in the given dialog + int i=0, j, k; + char buf[MSG_SIZ], *s; + if(!barbaric) return; + while(dialogItems[i][0] && dialogItems[i][0] != dialogID) i++; // find the dialog description + if(dialogItems[i][0] != dialogID) return; // unknown dialog, should not happen + GetWindowText( hDlg, buf, MSG_SIZ ); + s = T_(buf); + if(strcmp(buf, s)) SetWindowText(hDlg, s); // replace by translated string (if different) + for(j=1; k=dialogItems[i][j]; j++) { // translate all listed dialog items + GetDlgItemText(hDlg, k, buf, MSG_SIZ); + if(strlen(buf) == 0) continue; + s = T_(buf); + if(strcmp(buf, s)) SetDlgItemText(hDlg, k, s); // replace by translated string (if different) + } +} + +HMENU +TranslateOneMenu(int i, HMENU subMenu) +{ + int j; + static MENUITEMINFO info; + + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STATE | MIIM_TYPE; + for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ + char buf[MSG_SIZ]; + info.dwTypeData = buf; + info.cch = sizeof(buf); + GetMenuItemInfo(subMenu, j, TRUE, &info); + if(i < 10) { + if(menuText[i][j]) safeStrCpy(buf, menuText[i][j], sizeof(buf)/sizeof(buf[0]) ); + else menuText[i][j] = strdup(buf); // remember original on first change + } + if(buf[0] == NULLCHAR) continue; + info.dwTypeData = T_(buf); + info.cch = strlen(buf)+1; + SetMenuItemInfo(subMenu, j, TRUE, &info); + } + return subMenu; +} + +void +TranslateMenus(int addLanguage) +{ + int i; + WIN32_FIND_DATA fileData; + HANDLE hFind; +#define IDM_English 1970 + if(1) { + HMENU mainMenu = GetMenu(hwndMain); + for (i=GetMenuItemCount(mainMenu)-1; i>=0; i--) { + HMENU subMenu = GetSubMenu(mainMenu, i); + ModifyMenu(mainMenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP|EnableMenuItem(mainMenu, i, MF_BYPOSITION), + (UINT) subMenu, T_(menuBarText[tinyLayout][i])); + TranslateOneMenu(i, subMenu); + } + DrawMenuBar(hwndMain); + } + + if(!addLanguage) return; + if((hFind = FindFirstFile("*.LNG", &fileData)) != INVALID_HANDLE_VALUE) { + HMENU mainMenu = GetMenu(hwndMain); + HMENU subMenu = GetSubMenu(mainMenu, GetMenuItemCount(mainMenu)-1); + AppendMenu(subMenu, MF_SEPARATOR, (UINT_PTR) 0, NULL); + AppendMenu(subMenu, MF_ENABLED|MF_STRING|(barbaric?MF_UNCHECKED:MF_CHECKED), (UINT_PTR) IDM_English, (LPCTSTR) "English"); + i = 0; lastChecked = IDM_English; + do { + char *p, *q = fileData.cFileName; + int checkFlag = MF_UNCHECKED; + languageFile[i] = strdup(q); + if(barbaric && !strcmp(oldLanguage, q)) { + checkFlag = MF_CHECKED; + lastChecked = IDM_English + i + 1; + CheckMenuItem(mainMenu, IDM_English, MF_BYCOMMAND|MF_UNCHECKED); + } + *q = ToUpper(*q); while(*++q) *q = ToLower(*q); + p = strstr(fileData.cFileName, ".lng"); + if(p) *p = 0; + AppendMenu(subMenu, MF_ENABLED|MF_STRING|checkFlag, (UINT_PTR) IDM_English + ++i, (LPCTSTR) fileData.cFileName); + } while(FindNextFile(hFind, &fileData)); + FindClose(hFind); + } +} + +#endif + typedef struct { char *name; int squareSize; @@ -260,24 +527,24 @@ SizeInfo sizeInfo[] = #define MF(x) {x, {{0,}, 0. }, {0, }, 0} MyFont fontRec[NUM_SIZES][NUM_FONTS] = { - { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL) }, + { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL), MF (GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, }; MyFont *font[NUM_SIZES][NUM_FONTS]; @@ -302,10 +569,10 @@ MyButtonDesc buttonDesc[N_BUTTONS] = }; int tinyLayout = 0, smallLayout = 0; -#define MENU_BAR_ITEMS 7 +#define MENU_BAR_ITEMS 9 char *menuBarText[2][MENU_BAR_ITEMS+1] = { - { "&File", "&Mode", "&Action", "&Step", "&Options", "&Help", NULL }, - { "&F", "&M", "&A", "&S", "&O", "&H", NULL }, + { N_("&File"), N_("&Edit"), N_("&View"), N_("&Mode"), N_("&Action"), N_("E&ngine"), N_("&Options"), N_("&Help"), NULL }, + { N_("&F"), N_("&E"), N_("&V"), N_("&M"), N_("&A"), N_("&N"), N_("&O"), N_("&H"), NULL }, }; @@ -313,17 +580,17 @@ MySound sounds[(int)NSoundClasses]; MyTextAttribs textAttribs[(int)NColorClasses]; MyColorizeAttribs colorizeAttribs[] = { - { (COLORREF)0, 0, "Shout Text" }, - { (COLORREF)0, 0, "SShout/CShout" }, - { (COLORREF)0, 0, "Channel 1 Text" }, - { (COLORREF)0, 0, "Channel Text" }, - { (COLORREF)0, 0, "Kibitz Text" }, - { (COLORREF)0, 0, "Tell Text" }, - { (COLORREF)0, 0, "Challenge Text" }, - { (COLORREF)0, 0, "Request Text" }, - { (COLORREF)0, 0, "Seek Text" }, - { (COLORREF)0, 0, "Normal Text" }, - { (COLORREF)0, 0, "None" } + { (COLORREF)0, 0, N_("Shout Text") }, + { (COLORREF)0, 0, N_("SShout/CShout") }, + { (COLORREF)0, 0, N_("Channel 1 Text") }, + { (COLORREF)0, 0, N_("Channel Text") }, + { (COLORREF)0, 0, N_("Kibitz Text") }, + { (COLORREF)0, 0, N_("Tell Text") }, + { (COLORREF)0, 0, N_("Challenge Text") }, + { (COLORREF)0, 0, N_("Request Text") }, + { (COLORREF)0, 0, N_("Seek Text") }, + { (COLORREF)0, 0, N_("Normal Text") }, + { (COLORREF)0, 0, N_("None") } }; @@ -394,7 +661,6 @@ LRESULT CALLBACK StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); VOID APIENTRY MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def); void ParseIcsTextMenu(char *icsTextMenuString); -VOID PopUpMoveDialog(char firstchar); VOID PopUpNameDialog(char firstchar); VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca); @@ -471,7 +737,8 @@ void ThawUI() #define JAWS_INIT #define JAWS_ARGS #define JAWS_ALT_INTERCEPT -#define JAWS_KB_NAVIGATION +#define JAWS_KBUP_NAVIGATION +#define JAWS_KBDOWN_NAVIGATION #define JAWS_MENU_ITEMS #define JAWS_SILENCE #define JAWS_REPLAY @@ -509,6 +776,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, } JAWS_INIT + TranslateMenus(1); // InitCommonControlsEx(&ex); InitCommonControls(); @@ -629,14 +897,19 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, void SetUserLogo() { // update user logo if necessary - static char oldUserName[MSG_SIZ], *curName; + static char oldUserName[MSG_SIZ], dir[MSG_SIZ], *curName; if(appData.autoLogo) { curName = UserName(); if(strcmp(curName, oldUserName)) { - sprintf(oldUserName, "logos\\%s.bmp", curName); + GetCurrentDirectory(MSG_SIZ, dir); + SetCurrentDirectory(installDir); + snprintf(oldUserName, MSG_SIZ, "logos\\%s.bmp", curName); userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - strcpy(oldUserName, curName); + safeStrCpy(oldUserName, curName, sizeof(oldUserName)/sizeof(oldUserName[0]) ); + if(userLogo == NULL) + userLogo = LoadImage( 0, "logos\\dummy.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + SetCurrentDirectory(dir); /* return to prev directory */ } } } @@ -693,6 +966,56 @@ EnsureOnScreen(int *x, int *y, int minX, int minY) if (*y < minY) *y = minY; } +VOID +LoadLogo(ChessProgramState *cps, int n, Boolean ics) +{ + char buf[MSG_SIZ], dir[MSG_SIZ]; + GetCurrentDirectory(MSG_SIZ, dir); + SetCurrentDirectory(installDir); + if( appData.logo[n] && appData.logo[n][0] != NULLCHAR) { + cps->programLogo = LoadImage( 0, appData.logo[n], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + + if (cps->programLogo == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.logo[n] ); + } + } else if(appData.autoLogo) { + if(ics) { // [HGM] logo: in ICS mode second can be used for ICS + sprintf(buf, "logos\\%s.bmp", appData.icsHost); + cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } else + if(appData.directory[n] && appData.directory[n][0]) { + SetCurrentDirectory(appData.directory[n]); + cps->programLogo = LoadImage( 0, "logo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } + } + SetCurrentDirectory(dir); /* return to prev directory */ +} + +VOID +InitTextures() +{ + ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) ); + backTextureSquareSize = 0; // kludge to force recalculation of texturemode + + if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) { + liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + liteBackTextureMode = appData.liteBackTextureMode; + + if (liteBackTexture == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile ); + } + } + + if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) { + darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + darkBackTextureMode = appData.darkBackTextureMode; + + if (darkBackTexture == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile ); + } + } +} + BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) { @@ -728,6 +1051,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) setbuf(debugFP, NULL); } + LoadLanguageFile(appData.language); + InitBackEnd1(); // InitEngineUCI( installDir, &first ); // [HGM] incorporated in InitBackEnd1() @@ -746,37 +1071,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } /* [HGM] logo: Load logos if specified (must be done before InitDrawingSizes) */ - if( appData.firstLogo && appData.firstLogo[0] != NULLCHAR) { - first.programLogo = LoadImage( 0, appData.firstLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - - if (first.programLogo == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.firstLogo ); - } - } else if(appData.autoLogo) { - if(appData.firstDirectory && appData.firstDirectory[0]) { - char buf[MSG_SIZ]; - sprintf(buf, "%s/logo.bmp", appData.firstDirectory); - first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } - } - - if( appData.secondLogo && appData.secondLogo[0] != NULLCHAR) { - second.programLogo = LoadImage( 0, appData.secondLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - - if (second.programLogo == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo ); - } - } else if(appData.autoLogo) { - char buf[MSG_SIZ]; - if(appData.icsActive) { // [HGM] logo: in ICS mode second can be used for ICS - sprintf(buf, "logos\\%s.bmp", appData.icsHost); - second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } else - if(appData.secondDirectory && appData.secondDirectory[0]) { - sprintf(buf, "%s\\logo.bmp", appData.secondDirectory); - second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } - } + LoadLogo(&first, 0, FALSE); + LoadLogo(&second, 1, appData.icsActive); SetUserLogo(); @@ -803,25 +1099,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS); /* [AS] Load textures if specified */ - ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) ); - - if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) { - liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - liteBackTextureMode = appData.liteBackTextureMode; - - if (liteBackTexture == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile ); - } - } - - if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) { - darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - darkBackTextureMode = appData.darkBackTextureMode; - - if (darkBackTexture == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile ); - } - } + InitTextures(); mysrandom( (unsigned) time(NULL) ); @@ -863,7 +1141,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) ShowWindow(hwndConsole, nCmdShow); if(appData.chatBoxes) { // [HGM] chat: open chat boxes char buf[MSG_SIZ], *p = buf, *q; - strcpy(buf, appData.chatBoxes); + safeStrCpy(buf, appData.chatBoxes, sizeof(buf)/sizeof(buf[0]) ); do { q = strchr(p, ';'); if(q) *q++ = 0; @@ -923,7 +1201,7 @@ LFfromMFP(LOGFONT* lf, MyFontParams *mfp) lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; lf->lfQuality = DEFAULT_QUALITY; lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; - strcpy(lf->lfFaceName, mfp->faceName); + safeStrCpy(lf->lfFaceName, mfp->faceName, sizeof(lf->lfFaceName)/sizeof(lf->lfFaceName[0]) ); } void @@ -968,7 +1246,7 @@ ParseFontName(char *name, MyFontParams *mfp) q = strchr(p, ':'); if (q) { if (q - p >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name, TRUE); memcpy(mfp->faceName, p, q - p); mfp->faceName[q - p] = NULLCHAR; p = q + 1; @@ -977,12 +1255,12 @@ ParseFontName(char *name, MyFontParams *mfp) while (*p && !isdigit(*p)) { *q++ = *p++; if (q - mfp->faceName >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name, TRUE); } while (q > mfp->faceName && q[-1] == ' ') q--; *q = NULLCHAR; } - if (!*p) ExitArgError("Font point size missing:", name); + if (!*p) ExitArgError(_("Font point size missing:"), name, TRUE); mfp->pointSize = (float) atof(p); mfp->bold = (strchr(p, 'b') != NULL); mfp->italic = (strchr(p, 'i') != NULL); @@ -1039,7 +1317,7 @@ ParseColorName(char *name) &red, &green, &blue); } if (count != 3) { - sprintf(buf, "Can't parse color name %s", name); + snprintf(buf, MSG_SIZ, _("Can't parse color name %s"), name); DisplayError(buf, 0); return RGB(0, 0, 0); } @@ -1088,7 +1366,7 @@ ParseBoardSize(void *addr, char *name) } bs++; } - ExitArgError("Unrecognized board size value", name); + ExitArgError(_("Unrecognized board size value"), name, TRUE); } void @@ -1222,13 +1500,18 @@ PrintCommPortSettings(FILE *f, char *name) int MySearchPath(char *installDir, char *name, char *fullname) { - char *dummy, buf[MSG_SIZ]; - if(name[0] == '%' && strchr(name+1, '%')) { // [HGM] recognize %*% as environment variable - strcpy(buf, name+1); - *strchr(buf, '%') = 0; - installDir = getenv(buf); - sprintf(fullname, "%s\\%s", installDir, strchr(name+1, '%')+1); - return strlen(fullname); + char *dummy, buf[MSG_SIZ], *p = name, *q; + if(name[0]== '%') { + fullname[0] = 0; // [HGM] first expand any environment variables in the given name + while(*p == '%' && (q = strchr(p+1, '%'))) { // [HGM] recognize %*% as environment variable + safeStrCpy(buf, p+1, sizeof(buf)/sizeof(buf[0]) ); + *strchr(buf, '%') = 0; + strcat(fullname, getenv(buf)); + p = q+1; while(*p == '\\') { strcat(fullname, "\\"); p++; } + } + strcat(fullname, p); // after environment variables (if any), take the remainder of the given name + if(appData.debugMode) fprintf(debugFP, "name = '%s', expanded name = '%s'\n", name, fullname); + return (int) strlen(fullname); } return (int) SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy); } @@ -1251,6 +1534,7 @@ PopUpStartupDialog() { FARPROC lpProc; + LoadLanguageFile(appData.language); lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst); DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc); FreeProcInstance(lpProc); @@ -1703,7 +1987,8 @@ void CreatePiecesFromFont() return; } - if( appData.renderPiecesWithFont == NULL || appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) { + if( !appData.useFont || appData.renderPiecesWithFont == NULL || + appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) { fontBitmapSquareSize = -1; return; } @@ -1805,11 +2090,11 @@ DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix) { char name[128]; - sprintf(name, "%s%d%s", piece, squareSize, suffix); + snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix); if (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0 && strcmp(name, "k80s") == 0) { - strcpy(name, "tim"); + safeStrCpy(name, "tim", sizeof(name)/sizeof(name[0]) ); } return LoadBitmap(hinst, name); } @@ -1826,7 +2111,7 @@ InsertInPalette(COLORREF color) LPPALETTEENTRY pe = &(pLogPal->palPalEntry[pLogPal->palNumEntries]); if (pLogPal->palNumEntries++ >= PALETTESIZE) { - DisplayFatalError("Too many colors", 0, 1); + DisplayFatalError(_("Too many colors"), 0, 1); pLogPal->palNumEntries--; return; } @@ -1955,7 +2240,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) } if (tinyLayout != oldTinyLayout) { - long style = GetWindowLong(hwndMain, GWL_STYLE); + long style = GetWindowLongPtr(hwndMain, GWL_STYLE); if (tinyLayout) { style &= ~WS_SYSMENU; InsertMenu(hmenu, IDM_Exit, MF_BYCOMMAND, IDM_Minimize, @@ -1964,11 +2249,11 @@ InitDrawingSizes(BoardSize boardSize, int flags) style |= WS_SYSMENU; RemoveMenu(hmenu, IDM_Minimize, MF_BYCOMMAND); } - SetWindowLong(hwndMain, GWL_STYLE, style); + SetWindowLongPtr(hwndMain, GWL_STYLE, style); for (i=0; menuBarText[tinyLayout][i]; i++) { ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, - (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]); + (UINT)GetSubMenu(hmenu, i), T_(menuBarText[tinyLayout][i])); } DrawMenuBar(hwndMain); } @@ -1979,14 +2264,14 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* Get text area sizes */ hdc = GetDC(hwndMain); if (appData.clockMode) { - sprintf(buf, "White: %s", TimeString(23*60*60*1000L)); + snprintf(buf, MSG_SIZ, _("White: %s"), TimeString(23*60*60*1000L)); } else { - sprintf(buf, "White"); + snprintf(buf, MSG_SIZ, _("White")); } oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf); GetTextExtentPoint(hdc, buf, strlen(buf), &clockSize); SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf); - str = "We only care about the height here"; + str = _("We only care about the height here"); GetTextExtentPoint(hdc, str, strlen(str), &messageSize); SelectObject(hdc, oldFont); ReleaseDC(hwndMain, hdc); @@ -2113,7 +2398,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i), messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain, (HMENU) buttonDesc[i].id, - (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL); + (HINSTANCE) GetWindowLongPtr(hwndMain, GWLP_HINSTANCE), NULL); if (tinyLayout) { SendMessage(buttonDesc[i].hwnd, WM_SETFONT, (WPARAM)font[boardSize][MESSAGE_FONT]->hf, @@ -2122,7 +2407,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) if (buttonDesc[i].id == IDM_Pause) hwndPause = buttonDesc[i].hwnd; buttonDesc[i].wndproc = (WNDPROC) - SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc); + SetWindowLongPtr(buttonDesc[i].hwnd, GWLP_WNDPROC, (LONG_PTR) ButtonProc); } } if (gridPen != NULL) DeleteObject(gridPen); @@ -2203,7 +2488,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "w"); pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "w"); pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "w"); - if( !strcmp(appData.variant, "shogi") && (squareSize==72 || squareSize==49)) { + if( gameInfo.variant == VariantShogi && squareSize <= 72 && squareSize >= 33) { // in Shogi, Hijack the unused Queen for Lance pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "s"); pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "o"); @@ -2230,14 +2515,24 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o"); pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w"); } else { // Smirf-like - pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); - pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); - pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + if(gameInfo.variant == VariantSChess) { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "w"); + } else { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + } } if(gameInfo.variant == VariantGothic) { // Vortex-like pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "o"); pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "w"); + } else if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "s"); + pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "o"); + pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "w"); } else { // WinBoard standard pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "o"); @@ -2413,8 +2708,8 @@ SquareToPos(int row, int column, int * x, int * y) VOID DrawCoordsOnDC(HDC hdc) { - static char files[24] = {'0', '1','2','3','4','5','6','7','8','9','0','1','1','0','9','8','7','6','5','4','3','2','1','0'}; - static char ranks[24] = {'l', 'k','j','i','h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h','i','j','k','l'}; + static char files[] = "0123456789012345678901221098765432109876543210"; + static char ranks[] = "wvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvw"; char str[2] = { NULLCHAR, NULLCHAR }; int oldMode, oldAlign, x, y, start, i; HFONT oldFont; @@ -2423,7 +2718,7 @@ DrawCoordsOnDC(HDC hdc) if (!appData.showCoords) return; - start = flipView ? 1-(ONE!='1') : 23+(ONE!='1')-BOARD_HEIGHT; + start = flipView ? 1-(ONE!='1') : 45+(ONE!='1')-BOARD_HEIGHT; oldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH)); oldMode = SetBkMode(hdc, (appData.monoMode ? OPAQUE : TRANSPARENT)); @@ -2440,7 +2735,7 @@ DrawCoordsOnDC(HDC hdc) y += squareSize + lineGap; } - start = flipView ? 12-(BOARD_RGHT-BOARD_LEFT) : 12; + start = flipView ? 23-(BOARD_RGHT-BOARD_LEFT) : 23; SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM); for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) { @@ -2531,6 +2826,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceMask[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCAND); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -2540,6 +2838,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceFace[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCPAINT); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -2649,7 +2950,13 @@ VOID RebuildTextureSquareInfo() if( (col + row) & 1 ) { /* Lite square */ if( lite_w >= squareSize && lite_h >= squareSize ) { + if( lite_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1)*lite_w/(2*BOARD_WIDTH) - squareSize/2; /* [HGM] cut out of center of virtual square */ + else backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / (BOARD_WIDTH-1); /* [HGM] divide by size-1 in stead of size! */ + if( lite_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1)*lite_h/(2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (lite_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode); } @@ -2657,7 +2964,13 @@ VOID RebuildTextureSquareInfo() else { /* Dark square */ if( dark_w >= squareSize && dark_h >= squareSize ) { + if( dark_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1) * dark_w / (2*BOARD_WIDTH) - squareSize/2; + else backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / (BOARD_WIDTH-1); + if( dark_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1) * dark_h / (2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (dark_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode); } @@ -2668,7 +2981,7 @@ VOID RebuildTextureSquareInfo() /* [AS] Arrow highlighting support */ -static int A_WIDTH = 5; /* Width of arrow body */ +static double A_WIDTH = 5; /* Width of arrow body */ #define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */ #define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */ @@ -2692,50 +3005,50 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) if( d_x == s_x ) { int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; - arrow[0].x = s_x + A_WIDTH; + arrow[0].x = s_x + A_WIDTH + 0.5; arrow[0].y = s_y; - arrow[1].x = s_x + A_WIDTH; + arrow[1].x = s_x + A_WIDTH + 0.5; arrow[1].y = d_y - h; - arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[2].y = d_y - h; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR; - arrow[4].y = d_y - h; - - arrow[5].x = s_x - A_WIDTH; + arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[5].y = d_y - h; - arrow[6].x = s_x - A_WIDTH; + arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[4].y = d_y - h; + + arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[6].y = s_y; } else if( d_y == s_y ) { int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; arrow[0].x = s_x; - arrow[0].y = s_y + A_WIDTH; + arrow[0].y = s_y + A_WIDTH + 0.5; arrow[1].x = d_x - w; - arrow[1].y = s_y + A_WIDTH; + arrow[1].y = s_y + A_WIDTH + 0.5; arrow[2].x = d_x - w; - arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = d_x - w; - arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR; - arrow[5].x = d_x - w; - arrow[5].y = s_y - A_WIDTH; + arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5; + + arrow[4].x = d_x - w; + arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[6].x = s_x; - arrow[6].y = s_y - A_WIDTH; + arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5; } else { /* [AS] Needed a lot of paper for this! :-) */ @@ -2752,8 +3065,8 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) arrow[0].x = Round(x - j); arrow[0].y = Round(y + j*dx); - arrow[1].x = Round(x + j); - arrow[1].y = Round(y - j*dx); + arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice + arrow[1].y = Round(arrow[0].y - 2*j*dx); if( d_x > s_x ) { x = (double) d_x - k; @@ -2764,20 +3077,22 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) y = (double) d_y + k*dy; } - arrow[2].x = Round(x + j); - arrow[2].y = Round(y - j*dx); + x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends - arrow[3].x = Round(x + j*A_WIDTH_FACTOR); - arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx); + arrow[6].x = Round(x - j); + arrow[6].y = Round(y + j*dx); + + arrow[2].x = Round(arrow[6].x + 2*j); + arrow[2].y = Round(arrow[6].y - 2*j*dx); + + arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1)); + arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx); arrow[4].x = d_x; arrow[4].y = d_y; - arrow[5].x = Round(x - j*A_WIDTH_FACTOR); - arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx); - - arrow[6].x = Round(x - j); - arrow[6].y = Round(y + j*dx); + arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1)); + arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx); } Polygon( hdc, arrow, 7 ); @@ -2802,20 +3117,20 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro SquareToPos( d_row, d_col, &d_x, &d_y); if( d_y > s_y ) { - d_y += squareSize / 4; + d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides! } else if( d_y < s_y ) { - d_y += 3 * squareSize / 4; + d_y += squareSize / 2 + squareSize / 4; } else { d_y += squareSize / 2; } if( d_x > s_x ) { - d_x += squareSize / 4; + d_x += squareSize / 2 - squareSize / 4; } else if( d_x < s_x ) { - d_x += 3 * squareSize / 4; + d_x += squareSize / 2 + squareSize / 4; } else { d_x += squareSize / 2; @@ -2825,7 +3140,7 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro s_y += squareSize / 2; /* Adjust width */ - A_WIDTH = squareSize / 14; + A_WIDTH = squareSize / 14.; //[HGM] make float /* Draw */ stLB.lbStyle = BS_SOLID; @@ -3022,7 +3337,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) DrawPieceOnDC(hdc, piece, piece_color, square_color, x, y, tmphdc); } } - else if( backTextureSquareInfo[row][column].mode > 0 ) { + else if( appData.useBitmaps && backTextureSquareInfo[row][column].mode > 0 ) { /* [AS] Draw the square using a texture bitmap */ HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture ); int r = row, c = column; // [HGM] do not flip board in flipView @@ -3080,7 +3395,10 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) HBITMAP hbm; int w = 100, h = 50; - if(logo == NULL) return; + if(logo == NULL) { + if(!logoHeight) return; + FillRect( hdc, &logoRect, whitePieceBrush ); + } // GetClientRect(hwndMain, &Rect); // bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1, // Rect.bottom-Rect.top+1); @@ -3096,6 +3414,57 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) DeleteDC(tmphdc); } +VOID +DisplayLogos() +{ + if(logoHeight) { + HDC hdc = GetDC(hwndMain); + HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; + if(appData.autoLogo) { + + switch(gameMode) { // pick logos based on game mode + case IcsObserving: + whiteLogo = second.programLogo; // ICS logo + blackLogo = second.programLogo; + default: + break; + case IcsPlayingWhite: + if(!appData.zippyPlay) whiteLogo = userLogo; + blackLogo = second.programLogo; // ICS logo + break; + case IcsPlayingBlack: + whiteLogo = second.programLogo; // ICS logo + blackLogo = appData.zippyPlay ? first.programLogo : userLogo; + break; + case TwoMachinesPlay: + if(first.twoMachinesColor[0] == 'b') { + whiteLogo = second.programLogo; + blackLogo = first.programLogo; + } + break; + case MachinePlaysWhite: + blackLogo = userLogo; + break; + case MachinePlaysBlack: + whiteLogo = userLogo; + blackLogo = first.programLogo; + } + } + DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); + DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); + ReleaseDC(hwndMain, hdc); + } +} + +void +UpdateLogos(int display) +{ // called after loading new engine(s), in tourney or from menu + LoadLogo(&first, 0, FALSE); + LoadLogo(&second, 1, appData.icsActive); + InitDrawingSizes(-2, 0); // adapt layout of board window to presence/absence of logos + if(display) DisplayLogos(); +} + static HDC hdcSeek; // [HGM] seekgraph @@ -3140,9 +3509,9 @@ void DrawSeekText(char *buf, int x, int y) void DrawSeekDot(int x, int y, int color) { int square = color & 0x80; - color &= 0x7F; - HBRUSH oldBrush = SelectObject(hdcSeek, + HBRUSH oldBrush = SelectObject(hdcSeek, color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush); + color &= 0x7F; if(square) Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9, boardRect.left+x + squareSize/9, boardRect.top+y + squareSize/9); @@ -3231,7 +3600,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(--board[dragInfo.from.y][dragInfo.from.x-1] == 0 ) board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; } else - board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; + board[dragInfo.from.y][dragInfo.from.x] = gatingPiece; } /* Figure out which squares need updating by comparing the @@ -3393,6 +3762,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(explodeInfo.radius) { // [HGM] atomic HBRUSH oldBrush; int x, y, r=(explodeInfo.radius * squareSize)/100; + ChessSquare piece = board[explodeInfo.fromY][explodeInfo.fromX]; board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y); x += squareSize/2; @@ -3405,6 +3775,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); DrawBoardOnDC(hdcmem, board, tmphdc); + board[explodeInfo.fromY][explodeInfo.fromX] = piece; oldBrush = SelectObject(hdcmem, explodeBrush); Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); @@ -3432,41 +3803,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) } } } - if(logoHeight) { - HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; - if(appData.autoLogo) { - - switch(gameMode) { // pick logos based on game mode - case IcsObserving: - whiteLogo = second.programLogo; // ICS logo - blackLogo = second.programLogo; - default: - break; - case IcsPlayingWhite: - if(!appData.zippyPlay) whiteLogo = userLogo; - blackLogo = second.programLogo; // ICS logo - break; - case IcsPlayingBlack: - whiteLogo = second.programLogo; // ICS logo - blackLogo = appData.zippyPlay ? first.programLogo : userLogo; - break; - case TwoMachinesPlay: - if(first.twoMachinesColor[0] == 'b') { - whiteLogo = second.programLogo; - blackLogo = first.programLogo; - } - break; - case MachinePlaysWhite: - blackLogo = userLogo; - break; - case MachinePlaysBlack: - whiteLogo = userLogo; - blackLogo = first.programLogo; - } - } - DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); - DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); - } if( appData.highlightMoveWithArrow ) { DrawArrowHighlight(hdcmem); @@ -3488,8 +3824,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) board[dragInfo.from.y][dragInfo.from.x] = dragged_piece; x = dragInfo.pos.x - squareSize / 2; y = dragInfo.pos.y - squareSize / 2; - DrawPieceOnDC(hdcmem, dragged_piece, - ((int) dragged_piece < (int) BlackPawn), + DrawPieceOnDC(hdcmem, dragInfo.piece, + ((int) dragInfo.piece < (int) BlackPawn), (dragInfo.from.y + dragInfo.from.x) % 2, x, y, tmphdc); } @@ -3534,11 +3870,11 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) boardRect.bottom - boardRect.top, tmphdc, boardRect.left, boardRect.top, SRCCOPY); if(saveDiagFlag) { - BITMAP b; int i, j=0, m, w, wb, fac=0; char pData[1000000]; + BITMAP b; int i, j=0, m, w, wb, fac=0; char *pData; BITMAPINFOHEADER bih; int color[16], nrColors=0; GetObject(bufferBitmap, sizeof(b), &b); - if(b.bmWidthBytes*b.bmHeight <= 990000) { + if(pData = malloc(b.bmWidthBytes*b.bmHeight + 10000)) { bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = b.bmWidth; bih.biHeight = b.bmHeight; @@ -3602,6 +3938,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) // write bitmap data for(i=0; i 0 || !appData.testLegality /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse && !appData.icsActive); @@ -3748,12 +4083,14 @@ SetupDropMenu(HMENU hmenu) } } -void DragPieceBegin(int x, int y) +void DragPieceBegin(int x, int y, Boolean instantly) { dragInfo.lastpos.x = boardRect.left + x; dragInfo.lastpos.y = boardRect.top + y; + if(instantly) dragInfo.pos = dragInfo.lastpos; dragInfo.from.x = fromX; dragInfo.from.y = fromY; + dragInfo.piece = boards[currentMove][fromY][fromX]; dragInfo.start = dragInfo.from; SetCapture(hwndMain); } @@ -3766,6 +4103,11 @@ void DragPieceEnd(int x, int y) dragInfo.pos = dragInfo.lastpos = dragInfo.start; } +void ChangeDragPiece(ChessSquare piece) +{ + dragInfo.piece = piece; +} + /* Event handler for mouse messages */ VOID MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -3799,26 +4141,14 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) x = BOARD_WIDTH - 1 - x; } + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status + switch (message) { case WM_LBUTTONDOWN: if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditPosition) { - SetWhiteToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(flipClock, -1); - } else if (gameMode == IcsPlayingBlack || - gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } + ClockClick(flipClock); break; } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditPosition) { - SetBlackToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(!flipClock, -1); - } else if (gameMode == IcsPlayingWhite || - gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } + ClockClick(!flipClock); break; } dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; @@ -3838,6 +4168,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: if(SeekGraphClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, 1)) break; + if(PromoScroll(pt.x - boardRect.left, pt.y - boardRect.top)) break; MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top); if ((appData.animateDragging || appData.highlightDragging) && (wParam & MK_LBUTTON) @@ -3897,9 +4228,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(y == -2) { /* [HGM] right mouse button in clock area edit-game mode ups clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); } break; } @@ -3944,7 +4275,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK ButtonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - int id = GetWindowLong(hwnd, GWL_ID); + int id = GetWindowLongPtr(hwnd, GWLP_ID); int i, dir; for (i=0; i= 'A' && + ((PieceToChar(WhiteAngel) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteAngel) != '~') || - (PieceToChar(BlackAngel) >= 'A' && + (PieceToChar(BlackAngel) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackAngel) != '~') ) ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, PB_Chancellor), - ((PieceToChar(WhiteMarshall) >= 'A' && + ((PieceToChar(WhiteMarshall) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteMarshall) != '~') || - (PieceToChar(BlackMarshall) >= 'A' && + (PieceToChar(BlackMarshall) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackMarshall) != '~') ) ? SW_SHOW : SW_HIDE); /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */ @@ -4018,12 +4351,11 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) ShowWindow(GetDlgItem(hDlg, PB_Bishop), gameInfo.variant != VariantShogi ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_Yes), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_No), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); + if(gameInfo.variant == VariantShogi) { + SetDlgItemText(hDlg, PB_Queen, "YES"); + SetDlgItemText(hDlg, PB_Knight, "NO"); + SetWindowText(hDlg, "Promote?"); + } ShowWindow(GetDlgItem(hDlg, IDC_Centaur), gameInfo.variant == VariantSuper ? SW_SHOW : SW_HIDE); @@ -4040,31 +4372,30 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing); break; case PB_Queen: - promoChar = gameInfo.variant == VariantShogi ? '+' : PieceToChar(BlackQueen); + promoChar = gameInfo.variant == VariantShogi ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen)); break; case PB_Rook: - promoChar = PieceToChar(BlackRook); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteRook : BlackRook)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackDragon); break; case PB_Bishop: - promoChar = PieceToChar(BlackBishop); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteBishop : BlackBishop)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackAlfil); break; case PB_Chancellor: - promoChar = PieceToChar(BlackMarshall); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteMarshall : BlackMarshall)); break; case PB_Archbishop: - promoChar = PieceToChar(BlackAngel); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteAngel : BlackAngel)); break; case PB_Knight: - promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(BlackKnight); + promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight); break; default: return FALSE; } + if(promoChar == '.') return FALSE; // invalid piece chosen EndDialog(hDlg, TRUE); /* Exit the dialog */ - /* [HGM] Call FinishMove rather than UserMoveEvent, as we - only show the popup when we are already sure the move is valid or - legal. We pass a faulty move type, but the kludge is that FinishMove - will figure out it is a promotion from the promoChar. */ UserMoveEvent(fromX, fromY, toX, toY, promoChar); fromX = fromY = -1; if (!appData.highlightLastMove) { @@ -4118,7 +4449,7 @@ LoadGameDialog(HWND hwnd, char* title) if (number == 0) { int error = GameListBuild(f); if (error) { - DisplayError("Cannot build game list", error); + DisplayError(_("Cannot build game list"), error); } else if (!ListEmpty(&gameList) && ((ListGame *) gameList.tailPred)->number > 1) { GameListPopUp(f, fileTitle); @@ -4174,11 +4505,11 @@ void UpdateICSWidth(HWND hText) LONG old_width, new_width; new_width = get_term_width(hText, FALSE); - old_width = GetWindowLong(hText, GWL_USERDATA); + old_width = GetWindowLongPtr(hText, GWLP_USERDATA); if (new_width != old_width) { ics_update_width(new_width); - SetWindowLong(hText, GWL_USERDATA, new_width); + SetWindowLongPtr(hText, GWLP_USERDATA, new_width); } } @@ -4194,7 +4525,8 @@ ChangedConsoleFont() cfmt.cbSize = sizeof(CHARFORMAT); cfmt.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET; - strcpy(cfmt.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName); + safeStrCpy(cfmt.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName, + sizeof(cfmt.szFaceName)/sizeof(cfmt.szFaceName[0]) ); /* yHeight is expressed in twips. A twip is 1/20 of a font's point * size. This was undocumented in the version of MSVC++ that I had * when I wrote the code, but is apparently documented now. @@ -4242,6 +4574,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) char fileTitle[MSG_SIZ]; char buf[MSG_SIZ]; static SnapData sd; + static int peek=0; switch (message) { @@ -4269,7 +4602,23 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MouseEvent(hwnd, message, wParam, lParam); break; - JAWS_KB_NAVIGATION + case WM_KEYUP: + if((char)wParam == '\b') { + ForwardEvent(); peek = 0; + } + + JAWS_KBUP_NAVIGATION + + break; + + case WM_KEYDOWN: + if((char)wParam == '\b') { + if(!peek) BackwardEvent(), peek = 1; + } + + JAWS_KBDOWN_NAVIGATION + + break; case WM_CHAR: @@ -4283,7 +4632,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(h, message, wParam, lParam); } else if(lParam != KF_REPEAT) { if (isalpha((char)wParam) || isdigit((char)wParam)) { - PopUpMoveDialog((char)wParam); + TypeInEvent((char)wParam); } else if((char)wParam == 003) CopyGameToClipboard(); else if((char)wParam == 026) PasteGameOrFENFromClipboard(); } @@ -4340,7 +4689,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_LoadGame: - LoadGameDialog(hwnd, "Load Game from File"); + LoadGameDialog(hwnd, _("Load Game from File")); break; case IDM_LoadNextGame: @@ -4363,7 +4712,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "rb", "", appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Load Position from File", &number, fileTitle, NULL); + _("Load Position from File"), &number, fileTitle, NULL); if (f != NULL) { LoadPosition(f, number, fileTitle); } @@ -4386,7 +4735,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); } @@ -4397,7 +4746,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Save Position to File", NULL, fileTitle, NULL); + _("Save Position to File"), NULL, fileTitle, NULL); if (f != NULL) { SavePosition(f, 0, ""); } @@ -4408,7 +4757,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "wb", defName, "bmp", DIAGRAM_FILT, - "Save Diagram to File", NULL, fileTitle, NULL); + _("Save Diagram to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveDiagram(f); } @@ -4537,6 +4886,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SAY("computer starts playing black"); break; + case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games + MatchEvent(2); // distinguish from command-line-triggered case (matchMode=1) + break; + case IDM_TwoMachines: TwoMachinesEvent(); /* @@ -4553,14 +4906,14 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_AnalysisMode: if (!first.analysisSupport) { - sprintf(buf, "%s does not support analysis", first.tidy); + snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { SAY("analyzing current position"); /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */ if (appData.icsActive) { if (gameMode != IcsObserving) { - sprintf(buf, "You are not observing a game"); + snprintf(buf, MSG_SIZ, "You are not observing a game"); DisplayError(buf, 0); /* secure check */ if (appData.icsEngineAnalyze) { @@ -4590,12 +4943,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_AnalyzeFile: if (!first.analysisSupport) { char buf[MSG_SIZ]; - sprintf(buf, "%s does not support analysis", first.tidy); + snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { if (!appData.showThinking) ToggleShowThinking(); AnalyzeFileEvent(); - LoadGameDialog(hwnd, "Analyze Game from File"); +// LoadGameDialog(hwnd, _("Analyze Game from File")); AnalysisPeriodicEvent(1); } break; @@ -4605,11 +4958,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_EditGame: + case IDM_EditGame2: EditGameEvent(); SAY("edit game"); break; case IDM_EditPosition: + case IDM_EditPosition2: EditPositionEvent(); SAY("enter a FEN string or setup a position on the board using the control R pop up menu"); break; @@ -4622,11 +4977,30 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ShowGameListProc(); break; + case IDM_EditProgs1: + EditTagsPopUp(firstChessProgramNames, &firstChessProgramNames); + break; + + case IDM_EditProgs2: + LoadEnginePopUp(hwndMain); +// EditTagsPopUp(secondChessProgramNames, &secondChessProgramNames); + break; + + case IDM_EditServers: + EditTagsPopUp(icsNames, &icsNames); + break; + case IDM_EditTags: + case IDM_Tags: EditTagsProc(); break; + case IDM_EditBook: + EditBookEvent(); + break; + case IDM_EditComment: + case IDM_Comment: if (commentUp && editComment) { CommentPopDown(); } else { @@ -4683,7 +5057,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_TypeInMove: - PopUpMoveDialog('\000'); + TypeInEvent('\000'); break; case IDM_TypeInName: @@ -4712,6 +5086,11 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetFocus(hwndMain); break; + case OPT_GameListNext: // [HGM] forward these two accelerators to Game List + case OPT_GameListPrev: + if(gameListDialog) SendMessage(gameListDialog, WM_COMMAND, wmId, 0); + break; + case IDM_Revert: RevertEvent(FALSE); break; @@ -4740,7 +5119,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FlipClock: flipClock = !flipClock; DisplayBothClocks(); - DrawPosition(FALSE, NULL); + DisplayLogos(); break; case IDM_MuteSounds: @@ -4767,6 +5146,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Engine2Options: + savedHwnd = hwnd; + if(WaitForEngine(&second, SettingsMenuIfReady)) break; EngineOptionsPopup(hwnd, &second); break; @@ -4774,6 +5155,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) UciOptionsPopup(hwnd); break; + case IDM_Tourney: + TourneyPopup(hwnd); + break; + case IDM_IcsOptions: IcsOptionsPopup(hwnd); break; @@ -4844,7 +5229,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4853,7 +5238,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4861,7 +5246,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPHELP: if(!WinHelp(hwnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4875,12 +5260,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_DirectCommand1: - AskQuestionEvent("Direct Command", - "Send to chess program:", "", "1"); + AskQuestionEvent(_("Direct Command"), + _("Send to chess program:"), "", "1"); break; case IDM_DirectCommand2: - AskQuestionEvent("Direct Command", - "Send to second chess program:", "", "2"); + AskQuestionEvent(_("Direct Command"), + _("Send to second chess program:"), "", "2"); break; case EP_WhitePawn: @@ -5058,7 +5443,23 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) fromX = fromY = -1; break; + case IDM_English: + barbaric = 0; appData.language = ""; + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_English, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + default: + if(wmId > IDM_English && wmId < IDM_English+20) { + LoadLanguageFile(languageFile[wmId - IDM_English - 1]); + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), wmId, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + } return (DefWindowProc(hwnd, message, wParam, lParam)); } break; @@ -5259,7 +5660,7 @@ MyLoadSound(MySound *ms) struct stat st; FILE *f; - if (ms->data) free(ms->data); + if (ms->data && ms->flag) free(ms->data); ms->data = NULL; switch (ms->name[0]) { @@ -5280,6 +5681,7 @@ MyLoadSound(MySound *ms) HANDLE h = FindResource(hInst, ms->name + 1, "WAVE"); if (h == NULL) break; ms->data = (void *)LoadResource(hInst, h); + ms->flag = 0; // not maloced, so cannot be freed! if (h == NULL) break; ok = TRUE; } @@ -5290,6 +5692,7 @@ MyLoadSound(MySound *ms) if (f == NULL) break; if (fstat(fileno(f), &st) < 0) break; ms->data = malloc(st.st_size); + ms->flag = 1; if (fread(ms->data, st.st_size, 1, f) < 1) break; fclose(f); ok = TRUE; @@ -5297,7 +5700,7 @@ MyLoadSound(MySound *ms) } if (!ok) { char buf[MSG_SIZ]; - sprintf(buf, "Error loading sound %s", ms->name); + snprintf(buf, MSG_SIZ, _("Error loading sound %s"), ms->name); DisplayError(buf, GetLastError()); } return ok; @@ -5363,6 +5766,7 @@ OldOpenFileHook(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) number = NULL; } CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + Translate(hDlg, 1536); return FALSE; /* Allow for further processing */ case WM_COMMAND: @@ -5382,6 +5786,7 @@ OpenFileHook(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) OFNOTIFY *ofnot; switch (uiMsg) { case WM_INITDIALOG: + Translate(hdlg, DLG_IndexNumber); ofname = (OPENFILENAME *)lParam; number = (UINT *)(ofname->lCustData); break; @@ -5407,12 +5812,12 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia if (fileName == NULL) fileName = buf1; if (defName == NULL) { - strcpy(fileName, "*."); + safeStrCpy(fileName, "*.", 3 ); strcat(fileName, defExt); } else { - strcpy(fileName, defName); + safeStrCpy(fileName, defName, MSG_SIZ ); } - if (fileTitle) strcpy(fileTitle, ""); + if (fileTitle) safeStrCpy(fileTitle, "", MSG_SIZ ); if (number) *number = 0; openFileName.lStructSize = sizeof(OPENFILENAME); @@ -5445,13 +5850,13 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia /* open the file */ f = fopen(openFileName.lpstrFile, write); if (f == NULL) { - MessageBox(hwnd, "File open failed", NULL, + MessageBox(hwnd, _("File open failed"), NULL, MB_OK|MB_ICONEXCLAMATION); return NULL; } } else { int err = CommDlgExtendedError(); - if (err != 0) DisplayError("Internal error in file dialog box", err); + if (err != 0) DisplayError(_("Internal error in file dialog box"), err); return FALSE; } return f; @@ -5469,6 +5874,7 @@ MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def) * menu that TrackPopupMenu displays. */ hmenuTrackPopup = GetSubMenu(hmenu, 0); + TranslateOneMenu(10, hmenuTrackPopup); SetMenuDefaultItem(hmenuTrackPopup, def, FALSE); @@ -5611,7 +6017,7 @@ InitComboStrings(HANDLE hwndCombo, char **cd) SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0); while (*cd != NULL) { - SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) *cd); + SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) T_(*cd)); cd++; } } @@ -5690,10 +6096,10 @@ InitEngineBox(HWND hDlg, HWND hwndCombo, char* nthcp, char* nthd, char* nthdir, InitComboStringsFromOption(hwndCombo, nthnames); q = QuoteForFilename(nthcp); - sprintf(buf, "%s%s%s", q, nthcp, q); + snprintf(buf, MSG_SIZ, "%s%s%s", q, nthcp, q); if (*nthdir != NULLCHAR) { q = QuoteForFilename(nthdir); - sprintf(buf + strlen(buf), " /%s=%s%s%s", nthd, q, nthdir, q); + snprintf(buf + strlen(buf), MSG_SIZ, " /%s=%s%s%s", nthd, q, nthdir, q); } if (*nthcp == NULLCHAR) { SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0); @@ -5714,16 +6120,17 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: /* Center the dialog */ CenterWindow (hDlg, GetDesktopWindow()); + Translate(hDlg, DLG_Startup); /* Initialize the dialog items */ InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_ChessEngineName), appData.firstChessProgram, "fd", appData.firstDirectory, firstChessProgramNames); InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_SecondChessEngineName), - appData.secondChessProgram, "sd", appData.secondDirectory, - secondChessProgramNames); + appData.secondChessProgram, singleList ? "fd" : "sd", appData.secondDirectory, + singleList ? firstChessProgramNames : secondChessProgramNames); //[HGM] single: use first list in second combo hwndCombo = GetDlgItem(hDlg, OPT_ChessServerName); InitComboStringsFromOption(hwndCombo, icsNames); - sprintf(buf, "%s /icsport=%s", appData.icsHost, appData.icsPort); + snprintf(buf, MSG_SIZ, "%s /icsport=%s", appData.icsHost, appData.icsPort); if (*appData.icsHelper != NULLCHAR) { char *q = QuoteForFilename(appData.icsHelper); sprintf(buf + strlen(buf), " /icshelper=%s%s%s", q, appData.icsHelper, q); @@ -5753,23 +6160,25 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam)) { case IDOK: if (IsDlgButtonChecked(hDlg, OPT_ChessEngine)) { - strcpy(buf, "/fcp="); + safeStrCpy(buf, "/fcp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; ParseArgs(StringGet, &p); - strcpy(buf, "/scp="); + safeStrCpy(buf, singleList ? "/fcp=" : "/scp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); - p = buf; + p = buf; + SwapEngines(singleList); // temporarily swap first and second, to load a second 'first', ... ParseArgs(StringGet, &p); + SwapEngines(singleList); // ... and then make it 'second' appData.noChessProgram = FALSE; appData.icsActive = FALSE; } else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) { - strcpy(buf, "/ics /icshost="); + safeStrCpy(buf, "/ics /icshost=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; ParseArgs(StringGet, &p); if (appData.zippyPlay) { - strcpy(buf, "/fcp="); + safeStrCpy(buf, "/fcp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; ParseArgs(StringGet, &p); @@ -5778,8 +6187,8 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) appData.noChessProgram = TRUE; appData.icsActive = FALSE; } else { - MessageBox(hDlg, "Choose an option, or cancel to exit", - "Option Error", MB_OK|MB_ICONEXCLAMATION); + MessageBox(hDlg, _("Choose an option, or cancel to exit"), + _("Option Error"), MB_OK|MB_ICONEXCLAMATION); return TRUE; } if (IsDlgButtonChecked(hDlg, OPT_AnyAdditional)) { @@ -5797,7 +6206,7 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPCONTENTS: if (!WinHelp (hDlg, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -5826,6 +6235,7 @@ About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) /* Center the dialog over the application window */ CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); SetDlgItemText(hDlg, ABOUTBOX_Version, programVersion); + Translate(hDlg, ABOUTBOX); JAWS_COPYRIGHT return (TRUE); @@ -5859,6 +6269,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INITDIALOG: /* message: initialize dialog box */ /* Initialize the dialog items */ + Translate(hDlg, DLG_EditComment); hwndText = GetDlgItem(hDlg, OPT_CommentText); SetDlgItemText(hDlg, OPT_CommentText, commentText); EnableWindow(GetDlgItem(hDlg, OPT_CancelComment), editComment); @@ -5904,7 +6315,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) sizeY = newSizeY; } } - SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); + SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS ); return FALSE; case WM_COMMAND: /* message: received a command */ @@ -5953,13 +6364,19 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if( wParam == OPT_CommentText ) { MSGFILTER * lpMF = (MSGFILTER *) lParam; - if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) { + if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 || + lpMF->msg == WM_CHAR && lpMF->wParam == '\022' ) { POINTL pt; LRESULT index; pt.x = LOWORD( lpMF->lParam ); pt.y = HIWORD( lpMF->lParam ); + if(lpMF->msg == WM_CHAR) { + CHARRANGE sel; + SendDlgItemMessage( hDlg, OPT_CommentText, EM_EXGETSEL, 0, (LPARAM) &sel ); + index = sel.cpMin; + } else index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt ); hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above @@ -6003,7 +6420,7 @@ EitherCommentPopUp(int index, char *title, char *str, BOOLEAN edit) FARPROC lpProc; char *p, *q; - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, edit ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, edit ? MF_CHECKED : MF_UNCHECKED); if (str == NULL) str = ""; p = (char *) malloc(2 * strlen(str) + 2); @@ -6044,15 +6461,13 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char move[MSG_SIZ]; HWND hInput; - ChessMove moveType; - int fromX, fromY, toX, toY; - char promoChar; switch (message) { case WM_INITDIALOG: move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInMove); hInput = GetDlgItem(hDlg, OPT_Move); SetWindowText(hInput, move); SetFocus(hInput); @@ -6061,39 +6476,11 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: - GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); - { int n; Board board; - // [HGM] FENedit - if(gameMode == EditPosition && ParseFEN(board, &n, move) ) { - EditPositionPasteFEN(move); - EndDialog(hDlg, TRUE); - return TRUE; - } - // [HGM] movenum: allow move number to be typed in any mode - if(sscanf(move, "%d", &n) == 1 && n != 0 ) { - ToNrEvent(2*n-1); - EndDialog(hDlg, TRUE); - return TRUE; - } - } - if (gameMode != EditGame && currentMove != forwardMostMove && - gameMode != Training) { - DisplayMoveError("Displayed move is not current"); - } else { -// GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream - int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, - &moveType, &fromX, &fromY, &toX, &toY, &promoChar); - if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized - if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, - &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) { - if (gameMode != Training) - forwardMostMove = currentMove; - UserMoveEvent(fromX, fromY, toX, toY, promoChar); - } else { - DisplayMoveError("Could not parse move"); - } - } + case IDOK: + + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status + GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); + TypeInDoneEvent(move); EndDialog(hDlg, TRUE); return TRUE; case IDCANCEL: @@ -6111,21 +6498,11 @@ VOID PopUpMoveDialog(char firstchar) { FARPROC lpProc; - - if ((gameMode == BeginningOfGame && !appData.icsActive) || - gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack || - gameMode == AnalyzeMode || gameMode == EditGame || - gameMode == EditPosition || gameMode == IcsExamining || - gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack || - isdigit(firstchar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes - ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile || - gameMode == IcsObserving || gameMode == TwoMachinesPlay ) || - gameMode == Training) { + lpProc = MakeProcInstance((FARPROC)TypeInMoveDialog, hInst); DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInMove), hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar); FreeProcInstance(lpProc); - } } /*---------------------------------------------------------------------------*\ @@ -6145,6 +6522,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInName); hInput = GetDlgItem(hDlg, OPT_Name); SetWindowText(hInput, move); SetFocus(hInput); @@ -6159,7 +6537,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) SetUserLogo(); SetGameInfo(); if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) { - sprintf(move, "%s vs. %s", gameInfo.white, gameInfo.black); + snprintf(move, MSG_SIZ, "%s vs. %s", gameInfo.white, gameInfo.black); DisplayTitle(move); } @@ -6267,6 +6645,7 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) For now, just give it a default position. */ SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE); + Translate(hDlg, DLG_Error); errorDialog = hDlg; SetWindowText(hDlg, errorTitle); @@ -6489,12 +6868,13 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate) SendMessage(hwnd, EM_GETSELTEXT, 0, (LPARAM) name); } if (immediate) { - sprintf(buf, "%s %s", command, name); + if(strstr(command, "%s")) snprintf(buf, MSG_SIZ, command, name); else + snprintf(buf, MSG_SIZ, "%s %s", command, name); SetWindowText(hInput, buf); SendMessage(hInput, WM_CHAR, '\r', 0); } else { if(!strcmp(command, "chat")) { ChatPopUp(name); return; } - sprintf(buf, "%s %s ", command, name); /* trailing space */ + snprintf(buf, MSG_SIZ, "%s %s ", command, name); /* trailing space */ SetWindowText(hInput, buf); sel.cpMin = 999999; sel.cpMax = 999999; @@ -6512,6 +6892,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_KEYDOWN: if (!(GetKeyState(VK_CONTROL) & ~1)) break; + if(wParam=='R') return 0; switch (wParam) { case VK_PRIOR: SendMessage(hwnd, EM_LINESCROLL, 0, -999999); @@ -6545,7 +6926,8 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hInput, message, wParam, lParam); } return 0; - } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu + } // [HGM] navigate: for Ctrl+R, flow into next case (moved up here) to summon up menu + lParam = -1; case WM_RBUTTONDOWN: if (!(GetKeyState(VK_SHIFT) & ~1)) { /* Move selection here if it was empty */ @@ -6554,7 +6936,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pt.y = HIWORD(lParam); SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); if (sel.cpMin == sel.cpMax) { - sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ + if(lParam != -1) sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ sel.cpMax = sel.cpMin; SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); } @@ -6831,10 +7213,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) hwndConsole = hDlg; SetFocus(hInput); consoleTextWindowProc = (WNDPROC) - SetWindowLong(hText, GWL_WNDPROC, (LONG) ConsoleTextSubclass); + SetWindowLongPtr(hText, GWLP_WNDPROC, (LONG_PTR) ConsoleTextSubclass); SendMessage(hText, EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor); consoleInputWindowProc = (WNDPROC) - SetWindowLong(hInput, GWL_WNDPROC, (LONG) ConsoleInputSubclass); + SetWindowLongPtr(hInput, GWLP_WNDPROC, (LONG_PTR) ConsoleInputSubclass); SendMessage(hInput, EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor); Colorize(ColorNormal, TRUE); SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &consoleCF); @@ -6880,7 +7262,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) wMask = (WORD) SendMessage(hText, EM_GETEVENTMASK, 0, 0L); SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK); SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L); - SetWindowLong(hText, GWL_USERDATA, 79); // initialize the text window's width + SetWindowLongPtr(hText, GWLP_USERDATA, 79); // initialize the text window's width return FALSE; @@ -7060,7 +7442,8 @@ DisplayHoldingsCount(HDC hdc, int x, int y, int rightAlign, int copyNumber) HFONT oldFont; RECT rect; - if(copyNumber > 1) sprintf(buf, "%d", copyNumber); else buf[0] = 0; + if(copyNumber > 1) + snprintf(buf, sizeof(buf)/sizeof(buf[0]),"%d", copyNumber); else buf[0] = 0; oldFg = SetTextColor(hdc, RGB(255, 255, 255)); /* white */ oldBg = SetBkColor(hdc, RGB(0, 0, 0)); /* black */ @@ -7093,9 +7476,9 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, if (appData.clockMode) { if (tinyLayout) - sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%c %s %s", color[0], TimeString(timeRemaining), flagFell); else - sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell); str = buf; } else { str = color; @@ -7117,7 +7500,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, rect, str, strlen(str), NULL); if(logoHeight > 0 && appData.clockMode) { RECT r; - sprintf(buf, "%s %s", buf+7, flagFell); + str += strlen(color)+2; r.top = rect->top + logoHeight/2; r.left = rect->left; r.right = rect->right; @@ -7422,6 +7805,22 @@ Enables gnuEnables[] = { { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, + + // Needed to switch from ncp to GNU mode on Engine Load + { ACTION_POS, MF_BYPOSITION|MF_ENABLED }, + { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, + { IDM_MachineBlack, MF_BYCOMMAND|MF_ENABLED }, + { IDM_TwoMachines, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Match, MF_BYCOMMAND|MF_ENABLED }, + { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, + { IDM_AnalyzeFile, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine1Options, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine2Options, MF_BYCOMMAND|MF_ENABLED }, + { IDM_TimeControl, MF_BYCOMMAND|MF_ENABLED }, + { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, + { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Book, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } }; @@ -7431,6 +7830,7 @@ Enables icsEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, @@ -7438,14 +7838,16 @@ Enables icsEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED }, { IDM_Hint, MF_BYCOMMAND|MF_GRAYED }, { IDM_Book, MF_BYCOMMAND|MF_GRAYED }, + { IDM_EditProgs2, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Tourney, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; -#ifdef ZIPPY +#if ZIPPY Enables zippyEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, @@ -7461,6 +7863,7 @@ Enables ncpEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsClient, MF_BYCOMMAND|MF_GRAYED }, @@ -7476,11 +7879,13 @@ Enables ncpEnables[] = { { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Sounds, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; Enables trainingOnEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Comment, MF_BYCOMMAND|MF_GRAYED }, { IDM_Pause, MF_BYCOMMAND|MF_GRAYED }, { IDM_Forward, MF_BYCOMMAND|MF_GRAYED }, { IDM_Backward, MF_BYCOMMAND|MF_GRAYED }, @@ -7493,6 +7898,7 @@ Enables trainingOnEnables[] = { Enables trainingOffEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Comment, MF_BYCOMMAND|MF_ENABLED }, { IDM_Pause, MF_BYCOMMAND|MF_ENABLED }, { IDM_Forward, MF_BYCOMMAND|MF_ENABLED }, { IDM_Backward, MF_BYCOMMAND|MF_ENABLED }, @@ -7529,6 +7935,7 @@ Enables machineThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, +// { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } @@ -7548,6 +7955,7 @@ Enables userThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_ENABLED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_ENABLED }, +// { IDM_Match, MF_BYCOMMAND|MF_ENABLED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_ENABLED }, { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } @@ -7560,6 +7968,12 @@ Enables userThinkingEnables[] = { * \*---------------------------------------------------------------------------*/ VOID +CheckMark(UINT item, int state) +{ + if(item) CheckMenuItem(GetMenu(hwndMain), item, MF_BYCOMMAND|state); +} + +VOID ModeHighlight() { static UINT prevChecked = 0; @@ -7620,12 +8034,9 @@ ModeHighlight() nowChecked = 0; break; } - if (prevChecked != 0) - (void) CheckMenuItem(GetMenu(hwndMain), - prevChecked, MF_BYCOMMAND|MF_UNCHECKED); - if (nowChecked != 0) - (void) CheckMenuItem(GetMenu(hwndMain), - nowChecked, MF_BYCOMMAND|MF_CHECKED); + CheckMark(prevChecked, MF_UNCHECKED); + CheckMark(nowChecked, MF_CHECKED); + CheckMark(IDM_Match, matchMode && matchGame < appData.matchGames ? MF_CHECKED : MF_UNCHECKED); if (nowChecked == IDM_LoadGame || nowChecked == IDM_Training) { (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training, @@ -7640,13 +8051,12 @@ ModeHighlight() /* [DM] icsEngineAnalyze - Do a sceure check too */ if (appData.icsActive) { if (appData.icsEngineAnalyze) { - (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, - MF_BYCOMMAND|MF_CHECKED); + CheckMark(IDM_AnalysisMode, MF_CHECKED); } else { - (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, - MF_BYCOMMAND|MF_UNCHECKED); + CheckMark(IDM_AnalysisMode, MF_UNCHECKED); } } + DisplayLogos(); // [HGM] logos: mode change could have altered logos } VOID @@ -7654,9 +8064,9 @@ SetICSMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, icsEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), ICS_POS, - MF_BYPOSITION|MF_ENABLED); -#ifdef ZIPPY + EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), IDM_IcsOptions, + MF_BYCOMMAND|MF_ENABLED); +#if ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); if (!appData.noChessProgram) /* [DM] icsEngineAnalyze */ @@ -7677,8 +8087,6 @@ SetNCPMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, ncpEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), SOUNDS_POS, - MF_BYPOSITION|MF_GRAYED); DrawMenuBar(hwndMain); } @@ -7730,7 +8138,7 @@ SetMachineThinkingEnables() } else if (gameMode == MachinePlaysWhite) { (void)EnableMenuItem(hMenu, IDM_MachineWhite, flags); } else if (gameMode == TwoMachinesPlay) { - (void)EnableMenuItem(hMenu, IDM_TwoMachines, flags); + (void)EnableMenuItem(hMenu, matchMode ? IDM_Match : IDM_TwoMachines, flags); // [HGM] match } } @@ -7740,17 +8148,17 @@ DisplayTitle(char *str) { char title[MSG_SIZ], *host; if (str[0] != NULLCHAR) { - strcpy(title, str); + safeStrCpy(title, str, sizeof(title)/sizeof(title[0]) ); } else if (appData.icsActive) { if (appData.icsCommPort[0] != NULLCHAR) host = "ICS"; else host = appData.icsHost; - sprintf(title, "%s: %s", szTitle, host); + snprintf(title, MSG_SIZ, "%s: %s", szTitle, host); } else if (appData.noChessProgram) { - strcpy(title, szTitle); + safeStrCpy(title, szTitle, sizeof(title)/sizeof(title[0]) ); } else { - strcpy(title, szTitle); + safeStrCpy(title, szTitle, sizeof(title)/sizeof(title[0]) ); strcat(title, ": "); strcat(title, first.tidy); } @@ -7784,7 +8192,8 @@ DisplayMessage(char *str1, char *str2) if (len > remain) len = remain; strncat(messageText, str2, len); } - messageText[MESSAGE_TEXT_MAX - 1] = NULLCHAR; + messageText[MESSAGE_TEXT_MAX - 1] = NULLCHAR; + safeStrCpy(lastMsg, messageText, MSG_SIZ); if (hwndMain == NULL || IsIconic(hwndMain)) return; @@ -7805,25 +8214,25 @@ DisplayError(char *str, int error) int len; if (error == 0) { - strcpy(buf, str); + safeStrCpy(buf, str, sizeof(buf)/sizeof(buf[0]) ); } else { len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, LANG_NEUTRAL, (LPSTR) buf2, MSG_SIZ, NULL); if (len > 0) { - sprintf(buf, "%s:\n%s", str, buf2); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, buf2); } else { ErrorMap *em = errmap; while (em->err != 0 && em->err != error) em++; if (em->err != 0) { - sprintf(buf, "%s:\n%s", str, em->msg); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, em->msg); } else { - sprintf(buf, "%s:\nError code %d", str, error); + snprintf(buf, 2*MSG_SIZ, "%s:\nError code %d", str, error); } } } - ErrorPopUp("Error", buf); + ErrorPopUp(_("Error"), buf); } @@ -7834,7 +8243,7 @@ DisplayMoveError(char *str) ClearHighlights(); DrawPosition(FALSE, NULL); if (appData.popupMoveErrors) { - ErrorPopUp("Error", str); + ErrorPopUp(_("Error"), str); } else { DisplayMessage(str, ""); moveErrorMessageUp = TRUE; @@ -7846,21 +8255,21 @@ DisplayFatalError(char *str, int error, int exitStatus) { char buf[2*MSG_SIZ], buf2[MSG_SIZ]; int len; - char *label = exitStatus ? "Fatal Error" : "Exiting"; + char *label = exitStatus ? _("Fatal Error") : _("Exiting"); if (error != 0) { len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, LANG_NEUTRAL, (LPSTR) buf2, MSG_SIZ, NULL); if (len > 0) { - sprintf(buf, "%s:\n%s", str, buf2); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, buf2); } else { ErrorMap *em = errmap; while (em->err != 0 && em->err != error) em++; if (em->err != 0) { - sprintf(buf, "%s:\n%s", str, em->msg); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, em->msg); } else { - sprintf(buf, "%s:\nError code %d", str, error); + snprintf(buf, 2*MSG_SIZ, "%s:\nError code %d", str, error); } } str = buf; @@ -7879,14 +8288,14 @@ DisplayFatalError(char *str, int error, int exitStatus) VOID DisplayInformation(char *str) { - (void) MessageBox(hwndMain, str, "Information", MB_OK|MB_ICONINFORMATION); + (void) MessageBox(hwndMain, str, _("Information"), MB_OK|MB_ICONINFORMATION); } VOID DisplayNote(char *str) { - ErrorPopUp("Note", str); + ErrorPopUp(_("Note"), str); } @@ -7906,6 +8315,7 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: qp = (QuestionParams *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_Question); SetWindowText(hDlg, qp->title); SetDlgItemText(hDlg, OPT_QuestionText, qp->question); SetFocus(GetDlgItem(hDlg, OPT_QuestionInput)); @@ -7914,14 +8324,14 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: - strcpy(reply, qp->replyPrefix); + safeStrCpy(reply, qp->replyPrefix, sizeof(reply)/sizeof(reply[0]) ); if (*reply) strcat(reply, " "); len = strlen(reply); GetDlgItemText(hDlg, OPT_QuestionInput, reply + len, sizeof(reply) - len); strcat(reply, "\n"); OutputToProcess(qp->pr, reply, strlen(reply), &err); EndDialog(hDlg, TRUE); - if (err) DisplayFatalError("Error writing to chess program", err, 1); + if (err) DisplayFatalError(_("Error writing to chess program"), err, 1); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); @@ -7963,6 +8373,7 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lpIndexFRC = (int *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_NewGameFRC); SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 ); SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE ); @@ -7989,7 +8400,7 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM } return TRUE; case IDC_NFG_Random: - sprintf( buf, "%d", myrandom() ); /* [HGM] shuffle: no longer limit to 960 */ + snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%d", myrandom() ); /* [HGM] shuffle: no longer limit to 960 */ SetDlgItemText(hDlg, IDC_NFG_Edit, buf ); return TRUE; } @@ -8077,6 +8488,7 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP gameListOptionsDialog = hDlg; // [HGM] pass through global to keep out off back-end CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_GameListOptions); /* Initialize list */ GLT_TagsToList( lpUserGLT ); @@ -8123,7 +8535,7 @@ int GameListOptions() int result; FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst ); - strcpy( lpUserGLT, appData.gameListTags ); + safeStrCpy( lpUserGLT, appData.gameListTags ,LPUSERGLT_SIZE ); result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT ); @@ -8140,7 +8552,7 @@ DisplayIcsInteractionTitle(char *str) { char consoleTitle[MSG_SIZ]; - sprintf(consoleTitle, "%s: %s", szConsoleTitle, str); + snprintf(consoleTitle, MSG_SIZ, "%s: %s", szConsoleTitle, str); SetWindowText(hwndConsole, consoleTitle); } @@ -8185,7 +8597,7 @@ CommentPopUp(char *title, char *str) VOID CommentPopDown(void) { - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, MF_UNCHECKED); if (commentDialog) { ShowWindow(commentDialog, SW_HIDE); } @@ -8231,6 +8643,12 @@ PlayAlarmSound() MyPlaySound(&sounds[(int)SoundAlarm]); } +VOID +PlayTellSound() +{ + MyPlaySound(&textAttribs[ColorTell].sound); +} + VOID EchoOn() @@ -8279,7 +8697,7 @@ UserName() } if (!GetUserName(buf, &bufsiz)) { /*DisplayError("Error getting user name", GetLastError());*/ - strcpy(buf, "User"); + safeStrCpy(buf, _("User"), sizeof(buf)/sizeof(buf[0]) ); } return buf; } @@ -8292,7 +8710,7 @@ HostName() if (!GetComputerName(buf, &bufsiz)) { /*DisplayError("Error getting host name", GetLastError());*/ - strcpy(buf, "Unknown"); + safeStrCpy(buf, _("Unknown"), sizeof(buf)/sizeof(buf[0]) ); } return buf; } @@ -8330,7 +8748,7 @@ DisplayWhiteClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &blackRect : &whiteRect, "White", flag); + flipClock ? &blackRect : &whiteRect, _("White"), flag); } if (highlight && iconCurrent == iconBlack) { iconCurrent = iconWhite; @@ -8354,7 +8772,7 @@ DisplayBlackClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &whiteRect : &blackRect, "Black", flag); + flipClock ? &whiteRect : &blackRect, _("Black"), flag); } if (highlight && iconCurrent == iconWhite) { iconCurrent = iconBlack; @@ -8402,7 +8820,7 @@ AutoSaveGame() f = OpenFileDialog(hwndMain, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); fclose(f); @@ -8463,6 +8881,37 @@ IDLE_PRIORITY_CLASS 0x00000040 return 0x00000040; } +void RunCommand(char *cmdLine) +{ + /* Now create the child process. */ + STARTUPINFO siStartInfo; + PROCESS_INFORMATION piProcInfo; + + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.lpReserved = NULL; + siStartInfo.lpDesktop = NULL; + siStartInfo.lpTitle = NULL; + siStartInfo.dwFlags = STARTF_USESTDHANDLES; + siStartInfo.cbReserved2 = 0; + siStartInfo.lpReserved2 = NULL; + siStartInfo.hStdInput = NULL; + siStartInfo.hStdOutput = NULL; + siStartInfo.hStdError = NULL; + + CreateProcess(NULL, + cmdLine, /* command line */ + NULL, /* process security attributes */ + NULL, /* primary thread security attrs */ + TRUE, /* handles are inherited */ + DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP, + NULL, /* use parent's environment */ + NULL, + &siStartInfo, /* STARTUPINFO pointer */ + &piProcInfo); /* receives PROCESS_INFORMATION */ + + CloseHandle(piProcInfo.hThread); +} + /* Start a child process running the given program. The process's standard output can be read from "from", and its standard input can be written to "to". @@ -8706,9 +9155,9 @@ OpenTelnet(char *host, char *port, ProcRef *pr) char cmdLine[MSG_SIZ]; if (port[0] == NULLCHAR) { - sprintf(cmdLine, "%s %s", appData.telnetProgram, host); + snprintf(cmdLine, MSG_SIZ, "%s %s", appData.telnetProgram, host); } else { - sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port); + snprintf(cmdLine, MSG_SIZ, "%s %s %s", appData.telnetProgram, host, port); } return StartChildProcess(cmdLine, "", pr); } @@ -8807,9 +9256,9 @@ OpenCommPort(char *name, ProcRef *pr) char fullname[MSG_SIZ]; if (*name != '\\') - sprintf(fullname, "\\\\.\\%s", name); + snprintf(fullname, MSG_SIZ, "\\\\.\\%s", name); else - strcpy(fullname, name); + safeStrCpy(fullname, name, sizeof(fullname)/sizeof(fullname[0]) ); h = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); @@ -8841,7 +9290,7 @@ OpenCommPort(char *name, ProcRef *pr) int OpenLoopback(ProcRef *pr) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); return NO_ERROR; } @@ -8979,7 +9428,7 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr) break; } prevStderrPort = fromPort; // remember port used - sprintf(stderrPortStr, "%d", fromPort); + snprintf(stderrPortStr, MSG_SIZ, "%d", fromPort); if (send(s, stderrPortStr, strlen(stderrPortStr) + 1, 0) == SOCKET_ERROR) { err = WSAGetLastError(); @@ -9198,6 +9647,12 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError) return outCount; } +void +DoSleep(int n) +{ + if(n != 0) Sleep(n); +} + int OutputToProcessDelayed(ProcRef pr, char *message, int count, int *outError, long msdelay) @@ -9211,7 +9666,7 @@ void CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure, char *buf, int count, int error) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); } /* see wgamelist.c for Game List functions */ @@ -9299,26 +9754,26 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor, POINT frames[], int * nFrames); +#define kFactor 4 + void -AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames) +AnimateAtomicCapture(Board board, int fromX, int fromY, int toX, int toY) { // [HGM] atomic: animate blast wave int i; -if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY); + explodeInfo.fromX = fromX; explodeInfo.fromY = fromY; explodeInfo.toX = toX; explodeInfo.toY = toY; - for(i=1; i