Mercurial > mxe-octave
view src/readline-2-event-hook.patch @ 7199:ea296e38047a default tip @
maint: Merge release to default.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Thu, 16 May 2024 11:42:51 +0200 |
parents | 7c302266a10b |
children |
line wrap: on
line source
diff -urN readline-8.2/input.c.orig readline-8.2/input.c --- readline-8.2/input.c.orig 2022-04-08 21:43:24.000000000 +0200 +++ readline-8.2/input.c 2022-12-12 09:58:00.410673600 +0100 @@ -176,6 +176,14 @@ static unsigned char ibuffer[512]; static int ibuffer_len = sizeof (ibuffer) - 1; +#if defined (__MINGW32__) +#include <windows.h> +static int _win32_getch (void); +static int _win32_kbhit (void); +static char _win32_buf[16] = {'0'}; +static int _win32_bufidx = 0; +#endif + #define any_typein (push_index != pop_index) int @@ -187,7 +195,11 @@ int _rl_pushed_input_available (void) { - return (push_index != pop_index); + return ((push_index != pop_index) +#if defined (__MINGW32__) + || (_win32_bufidx > 0) +#endif + ); } /* Return the amount of space available in the buffer for stuffing @@ -306,7 +318,7 @@ #if defined (__MINGW32__) /* Use getch/_kbhit to check for available console input, in the same way that we read it normally. */ - chars_avail = isatty (tty) ? _kbhit () : 0; + chars_avail = isatty (tty) ? _win32_kbhit () : 0; result = 0; #endif @@ -404,7 +416,7 @@ #if defined (__MINGW32__) if (isatty (tty)) - return (_kbhit ()); + return (_win32_kbhit ()); #endif return 0; @@ -799,6 +811,139 @@ return (c); } +#if defined (__MINGW32__) +#define _WIN32_READ_NOCHAR (-2) + +static int +_win32_getch_internal (int block) +{ + INPUT_RECORD rec; + DWORD evRead, waitResult; + HANDLE hInput = (HANDLE) _get_osfhandle (fileno (rl_instream)); + + if (_win32_bufidx > 0) + return _win32_buf[--_win32_bufidx]; + + hInput = (HANDLE) _get_osfhandle (fileno (rl_instream)); + + do + { + if (! block) + { + if (WaitForSingleObject (hInput, _keyboard_input_timeout/1000) != WAIT_OBJECT_0) + return _WIN32_READ_NOCHAR; + } + + if (! ReadConsoleInputW (hInput, &rec, 1, &evRead) || evRead != 1) + return EOF; + + switch (rec.EventType) + { + case KEY_EVENT: + if ((rec.Event.KeyEvent.bKeyDown && + (rec.Event.KeyEvent.wVirtualKeyCode < VK_SHIFT || + rec.Event.KeyEvent.wVirtualKeyCode > VK_MENU)) || + (!rec.Event.KeyEvent.bKeyDown && + rec.Event.KeyEvent.wVirtualKeyCode == VK_MENU && + rec.Event.KeyEvent.uChar.UnicodeChar)) + { + if (rec.Event.KeyEvent.uChar.UnicodeChar) + { + int result = (int) rec.Event.KeyEvent.uChar.UnicodeChar; + char charbuf[5] = {0}; + wchar_t unicode[2] = {result, 0}; + int utf16_code_units = 1; + if ((unicode[0] & 0xF800) == 0xD800) /* outside BMP */ + { + ReadConsoleInputW (hInput, &rec, 1, &evRead); + unicode[1] = (int) rec.Event.KeyEvent.uChar.UnicodeChar; + utf16_code_units++; + } + /* convert to current codepage or UTF-8 byte sequence */ + unsigned int codepage = CP_THREAD_ACP; + if (_rl_utf8locale) + codepage = CP_UTF8; + int len = WideCharToMultiByte (codepage, 0, + (wchar_t *) &unicode, utf16_code_units, + charbuf, 5, NULL, NULL); + /* buffer is read from back to front */ + for (int i=0; i<len-1; i++) + _win32_buf[_win32_bufidx++] = (unsigned char) charbuf[len-i-1]; + + return (int) (unsigned char) charbuf[0]; + } + + switch (rec.Event.KeyEvent.wVirtualKeyCode) + { + /* buffer is read from back to front */ + case VK_UP: + _win32_buf[_win32_bufidx++] = 'A'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_DOWN: + _win32_buf[_win32_bufidx++] = 'B'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_RIGHT: + _win32_buf[_win32_bufidx++] = 'C'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_LEFT: + _win32_buf[_win32_bufidx++] = 'D'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_HOME: + _win32_buf[_win32_bufidx++] = 'H'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_END: + _win32_buf[_win32_bufidx++] = 'F'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + case VK_DELETE: + _win32_buf[_win32_bufidx++] = 8; + _win32_buf[_win32_bufidx++] = 'C'; + _win32_buf[_win32_bufidx++] = '['; + return 0x1b; /* ESC */ + default: + break; + } + } + break; + + case WINDOW_BUFFER_SIZE_EVENT: + rl_resize_terminal (); + break; + + default: + break; + } + } + while (1); +} + +static int +_win32_kbhit (void) +{ + int result; + + result = _win32_getch_internal (0); + if (result == _WIN32_READ_NOCHAR + || result == EOF) + return 0; + + _win32_buf[_win32_bufidx++] = result; + + return _win32_bufidx; +} + +static int +_win32_getch (void) +{ + return (_win32_getch_internal (1)); +} +#endif + int rl_getc (FILE *stream) { @@ -818,8 +963,8 @@ /* We know at this point that _rl_caught_signal == 0 */ #if defined (__MINGW32__) - if (isatty (fd) - return (_getch ()); /* "There is no error return." */ + if (isatty (fd)) + return (_win32_getch ()); #endif result = 0; #if defined (HAVE_PSELECT) || defined (HAVE_SELECT)