Mercurial > emacs
diff src/keyboard.c @ 83047:55d4fe5962fd
Merged in changes from CVS HEAD
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-104
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-105
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-106
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-87
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Fri, 20 Feb 2004 15:41:31 +0000 |
parents | 30ccd595ccb0 5a946bc3433a |
children | b8aef5cd0bf2 |
line wrap: on
line diff
--- a/src/keyboard.c Fri Feb 20 03:02:04 2004 +0000 +++ b/src/keyboard.c Fri Feb 20 15:41:31 2004 +0000 @@ -4051,9 +4051,9 @@ If there is no valid info, it does not store anything so x remains nil. */ x = Qnil; - + /* XXX Can f or mouse_position_hook be NULL here? */ - if (f && FRAME_DISPLAY (f)->mouse_position_hook) + if (f && FRAME_DISPLAY (f)->mouse_position_hook) (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time); @@ -4986,7 +4986,7 @@ { Lisp_Object string; int charpos; - + posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin; rx = wx, ry = wy; string = marginal_area_string (w, part, &rx, &ry, &charpos, @@ -5469,7 +5469,7 @@ { Lisp_Object position; Lisp_Object head; - + /* Build the position as appropriate for this mouse click. */ struct frame *f = XFRAME (event->frame_or_window); @@ -6457,7 +6457,7 @@ /* If input is being read as it arrives, and we have none, there is none. */ if (*addr > 0 || (interrupt_input && ! interrupts_deferred)) return; - + /* Try to read some input and see how much we get. */ gobble_input (0); *addr = (!NILP (Vquit_flag) @@ -6560,14 +6560,6 @@ #ifndef VMS -/* We make the read_avail_input buffer static to avoid zeroing out the - whole struct input_event buf on every call. */ -static struct input_event read_avail_input_buf[KBD_BUFFER_SIZE]; - -/* I don't know whether it is necessary, but make read_avail_input - re-entrant. */ -static int in_read_avail_input = 0; - /* Read any terminal input already buffered up by the system into the kbd_buffer, but do not wait. @@ -6578,75 +6570,89 @@ 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. */ + 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 8 static int read_avail_input (expected) int expected; { - struct input_event *buf = read_avail_input_buf; - struct input_event tmp_buf[KBD_BUFFER_SIZE]; register int i; int nread = 0; struct display *d; - - /* Trivial hack to make read_avail_input re-entrant. */ - if (in_read_avail_input++) - { - buf = tmp_buf; - for (i = 0; i < KBD_BUFFER_SIZE; i++) - EVENT_INIT (buf[i]); - } /* Loop through the available displays, and call their input hooks. */ d = display_list; while (d) { struct display *next = d->next_display; - + if (d->read_socket_hook) - /* No need for FIONREAD or fcntl; just say don't wait. */ - nread = (*d->read_socket_hook) (d, buf, KBD_BUFFER_SIZE, expected); - - if (nread == -2) /* -2 means non-transient error */ { - /* The display device terminated; it should be closed. */ - - /* Kill Emacs if this was our last display. */ - if (! display_list->next_display) - kill (getpid (), SIGHUP); - - /* XXX Is calling delete_display safe here? It calls Fdelete_frame. */ - if (d->delete_display_hook) - (*d->delete_display_hook) (d); - else - delete_display (d); - } - else if (nread > 0) - { - /* We've got input. */ - break; + 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 = (*d->read_socket_hook) (d, buf, NREAD_INPUT_EVENTS, expected); + + if (nr > 0) + { + /* We've got input. */ + 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; + } + } + else if (nr == -2) /* Non-transient error. */ + { + /* The display device terminated; it should be closed. */ + + /* Kill Emacs if this was our last display. */ + if (! display_list->next_display) + /* Formerly simply reported no input, but that + sometimes led to a failure of Emacs to terminate. + SIGHUP seems appropriate if we can't reach the + terminal. */ + /* ??? Is it really right to send the signal just to + this process rather than to the whole process + group? Perhaps on systems with FIONREAD Emacs is + alone in its group. */ + kill (getpid (), SIGHUP); + + /* XXX Is calling delete_display safe here? It calls Fdelete_frame. */ + if (d->delete_display_hook) + (*d->delete_display_hook) (d); + else + delete_display (d); + } + } while (nr == NREAD_INPUT_EVENTS); } d = next; } - /* Scan the chars for C-g and store them in kbd_buffer. */ - for (i = 0; i < nread; 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) - break; - } - - /* Clear used events */ - if (--in_read_avail_input == 0) - for (i = 0; i < nread; i++) - EVENT_INIT (buf[i]); - return nread; } @@ -6668,10 +6674,10 @@ int n_to_read, i; struct tty_display_info *tty = display->display_info.tty; int nread = 0; - + if (display->type != output_termcap) abort (); - + /* XXX I think the following code should be moved to separate hook functions in system-dependent files. */ #ifdef WINDOWSNT @@ -6681,15 +6687,15 @@ n_to_read = dos_keysns (); if (n_to_read == 0) return 0; - + cbuf[0] = dos_keyread (); nread = 1; - + #else /* not MSDOS */ if (! tty->term_initted) /* In case we get called during bootstrap. */ return 0; - + /* Determine how many characters we should *try* to read. */ #ifdef FIONREAD /* Find out how much input is available. */ @@ -6713,7 +6719,7 @@ you lose; #endif #endif - + /* Now read; for one reason or another, this will not block. NREAD is set to the number of chars read. */ do @@ -6753,19 +6759,19 @@ 0 #endif ); - + #ifndef FIONREAD #if defined (USG) || defined (DGUX) || defined (CYGWIN) fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0); #endif /* USG or DGUX or CYGWIN */ #endif /* no FIONREAD */ - + if (nread <= 0) return nread; - + #endif /* not MSDOS */ #endif /* not WINDOWSNT */ - + for (i = 0; i < nread; i++) { buf[i].kind = ASCII_KEYSTROKE_EVENT; @@ -6774,7 +6780,7 @@ buf[i].modifiers = meta_modifier; if (tty->meta_key != 2) cbuf[i] &= ~0x80; - + buf[i].code = cbuf[i]; /* Set the frame corresponding to the active tty. Note that the value of selected_frame is not reliable here, redisplay tends @@ -6785,7 +6791,6 @@ return nread; } - #endif /* not VMS */ void @@ -8316,7 +8321,7 @@ int do_funcall; { Lisp_Object next; - + next = access_keymap (map, key, 1, 0, 1); /* Handle symbol with autoload definition. */ @@ -8331,7 +8336,7 @@ && (!NILP (Farrayp (XSYMBOL (next)->function)) || KEYMAPP (XSYMBOL (next)->function))) next = XSYMBOL (next)->function; - + /* If the keymap gives a function, not an array, then call the function with one arg and use its value instead. */ @@ -9345,7 +9350,7 @@ /* Adjust the function-key-map counters. */ fkey.end += diff; fkey.start += diff; - + goto replay_sequence; } } @@ -10146,7 +10151,7 @@ if (tty_list && tty_list->next) error ("Suspend is not supported with multiple ttys"); - + if (!NILP (stuffstring)) CHECK_STRING (stuffstring); @@ -10280,7 +10285,7 @@ else { /* Otherwise, the SIGINT was probably generated by C-g. */ - + /* Set internal_last_event_frame to the top frame of the controlling tty, if we have a frame there. We disable the interrupt key on secondary ttys, so the SIGINT must have come @@ -10294,7 +10299,7 @@ } /* This routine is called at interrupt level in response to C-g. - + It is called from the SIGINT handler or kbd_buffer_store_event. If `waiting_for_input' is non zero, then unless `echoing' is @@ -10307,7 +10312,7 @@ static void handle_interrupt () { - char c; + char c; struct frame *sf = SELECTED_FRAME (); cancel_echoing (); @@ -10480,7 +10485,7 @@ Currently it compiles fine, but its semantics are wrong. It sets global parameters (e.g. interrupt_input) based on only the current frame's device. */ - + if (!NILP (quit) && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400)) error ("set-input-mode: QUIT must be an ASCII character"); @@ -10528,7 +10533,7 @@ else tty->meta_key = 2; } - + if (!NILP (quit)) /* Don't let this value be out of range. */ quit_char = XINT (quit) & (NILP (meta) ? 0177 : 0377); @@ -10562,7 +10567,7 @@ { Lisp_Object val[4]; struct frame *sf = XFRAME (selected_frame); - + val[0] = interrupt_input ? Qt : Qnil; if (FRAME_TERMCAP_P (sf)) { @@ -10671,13 +10676,6 @@ do_mouse_tracking = Qnil; #endif input_pending = 0; -#ifndef VMS - { - int i; - for (i = 0; i < KBD_BUFFER_SIZE; i++) - EVENT_INIT (read_avail_input_buf[i]); - } -#endif /* This means that command_loop_1 won't try to select anything the first time through. */ @@ -11423,7 +11421,7 @@ /* Handling it at such a low-level causes read_key_sequence to get * confused because it doesn't realize that the current_buffer was * changed by read_char. - * + * * initial_define_lispy_key (Vspecial_event_map, "select-window", * "handle-select-window"); */ initial_define_lispy_key (Vspecial_event_map, "save-session",