Cygwin: console: Fix read() in non-canonical mode.
- In non-canonical mode, cygwin console returned only one character even if several keys are typed before read() called. This patch fixes this behaviour.
This commit is contained in:
parent
3355a6d4b9
commit
fca4cda7a4
|
@ -499,21 +499,31 @@ fhandler_console::process_input_message (void)
|
|||
|
||||
termios *ti = &(get_ttyp ()->ti);
|
||||
|
||||
DWORD nread;
|
||||
INPUT_RECORD input_rec;
|
||||
const char *toadd = NULL;
|
||||
/* Per MSDN, max size of buffer required is below 64K. */
|
||||
#define INREC_SIZE (65536 / sizeof (INPUT_RECORD))
|
||||
|
||||
if (!ReadConsoleInputW (get_handle (), &input_rec, 1, &nread))
|
||||
fhandler_console::input_states stat = input_processing;
|
||||
DWORD total_read, i;
|
||||
INPUT_RECORD input_rec[INREC_SIZE];
|
||||
|
||||
if (!PeekConsoleInputW (get_handle (), input_rec, INREC_SIZE, &total_read))
|
||||
{
|
||||
termios_printf ("ReadConsoleInput failed, %E");
|
||||
termios_printf ("PeekConsoleInput failed, %E");
|
||||
return input_error;
|
||||
}
|
||||
|
||||
const WCHAR &unicode_char = input_rec.Event.KeyEvent.uChar.UnicodeChar;
|
||||
const DWORD &ctrl_key_state = input_rec.Event.KeyEvent.dwControlKeyState;
|
||||
for (i = 0; i < total_read; i ++)
|
||||
{
|
||||
DWORD nread = 1;
|
||||
const char *toadd = NULL;
|
||||
|
||||
const WCHAR &unicode_char =
|
||||
input_rec[i].Event.KeyEvent.uChar.UnicodeChar;
|
||||
const DWORD &ctrl_key_state =
|
||||
input_rec[i].Event.KeyEvent.dwControlKeyState;
|
||||
|
||||
/* check the event that occurred */
|
||||
switch (input_rec.EventType)
|
||||
switch (input_rec[i].EventType)
|
||||
{
|
||||
case KEY_EVENT:
|
||||
|
||||
|
@ -521,39 +531,39 @@ fhandler_console::process_input_message (void)
|
|||
|
||||
#ifdef DEBUGGING
|
||||
/* allow manual switching to/from raw mode via ctrl-alt-scrolllock */
|
||||
if (input_rec.Event.KeyEvent.bKeyDown
|
||||
&& input_rec.Event.KeyEvent.wVirtualKeyCode == VK_SCROLL
|
||||
if (input_rec[i].Event.KeyEvent.bKeyDown
|
||||
&& input_rec[i].Event.KeyEvent.wVirtualKeyCode == VK_SCROLL
|
||||
&& (ctrl_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED))
|
||||
== (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED))
|
||||
{
|
||||
set_raw_win32_keyboard_mode (!con.raw_win32_keyboard_mode);
|
||||
return input_processing;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (con.raw_win32_keyboard_mode)
|
||||
{
|
||||
__small_sprintf (tmp, "\033{%u;%u;%u;%u;%u;%luK",
|
||||
input_rec.Event.KeyEvent.bKeyDown,
|
||||
input_rec.Event.KeyEvent.wRepeatCount,
|
||||
input_rec.Event.KeyEvent.wVirtualKeyCode,
|
||||
input_rec.Event.KeyEvent.wVirtualScanCode,
|
||||
input_rec.Event.KeyEvent.uChar.UnicodeChar,
|
||||
input_rec.Event.KeyEvent.dwControlKeyState);
|
||||
input_rec[i].Event.KeyEvent.bKeyDown,
|
||||
input_rec[i].Event.KeyEvent.wRepeatCount,
|
||||
input_rec[i].Event.KeyEvent.wVirtualKeyCode,
|
||||
input_rec[i].Event.KeyEvent.wVirtualScanCode,
|
||||
input_rec[i].Event.KeyEvent.uChar.UnicodeChar,
|
||||
input_rec[i].Event.KeyEvent.dwControlKeyState);
|
||||
toadd = tmp;
|
||||
nread = strlen (toadd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ignore key up events, except for Alt+Numpad events. */
|
||||
if (!input_rec.Event.KeyEvent.bKeyDown &&
|
||||
!is_alt_numpad_event (&input_rec))
|
||||
return input_processing;
|
||||
if (!input_rec[i].Event.KeyEvent.bKeyDown &&
|
||||
!is_alt_numpad_event (&input_rec[i]))
|
||||
continue;
|
||||
/* Ignore Alt+Numpad keys. They are eventually handled below after
|
||||
releasing the Alt key. */
|
||||
if (input_rec.Event.KeyEvent.bKeyDown
|
||||
&& is_alt_numpad_key (&input_rec))
|
||||
return input_processing;
|
||||
if (input_rec[i].Event.KeyEvent.bKeyDown
|
||||
&& is_alt_numpad_key (&input_rec[i]))
|
||||
continue;
|
||||
|
||||
if (ctrl_key_state & SHIFT_PRESSED)
|
||||
con.nModifiers |= 1;
|
||||
|
@ -565,7 +575,7 @@ fhandler_console::process_input_message (void)
|
|||
con.nModifiers |= 8;
|
||||
|
||||
/* Allow Backspace to emit ^? and escape sequences. */
|
||||
if (input_rec.Event.KeyEvent.wVirtualKeyCode == VK_BACK)
|
||||
if (input_rec[i].Event.KeyEvent.wVirtualKeyCode == VK_BACK)
|
||||
{
|
||||
char c = con.backspace_keycode;
|
||||
nread = 0;
|
||||
|
@ -581,20 +591,21 @@ fhandler_console::process_input_message (void)
|
|||
toadd = tmp;
|
||||
}
|
||||
/* Allow Ctrl-Space to emit ^@ */
|
||||
else if (input_rec.Event.KeyEvent.wVirtualKeyCode
|
||||
else if (input_rec[i].Event.KeyEvent.wVirtualKeyCode
|
||||
== (wincap.has_con_24bit_colors () ? '2' : VK_SPACE)
|
||||
&& (ctrl_key_state & CTRL_PRESSED)
|
||||
&& !(ctrl_key_state & ALT_PRESSED))
|
||||
toadd = "";
|
||||
else if (unicode_char == 0
|
||||
/* arrow/function keys */
|
||||
|| (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
|
||||
|| (input_rec[i].Event.KeyEvent.dwControlKeyState
|
||||
& ENHANCED_KEY))
|
||||
{
|
||||
toadd = get_nonascii_key (input_rec, tmp);
|
||||
toadd = get_nonascii_key (input_rec[i], tmp);
|
||||
if (!toadd)
|
||||
{
|
||||
con.nModifiers = 0;
|
||||
return input_processing;
|
||||
continue;
|
||||
}
|
||||
nread = strlen (toadd);
|
||||
}
|
||||
|
@ -643,7 +654,7 @@ fhandler_console::process_input_message (void)
|
|||
case MOUSE_EVENT:
|
||||
send_winch_maybe ();
|
||||
{
|
||||
MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;
|
||||
MOUSE_EVENT_RECORD& mouse_event = input_rec[i].Event.MouseEvent;
|
||||
/* As a unique guard for mouse report generation,
|
||||
call mouse_aware() which is common with select(), so the result
|
||||
of select() and the actual read() will be consistent on the
|
||||
|
@ -816,7 +827,7 @@ fhandler_console::process_input_message (void)
|
|||
case FOCUS_EVENT:
|
||||
if (con.use_focus)
|
||||
{
|
||||
if (input_rec.Event.FocusEvent.bSetFocus)
|
||||
if (input_rec[i].Event.FocusEvent.bSetFocus)
|
||||
__small_sprintf (tmp, "\033[I");
|
||||
else
|
||||
__small_sprintf (tmp, "\033[O");
|
||||
|
@ -828,10 +839,13 @@ fhandler_console::process_input_message (void)
|
|||
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
if (send_winch_maybe ())
|
||||
return input_winch;
|
||||
{
|
||||
stat = input_winch;
|
||||
goto out;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
return input_processing;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (toadd)
|
||||
|
@ -839,14 +853,24 @@ fhandler_console::process_input_message (void)
|
|||
ssize_t ret;
|
||||
line_edit_status res = line_edit (toadd, nread, *ti, &ret);
|
||||
if (res == line_edit_signalled)
|
||||
return input_signalled;
|
||||
{
|
||||
stat = input_signalled;
|
||||
goto out;
|
||||
}
|
||||
else if (res == line_edit_input_done)
|
||||
{
|
||||
input_ready = true;
|
||||
return input_ok;
|
||||
stat = input_ok;
|
||||
if (ti->c_lflag & ICANON)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
return input_processing;
|
||||
}
|
||||
out:
|
||||
/* Discard processed recored. */
|
||||
DWORD dummy;
|
||||
ReadConsoleInputW (get_handle (), input_rec, min (total_read, i+1), &dummy);
|
||||
return stat;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue