# HG changeset patch # User Kim F. Storm # Date 1077925591 0 # Node ID 09b6da7723eb59db9a5c6dc890491c03842939b3 # Parent 197b774698f8f2e9975d239b1fc399dadeffa5c9 (kbd_buffer_store_event_hold): New function to store an event into kbd fifo, but with special handling of quit event; a quit event is saved for later, and further events are discarded until the saved quit event has been processed. (kbd_buffer_store_event): Use kbd_buffer_store_event_hold. (gen_help_event): Store help event in kbd fifo. (NREAD_INPUT_EVENTS): Remove. (read_avail_input): Adapt to new read_socket_hook interface. Remove allocation and initialization of local input_event buffer, as read_socket_hook stores events directly in fifo. Allocate and initialize local hold_quit event to handle postponed quit event (and store it if set by kbd_buffer_store_event_hold). diff -r 197b774698f8 -r 09b6da7723eb src/keyboard.c --- a/src/keyboard.c Fri Feb 27 17:32:57 2004 +0000 +++ b/src/keyboard.c Fri Feb 27 23:46:31 2004 +0000 @@ -3519,9 +3519,32 @@ kbd_buffer_store_event (event) register struct input_event *event; { + kbd_buffer_store_event_hold (event, 0); +} + +/* Store EVENT obtained at interrupt level into kbd_buffer, fifo. + + If HOLD_QUIT is 0, just stuff EVENT into the fifo. + Else, if HOLD_QUIT.kind != NO_EVENT, discard EVENT. + Else, if EVENT is a quit event, store the quit event + in HOLD_QUIT, and return (thus ignoring further events). + + This is used in read_avail_input to postpone the processing + of the quit event until all subsequent input events have been + parsed (and discarded). + */ + +void +kbd_buffer_store_event_hold (event, hold_quit) + register struct input_event *event; + struct input_event *hold_quit; +{ if (event->kind == NO_EVENT) abort (); + if (hold_quit && hold_quit->kind != NO_EVENT) + return; + if (event->kind == ASCII_KEYSTROKE_EVENT) { register int c = event->code & 0377; @@ -3563,6 +3586,12 @@ } #endif + if (hold_quit) + { + bcopy (event, (char *) hold_quit, sizeof (*event)); + return; + } + /* If this results in a quit_char being returned to Emacs as input, set Vlast_event_frame properly. If this doesn't get returned to Emacs as an event, the next event read @@ -3592,7 +3621,9 @@ Just ignore the second one. */ else if (event->kind == BUFFER_SWITCH_EVENT && kbd_fetch_ptr != kbd_store_ptr - && kbd_store_ptr->kind == BUFFER_SWITCH_EVENT) + && ((kbd_store_ptr == kbd_buffer + ? kbd_buffer + KBD_BUFFER_SIZE - 1 + : kbd_store_ptr - 1)->kind) == BUFFER_SWITCH_EVENT) return; if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE) @@ -3651,24 +3682,22 @@ Value is the number of input_events generated. */ -int -gen_help_event (bufp, size, help, frame, window, object, pos) - struct input_event *bufp; - int size; +void +gen_help_event (help, frame, window, object, pos) Lisp_Object help, frame, object, window; int pos; { - if (size >= 1) - { - bufp->kind = HELP_EVENT; - bufp->frame_or_window = frame; - bufp->arg = object; - bufp->x = WINDOWP (window) ? window : frame; - bufp->y = help; - bufp->code = pos; - return 1; - } - return 0; + struct input_event event; + + EVENT_INIT (event); + + event.kind = HELP_EVENT; + event.frame_or_window = frame; + event.arg = object; + event.x = WINDOWP (window) ? window : frame; + event.y = help; + event.code = pos; + kbd_buffer_store_event (&event); } @@ -6566,15 +6595,7 @@ only when SIGIO is blocked. Returns the number of keyboard chars read, or -1 meaning - this is a bad time to try to read input. - - Typically, there are just a few available input events to be read - here, so we really don't need to allocate and initialize a big - buffer of input_events as we used to do. Instead, we just allocate - a small buffer of input events -- and then poll for more input if we - read a full buffer of input events. */ - -#define NREAD_INPUT_EVENTS 512 + this is a bad time to try to read input. */ static int read_avail_input (expected) @@ -6587,32 +6608,19 @@ { int discard = 0; int nr; - - do { - struct input_event buf[NREAD_INPUT_EVENTS]; - - for (i = 0; i < NREAD_INPUT_EVENTS; i++) - EVENT_INIT (buf[i]); - - /* No need for FIONREAD or fcntl; just say don't wait. */ - nr = (*read_socket_hook) (input_fd, buf, NREAD_INPUT_EVENTS, expected); - if (nr <= 0) - break; - - nread += nr; - expected = 0; - - /* Scan the chars for C-g and store them in kbd_buffer. */ - for (i = 0; !discard && i < nr; i++) - { - kbd_buffer_store_event (&buf[i]); - /* Don't look at input that follows a C-g too closely. - This reduces lossage due to autorepeat on C-g. */ - if (buf[i].kind == ASCII_KEYSTROKE_EVENT - && buf[i].code == quit_char) - discard = 1; - } - } while (nr == NREAD_INPUT_EVENTS); + struct input_event hold_quit; + + EVENT_INIT (hold_quit); + hold_quit.kind = NO_EVENT; + + /* No need for FIONREAD or fcntl; just say don't wait. */ + while (nr = (*read_socket_hook) (input_fd, expected, &hold_quit), nr > 0) + { + nread += nr; + expected = 0; + } + if (hold_quit.kind != NO_EVENT) + kbd_buffer_store_event (&hold_quit); } else {