X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=884c85cc0ae5e3cc7c8d3903936692cb72f6c5b1;hb=bdd61153a00af769f75d1f20d7938642592cbce9;hp=fb983363cb723f40e3c2de76aa5bf5c5ebfbe22e;hpb=2e85821da14eed8befd74e9aeb7ccf49c94a38a9;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index fb98336..884c85c 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -100,6 +100,8 @@ 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); @@ -108,6 +110,7 @@ int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, 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 */ @@ -222,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[] = @@ -449,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 @@ -485,13 +494,14 @@ void ThawUI() DrawMenuBar(hwndMain); } -static int fromX = -1, fromY = -1, toX, toY; // [HGM] moved upstream, so JAWS can use them +/*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 @@ -570,7 +580,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 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 = 7; 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++) { @@ -595,7 +605,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, case 4: if(!MoveHistoryIsUp()) continue; h = mh; break; -// case 5: // input to eval graph does not seem to get here! +// case 6: // input to eval graph does not seem to get here! // if(!EvalGraphIsUp()) continue; // h = evalGraphDialog; break; case 5: @@ -627,6 +637,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, !(!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++) { @@ -4844,7 +4751,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) && @@ -5124,39 +5030,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)) { @@ -5204,7 +5111,7 @@ 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(); @@ -5232,6 +5139,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 */ @@ -5333,16 +5241,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. */ @@ -5350,7 +5248,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: @@ -5560,6 +5457,36 @@ LoadGameDialog(HWND hwnd, char* title) } } +void UpdateICSWidth(HWND hText) +{ + HDC hdc; + TEXTMETRIC tm; + RECT rc; + HFONT hfont, hold_font; + LONG old_width, new_width; + + // get the text metrics + hdc = GetDC(hText); + hfont = CreateFontIndirect(&font[boardSize][CONSOLE_FONT]->lf); + hold_font = SelectObject(hdc, hfont); + GetTextMetrics(hdc, &tm); + SelectObject(hdc, hold_font); + DeleteObject(hfont); + ReleaseDC(hText, hdc); + + // get the rectangle + SendMessage(hText, EM_GETRECT, 0, (LPARAM)&rc); + + // update the width + new_width = (rc.right-rc.left) / tm.tmAveCharWidth; + old_width = GetWindowLong(hText, GWL_USERDATA); + if (new_width != old_width) + { + ics_update_width(new_width); + SetWindowLong(hText, GWL_USERDATA, new_width); + } +} + VOID ChangedConsoleFont() { @@ -5599,6 +5526,7 @@ ChangedConsoleFont() paraf.dxOffset = WRAP_INDENT; SendMessage(hText, EM_SETPARAFORMAT, 0, (LPARAM) ¶f); SendMessage(hText, EM_EXSETSEL, 0, (LPARAM)&sel); + UpdateICSWidth(hText); } /*---------------------------------------------------------------------------*\ @@ -5652,7 +5580,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) JAWS_ALT_INTERCEPT - if (appData.icsActive && (isalpha((char)wParam) || wParam == '0')) { + 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); @@ -5675,11 +5603,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); } @@ -5863,6 +5787,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GameListOptions(); break; + case IDM_NewChat: + ChatPopUp(); + break; + case IDM_CopyPosition: CopyFENToClipboard(); break; @@ -6114,6 +6042,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); @@ -6127,6 +6061,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; @@ -6665,6 +6607,7 @@ 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"); @@ -6697,13 +6640,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; } @@ -8195,18 +8131,35 @@ LRESULT CALLBACK ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static SnapData sd; - static HWND hText, hInput /*, hFocus*/; -// InputSource *is = consoleInputSource; + HWND hText, hInput; RECT rect; static int sizeX, sizeY; int newSizeX, newSizeY; MINMAXINFO *mmi; + WORD wMask; + + hText = GetDlgItem(hDlg, OPT_ConsoleText); + hInput = GetDlgItem(hDlg, OPT_ConsoleInput); 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); - hInput = GetDlgItem(hDlg, OPT_ConsoleInput); SetFocus(hInput); consoleTextWindowProc = (WNDPROC) SetWindowLong(hText, GWL_WNDPROC, (LONG) ConsoleTextSubclass); @@ -8234,7 +8187,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height; SetWindowPlacement(hDlg, &wp); } -#if 1 + // [HGM] Chessknight's change 2004-07-13 else { /* Determine Defaults */ WINDOWPLACEMENT wp; @@ -8253,7 +8206,13 @@ 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); + SetWindowLong(hText, GWL_USERDATA, 79); // initialize the text window's width + return FALSE; case WM_SETFOCUS: @@ -8313,6 +8272,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) return OnMoving( &sd, hDlg, wParam, lParam ); case WM_EXITSIZEMOVE: + UpdateICSWidth(hText); return OnExitSizeMove( &sd, hDlg, wParam, lParam ); } @@ -9383,6 +9343,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 } }; @@ -9582,6 +9543,11 @@ DrawPosition(int fullRedraw, Board board) HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board); } +void NotifyFrontendLogin() +{ + if (hwndConsole) + UpdateICSWidth(GetDlgItem(hwndConsole, OPT_ConsoleText)); +} VOID ResetFrontEnd() @@ -9604,6 +9570,7 @@ CommentPopUp(char *title, char *str) { HWND hwnd = GetActiveWindow(); EitherCommentPopUp(0, title, str, FALSE); + SAY(str); SetActiveWindow(hwnd); } @@ -9839,11 +9806,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; @@ -10966,15 +10934,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 ); @@ -10982,14 +10941,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 ); }