X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fjaws.c;h=9d8ec9c9269541312662bacb0f314f6f315e23b1;hb=08b791a1526fb669916eec752752f1cbb0582de1;hp=a8555a0447dfe54da4848f80fe77ecd0eb0f816e;hpb=9370698c82696695f0bcd0327a8b5c3703d3eea7;p=xboard.git diff --git a/winboard/jaws.c b/winboard/jaws.c index a8555a0..9d8ec9c 100644 --- a/winboard/jaws.c +++ b/winboard/jaws.c @@ -1,11 +1,11 @@ /* * JAWS.c -- Code for Windows front end to XBoard to use it with JAWS - * $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. * * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess, * which was written and is copyrighted by Wayne Christopher. @@ -60,6 +60,25 @@ // BOARD_LEFT as 0, BOARD_RGHT and BOARD_HEIGHT as 8, and set holdingssizes to 0. // You will need to build with jaws.rc in stead of winboard.rc. +// from resource.h + +#define IDM_PossibleAttackMove 1800 +#define IDM_PossibleAttacked 1801 +#define IDM_SayMachineMove 1802 +#define IDM_ReadRow 1803 +#define IDM_ReadColumn 1804 +#define IDM_SayCurrentPos 1805 +#define IDM_SayAllBoard 1806 +#define IDM_SayUpperDiagnols 1807 +#define IDM_SayLowerDiagnols 1808 +#define IDM_SayClockTime 1810 +#define IDM_SayWhosTurn 1811 +#define IDM_SayKnightMoves 1812 +#define ID_SHITTY_HI 1813 +#define IDM_SayWhitePieces 1816 +#define IDM_SayBlackPieces 1817 + + // from common.h, but 'extern' added to it, so the actual declaraton can remain in backend.c extern long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement; @@ -98,6 +117,22 @@ char *pieceToName[] = { "Empty" }; +char *pieceTypeName[] = { + "Pawn", "Knight", "Bishop", "Rook", "Queen", + "Guard", "Elephant", "Arch Bishop", "Chancellor", + "General", "Man", "Cannon", "Night Rider", + "Crowned Bishop", "Crowned Rook", "Grass Hopper", "Veteran", + "Falcon", "Amazon", "Snake", "Unicorn", + "King", + "Pawn", "Knight", "Bishop", "Rook", "Queen", + "Guard", "Elephant", "Arch Bishop", "Chancellor", + "General", "Man", "Cannon", "Night Rider", + "Crowned Bishop", "Crowned Rook", "Grass Hopper", "Veteran", + "Falcon", "Amazon", "Snake", "Unicorn", + "King", + "Empty" + }; + int CoordToNum(c) char c; { @@ -111,7 +146,7 @@ char* PieceToName(p, i) int i; { if(i) return pieceToName[(int) p]; - return pieceToName[(int) p]+6; + return pieceTypeName[(int) p]; } char* SquareToChar(x) @@ -128,9 +163,8 @@ char* SquareToNum(y) // from winboard.c: all new routines - -#include "jfwapi.h" -#include "jaws.h" +#define JFWAPI __declspec(dllimport) +JFWAPI BOOL WINAPI JFWSayString (LPCTSTR lpszStrinToSpeak, BOOL bInterrupt); typedef JFWAPI BOOL (WINAPI *PSAYSTRING)(LPCTSTR lpszStrinToSpeak, BOOL bInterrupt); @@ -153,6 +187,72 @@ VOID SayString(char *mess, BOOL flag) static int oldFromX, oldFromY; static int timeflag; static int suppressClocks = 0; +static int suppressOneKey = 0; +static HANDLE hAccelJAWS; + +typedef struct { char *name; int code; } MenuItemDesc; + +MenuItemDesc menuItemJAWS[] = { +{"Say Clock &Time\tAlt+T", IDM_SayClockTime }, +{"-", 0 }, +{"Say Last &Move\tAlt+M", IDM_SayMachineMove }, +{"Say W&ho's Turn\tAlt+X", IDM_SayWhosTurn }, +{"-", 0 }, +{"Say Complete &Position\tAlt+P",IDM_SayAllBoard }, +{"Say &White Pieces\tAlt+W", IDM_SayWhitePieces }, +{"Say &Black Pieces\tAlt+B", IDM_SayBlackPieces }, +{"Say Board &Rank\tAlt+R", IDM_ReadRow }, +{"Say Board &File\tAlt+F", IDM_ReadColumn }, +{"-", 0 }, +{"Say &Upper Diagonals\tAlt+U", IDM_SayUpperDiagnols }, +{"Say &Lower Diagonals\tAlt+L", IDM_SayLowerDiagnols }, +{"Say K&night Moves\tAlt+N", IDM_SayKnightMoves }, +{"Say Current &Square\tAlt+S", IDM_SayCurrentPos }, +{"Say &Attacks\tAlt+A", IDM_PossibleAttackMove }, +{"Say Attacke&d\tAlt+D", IDM_PossibleAttacked }, +{NULL, 0} +}; + +ACCEL acceleratorsJAWS[] = { +{FVIRTKEY|FALT, 'T', IDM_SayClockTime }, +{FVIRTKEY|FALT, 'M', IDM_SayMachineMove }, +{FVIRTKEY|FALT, 'X', IDM_SayWhosTurn }, +{FVIRTKEY|FALT, 'P', IDM_SayAllBoard }, +{FVIRTKEY|FALT, 'W', IDM_SayWhitePieces }, +{FVIRTKEY|FALT, 'B', IDM_SayBlackPieces }, +{FVIRTKEY|FALT, 'R', IDM_ReadRow }, +{FVIRTKEY|FALT, 'F', IDM_ReadColumn }, +{FVIRTKEY|FALT, 'U', IDM_SayUpperDiagnols }, +{FVIRTKEY|FALT, 'L', IDM_SayLowerDiagnols }, +{FVIRTKEY|FALT, 'N', IDM_SayKnightMoves }, +{FVIRTKEY|FALT, 'S', IDM_SayCurrentPos }, +{FVIRTKEY|FALT, 'A', IDM_PossibleAttackMove }, +{FVIRTKEY|FALT, 'D', IDM_PossibleAttacked } +}; + +void +AdaptMenu() +{ + HMENU menuMain, menuJAWS; + MENUBARINFO helpMenuInfo; + int i; + + helpMenuInfo.cbSize = sizeof(helpMenuInfo); + menuMain = GetMenu(hwndMain); + if(appData.debugMode) fprintf(debugFP, "hwndMain: %8x %8x\n", hwndMain, menuMain); + menuJAWS = CreatePopupMenu(); + + for(i=0; menuItemJAWS[i].name; i++) { + if(menuItemJAWS[i].name[0] == '-') + AppendMenu(menuJAWS, MF_SEPARATOR, (UINT_PTR) 0, NULL); + else AppendMenu(menuJAWS, MF_ENABLED|MF_STRING, + (UINT_PTR) menuItemJAWS[i].code, (LPCTSTR) menuItemJAWS[i].name); + } + InsertMenu(menuMain, 5, MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, + (UINT_PTR) menuJAWS, "&JAWS"); + oldMenuItemState[6] = oldMenuItemState[5]; + DrawMenuBar(hwndMain); +} BOOL InitJAWS() @@ -170,20 +270,17 @@ InitJAWS() } { - // [HGM] kludge to reduce need for modification of winboard.c: mak tinyLayout menu identical + // [HGM] kludge to reduce need for modification of winboard.c: make tinyLayout menu identical // to standard layout, so that code for switching between them does not have to be deleted - HMENU hmenu = GetMenu(hwndMain); int i; + AdaptMenu(); menuBarText[0][5] = "&JAWS"; for(i=0; i<7; i++) menuBarText[1][i] = menuBarText[0][i]; - for (i=0; menuBarText[tinyLayout][i]; i++) { - ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, - (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]); - } - DrawMenuBar(hwndMain); } + hAccelJAWS = CreateAcceleratorTable(acceleratorsJAWS, 14); + /* initialize cursor position */ fromX = fromY = 0; SetHighlights(fromX, fromY, -1, -1); @@ -194,12 +291,15 @@ InitJAWS() return TRUE; } +int beeps[] = { 1, 0, 0, 0, 0 }; +int beepCodes[] = { 0, MB_OK, MB_ICONERROR, MB_ICONQUESTION, MB_ICONEXCLAMATION, MB_ICONASTERISK }; + VOID KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { ChessSquare currentPiece; char *piece, *xchar, *ynum ; - int n; + int n, beepType = 1; // empty beep if(fromX == -1 || fromY == -1) { fromX = BOARD_LEFT; fromY = 0; @@ -207,34 +307,37 @@ KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch(wParam) { case VK_LEFT: if(fromX == BOARD_RGHT+1) fromX -= 2; else - if(fromX == BOARD_LEFT) { if(fromY >= BOARD_HEIGHT - gameInfo.holdingsSize) fromX -= 2; } else - if(fromX > BOARD_LEFT) fromX--; + if(fromX == BOARD_LEFT) { if(fromY >= BOARD_HEIGHT - gameInfo.holdingsSize) fromX -= 2; else beepType = 0; } else + if(fromX > BOARD_LEFT) fromX--; else beepType = 0; // off-board beep break; case VK_RIGHT: if(fromX == BOARD_LEFT-2) fromX += 2; else - if(fromX == BOARD_RGHT-1) { if(fromY < gameInfo.holdingsSize) fromX += 2; } else - if(fromX < BOARD_RGHT-1) fromX++; + if(fromX == BOARD_RGHT-1) { if(fromY < gameInfo.holdingsSize) fromX += 2; else beepType = 0; } else + if(fromX < BOARD_RGHT-1) fromX++; else beepType = 0; break; case VK_UP: - if(fromX == BOARD_RGHT+1) { if(fromY < gameInfo.holdingsSize - 1) fromY++; } else - if(fromY < BOARD_HEIGHT-1) fromY++; + if(fromX == BOARD_RGHT+1) { if(fromY < gameInfo.holdingsSize - 1) fromY++; else beepType = 0; } else + if(fromY < BOARD_HEIGHT-1) fromY++; else beepType = 0; break; case VK_DOWN: - if(fromX == BOARD_LEFT-2) { if(fromY > BOARD_HEIGHT - gameInfo.holdingsSize) fromY--; } else - if(fromY > 0) fromY--; + if(fromX == BOARD_LEFT-2) { if(fromY > BOARD_HEIGHT - gameInfo.holdingsSize) fromY--; else beepType = 0; } else + if(fromY > 0) fromY--; else beepType = 0; break; } SetHighlights(fromX, fromY, -1, -1); DrawPosition(FALSE, NULL); currentPiece = boards[currentMove][fromY][fromX]; piece = PieceToName(currentPiece,1); - if(currentPiece != EmptySquare) MessageBeep(currentPiece < (int)BlackPawn ? MB_OK : MB_ICONEXCLAMATION); + if(beepType == 1 && currentPiece != EmptySquare) beepType = currentPiece < (int) BlackPawn ? 2 : 3; // white or black beep + if(beeps[beepType] == beeps[1] && (fromX == BOARD_RGHT+1 || fromX == BOARD_LEFT-2)) beepType = 4; // holdings beep + beepType = beeps[beepType]%6; + if(beepType) MessageBeep(beepCodes[beepType]); if(fromX == BOARD_LEFT - 2) { SayString("black holdings", FALSE); if(currentPiece != EmptySquare) { char buf[MSG_SIZ]; n = boards[currentMove][fromY][1]; - sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s"); + sprintf(buf, "%d %s%s", n, PieceToName(currentPiece,0), n == 1 ? "" : "s"); SayString(buf, TRUE); } } else @@ -243,7 +346,7 @@ KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(currentPiece != EmptySquare) { char buf[MSG_SIZ]; n = boards[currentMove][fromY][BOARD_WIDTH-2]; - sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s"); + sprintf(buf, "%d %s%s", n, PieceToName(currentPiece,0), n == 1 ? "" : "s"); SayString(buf, TRUE); } } else @@ -719,10 +822,10 @@ SayCurrentPos() SayString(xchar, FALSE); SayString(ynum, FALSE); SayString(piece, FALSE); - if((fromX-BOARD_LEFT) ^ fromY) - SayString("on a dark square",FALSE); - else + if(((fromX-BOARD_LEFT) ^ fromY)&1) SayString("on a light square",FALSE); + else + SayString("on a dark square",FALSE); PossibleAttacked(); return; @@ -733,7 +836,7 @@ SayAllBoard() { int Xpos, Ypos; ChessSquare currentpiece; - char *piece, *xchar, *ynum ; + char *piece, *ynum ; if(gameInfo.holdingsWidth) { int first = 0; @@ -767,7 +870,7 @@ SayAllBoard() for(Xpos=BOARD_LEFT; Xpos. Pop up piece menu */\ POINT pt; int x, y;\ @@ -1126,6 +1227,30 @@ NiceTime(int x) #define JAWS_KB_NAVIGATION \ \ case WM_KEYDOWN:\ +\ + if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) {\ + /* Control + Alt + letter used for speaking piece positions */\ + static int lastTime; static char lastChar;\ + int mine = 0, time = GetTickCount(); char c;\ +\ + if((char)wParam == lastChar && time-lastTime < 250) mine = 1;\ + lastChar = wParam; lastTime = time;\ + c = wParam;\ +\ + if(gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) mine = !mine;\ +\ + if(ToLower(c) == 'x') {\ + SayPieces(mine ? WhitePlay : BlackPlay);\ + suppressOneKey = 1;\ + break;\ + } else\ + if(CharToPiece(c) != EmptySquare) {\ + SayPieces(CharToPiece(mine ? ToUpper(c) : ToLower(c)));\ + suppressOneKey = 1;\ + break;\ + }\ + }\ +\ switch (wParam) {\ case VK_LEFT:\ case VK_RIGHT:\ @@ -1239,23 +1364,21 @@ NiceTime(int x) \ +#define JAWS_ACCEL \ + !(!frozen && TranslateAccelerator(hwndMain, hAccelJAWS, &msg)) && + #define JAWS_INIT if (!InitJAWS()) return (FALSE); #define JAWS_DELETE(X) #define JAWS_SILENCE if(suppressClocks) return; +#define JAWS_COPYRIGHT \ + SetDlgItemText(hDlg, OPT_MESS, "Auditory/Keyboard Enhancements By: Ed Rodriguez (sort of)"); + #define SAY(S) SayString((S), FALSE) #define SAYMACHINEMOVE() SayMachineMove(0) // After inclusion of this file somewhere early in winboard.c, the remaining part of the patch // is scattered over winboard.c for actually calling the routines. -// -// * move fromX, fromY declaration to front, before incusion of this file. (Can be permanent change in winboard.c.) -// * call InitJAWS(), after calling InitIntance(). (Using JAWS_INIT macro) -// * add keyboard cases in main switch of WndProc, though JAWS_KB_NAVIGATION above, e.g. before WM_CHAR case. -// * change the WM_CHAR case of same switch from "if(appData.icsActive)" to "if(appData.icsActive JAWS_IF_TAB)" -// * add new menu cases in WM_COMMAND case of WndProc, e.g. before IDM_Forward. (throug macro defined above) -// * add SAYMACHINEMOVE(); at the end of DisplayMessage(); -// * add SAY("board"); in WM_CHAR case of ConsoleTextSubclass, just before "SetFocus(buttondesc..."