X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=6c5d0eeab93d5c43af9a24d79920ee0cccaff1e8;hb=e833cd22af38d0042dd3e5e6ccf7914fb18cf767;hp=c7fad6606f676a0453d7ecbfb1907a311323e5c0;hpb=e231271367c5533f71ee72939f471bd1b4f0fe41;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index c7fad66..6c5d0ee 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -1,11 +1,13 @@ /* * WinBoard.c -- Windows NT front end to XBoard - * $Id: winboard.c,v 2.3 2003/11/25 05:25:20 mann Exp $ * * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. Enhancements Copyright - * 1992-2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software - * Foundation, Inc. + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti * * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess, * which was written and is copyrighted by Wayne Christopher. @@ -88,7 +90,7 @@ #include "woptions.h" #include "wsockerr.h" #include "defaults.h" - +#include "help.h" #include "wsnap.h" //void InitEngineUCI( const char * iniDir, ChessProgramState * cps ); @@ -98,13 +100,17 @@ extern int whiteFlag, blackFlag; Boolean flipClock = FALSE; +extern HANDLE chatHandle[]; +extern int ics_type; 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(()); typedef struct { ChessSquare piece; POINT pos; /* window coordinates of current pos */ @@ -143,7 +149,7 @@ char szConsoleName[] = "WBConsole"; /* Title bar text */ char szTitle[] = "WinBoard"; -char szConsoleTitle[] = "ICS Interaction"; +char szConsoleTitle[] = "I C S Interaction"; char *programName; char *settingsFileName; @@ -219,7 +225,11 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOAR #if __GNUC__ && !defined(_winmajor) #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */ #else +#if defined(_winmajor) #define oldDialog (_winmajor < 4) +#else +#define oldDialog 0 +#endif #endif char *defaultTextAttribs[] = @@ -306,7 +316,7 @@ MyButtonDesc buttonDesc[N_BUTTONS] = }; int tinyLayout = 0, smallLayout = 0; -#define MENU_BAR_ITEMS 6 +#define MENU_BAR_ITEMS 7 char *menuBarText[2][MENU_BAR_ITEMS+1] = { { "&File", "&Mode", "&Action", "&Step", "&Options", "&Help", NULL }, { "&F", "&M", "&A", "&S", "&O", "&H", NULL }, @@ -446,6 +456,8 @@ VOID EngineOutputPopDown(); BOOL EngineOutputIsUp(); VOID EngineOutputUpdate( FrontEndProgramStats * stats ); +VOID EngineOptionsPopup(); // [HGM] settings + VOID GothicPopUp(char *title, VariantClass variant); /* * Setting "frozen" should disable all user input other than deleting @@ -482,6 +494,26 @@ void ThawUI() DrawMenuBar(hwndMain); } +/*static*/ int fromX = -1, fromY = -1, toX, toY; // [HGM] moved upstream, so JAWS can use them + +/* JAWS preparation patch (WinBoard for the sight impaired). Define required insertions as empty */ +#ifdef JAWS +#include "jaws.c" +#else +#define JAWS_INIT +#define JAWS_ARGS +#define JAWS_ALT_INTERCEPT +#define JAWS_KB_NAVIGATION +#define JAWS_MENU_ITEMS +#define JAWS_SILENCE +#define JAWS_REPLAY +#define JAWS_ACCEL +#define JAWS_COPYRIGHT +#define JAWS_DELETE(X) X +#define SAYMACHINEMOVE() +#define SAY(X) +#endif + /*---------------------------------------------------------------------------*\ * * WinMain @@ -508,6 +540,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, return (FALSE); } + JAWS_INIT + // InitCommonControlsEx(&ex); InitCommonControls(); @@ -522,6 +556,77 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 0, /* lowest message to examine */ 0)) /* highest message to examine */ { + + if(msg.message == WM_CHAR && msg.wParam == '\t') { + // [HGM] navigate: switch between all windows with tab + HWND e1 = NULL, e2 = NULL, mh = NULL, hInput = NULL, hText = NULL; + int i, currentElement = 0; + + // first determine what element of the chain we come from (if any) + if(appData.icsActive) { + hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput); + hText = GetDlgItem(hwndConsole, OPT_ConsoleText); + } + if(engineOutputDialog && EngineOutputIsUp()) { + e1 = GetDlgItem(engineOutputDialog, IDC_EngineMemo1); + e2 = GetDlgItem(engineOutputDialog, IDC_EngineMemo2); + } + if(moveHistoryDialog && MoveHistoryIsUp()) { + mh = GetDlgItem(moveHistoryDialog, IDC_MoveHistory); + } + if(msg.hwnd == hwndMain) currentElement = 7 ; else + if(msg.hwnd == engineOutputDialog) currentElement = 2; else + if(msg.hwnd == e1) currentElement = 2; else + if(msg.hwnd == e2) currentElement = 3; else + if(msg.hwnd == moveHistoryDialog) currentElement = 4; else + if(msg.hwnd == mh) currentElement = 4; else + if(msg.hwnd == evalGraphDialog) currentElement = 6; else + if(msg.hwnd == hText) currentElement = 5; else + if(msg.hwnd == hInput) currentElement = 6; else + for (i = 0; i < N_BUTTONS; i++) { + if (buttonDesc[i].hwnd == msg.hwnd) { currentElement = 1; break; } + } + + // determine where to go to + if(currentElement) { HWND h = NULL; int direction = GetKeyState(VK_SHIFT) < 0 ? -1 : 1; + do { + currentElement = (currentElement + direction) % 7; + switch(currentElement) { + case 0: + h = hwndMain; break; // passing this case always makes the loop exit + case 1: + h = buttonDesc[0].hwnd; break; // could be NULL + case 2: + if(!EngineOutputIsUp()) continue; // skip closed auxiliary windows + h = e1; break; + case 3: + if(!EngineOutputIsUp()) continue; + h = e2; break; + case 4: + if(!MoveHistoryIsUp()) continue; + h = mh; break; +// case 6: // input to eval graph does not seem to get here! +// if(!EvalGraphIsUp()) continue; +// h = evalGraphDialog; break; + case 5: + if(!appData.icsActive) continue; + SAY("display"); + h = hText; break; + case 6: + if(!appData.icsActive) continue; + SAY("input"); + h = hInput; break; + } + } while(h == 0); + + if(currentElement > 4 && IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); + if(currentElement < 5 && IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE); // all open together + SetFocus(h); + + continue; // this message now has been processed + } + } + if (!(commentDialog && IsDialogMessage(commentDialog, &msg)) && !(moveHistoryDialog && IsDialogMessage(moveHistoryDialog, &msg)) && !(evalGraphDialog && IsDialogMessage(evalGraphDialog, &msg)) && @@ -529,9 +634,15 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) && !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) && !(errorDialog && IsDialogMessage(errorDialog, &msg)) && - !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && + !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && JAWS_ACCEL !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) && !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) { + int done = 0, i; // [HGM] chat: dispatch cat-box messages + for(i=0; i>2; i++) { @@ -4749,7 +4750,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) // write bitmap data for(i=0; i now always do UserMoveTest(), and check colors there */ + /* [HGM] now always do UserMoveTest(), and check colors there */ toX = x; toY = y; /* [HGM] UserMoveEvent requires two calls now, to make sure move is legal before showing promotion popup */ - moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR); + moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, FALSE); if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ fromX = fromY = -1; ClearHighlights(); DrawPosition(FALSE, boards[currentMove]); break; } else - if(moveType != ImpossibleMove) { + if(moveType != ImpossibleMove && moveType != Comment) { /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */ if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && @@ -5031,39 +5029,40 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) If promotion to Q is legal, all are legal! */ if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; - // kludge to temporarily execute move on display, wthout promotng yet + // kludge to temporarily execute move on display, without promoting yet promotionChoice = TRUE; boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank boards[currentMove][toY][toX] = p; DrawPosition(FALSE, boards[currentMove]); boards[currentMove][fromY][fromX] = p; // take back, but display stays boards[currentMove][toY][toX] = q; + DisplayMessage("Select piece from holdings", ""); } else PromotionPopup(hwnd); - } else { /* not a promotion */ + goto noClear; + } else { // not a promotion. Move can be illegal if testLegality off, and should be made then. if (appData.animate || appData.highlightLastMove) { SetHighlights(fromX, fromY, toX, toY); } else { ClearHighlights(); } FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); - fromX = fromY = -1; if (appData.animate && !appData.highlightLastMove) { ClearHighlights(); DrawPosition(forceFullRepaint || FALSE, NULL); } } - break; - } - if (gotPremove) { - /* [HGM] it seemed that braces were missing here */ - SetPremoveHighlights(fromX, fromY, toX, toY); - fromX = fromY = -1; - break; + fromX = fromY = -1; + noClear: + break; } - } - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); + if (gotPremove && moveType != Comment) { + SetPremoveHighlights(fromX, fromY, toX, toY); +// DrawPosition(forceFullRepaint || FALSE, NULL); + } else ClearHighlights(); + fromX = fromY = -1; + DrawPosition(forceFullRepaint || FALSE, NULL); + if(moveType != Comment) break; } /* First downclick, or restart on a square with same color piece */ if (!frozen && OKToStartUserMove(x, y)) { @@ -5111,11 +5110,12 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) toY = y; saveAnimate = appData.animate; /* sorry, Hawk :) */ appData.animate = appData.animate && !appData.animateDragging; - moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR); + moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, TRUE); if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ fromX = fromY = -1; ClearHighlights(); DrawPosition(FALSE, boards[currentMove]); + appData.animate = saveAnimate; break; } else if(moveType != ImpossibleMove) { @@ -5137,6 +5137,8 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawPosition(FALSE, boards[currentMove]); boards[currentMove][fromY][fromX] = p; // take back, but display stays boards[currentMove][toY][toX] = q; + appData.animate = saveAnimate; + DisplayMessage("Select piece from holdings", ""); break; } else PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */ @@ -5238,16 +5240,6 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) else MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1); } else { /* message == WM_RBUTTONDOWN */ -#if 0 - if (buttonCount == 3) { - if (wParam & MK_SHIFT) - MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1); - else - MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1); - } else { - MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1); - } -#else /* Just have one menu, on the right button. Windows users don't think to try the middle one, and sometimes other software steals it, or it doesn't really exist. */ @@ -5255,7 +5247,6 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1); else MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1); -#endif } break; case IcsPlayingWhite: @@ -5308,24 +5299,9 @@ ButtonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case '\r': SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(buttonDesc[i].id, 0), 0); return TRUE; - case '\t': - if (appData.icsActive) { - if (GetKeyState(VK_SHIFT) < 0) { - /* shifted */ - HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput); - if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); - SetFocus(h); - } else { - /* unshifted */ - HWND h = GetDlgItem(hwndConsole, OPT_ConsoleText); - if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); - SetFocus(h); - } - return TRUE; - } - break; default: - if (appData.icsActive) { + if (appData.icsActive && (isalpha((char)wParam) || wParam == '0')) { + // [HGM] movenum: only letters or leading zero should go to ICS input HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput); if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); SetFocus(h); @@ -5566,30 +5542,25 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MouseEvent(hwnd, message, wParam, lParam); break; + JAWS_KB_NAVIGATION + case WM_CHAR: - if (appData.icsActive) { - if (wParam == '\t') { - if (GetKeyState(VK_SHIFT) < 0) { - /* shifted */ - HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput); - if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); - SetFocus(h); - } else { - /* unshifted */ - HWND h = GetDlgItem(hwndConsole, OPT_ConsoleText); - if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); - SetFocus(h); - } - } else { + JAWS_ALT_INTERCEPT + + if (appData.icsActive && (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9')) { + // [HGM] movenum: for non-zero digits we always do type-in dialog HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput); if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); SetFocus(h); SendMessage(h, message, wParam, lParam); - } - } else if (isalpha((char)wParam) || isdigit((char)wParam)) { - PopUpMoveDialog((char)wParam); + } else if(lParam != KF_REPEAT) { + if (isalpha((char)wParam) || isdigit((char)wParam)) { + PopUpMoveDialog((char)wParam); + } else if((char)wParam == 003) CopyGameToClipboard(); + else if((char)wParam == 026) PasteGameOrFENFromClipboard(); } + break; case WM_PALETTECHANGED: @@ -5600,11 +5571,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nnew = RealizePalette(hdc); if (nnew > 0) { paletteChanged = TRUE; -#if 0 - UpdateColors(hdc); -#else - InvalidateRect(hwnd, &boardRect, FALSE);/*faster!*/ -#endif + InvalidateRect(hwnd, &boardRect, FALSE); } ReleaseDC(hwnd, hdc); } @@ -5633,6 +5600,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_NewGame: ResetGameEvent(); AnalysisPopDown(); + SAY("new game enter a move to play against the computer with white"); break; case IDM_NewGameFRC: @@ -5755,6 +5723,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } else { EvalGraphPopUp(); + SetFocus(hwndMain); } break; @@ -5786,6 +5755,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GameListOptions(); break; + case IDM_NewChat: + ChatPopUp(); + break; + case IDM_CopyPosition: CopyFENToClipboard(); break; @@ -5822,6 +5795,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } + SAY("computer starts playing white"); break; case IDM_MachineBlack: @@ -5835,6 +5809,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } + SAY("computer starts playing black"); break; case IDM_TwoMachines: @@ -5848,6 +5823,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } + SAY("programs start playing each other"); break; case IDM_AnalysisMode: @@ -5855,6 +5831,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) sprintf(buf, "%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) { @@ -5904,10 +5881,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_EditGame: EditGameEvent(); + SAY("edit game"); break; case IDM_EditPosition: EditPositionEvent(); + SAY("to set up a position type a FEN"); break; case IDM_Training: @@ -5987,6 +5966,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetFocus(hwndMain); break; + JAWS_MENU_ITEMS + case IDM_Forward: ForwardEvent(); SetFocus(hwndMain); @@ -6029,6 +6010,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawPosition(FALSE, NULL); break; + case IDM_MuteSounds: + mute = !mute; // [HGM] mute: keep track of global muting variable + CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds, + MF_BYCOMMAND|(mute?MF_CHECKED:MF_UNCHECKED)); + break; + case IDM_GeneralOptions: GeneralOptionsPopup(hwnd); DrawPosition(TRUE, NULL); @@ -6042,6 +6029,14 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) EnginePlayOptionsPopup(hwnd); break; + case IDM_Engine1Options: + EngineOptionsPopup(hwnd, &first); + break; + + case IDM_Engine2Options: + EngineOptionsPopup(hwnd, &second); + break; + case IDM_OptionsUCI: UciOptionsPopup(hwnd); break; @@ -6113,15 +6108,17 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_HELPCONTENTS: - if (!WinHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) { - MessageBox (GetFocus(), + if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") && + !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { + MessageBox (GetFocus(), "Unable to activate help", szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; case IDM_HELPSEARCH: - if (!WinHelp(hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"")) { + if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") && + !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), "Unable to activate help", szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); @@ -6577,8 +6574,11 @@ BOOLEAN MyPlaySound(MySound *ms) { BOOLEAN ok = FALSE; + + if(mute) return TRUE; // [HGM] mute: suppress all sound play when muted switch (ms->name[0]) { case NULLCHAR: + if(appData.debugMode) fprintf(debugFP, "silence\n"); /* Silence */ ok = TRUE; break; @@ -6608,13 +6608,6 @@ MyPlaySound(MySound *ms) /* Don't print an error: this can happen innocently if the sound driver is busy; for instance, if another instance of WinBoard is playing a sound at about the same time. */ -#if 0 - if (!ok) { - char buf[MSG_SIZ]; - sprintf(buf, "Error playing sound %s", ms->name); - DisplayError(buf, GetLastError()); - } -#endif return ok; } @@ -7100,6 +7093,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); + JAWS_COPYRIGHT return (TRUE); case WM_COMMAND: /* message: received a command */ @@ -7304,12 +7298,35 @@ 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 ) { + currentMove = 2*n-1; + if(currentMove > forwardMostMove) currentMove = forwardMostMove; + if(currentMove < backwardMostMove) currentMove = backwardMostMove; + EndDialog(hDlg, TRUE); + DrawPosition(TRUE, boards[currentMove]); + if(currentMove > backwardMostMove) DisplayMove(currentMove - 1); + else DisplayMessage("", ""); + return TRUE; + } + } if (gameMode != EditGame && currentMove != forwardMostMove && gameMode != Training) { DisplayMoveError("Displayed move is not current"); } else { - GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); - if (ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, +// 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; @@ -7341,6 +7358,9 @@ PopUpMoveDialog(char firstchar) 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), @@ -7806,6 +7826,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } break; case WM_CHAR: + if(wParam != '\022') { if (wParam == '\t') { if (GetKeyState(VK_SHIFT) < 0) { /* shifted */ @@ -7821,10 +7842,31 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } } else { hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput); - SetFocus(hInput); + JAWS_DELETE( SetFocus(hInput); ) SendMessage(hInput, message, wParam, lParam); } return 0; + } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu + case WM_RBUTTONUP: + if (GetKeyState(VK_SHIFT) & ~1) { + SendDlgItemMessage(hwndConsole, OPT_ConsoleText, + WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); + } else { + POINT pt; + HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry); + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) { + EnableMenuItem(hmenu, IDM_Copy, MF_BYCOMMAND|MF_GRAYED); + EnableMenuItem(hmenu, IDM_QuickPaste, MF_BYCOMMAND|MF_GRAYED); + } + if (!IsClipboardFormatAvailable(CF_TEXT)) { + EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED); + } + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + MenuPopup(hwnd, pt, hmenu, -1); + } + return 0; case WM_PASTE: hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput); SetFocus(hInput); @@ -7846,26 +7888,6 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE); } return 0; - case WM_RBUTTONUP: - if (GetKeyState(VK_SHIFT) & ~1) { - SendDlgItemMessage(hwndConsole, OPT_ConsoleText, - WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); - } else { - POINT pt; - HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry); - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - EnableMenuItem(hmenu, IDM_Copy, MF_BYCOMMAND|MF_GRAYED); - EnableMenuItem(hmenu, IDM_QuickPaste, MF_BYCOMMAND|MF_GRAYED); - } - if (!IsClipboardFormatAvailable(CF_TEXT)) { - EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED); - } - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - MenuPopup(hwnd, pt, hmenu, -1); - } - return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_QuickPaste: @@ -7982,6 +8004,7 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case '\021': /* Ctrl+Q */ quoteNextChar = TRUE; return 0; + JAWS_REPLAY default: break; } @@ -8082,8 +8105,25 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) static int sizeX, sizeY; int newSizeX, newSizeY; MINMAXINFO *mmi; + WORD wMask; switch (message) { + case WM_NOTIFY: + if (((NMHDR*)lParam)->code == EN_LINK) + { + ENLINK *pLink = (ENLINK*)lParam; + if (pLink->msg == WM_LBUTTONUP) + { + TEXTRANGE tr; + + tr.chrg = pLink->chrg; + tr.lpstrText = malloc(1+tr.chrg.cpMax-tr.chrg.cpMin); + SendMessage(hText, EM_GETTEXTRANGE, 0, (LPARAM)&tr); + ShellExecute(NULL, "open", tr.lpstrText, NULL, NULL, SW_SHOW); + free(tr.lpstrText); + } + } + break; case WM_INITDIALOG: /* message: initialize dialog box */ hwndConsole = hDlg; hText = GetDlgItem(hDlg, OPT_ConsoleText); @@ -8115,14 +8155,14 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height; SetWindowPlacement(hDlg, &wp); } -#if 0 + // [HGM] Chessknight's change 2004-07-13 else { /* Determine Defaults */ WINDOWPLACEMENT wp; wpConsole.x = winWidth + 1; wpConsole.y = boardY; - wpConsoleW = screenWidth - winWidth; - wpConsoleH = winHeight; + wpConsole.width = screenWidth - winWidth; + wpConsole.height = winHeight; EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; @@ -8134,7 +8174,12 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height; SetWindowPlacement(hDlg, &wp); } -#endif + + // Allow hText to highlight URLs and send notifications on them + wMask = SendMessage(hText, EM_GETEVENTMASK, 0, 0L); + SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK); + SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L); + return FALSE; case WM_SETFOCUS: @@ -8362,12 +8407,14 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, } oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf); + JAWS_SILENCE + ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN, rect->top, ETO_CLIPPED|ETO_OPAQUE, rect, str, strlen(str), NULL); if(logoHeight > 0 && appData.clockMode) { RECT r; - sprintf(buf, "%s %s", TimeString(timeRemaining), flagFell); + sprintf(buf, "%s %s", buf+7, flagFell); r.top = rect->top + logoHeight/2; r.left = rect->left; r.right = rect->right; @@ -9016,6 +9063,9 @@ DisplayMessage(char *str1, char *str2) messageText[MESSAGE_TEXT_MAX - 1] = NULLCHAR; if (hwndMain == NULL || IsIconic(hwndMain)) return; + + SAYMACHINEMOVE(); + hdc = GetDC(hwndMain); oldFont = SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf); ExtTextOut(hdc, messageRect.left, messageRect.top, ETO_CLIPPED|ETO_OPAQUE, @@ -9259,6 +9309,7 @@ static GLT_Item GLT_ItemInfo[] = { { GLT_TIME_CONTROL,"Time Control" }, { GLT_VARIANT, "Variant" }, { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK }, + { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom { 0, 0 } }; @@ -9480,6 +9531,7 @@ CommentPopUp(char *title, char *str) { HWND hwnd = GetActiveWindow(); EitherCommentPopUp(0, title, str, FALSE); + SAY(str); SetActiveWindow(hwnd); } @@ -9715,11 +9767,12 @@ void ScheduleDelayedEvent(DelayedEventCallback cb, long millisec) { if (delayedTimerEvent != 0) { - if (appData.debugMode) { + if (appData.debugMode && cb != delayedTimerCallback) { // [HGM] alive: not too much debug fprintf(debugFP, "ScheduleDelayedEvent: event already scheduled\n"); } KillTimer(hwndMain, delayedTimerEvent); delayedTimerEvent = 0; + if(delayedTimerCallback != cb) // [HGM] alive: do not "flush" same event, just postpone it delayedTimerCallback(); } delayedTimerCallback = cb; @@ -10842,15 +10895,6 @@ Tween(start, mid, finish, factor, frames, nFrames) void HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current ) { -#if 0 - char buf[256]; - - sprintf( buf, "HistorySet: first=%d, last=%d, current=%d (%s)\n", - first, last, current, current >= 0 ? movelist[current] : "n/a" ); - - OutputDebugString( buf ); -#endif - MoveHistorySet( movelist, first, last, current, pvInfoList ); EvalGraphSet( first, last, current, pvInfoList ); @@ -10858,14 +10902,5 @@ HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current ) void SetProgramStats( FrontEndProgramStats * stats ) { -#if 0 - char buf[1024]; - - sprintf( buf, "SetStats for %d: depth=%d, nodes=%lu, score=%5.2f, time=%5.2f, pv=%s\n", - stats->which, stats->depth, stats->nodes, stats->score / 100.0, stats->time / 100.0, stats->pv == 0 ? "n/a" : stats->pv ); - - OutputDebugString( buf ); -#endif - EngineOutputUpdate( stats ); }