diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c index 15418583aad..c714e50c409 100644 --- a/dlls/kernel32/console.c +++ b/dlls/kernel32/console.c @@ -1096,117 +1096,15 @@ BOOL WINAPI GetNumberOfConsoleInputEvents( HANDLE handle, LPDWORD nrofevents ) * 0 for error, 1 for no INPUT_RECORD ready, 2 with INPUT_RECORD ready */ enum read_console_input_return {rci_error = 0, rci_timeout = 1, rci_gotone = 2}; -static const int vkkeyscan_table[256] = -{ - 0,0,0,0,0,0,0,0,8,9,0,0,0,13,0,0,0,0,0,19,145,556,0,0,0,0,0,27,0,0,0, - 0,32,305,478,307,308,309,311,222,313,304,312,443,188,189,190,191,48, - 49,50,51,52,53,54,55,56,57,442,186,444,187,446,447,306,321,322,323, - 324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340, - 341,342,343,344,345,346,219,220,221,310,445,192,65,66,67,68,69,70,71, - 72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,475,476,477, - 448,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0 -}; - -static const int mapvkey_0[256] = -{ - 0,0,0,0,0,0,0,0,14,15,0,0,0,28,0,0,42,29,56,69,58,0,0,0,0,0,0,1,0,0, - 0,0,57,73,81,79,71,75,72,77,80,0,0,0,55,82,83,0,11,2,3,4,5,6,7,8,9, - 10,0,0,0,0,0,0,0,30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16, - 19,31,20,22,47,17,45,21,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,78,0,74, - 0,53,59,60,61,62,63,64,65,66,67,68,87,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,69,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,13,51,12,52,53,41,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,43,27,40,76,96,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -static inline void init_complex_char(INPUT_RECORD* ir, BOOL down, WORD vk, WORD kc, DWORD cks) -{ - ir->EventType = KEY_EVENT; - ir->Event.KeyEvent.bKeyDown = down; - ir->Event.KeyEvent.wRepeatCount = 1; - ir->Event.KeyEvent.wVirtualScanCode = vk; - ir->Event.KeyEvent.wVirtualKeyCode = kc; - ir->Event.KeyEvent.dwControlKeyState = cks; - ir->Event.KeyEvent.uChar.UnicodeChar = 0; -} - -/****************************************************************** - * handle_simple_char - * - * - */ -static BOOL handle_simple_char(HANDLE conin, unsigned real_inchar) -{ - unsigned vk; - unsigned inchar; - char ch; - unsigned numEvent = 0; - DWORD cks = 0, written; - INPUT_RECORD ir[8]; - - switch (real_inchar) - { - case 9: inchar = real_inchar; - real_inchar = 27; /* so that we don't think key is ctrl- something */ - break; - case 13: - case 10: inchar = '\r'; - real_inchar = 27; /* Fixme: so that we don't think key is ctrl- something */ - break; - case 127: inchar = '\b'; - break; - default: - inchar = real_inchar; - break; - } - if ((inchar & ~0xFF) != 0) FIXME("What a char (%u)\n", inchar); - vk = vkkeyscan_table[inchar]; - if (vk & 0x0100) - init_complex_char(&ir[numEvent++], 1, 0x2a, 0x10, SHIFT_PRESSED); - if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) - init_complex_char(&ir[numEvent++], 1, 0x1d, 0x11, LEFT_CTRL_PRESSED); - if (vk & 0x0400) - init_complex_char(&ir[numEvent++], 1, 0x38, 0x12, LEFT_ALT_PRESSED); - - ir[numEvent].EventType = KEY_EVENT; - ir[numEvent].Event.KeyEvent.bKeyDown = 1; - ir[numEvent].Event.KeyEvent.wRepeatCount = 1; - ir[numEvent].Event.KeyEvent.dwControlKeyState = cks; - if (vk & 0x0100) - ir[numEvent].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED; - if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) - ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; - if (vk & 0x0400) - ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; - ir[numEvent].Event.KeyEvent.wVirtualKeyCode = vk; - ir[numEvent].Event.KeyEvent.wVirtualScanCode = mapvkey_0[vk & 0x00ff]; /* VirtualKeyCodes to ScanCode */ - - ch = inchar; - MultiByteToWideChar(CP_UNIXCP, 0, &ch, 1, &ir[numEvent].Event.KeyEvent.uChar.UnicodeChar, 1); - ir[numEvent + 1] = ir[numEvent]; - ir[numEvent + 1].Event.KeyEvent.bKeyDown = 0; - - numEvent += 2; - - if (vk & 0x0400) - init_complex_char(&ir[numEvent++], 0, 0x38, 0x12, LEFT_ALT_PRESSED); - if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) - init_complex_char(&ir[numEvent++], 0, 0x1d, 0x11, 0); - if (vk & 0x0100) - init_complex_char(&ir[numEvent++], 0, 0x2a, 0x10, 0); - - return WriteConsoleInputW(conin, ir, numEvent, &written); -} static enum read_console_input_return bare_console_fetch_input(HANDLE handle, int fd, DWORD timeout) { struct pollfd pollfd; char ch; enum read_console_input_return ret; + unsigned numEvent; + INPUT_RECORD ir[8]; + DWORD written; pollfd.fd = fd; pollfd.events = POLLIN; @@ -1218,7 +1116,10 @@ static enum read_console_input_return bare_console_fetch_input(HANDLE handle, in RtlEnterCriticalSection(&CONSOLE_CritSect); switch (read(fd, &ch, 1)) { - case 1: ret = handle_simple_char(handle, ch) ? rci_gotone : rci_error; break; + case 1: + numEvent = TERM_FillSimpleChar(ch, ir); + ret = WriteConsoleInputW(handle, ir, numEvent, &written) ? rci_gotone : rci_error; + break; /* actually another thread likely beat us to reading the char * return gotone, while not perfect, it should work in most of the cases (as the new event * should be now in the queue) diff --git a/dlls/kernel32/console_private.h b/dlls/kernel32/console_private.h index bb16d0b64b3..c5b8799f132 100644 --- a/dlls/kernel32/console_private.h +++ b/dlls/kernel32/console_private.h @@ -36,5 +36,6 @@ extern WCHAR* CONSOLE_Readline(HANDLE, BOOL); /* term.c */ extern BOOL TERM_Init(void); extern BOOL TERM_Exit(void); +extern unsigned TERM_FillSimpleChar(unsigned real_inchar, INPUT_RECORD* ir); #endif /* __WINE_CONSOLE_PRIVATE_H */ diff --git a/dlls/kernel32/term.c b/dlls/kernel32/term.c index 56ddd670b93..acffd43871d 100644 --- a/dlls/kernel32/term.c +++ b/dlls/kernel32/term.c @@ -42,6 +42,109 @@ WINE_DEFAULT_DEBUG_CHANNEL(console); +static const int vkkeyscan_table[256] = +{ + 0,0,0,0,0,0,0,0,8,9,0,0,0,13,0,0,0,0,0,19,145,556,0,0,0,0,0,27,0,0,0, + 0,32,305,478,307,308,309,311,222,313,304,312,443,188,189,190,191,48, + 49,50,51,52,53,54,55,56,57,442,186,444,187,446,447,306,321,322,323, + 324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340, + 341,342,343,344,345,346,219,220,221,310,445,192,65,66,67,68,69,70,71, + 72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,475,476,477, + 448,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0 +}; + +static const int mapvkey_0[256] = +{ + 0,0,0,0,0,0,0,0,14,15,0,0,0,28,0,0,42,29,56,69,58,0,0,0,0,0,0,1,0,0, + 0,0,57,73,81,79,71,75,72,77,80,0,0,0,55,82,83,0,11,2,3,4,5,6,7,8,9, + 10,0,0,0,0,0,0,0,30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16, + 19,31,20,22,47,17,45,21,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,78,0,74, + 0,53,59,60,61,62,63,64,65,66,67,68,87,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,69,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,13,51,12,52,53,41,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,43,27,40,76,96,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static inline void init_complex_char(INPUT_RECORD* ir, BOOL down, WORD vk, WORD kc, DWORD cks) +{ + ir->EventType = KEY_EVENT; + ir->Event.KeyEvent.bKeyDown = down; + ir->Event.KeyEvent.wRepeatCount = 1; + ir->Event.KeyEvent.wVirtualScanCode = vk; + ir->Event.KeyEvent.wVirtualKeyCode = kc; + ir->Event.KeyEvent.dwControlKeyState = cks; + ir->Event.KeyEvent.uChar.UnicodeChar = 0; +} + +/****************************************************************** + * TERM_FillSimpleChar + * + */ +unsigned TERM_FillSimpleChar(unsigned real_inchar, INPUT_RECORD* ir) +{ + unsigned vk; + unsigned inchar; + char ch; + unsigned numEvent = 0; + DWORD cks = 0; + + switch (real_inchar) + { + case 9: inchar = real_inchar; + real_inchar = 27; /* so that we don't think key is ctrl- something */ + break; + case 13: + case 10: inchar = '\r'; + real_inchar = 27; /* Fixme: so that we don't think key is ctrl- something */ + break; + case 127: inchar = '\b'; + break; + default: + inchar = real_inchar; + break; + } + if ((inchar & ~0xFF) != 0) FIXME("What a char (%u)\n", inchar); + vk = vkkeyscan_table[inchar]; + if (vk & 0x0100) + init_complex_char(&ir[numEvent++], 1, 0x2a, 0x10, SHIFT_PRESSED); + if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) + init_complex_char(&ir[numEvent++], 1, 0x1d, 0x11, LEFT_CTRL_PRESSED); + if (vk & 0x0400) + init_complex_char(&ir[numEvent++], 1, 0x38, 0x12, LEFT_ALT_PRESSED); + + ir[numEvent].EventType = KEY_EVENT; + ir[numEvent].Event.KeyEvent.bKeyDown = 1; + ir[numEvent].Event.KeyEvent.wRepeatCount = 1; + ir[numEvent].Event.KeyEvent.dwControlKeyState = cks; + if (vk & 0x0100) + ir[numEvent].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED; + if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) + ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; + if (vk & 0x0400) + ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; + ir[numEvent].Event.KeyEvent.wVirtualKeyCode = vk; + ir[numEvent].Event.KeyEvent.wVirtualScanCode = mapvkey_0[vk & 0x00ff]; /* VirtualKeyCodes to ScanCode */ + + ch = inchar; + MultiByteToWideChar(CP_UNIXCP, 0, &ch, 1, &ir[numEvent].Event.KeyEvent.uChar.UnicodeChar, 1); + ir[numEvent + 1] = ir[numEvent]; + ir[numEvent + 1].Event.KeyEvent.bKeyDown = 0; + + numEvent += 2; + + if (vk & 0x0400) + init_complex_char(&ir[numEvent++], 0, 0x38, 0x12, LEFT_ALT_PRESSED); + if ((vk & 0x0200) || (unsigned char)real_inchar <= 26) + init_complex_char(&ir[numEvent++], 0, 0x1d, 0x11, 0); + if (vk & 0x0100) + init_complex_char(&ir[numEvent++], 0, 0x2a, 0x10, 0); + return numEvent; +} + #if defined(SONAME_LIBCURSES) || defined(SONAME_LIBNCURSES) #ifdef HAVE_NCURSES_H