X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=24fd967df54780be9da6bdc0cd0dd3106e5ebf7a;hb=8e0e2f1c14e76ea660f7bff6a104baed0f0048df;hp=fb317b741af53d4ca46b0fc45bf85fb077c93c40;hpb=b95871c81d97fab30442cb1509b06168dfd3aeff;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index fb317b7..24fd967 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 toX, int toY, int nFrames); - +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 */ @@ -132,10 +138,10 @@ static HighlightInfo highlightInfo = { {{-1, -1}, {-1, -1}} }; static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} }; typedef struct { // [HGM] atomic - int x, y, radius; + int fromX, fromY, toX, toY, radius; } ExplodeInfo; -static ExplodeInfo explodeInfo = {0, 0, 0}; +static ExplodeInfo explodeInfo; /* Window class names */ char szAppName[] = "WinBoard"; @@ -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; @@ -152,9 +158,10 @@ char installDir[MSG_SIZ]; BoardSize boardSize; BOOLEAN chessProgram; -static int boardX, boardY, consoleX, consoleY, consoleW, consoleH; +static int boardX, boardY; +int minX, minY; // [HGM] placement: volatile limits on upper-left corner static int squareSize, lineGap, minorSize; -static int winWidth, winHeight; +static int winWidth, winHeight, winW, winH; static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo static int logoHeight = 0; static char messageText[MESSAGE_TEXT_MAX]; @@ -201,6 +208,7 @@ static HICON iconWhite, iconBlack, iconCurrent; static int doingSizing = FALSE; static int lastSizing = 0; static int prevStderrPort; +static HBITMAP userLogo; /* [AS] Support for background textures */ #define BACK_TEXTURE_MODE_DISABLED 0 @@ -217,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[] = @@ -304,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 }, @@ -426,6 +438,8 @@ HWND engineOutputDialog = NULL; BOOLEAN engineOutputDialogUp = FALSE; WindowPlacement wpEngineOutput; +WindowPlacement wpGameList; +WindowPlacement wpConsole; VOID MoveHistoryPopUp(); VOID MoveHistoryPopDown(); @@ -442,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 @@ -478,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 @@ -504,6 +540,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, return (FALSE); } + JAWS_INIT + // InitCommonControlsEx(&ex); InitCommonControls(); @@ -518,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)) && @@ -525,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 screenWidth - 32) *x = 0; if (*y > screenHeight - 32) *y = 0; - if (*x < 0) *x = 0; - if (*y < 0) *y = 0; -// if (*x < 10) *x = 10; -// if (*y < gap) *y = gap; + if (*x < minX) *x = minX; + if (*y < minY) *y = minY; } BOOL @@ -613,6 +741,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) GetCurrentDirectory(MSG_SIZ, installDir); } gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] won't have open window otherwise + screenWidth = screenHeight = 1000; // [HGM] placement: kludge to allow calling EnsureOnScreen from InitAppData InitAppData(lpCmdLine); /* Get run-time parameters */ if (appData.debugMode) { debugFP = fopen(appData.nameOfDebugFile, "w"); @@ -658,13 +787,19 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) 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]) { - char buf[MSG_SIZ]; sprintf(buf, "%s\\logo.bmp", appData.secondDirectory); second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); } } + SetUserLogo(); + iconWhite = LoadIcon(hInstance, "icon_white"); iconBlack = LoadIcon(hInstance, "icon_black"); iconCurrent = iconWhite; @@ -674,11 +809,11 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) for (ibs = (int) NUM_SIZES - 1; ibs >= 0; ibs--) { /* Compute window size for each board size, and use the largest size that fits on this screen as the default. */ - InitDrawingSizes((BoardSize)ibs, 0); + InitDrawingSizes((BoardSize)(ibs+1000), 0); if (boardSize == (BoardSize)-1 && - winHeight <= screenHeight + winH <= screenHeight - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYCAPTION) - 10 - && winWidth <= screenWidth) { + && winW <= screenWidth) { boardSize = (BoardSize)ibs; } } @@ -726,7 +861,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) InitBackEnd2(); /* Make the window visible; update its client area; and return "success" */ - EnsureOnScreen(&boardX, &boardY); + EnsureOnScreen(&boardX, &boardY, minX, minY); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = nCmdShow; @@ -737,15 +872,9 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) wp.rcNormalPosition.bottom = boardY + winHeight; SetWindowPlacement(hwndMain, &wp); - SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, + if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); -#if 0 - /* [AS] Disable the FRC stuff if not playing the proper variant */ - if( gameInfo.variant != VariantFischeRandom ) { - EnableMenuItem( GetMenu(hwndMain), IDM_NewGameFRC, MF_GRAYED ); - } -#endif if (hwndConsole) { #if AOT_CONSOLE SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, @@ -753,7 +882,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) #endif ShowWindow(hwndConsole, nCmdShow); } - UpdateWindow(hwnd); + if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE); + if(gameListDialog) SetFocus(gameListDialog); // [HGM] jaws: for if we clicked multi-game game file return TRUE; @@ -763,7 +893,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) typedef enum { ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone, ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings, - ArgSettingsFilename + ArgSettingsFilename, + ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window } ArgType; typedef struct { @@ -794,6 +925,7 @@ ArgDescriptor argDescriptors[] = { { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, { "", ArgNone, NULL }, /* keyword arguments */ + JAWS_ARGS { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE }, { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE }, { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE }, @@ -973,10 +1105,6 @@ ArgDescriptor argDescriptors[] = { { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE }, { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, -#if 0 - { "cmailGameName", ArgString, (LPVOID) &appData.cmailGameName, FALSE }, - { "cmail", ArgString, (LPVOID) &appData.cmailGameName, FALSE }, -#endif { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE }, { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, @@ -1099,28 +1227,6 @@ ArgDescriptor argDescriptors[] = { { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE }, - { "x", ArgInt, (LPVOID) &boardX, TRUE }, - { "y", ArgInt, (LPVOID) &boardY, TRUE }, - { "icsX", ArgInt, (LPVOID) &consoleX, TRUE }, - { "icsY", ArgInt, (LPVOID) &consoleY, TRUE }, - { "icsW", ArgInt, (LPVOID) &consoleW, TRUE }, - { "icsH", ArgInt, (LPVOID) &consoleH, TRUE }, - { "analysisX", ArgInt, (LPVOID) &analysisX, TRUE }, - { "analysisY", ArgInt, (LPVOID) &analysisY, TRUE }, - { "analysisW", ArgInt, (LPVOID) &analysisW, TRUE }, - { "analysisH", ArgInt, (LPVOID) &analysisH, TRUE }, - { "commentX", ArgInt, (LPVOID) &commentX, TRUE }, - { "commentY", ArgInt, (LPVOID) &commentY, TRUE }, - { "commentW", ArgInt, (LPVOID) &commentW, TRUE }, - { "commentH", ArgInt, (LPVOID) &commentH, TRUE }, - { "tagsX", ArgInt, (LPVOID) &editTagsX, TRUE }, - { "tagsY", ArgInt, (LPVOID) &editTagsY, TRUE }, - { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE }, - { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE }, - { "gameListX", ArgInt, (LPVOID) &gameListX, TRUE }, - { "gameListY", ArgInt, (LPVOID) &gameListY, TRUE }, - { "gameListW", ArgInt, (LPVOID) &gameListW, TRUE }, - { "gameListH", ArgInt, (LPVOID) &gameListH, TRUE }, { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE }, @@ -1195,25 +1301,6 @@ ArgDescriptor argDescriptors[] = { { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE }, { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE }, - /* [AS] Layout stuff */ - { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE }, - { "moveHistoryX", ArgInt, (LPVOID) &wpMoveHistory.x, TRUE }, - { "moveHistoryY", ArgInt, (LPVOID) &wpMoveHistory.y, TRUE }, - { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE }, - { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE }, - - { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE }, - { "evalGraphX", ArgInt, (LPVOID) &wpEvalGraph.x, TRUE }, - { "evalGraphY", ArgInt, (LPVOID) &wpEvalGraph.y, TRUE }, - { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE }, - { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE }, - - { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE }, - { "engineOutputX", ArgInt, (LPVOID) &wpEngineOutput.x, TRUE }, - { "engineOutputY", ArgInt, (LPVOID) &wpEngineOutput.y, TRUE }, - { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE }, - { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE }, - /* [HGM] board-size, adjudication and misc. options */ { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE }, { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE }, @@ -1246,6 +1333,9 @@ ArgDescriptor argDescriptors[] = { { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE }, { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE }, { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE }, + { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE }, + { "icstype", ArgInt, (LPVOID) &ics_type, FALSE }, + { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE }, #ifdef ZIPPY { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE }, @@ -1286,6 +1376,7 @@ ArgDescriptor argDescriptors[] = { { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE }, { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE }, { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE }, + { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE }, /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */ { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE }, #endif @@ -1301,6 +1392,56 @@ ArgDescriptor argDescriptors[] = { { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE }, { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE }, { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE }, + { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE }, + { "wrapContinuationSequence", ArgString, (LPVOID) &appData.wrapContSeq, FALSE }, + { "useInternalWrap", ArgTrue, (LPVOID) &appData.useInternalWrap, FALSE }, /* noJoin usurps this if set */ + + // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others + { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed + { "minY", ArgZ, (LPVOID) &minY, FALSE }, + { "winWidth", ArgInt, (LPVOID) &winWidth, TRUE }, // [HGM] placement: dummies to remember right & bottom + { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, // for attaching auxiliary windows to them + { "x", ArgInt, (LPVOID) &boardX, TRUE }, + { "y", ArgInt, (LPVOID) &boardY, TRUE }, + { "icsX", ArgX, (LPVOID) &wpConsole.x, TRUE }, + { "icsY", ArgY, (LPVOID) &wpConsole.y, TRUE }, + { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE }, + { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE }, + { "analysisX", ArgX, (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists + { "analysisY", ArgY, (LPVOID) &analysisY, FALSE }, // provided for compatibility with old ini files + { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE }, + { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE }, + { "commentX", ArgX, (LPVOID) &commentX, TRUE }, + { "commentY", ArgY, (LPVOID) &commentY, TRUE }, + { "commentW", ArgInt, (LPVOID) &commentW, TRUE }, + { "commentH", ArgInt, (LPVOID) &commentH, TRUE }, + { "tagsX", ArgX, (LPVOID) &editTagsX, TRUE }, + { "tagsY", ArgY, (LPVOID) &editTagsY, TRUE }, + { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE }, + { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE }, + { "gameListX", ArgX, (LPVOID) &wpGameList.x, TRUE }, + { "gameListY", ArgY, (LPVOID) &wpGameList.y, TRUE }, + { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE }, + { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE }, + /* [AS] Layout stuff */ + { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE }, + { "moveHistoryX", ArgX, (LPVOID) &wpMoveHistory.x, TRUE }, + { "moveHistoryY", ArgY, (LPVOID) &wpMoveHistory.y, TRUE }, + { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE }, + { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE }, + + { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE }, + { "evalGraphX", ArgX, (LPVOID) &wpEvalGraph.x, TRUE }, + { "evalGraphY", ArgY, (LPVOID) &wpEvalGraph.y, TRUE }, + { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE }, + { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE }, + + { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE }, + { "engineOutputX", ArgX, (LPVOID) &wpEngineOutput.x, TRUE }, + { "engineOutputY", ArgY, (LPVOID) &wpEngineOutput.y, TRUE }, + { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE }, + { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE }, + { NULL, ArgNone, NULL, FALSE } }; @@ -1355,6 +1496,10 @@ ParseFontName(char *name, MyFontParams *mfp) mfp->italic = (strchr(p, 'i') != NULL); mfp->underline = (strchr(p, 'u') != NULL); mfp->strikeout = (strchr(p, 's') != NULL); + mfp->charset = DEFAULT_CHARSET; + q = strchr(p, 'c'); + if (q) + mfp->charset = (BYTE) atoi(q+1); } /* Color name parser. @@ -1631,6 +1776,19 @@ ParseArgs(GetFunc get, void *cl) *(int *) ad->argLoc = atoi(argValue); break; + case ArgX: + *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute + break; + + case ArgY: + *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...) + break; + + case ArgZ: + *(int *) ad->argLoc = atoi(argValue); + EnsureOnScreen(&boardX, &boardY, minX, minY); + break; + case ArgFloat: *(float *) ad->argLoc = (float) atof(argValue); break; @@ -1716,7 +1874,7 @@ LFfromMFP(LOGFONT* lf, MyFontParams *mfp) lf->lfItalic = mfp->italic; lf->lfUnderline = mfp->underline; lf->lfStrikeOut = mfp->strikeout; - lf->lfCharSet = DEFAULT_CHARSET; + lf->lfCharSet = mfp->charset; lf->lfOutPrecision = OUT_DEFAULT_PRECIS; lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; lf->lfQuality = DEFAULT_QUALITY; @@ -1894,10 +2052,6 @@ InitAppData(LPSTR lpCmdLine) saveSettingsOnExit = TRUE; boardX = CW_USEDEFAULT; boardY = CW_USEDEFAULT; - consoleX = CW_USEDEFAULT; - consoleY = CW_USEDEFAULT; - consoleW = CW_USEDEFAULT; - consoleH = CW_USEDEFAULT; analysisX = CW_USEDEFAULT; analysisY = CW_USEDEFAULT; analysisW = CW_USEDEFAULT; @@ -1910,10 +2064,6 @@ InitAppData(LPSTR lpCmdLine) editTagsY = CW_USEDEFAULT; editTagsW = CW_USEDEFAULT; editTagsH = CW_USEDEFAULT; - gameListX = CW_USEDEFAULT; - gameListY = CW_USEDEFAULT; - gameListW = CW_USEDEFAULT; - gameListH = CW_USEDEFAULT; icsTextMenuString = ICS_TEXT_MENU_DEFAULT; icsNames = ICS_NAMES; firstChessProgramNames = FCP_NAMES; @@ -1971,9 +2121,11 @@ InitAppData(LPSTR lpCmdLine) appData.firstOptions = ""; appData.secondOptions = ""; + InitWindowPlacement( &wpGameList ); InitWindowPlacement( &wpMoveHistory ); InitWindowPlacement( &wpEvalGraph ); InitWindowPlacement( &wpEngineOutput ); + InitWindowPlacement( &wpConsole ); /* [HGM] User-selectable board size, adjudication control, miscellaneous */ appData.NrFiles = -1; @@ -2172,7 +2324,7 @@ SaveSettings(char* name) return; } fprintf(f, ";\n"); - fprintf(f, "; %s %s.%s Save Settings file\n", PRODUCT, VERSION, PATCHLEVEL); + fprintf(f, "; %s Save Settings file\n", PACKAGE_STRING); fprintf(f, ";\n"); fprintf(f, "; You can edit the values of options that are already set in this file,\n"); fprintf(f, "; but if you add other options, the next Save Settings will not save them.\n"); @@ -2186,10 +2338,10 @@ SaveSettings(char* name) if (hwndConsole) { GetWindowPlacement(hwndConsole, &wp); - consoleX = wp.rcNormalPosition.left; - consoleY = wp.rcNormalPosition.top; - consoleW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - consoleH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + wpConsole.x = wp.rcNormalPosition.left; + wpConsole.y = wp.rcNormalPosition.top; + wpConsole.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + wpConsole.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; } if (analysisDialog) { @@ -2218,10 +2370,10 @@ SaveSettings(char* name) if (gameListDialog) { GetWindowPlacement(gameListDialog, &wp); - gameListX = wp.rcNormalPosition.left; - gameListY = wp.rcNormalPosition.top; - gameListW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - gameListH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + wpGameList.x = wp.rcNormalPosition.left; + wpGameList.y = wp.rcNormalPosition.top; + wpGameList.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + wpGameList.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; } /* [AS] Move history */ @@ -2287,8 +2439,15 @@ SaveSettings(char* name) } break; case ArgInt: + case ArgZ: fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc); break; + case ArgX: + fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value + break; + case ArgY: + fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY); + break; case ArgFloat: fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc); break; @@ -2338,13 +2497,14 @@ SaveSettings(char* name) for (bs=0; bsargLoc]->mfp; fprintf(f, "/size=%s ", sizeInfo[bs].name); - fprintf(f, "/%s=\"%s:%g%s%s%s%s%s\"\n", + fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n", ad->argName, mfp->faceName, mfp->pointSize, mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "", mfp->bold ? "b" : "", mfp->italic ? "i" : "", mfp->underline ? "u" : "", - mfp->strikeout ? "s" : ""); + mfp->strikeout ? "s" : "", + (int)mfp->charset); } } break; @@ -2884,57 +3044,10 @@ void CreatePiecesFromFont() /* Create bitmaps */ hfont_old = SelectObject( hdc, hPieceFont ); -#if 0 - CreatePieceMaskFromFont( hdc_window, hdc, PM_WP ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WN ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WB ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WR ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WQ ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WK ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BP ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BN ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BB ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BR ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BK ); - - CreatePieceMaskFromFont( hdc_window, hdc, PM_WA ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WC ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WF ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WH ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WE ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WW ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WU ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WO ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WG ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WM ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WSG ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WV ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WAB ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WD ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WL ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_WS ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BA ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BC ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BF ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BH ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BE ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BW ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BU ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BO ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BG ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BM ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BSG ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BV ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BAB ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BD ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BL ); - CreatePieceMaskFromFont( hdc_window, hdc, PM_BS ); -#else for(i=(int)WhitePawn; i<(int)EmptySquare; i++) /* [HGM] made a loop for this */ if(PieceToChar((ChessSquare)i) != '.') /* skip unused pieces */ CreatePieceMaskFromFont( hdc_window, hdc, i ); -#endif + SelectObject( hdc, hfont_old ); fontBitmapSquareSize = squareSize; @@ -3077,7 +3190,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) char buf[MSG_SIZ]; char *str; HMENU hmenu = GetMenu(hwndMain); - RECT crect, wrect; + RECT crect, wrect, oldRect; int offby; LOGBRUSH logbrush; @@ -3087,6 +3200,11 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize; + oldRect.left = boardX; //[HGM] placement: remember previous window params + oldRect.top = boardY; + oldRect.right = boardX + winWidth; + oldRect.bottom = boardY + winHeight; + tinyLayout = sizeInfo[boardSize].tinyLayout; smallLayout = sizeInfo[boardSize].smallLayout; squareSize = sizeInfo[boardSize].squareSize; @@ -3135,7 +3253,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) ReleaseDC(hwndMain, hdc); /* Compute where everything goes */ - if(first.programLogo || second.programLogo) { + if((first.programLogo || second.programLogo) && !tinyLayout) { /* [HGM] logo: if either logo is on, reserve space for it */ logoHeight = 2*clockSize.cy; leftLogoRect.left = OUTER_MARGIN; @@ -3149,19 +3267,19 @@ InitDrawingSizes(BoardSize boardSize, int flags) rightLogoRect.bottom = OUTER_MARGIN + logoHeight; - blackRect.left = leftLogoRect.right; - blackRect.right = rightLogoRect.left; - blackRect.top = OUTER_MARGIN; - blackRect.bottom = blackRect.top + clockSize.cy; + whiteRect.left = leftLogoRect.right; + whiteRect.right = OUTER_MARGIN + boardWidth/2 - INNER_MARGIN/2; + whiteRect.top = OUTER_MARGIN; + whiteRect.bottom = whiteRect.top + logoHeight; - whiteRect.left = blackRect.left ; - whiteRect.right = blackRect.right; - whiteRect.top = blackRect.bottom; - whiteRect.bottom = leftLogoRect.bottom; + blackRect.right = rightLogoRect.left; + blackRect.left = whiteRect.right + INNER_MARGIN; + blackRect.top = whiteRect.top; + blackRect.bottom = whiteRect.bottom; } else { whiteRect.left = OUTER_MARGIN; whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2; - whiteRect.top = OUTER_MARGIN + logoHeight; + whiteRect.top = OUTER_MARGIN; whiteRect.bottom = whiteRect.top + clockSize.cy; blackRect.left = whiteRect.right + INNER_MARGIN; @@ -3187,13 +3305,25 @@ InitDrawingSizes(BoardSize boardSize, int flags) sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN; sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN; - if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only - winWidth = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN; - winHeight = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + + oldBoardSize = boardSize; + oldTinyLayout = tinyLayout; + winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN; + winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN; + if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only + winWidth = winW; // [HGM] placement: set through temporary which can used by initial sizing choice + winHeight = winH; // without disturbing window attachments GetWindowRect(hwndMain, &wrect); SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE); + + // [HGM] placement: let attached windows follow size change. + ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory ); + ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph ); + ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput ); + ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList ); + ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole ); + /* compensate if menu bar wrapped */ GetClientRect(hwndMain, &crect); offby = boardRect.bottom + OUTER_MARGIN - crect.bottom; @@ -3303,8 +3433,6 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* if (boardSize == oldBoardSize) return; [HGM] variant might have changed */ - oldBoardSize = boardSize; - oldTinyLayout = tinyLayout; /* Load piece bitmaps for this board size */ for (i=0; i<=2; i++) { @@ -3715,35 +3843,13 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); -#if 0 - /* Use black piece color for outline of white pieces */ - /* Not sure this looks really good (though xboard does it). - Maybe better to have another selectable color, default black */ - SelectObject(hdc, blackPieceBrush); /* could have own brush */ - SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE)); - BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); -#else /* Use black for outline of white pieces */ SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE)); if(appData.upsideDown && color==flipView) StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND); -#endif } else { -#if 0 - /* Use white piece color for details of black pieces */ - /* Requires filled-in solid bitmaps (BLACK_PIECE class); the - WHITE_PIECE ones aren't always the right shape. */ - /* Not sure this looks really good (though xboard does it). - Maybe better to have another selectable color, default medium gray? */ - oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, BLACK_PIECE)); - oldBrush = SelectObject(hdc, whitePieceBrush); /* could have own brush */ - BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); - SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE)); - SelectObject(hdc, blackPieceBrush); - BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); -#else /* Use square color for details of black pieces */ oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE)); oldBrush = SelectObject(hdc, blackPieceBrush); @@ -3751,7 +3857,6 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); -#endif } SelectObject(hdc, oldBrush); SelectObject(tmphdc, oldBitmap); @@ -4233,7 +4338,7 @@ void fputDW(FILE *f, int x) #define MAX_CLIPS 200 /* more than enough */ VOID -DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps) +DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) { // HBITMAP bufferBitmap; BITMAP bi; @@ -4242,13 +4347,13 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps) HBITMAP hbm; int w = 100, h = 50; - if(cps->programLogo == NULL) return; + if(logo == NULL) return; // GetClientRect(hwndMain, &Rect); // bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1, // Rect.bottom-Rect.top+1); tmphdc = CreateCompatibleDC(hdc); - hbm = SelectObject(tmphdc, (HBITMAP) cps->programLogo); - if( GetObject( cps->programLogo, sizeof(bi), &bi ) > 0 ) { + hbm = SelectObject(tmphdc, logo); + if( GetObject( logo, sizeof(bi), &bi ) > 0 ) { w = bi.bmWidth; h = bi.bmHeight; } @@ -4288,17 +4393,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) fullrepaint = TRUE; } -#if 0 - if( fullrepaint ) { - static int repaint_count = 0; - char buf[128]; - - repaint_count++; - sprintf( buf, "FULL repaint: %d\n", repaint_count ); - OutputDebugString( buf ); - } -#endif - if (board == NULL) { if (!lastReqValid) { return; @@ -4328,35 +4422,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) releaseDC = FALSE; } -#if 0 - fprintf(debugFP, "*******************************\n" - "repaint = %s\n" - "dragInfo.from (%d,%d)\n" - "dragInfo.start (%d,%d)\n" - "dragInfo.pos (%d,%d)\n" - "dragInfo.lastpos (%d,%d)\n", - repaint ? "TRUE" : "FALSE", - dragInfo.from.x, dragInfo.from.y, - dragInfo.start.x, dragInfo.start.y, - dragInfo.pos.x, dragInfo.pos.y, - dragInfo.lastpos.x, dragInfo.lastpos.y); - fprintf(debugFP, "prev: "); - for (row = 0; row < BOARD_HEIGHT; row++) { - for (column = 0; column < BOARD_WIDTH; column++) { - fprintf(debugFP, "%d ", lastDrawn[row][column]); - } - } - fprintf(debugFP, "\n"); - fprintf(debugFP, "board: "); - for (row = 0; row < BOARD_HEIGHT; row++) { - for (column = 0; column < BOARD_WIDTH; column++) { - fprintf(debugFP, "%d ", board[row][column]); - } - } - fprintf(debugFP, "\n"); - fflush(debugFP); -#endif - /* Create some work-DCs */ hdcmem = CreateCompatibleDC(hdc); tmphdc = CreateCompatibleDC(hdc); @@ -4511,7 +4576,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(explodeInfo.radius) { // [HGM] atomic HBRUSH oldBrush; int x, y, r=(explodeInfo.radius * squareSize)/100; - SquareToPos(explodeInfo.y, explodeInfo.x, &x, &y); + board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer + SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y); x += squareSize/2; y += squareSize/2; if(!fullrepaint) { @@ -4530,8 +4596,39 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawBoardOnDC(hdcmem, board, tmphdc); } if(logoHeight) { - DrawLogoOnDC(hdc, leftLogoRect, flipClock ? &second : &first); - DrawLogoOnDC(hdc, rightLogoRect, flipClock ? &first : &second); + 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 ) { @@ -4614,7 +4711,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) GetDIBits(tmphdc,bufferBitmap,0,b.bmHeight,pData,(BITMAPINFO*)&bih,DIB_RGB_COLORS); // fprintf(diagFile, "%8x\n", (int) pData); -#if 1 wb = b.bmWidthBytes; // count colors for(i=0; i>2; i++) { @@ -4662,7 +4758,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) // write bitmap data for(i=0; i= squareSize) return -1; x /= (squareSize + lineGap); - if (x >= BOARD_SIZE) + if (x >= limit) return -2; return x; } @@ -4804,7 +4899,23 @@ SetupDropMenu(HMENU hmenu) } } -static int fromX = -1, fromY = -1, toX, toY; +void DragPieceBegin(int x, int y) +{ + dragInfo.lastpos.x = boardRect.left + x; + dragInfo.lastpos.y = boardRect.top + y; + dragInfo.from.x = fromX; + dragInfo.from.y = fromY; + dragInfo.start = dragInfo.from; + SetCapture(hwndMain); +} + +void DragPieceEnd(int x, int y) +{ + ReleaseCapture(); + dragInfo.start.x = dragInfo.start.y = -1; + dragInfo.from = dragInfo.start; + dragInfo.pos = dragInfo.lastpos = dragInfo.start; +} /* Event handler for mouse messages */ VOID @@ -4814,11 +4925,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) POINT pt; static int recursive = 0; HMENU hmenu; -// BOOLEAN needsRedraw = FALSE; - BOOLEAN saveAnimate; BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */ - static BOOLEAN sameAgain = FALSE, promotionChoice = FALSE; - ChessMove moveType; if (recursive) { if (message == WM_MBUTTONUP) { @@ -4834,8 +4941,8 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); - x = EventToSquare(pt.x - boardRect.left); - y = EventToSquare(pt.y - boardRect.top); + x = EventToSquare(pt.x - boardRect.left, BOARD_WIDTH); + y = EventToSquare(pt.y - boardRect.top, BOARD_HEIGHT); if (!flipView && y >= 0) { y = BOARD_HEIGHT - 1 - y; } @@ -4845,29 +4952,6 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_LBUTTONDOWN: - if(promotionChoice) { // we are waiting for a click to indicate promotion piece - promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel - if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y); - if(gameInfo.holdingsWidth && - (WhiteOnMove(currentMove) - ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0 - : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) { - // click in right holdings, for determining promotion piece - ChessSquare p = boards[currentMove][y][x]; - if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p); - if(p != EmptySquare) { - FinishMove(WhitePromotionQueen, fromX, fromY, toX, toY, ToLower(PieceToChar(p))); - fromX = fromY = -1; - break; - } - } - DrawPosition(FALSE, boards[currentMove]); - break; - } - ErrorPopDown(); - sameAgain = FALSE; - if (y == -2) { - /* Downclick vertically off board; check if on clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { if (gameMode == EditPosition) { SetWhiteToPlayEvent(); @@ -4875,7 +4959,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) gameMode == MachinePlaysWhite) { CallFlagEvent(); } else if (gameMode == EditGame) { - AdjustClock((logoHeight > 0 ? flipView: flipClock), -1); + AdjustClock(flipClock, -1); } } else if (PtInRect((LPRECT) &blackRect, pt)) { if (gameMode == EditPosition) { @@ -4884,194 +4968,23 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) gameMode == MachinePlaysBlack) { CallFlagEvent(); } else if (gameMode == EditGame) { - AdjustClock(!(logoHeight > 0 ? flipView: flipClock), -1); + AdjustClock(!flipClock, -1); } } - if (!appData.highlightLastMove) { - ClearHighlights(); - DrawPosition((int) (forceFullRepaint || FALSE), NULL); - } - fromX = fromY = -1; dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; - break; - } else if (x < 0 || y < 0 - /* [HGM] block clicks between board and holdings */ - || x == BOARD_LEFT-1 || x == BOARD_RGHT - || (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize) - || (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) - /* EditPosition, empty square, or different color piece; - click-click move is possible */ - ) { - break; - } else if (fromX == x && fromY == y) { - /* Downclick on same square again */ - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - sameAgain = TRUE; - } else if (fromX != -1 && - x != BOARD_LEFT-2 && x != BOARD_RGHT+1 - ) { - /* Downclick on different square. */ - /* [HGM] if on holdings file, should count as new first click ! */ - { /* [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); - if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ + if(fromX == -1 && frozen) { // not sure where this is for fromX = fromY = -1; - ClearHighlights(); - DrawPosition(FALSE, boards[currentMove]); - break; - } else - if(moveType != ImpossibleMove) { - /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */ - if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || - ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && - appData.alwaysPromoteToQueen)) { - FinishMove(moveType, fromX, fromY, toX, toY, 'q'); - if (!appData.highlightLastMove) { - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - } - } else - if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { - SetHighlights(fromX, fromY, toX, toY); - DrawPosition(forceFullRepaint || FALSE, NULL); - /* [HGM] Popup calls FinishMove now. - 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 - 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; - } else - PromotionPopup(hwnd); - } else { /* not a promotion */ - 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; - } - } - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - } - /* First downclick, or restart on a square with same color piece */ - if (!frozen && OKToStartUserMove(x, y)) { - fromX = x; - fromY = y; - dragInfo.lastpos = pt; - dragInfo.from.x = fromX; - dragInfo.from.y = fromY; - dragInfo.start = dragInfo.from; - SetCapture(hwndMain); - } else { - fromX = fromY = -1; - dragInfo.start.x = dragInfo.start.y = -1; - dragInfo.from = dragInfo.start; DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */ + break; } + LeftClick(Press, pt.x - boardRect.left, pt.y - boardRect.top); + DrawPosition(TRUE, NULL); break; case WM_LBUTTONUP: - ReleaseCapture(); - if (fromX == -1) break; - if (x == fromX && y == fromY) { - dragInfo.from.x = dragInfo.from.y = -1; - /* Upclick on same square */ - if (sameAgain) { - /* Clicked same square twice: abort click-click move */ - fromX = fromY = -1; - gotPremove = 0; - ClearPremoveHighlights(); - } else { - /* First square clicked: start click-click move */ - SetHighlights(fromX, fromY, -1, -1); - } - DrawPosition(forceFullRepaint || FALSE, NULL); - } else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) { - /* Errant click; ignore */ - break; - } else { - /* Finish drag move. */ - if (appData.debugMode) { - fprintf(debugFP, "release\n"); - } - dragInfo.from.x = dragInfo.from.y = -1; - toX = x; - toY = y; - saveAnimate = appData.animate; /* sorry, Hawk :) */ - appData.animate = appData.animate && !appData.animateDragging; - moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR); - if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ - fromX = fromY = -1; - ClearHighlights(); - DrawPosition(FALSE, boards[currentMove]); - break; - } else - if(moveType != ImpossibleMove) { - /* [HGM] use move type to determine if move is promotion. - Knight is Shogi kludge for mandatory promotion, Queen means choice */ - if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || - ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && - appData.alwaysPromoteToQueen)) - FinishMove(moveType, fromX, fromY, toX, toY, 'q'); - else - if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { - DrawPosition(forceFullRepaint || FALSE, NULL); - 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 - 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; - break; - } else - PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */ - } else { - if(saveAnimate /* ^$!%@#$!$ */ && gameInfo.variant == VariantAtomic - && boards[currentMove][toY][toX] != EmptySquare) AnimateAtomicCapture(toX, toY, 20); - FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); - } - } - if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY); - appData.animate = saveAnimate; - fromX = fromY = -1; - if (appData.highlightDragging && !appData.highlightLastMove) { - ClearHighlights(); - } - if (appData.animate || appData.animateDragging || - appData.highlightDragging || gotPremove) { - DrawPosition(forceFullRepaint || FALSE, NULL); - } - } - dragInfo.start.x = dragInfo.start.y = -1; - dragInfo.pos = dragInfo.lastpos = dragInfo.start; + LeftClick(Release, pt.x - boardRect.left, pt.y - boardRect.top); + DrawPosition(TRUE, NULL); break; case WM_MOUSEMOVE: @@ -5081,7 +4994,6 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { BOOL full_repaint = FALSE; - sameAgain = FALSE; /* [HGM] if we drag something around, do keep square selected */ if (appData.animateDragging) { dragInfo.pos = pt; } @@ -5128,9 +5040,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) AdjustClock((logoHeight > 0 ? flipView: flipClock), 1); + if (gameMode == EditGame) AdjustClock(flipClock, 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame) AdjustClock(!(logoHeight > 0 ? flipView: flipClock), 1); + if (gameMode == EditGame) AdjustClock(!flipClock, 1); } } DrawPosition(TRUE, NULL); @@ -5148,16 +5060,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. */ @@ -5165,7 +5067,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: @@ -5218,24 +5119,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); @@ -5332,7 +5218,8 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 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. */ - FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar); + UserMoveEvent(fromX, fromY, toX, toY, promoChar); + fromX = fromY = -1; if (!appData.highlightLastMove) { ClearHighlights(); DrawPosition(FALSE, NULL); @@ -5354,6 +5241,13 @@ PromotionPopup(HWND hwnd) FreeProcInstance(lpProc); } +void +PromotionPopUp() +{ + DrawPosition(TRUE, NULL); + PromotionPopup(hwndMain); +} + /* Toggle ShowThinking */ VOID ToggleShowThinking() @@ -5390,6 +5284,57 @@ LoadGameDialog(HWND hwnd, char* title) } } +int get_term_width() +{ + HDC hdc; + TEXTMETRIC tm; + RECT rc; + HFONT hfont, hold_font; + LOGFONT lf; + HWND hText; + + if (hwndConsole) + hText = GetDlgItem(hwndConsole, OPT_ConsoleText); + else + return 79; + + // get the text metrics + hdc = GetDC(hText); + lf = font[boardSize][CONSOLE_FONT]->lf; + if (consoleCF.dwEffects & CFE_BOLD) + lf.lfWeight = FW_BOLD; + if (consoleCF.dwEffects & CFE_ITALIC) + lf.lfItalic = TRUE; + if (consoleCF.dwEffects & CFE_STRIKEOUT) + lf.lfStrikeOut = TRUE; + if (consoleCF.dwEffects & CFE_UNDERLINE) + lf.lfUnderline = TRUE; + hfont = CreateFontIndirect(&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); + + return (rc.right-rc.left) / tm.tmAveCharWidth; +} + +void UpdateICSWidth(HWND hText) +{ + LONG old_width, new_width; + + new_width = get_term_width(hText, FALSE); + old_width = GetWindowLong(hText, GWL_USERDATA); + if (new_width != old_width) + { + ics_update_width(new_width); + SetWindowLong(hText, GWL_USERDATA, new_width); + } +} + VOID ChangedConsoleFont() { @@ -5429,6 +5374,7 @@ ChangedConsoleFont() paraf.dxOffset = WRAP_INDENT; SendMessage(hText, EM_SETPARAFORMAT, 0, (LPARAM) ¶f); SendMessage(hText, EM_EXSETSEL, 0, (LPARAM)&sel); + UpdateICSWidth(hText); } /*---------------------------------------------------------------------------*\ @@ -5476,30 +5422,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 == '\r' || (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: @@ -5510,11 +5451,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); } @@ -5542,13 +5479,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wmId) { case IDM_NewGame: ResetGameEvent(); - AnalysisPopDown(); + SAY("new game enter a move to play against the computer with white"); break; case IDM_NewGameFRC: if( NewGameFRC() == 0 ) { ResetGameEvent(); - AnalysisPopDown(); } break; @@ -5665,6 +5601,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } else { EvalGraphPopUp(); + SetFocus(hwndMain); } break; @@ -5696,6 +5633,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GameListOptions(); break; + case IDM_NewChat: + ChatPopUp(); + break; + case IDM_CopyPosition: CopyFENToClipboard(); break; @@ -5732,6 +5673,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } + SAY("computer starts playing white"); break; case IDM_MachineBlack: @@ -5745,6 +5687,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } + SAY("computer starts playing black"); break; case IDM_TwoMachines: @@ -5758,6 +5701,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: @@ -5765,6 +5709,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) { @@ -5814,10 +5759,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: @@ -5897,6 +5844,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetFocus(hwndMain); break; + JAWS_MENU_ITEMS + case IDM_Forward: ForwardEvent(); SetFocus(hwndMain); @@ -5936,6 +5885,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FlipClock: flipClock = !flipClock; DisplayBothClocks(); + 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: @@ -5951,6 +5907,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; @@ -6022,15 +5986,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); @@ -6294,6 +6260,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput ); + ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList ); + ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole ); boardX = lpwp->x; boardY = lpwp->y; } @@ -6484,8 +6452,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; @@ -6515,13 +6486,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; } @@ -7007,6 +6971,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 */ @@ -7064,7 +7029,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT && commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&commentX, &commentY); + EnsureOnScreen(&commentX, &commentY, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; @@ -7211,12 +7176,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; @@ -7248,6 +7236,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), @@ -7284,6 +7275,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case IDOK: GetDlgItemText(hDlg, OPT_Name, move, sizeof(move)); appData.userName = strdup(move); + SetUserLogo(); EndDialog(hDlg, TRUE); return TRUE; @@ -7712,6 +7704,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 */ @@ -7727,10 +7720,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); @@ -7752,26 +7766,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: @@ -7888,6 +7882,7 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case '\021': /* Ctrl+Q */ quoteNextChar = TRUE; return 0; + JAWS_REPLAY default: break; } @@ -7982,18 +7977,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); @@ -8007,40 +8019,46 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetClientRect(hDlg, &rect); sizeX = rect.right; sizeY = rect.bottom; - if (consoleX != CW_USEDEFAULT && consoleY != CW_USEDEFAULT && - consoleW != CW_USEDEFAULT && consoleH != CW_USEDEFAULT) { + if (wpConsole.x != CW_USEDEFAULT && wpConsole.y != CW_USEDEFAULT && + wpConsole.width != CW_USEDEFAULT && wpConsole.height != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&consoleX, &consoleY); + EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = consoleX; - wp.rcNormalPosition.right = consoleX + consoleW; - wp.rcNormalPosition.top = consoleY; - wp.rcNormalPosition.bottom = consoleY + consoleH; + wp.rcNormalPosition.left = wpConsole.x; + wp.rcNormalPosition.right = wpConsole.x + wpConsole.width; + wp.rcNormalPosition.top = wpConsole.y; + wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height; SetWindowPlacement(hDlg, &wp); } -#if 0 + // [HGM] Chessknight's change 2004-07-13 else { /* Determine Defaults */ WINDOWPLACEMENT wp; - consoleX = winWidth + 1; - consoleY = boardY; - consoleW = screenWidth - winWidth; - consoleH = winHeight; - EnsureOnScreen(&consoleX, &consoleY); + wpConsole.x = winWidth + 1; + wpConsole.y = boardY; + wpConsole.width = screenWidth - winWidth; + wpConsole.height = winHeight; + EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = consoleX; - wp.rcNormalPosition.right = consoleX + consoleW; - wp.rcNormalPosition.top = consoleY; - wp.rcNormalPosition.bottom = consoleY + consoleH; + wp.rcNormalPosition.left = wpConsole.x; + wp.rcNormalPosition.right = wpConsole.x + wpConsole.width; + wp.rcNormalPosition.top = wpConsole.y; + wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height; SetWindowPlacement(hDlg, &wp); } -#endif + + // Allow hText to highlight URLs and send notifications on them + 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 + return FALSE; case WM_SETFOCUS: @@ -8100,6 +8118,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 ); } @@ -8253,7 +8272,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, if (tinyLayout) sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell); else - sprintf(buf, "%s: %s %s", color, TimeString(timeRemaining), flagFell); + sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell); str = buf; } else { str = color; @@ -8268,10 +8287,22 @@ 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", buf+7, flagFell); + r.top = rect->top + logoHeight/2; + r.left = rect->left; + r.right = rect->right; + r.bottom = rect->bottom; + ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN, + r.top, ETO_CLIPPED|ETO_OPAQUE, + &r, str, strlen(str), NULL); + } (void) SetTextColor(hdc, oldFg); (void) SetBkColor(hdc, oldBg); (void) SelectObject(hdc, oldFont); @@ -8557,6 +8588,7 @@ Enables gnuEnables[] = { { IDM_StopExamining, MF_BYCOMMAND|MF_GRAYED }, { IDM_StopObserving, MF_BYCOMMAND|MF_GRAYED }, { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, + { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; @@ -8566,6 +8598,7 @@ Enables icsEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED }, @@ -8573,6 +8606,8 @@ Enables icsEnables[] = { { IDM_Hint, MF_BYCOMMAND|MF_GRAYED }, { IDM_Book, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; @@ -8581,6 +8616,7 @@ Enables zippyEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, { IDM_Book, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine1Options, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } }; #endif @@ -8601,6 +8637,10 @@ Enables ncpEnables[] = { { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED }, { IDM_Hint, MF_BYCOMMAND|MF_GRAYED }, { IDM_Book, MF_BYCOMMAND|MF_GRAYED }, + { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED }, + { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; @@ -8912,6 +8952,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, @@ -9155,6 +9198,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 } }; @@ -9354,6 +9398,11 @@ DrawPosition(int fullRedraw, Board board) HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board); } +void NotifyFrontendLogin() +{ + if (hwndConsole) + UpdateICSWidth(GetDlgItem(hwndConsole, OPT_ConsoleText)); +} VOID ResetFrontEnd() @@ -9376,6 +9425,7 @@ CommentPopUp(char *title, char *str) { HWND hwnd = GetActiveWindow(); EitherCommentPopUp(0, title, str, FALSE); + SAY(str); SetActiveWindow(hwnd); } @@ -9527,7 +9577,7 @@ DisplayWhiteClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - (logoHeight > 0 ? flipView: flipClock) ? &blackRect : &whiteRect, "White", flag); + flipClock ? &blackRect : &whiteRect, "White", flag); } if (highlight && iconCurrent == iconBlack) { iconCurrent = iconWhite; @@ -9551,7 +9601,7 @@ DisplayBlackClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - (logoHeight > 0 ? flipView: flipClock) ? &whiteRect : &blackRect, "Black", flag); + flipClock ? &whiteRect : &blackRect, "Black", flag); } if (highlight && iconCurrent == iconWhite) { iconCurrent = iconBlack; @@ -9611,11 +9661,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; @@ -10317,6 +10368,11 @@ RemoveInputSource(InputSourceRef isr) } } +int no_wrap(char *message, int count) +{ + ConsoleOutput(message, count, FALSE); + return count; +} int OutputToProcess(ProcRef pr, char *message, int count, int *outError) @@ -10325,11 +10381,32 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError) int outCount = SOCKET_ERROR; ChildProc *cp = (ChildProc *) pr; static OVERLAPPED ovl; + static int line = 0; - if (pr == NoProc) { - ConsoleOutput(message, count, FALSE); - return count; - } + if (pr == NoProc) + { + if (appData.noJoin || !appData.useInternalWrap) + return no_wrap(message, count); + else + { + int width = get_term_width(); + int len = wrap(NULL, message, count, width, &line); + char *msg = malloc(len); + int dbgchk; + + if (!msg) + return no_wrap(message, count); + else + { + dbgchk = wrap(msg, message, count, width, &line); + if (dbgchk != len && appData.debugMode) + fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); + ConsoleOutput(msg, len, FALSE); + free(msg); + return len; + } + } + } if (ovl.hEvent == NULL) { ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -10438,7 +10515,7 @@ AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT && analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&analysisX, &analysisY); + EnsureOnScreen(&analysisX, &analysisY, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; @@ -10494,51 +10571,6 @@ AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } VOID -AnalysisPopUp(char* title, char* str) -{ - FARPROC lpProc; - char *p, *q; - - /* [AS] */ - EngineOutputPopUp(); - return; - - if (str == NULL) str = ""; - p = (char *) malloc(2 * strlen(str) + 2); - q = p; - while (*str) { - if (*str == '\n') *q++ = '\r'; - *q++ = *str++; - } - *q = NULLCHAR; - if (analysisText != NULL) free(analysisText); - analysisText = p; - - if (analysisDialog) { - SetWindowText(analysisDialog, title); - SetDlgItemText(analysisDialog, OPT_AnalysisText, analysisText); - ShowWindow(analysisDialog, SW_SHOW); - } else { - analysisTitle = title; - lpProc = MakeProcInstance((FARPROC)AnalysisDialog, hInst); - CreateDialog(hInst, MAKEINTRESOURCE(DLG_Analysis), - hwndMain, (DLGPROC)lpProc); - FreeProcInstance(lpProc); - } - analysisDialogUp = TRUE; -} - -VOID -AnalysisPopDown() -{ - if (analysisDialog) { - ShowWindow(analysisDialog, SW_HIDE); - } - analysisDialogUp = FALSE; -} - - -VOID SetHighlights(int fromX, int fromY, int toX, int toY) { highlightInfo.sq[0].x = fromX; @@ -10595,13 +10627,15 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor, void -AnimateAtomicCapture(int toX, int toY, int nFrames) +AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames) { // [HGM] atomic: animate blast wave int i; if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY); - explodeInfo.x = toX; - explodeInfo.y = toY; - for(i=0; i= 0 ? movelist[current] : "n/a" ); - - OutputDebugString( buf ); -#endif - MoveHistorySet( movelist, first, last, current, pvInfoList ); EvalGraphSet( first, last, current, pvInfoList ); @@ -10751,14 +10777,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 ); }