summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog88
-rw-r--r--src/dispnew.c20
-rw-r--r--src/keyboard.c199
-rw-r--r--src/keyboard.h10
-rw-r--r--src/lisp.h1
-rw-r--r--src/macterm.c149
-rw-r--r--src/sysdep.c30
-rw-r--r--src/termhooks.h7
-rw-r--r--src/w32inevt.c25
-rw-r--r--src/w32inevt.h4
-rw-r--r--src/w32term.c251
-rw-r--r--src/window.c9
-rw-r--r--src/xsmfns.c20
-rw-r--r--src/xterm.c811
-rw-r--r--src/xterm.h3
15 files changed, 748 insertions, 879 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0fe8fbf9225..8b5944a1866 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,91 @@
+2004-02-28 Miles Bader <miles@gnu.org>
+
+ * keyboard.c (adjust_point_for_property): #ifdef-out dodgy xassert.
+
+2004-02-28 Kim F. Storm <storm@cua.dk>
+
+ * keyboard.c (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).
+
+ * keyboard.h (kbd_buffer_store_event_hold): Add prototype.
+ (gen_help_event): Fix prototype.
+
+ * macterm.c (XTread_socket): Remove bufp_r and
+ numcharsp args. Add hold_quit arg.
+ Rework to use just one, local, inev input_event. Store inev
+ directly in fifo using kbd_buffer_store_event_hold.
+
+ * sysdep.c (BUFFER_SIZE_FACTOR): Remove.
+ (read_input_waiting): 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).
+
+ * term.c (read_socket_hook): Fix arg list.
+
+ * termhooks.h (read_socket_hook): Fix prototype.
+
+ * w32inevt.c (w32_console_read_socket): Remove bufp_r and
+ numcharsp args. Add hold_quit arg.
+ Rework to use just one, local, inev input_event. Store inev
+ directly in fifo using kbd_buffer_store_event_hold.
+
+ * w32inevt.h (w32_console_mouse_position): Fix prototype.
+
+ * w32term.c (w32_read_socket): Remove bufp_r and numcharsp args.
+ Add hold_quit arg. Rework to use just one, local, inev
+ input_event. Store inev directly in fifo using
+ kbd_buffer_store_event_hold. Update count in one place.
+ Postpone call to gen_help_event until inev is stored; use new
+ local do_help for this.
+ Remove local emacs_event in handing of ButtonPress event; just use
+ inev instead (so no reason to copy it later).
+
+ * xsmfns.c (x_session_check_input): Remove numchars arg.
+
+ * xterm.c (x_focus_changed, x_detect_focus_change): Remove
+ numchars arg. Always store event into bufp arg. Return nothing.
+ Callers changed accordingly.
+ (glyph_rect): Simplify.
+ (STORE_KEYSYM_FOR_DEBUG): New macro.
+ (SET_SAVED_MENU_EVENT): Use inev instead of bufp, etc.
+ (current_bufp, current_numcharsp) [USE_GTK]: Remove.
+ (current_hold_quit) [USE_GTK]: Add.
+ (event_handler_gdk): Adapt to new handle_one_xevent.
+ (handle_one_xevent): Remove bufp_r and numcharsp args.
+ Add hold_quit arg. Rework to use just one, local, inev
+ input_event. Store inev directly in fifo using
+ kbd_buffer_store_event_hold. Update count in one place.
+ Postpone call to gen_help_event until inev is stored; use new
+ local do_help for this.
+ Simplify handling of keysyms (consolidate common code). Fix bug
+ where count was updated with nchars instead of nbytes.
+ Remove local emacs_event in handing of ButtonPress event; just use
+ inev instead (so no reason to copy it later).
+ Remove `out' label. Rename label `ret' to `done'; add various
+ `goto done' to clarify code flow in deeply nested blocks.
+ (x_dispatch_event): Simplify as handle_one_xevent now calls
+ kbd_buffer_store_event itself.
+ (XTread_socket): Remove bufp_r and numcharsp args. Add hold_quit
+ arg. Call handle_one_xevent with new arglist. Store event from
+ x_session_check_input in fifo.
+ [USE_GTK]: Setup current_hold_quit.
+ Decrement handling_signal before unblocking input.
+ (x_initialize) [USE_GTK]: Initialize current_count.
+
+ * xterm.h (x_session_check_input): Fix prototype.
+
2004-02-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* s/darwin.h (LD_SWITCH_SYSTEM_TEMACS): Add `-framework
diff --git a/src/dispnew.c b/src/dispnew.c
index 8a3d7013c3e..b4d3020e81d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -4137,16 +4137,6 @@ update_window (w, force_p)
changed_p = 1;
}
- /* Update the header line after scrolling because a new header
- line would otherwise overwrite lines at the top of the window
- that can be scrolled. */
- if (header_line_row && header_line_row->enabled_p)
- {
- header_line_row->y = 0;
- update_window_line (w, 0, &mouse_face_overwritten_p);
- changed_p = 1;
- }
-
/* Update the rest of the lines. */
for (n_updated = 0; row < end && (force_p || !input_pending); ++row)
if (row->enabled_p)
@@ -4183,6 +4173,16 @@ update_window (w, force_p)
set_cursor:
+ /* Update the header line after scrolling because a new header
+ line would otherwise overwrite lines at the top of the window
+ that can be scrolled. */
+ if (header_line_row && header_line_row->enabled_p)
+ {
+ header_line_row->y = 0;
+ update_window_line (w, 0, &mouse_face_overwritten_p);
+ changed_p = 1;
+ }
+
/* Fix the appearance of overlapping/overlapped rows. */
if (!paused_p && !w->pseudo_window_p)
{
diff --git a/src/keyboard.c b/src/keyboard.c
index 2aff293c610..5e8397e7458 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1916,7 +1916,12 @@ adjust_point_for_property (last_pt, modified)
: (PT < last_pt ? beg : end));
check_composition = check_display = 1;
}
+#if 0 /* This assertion isn't correct, because SET_PT may end up setting
+ the point to something other than its argument, due to
+ point-motion hooks, intangibility, etc. */
xassert (PT == beg || PT == end);
+#endif
+
/* Pretend the area doesn't exist if the buffer is not
modified. */
if (!modified && !ellipsis && beg < end)
@@ -3516,9 +3521,32 @@ void
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;
@@ -3560,6 +3588,12 @@ kbd_buffer_store_event (event)
}
#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
@@ -3589,7 +3623,9 @@ kbd_buffer_store_event (event)
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)
@@ -3648,24 +3684,22 @@ kbd_buffer_store_event (event)
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);
}
@@ -6570,15 +6604,7 @@ record_asynch_buffer_change ()
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)
@@ -6600,59 +6626,47 @@ read_avail_input (expected)
int discard = 0;
int nr;
- do {
- struct input_event buf[NREAD_INPUT_EVENTS];
+ struct input_event hold_quit;
- for (i = 0; i < NREAD_INPUT_EVENTS; i++)
- EVENT_INIT (buf[i]);
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
- /* No need for FIONREAD or fcntl; just say don't wait. */
- nr = (*d->read_socket_hook) (d, buf, NREAD_INPUT_EVENTS, expected);
+ /* No need for FIONREAD or fcntl; just say don't wait. */
+ while (nr = (*d->read_socket_hook) (d, expected, &hold_quit), nr > 0)
+ {
+ nread += nr;
+ expected = 0;
+ }
+
+ if (nr == -1) /* Not OK to read input now. */
+ {
+ err = 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);
+ }
- 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 == -1) /* Not OK to read input now. */
- {
- err = 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);
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
}
d = next;
@@ -6672,13 +6686,13 @@ read_avail_input (expected)
int
tty_read_avail_input (struct display *display,
- struct input_event *buf,
- int numchars, int expected)
+ int expected,
+ struct input_event *hold_quit)
{
- /* Using numchars here avoids reading more than the buf can
- really hold. That may prevent loss of characters on some systems
- when input is stuffed at us. */
- unsigned char cbuf[numchars];
+ /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
+ the kbd_buffer can really hold. That may prevent loss
+ of characters on some systems when input is stuffed at us. */
+ unsigned char cbuf[KBD_BUFFER_SIZE - 1];
int n_to_read, i;
struct tty_display_info *tty = display->display_info.tty;
int nread = 0;
@@ -6785,19 +6799,28 @@ tty_read_avail_input (struct display *display,
for (i = 0; i < nread; i++)
{
- buf[i].kind = ASCII_KEYSTROKE_EVENT;
- buf[i].modifiers = 0;
+ struct input_event buf;
+ EVENT_INIT (buf);
+ buf.kind = ASCII_KEYSTROKE_EVENT;
+ buf.modifiers = 0;
if (tty->meta_key == 1 && (cbuf[i] & 0x80))
- buf[i].modifiers = meta_modifier;
+ buf.modifiers = meta_modifier;
if (tty->meta_key != 2)
cbuf[i] &= ~0x80;
-
- buf[i].code = cbuf[i];
+
+ buf.code = cbuf[i];
/* Set the frame corresponding to the active tty. Note that the
value of selected_frame is not reliable here, redisplay tends
to temporarily change it. */
- buf[i].frame_or_window = tty->top_frame;
- buf[i].arg = Qnil;
+ buf.frame_or_window = tty->top_frame;
+ buf.arg = Qnil;
+
+ kbd_buffer_store_event (&buf);
+ /* Don't look at input that follows a C-g too closely.
+ This reduces lossage due to autorepeat on C-g. */
+ if (buf.kind == ASCII_KEYSTROKE_EVENT
+ && buf.code == quit_char)
+ break;
}
return nread;
diff --git a/src/keyboard.h b/src/keyboard.h
index a084efa7791..3f38b7ded6b 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -329,19 +329,21 @@ extern void timer_start_idle P_ ((void));
extern void timer_stop_idle P_ ((void));
extern int lucid_event_type_list_p P_ ((Lisp_Object));
extern void kbd_buffer_store_event P_ ((struct input_event *));
+extern void kbd_buffer_store_event_hold P_ ((struct input_event *,
+ struct input_event *));
#ifdef POLL_FOR_INPUT
extern void poll_for_input_1 P_ ((void));
#endif
extern void show_help_echo P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, int));
-extern int gen_help_event P_ ((struct input_event *, int, Lisp_Object,
- Lisp_Object, Lisp_Object, Lisp_Object, int));
+extern void gen_help_event P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
+ Lisp_Object, int));
extern void kbd_buffer_store_help_event P_ ((Lisp_Object, Lisp_Object));
extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
extern int kbd_buffer_events_waiting P_ ((int));
-extern int tty_read_avail_input P_ ((struct display *,
- struct input_event *, int, int));
+extern int tty_read_avail_input P_ ((struct display *, int,
+ struct input_event *));
/* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
(do not change this comment) */
diff --git a/src/lisp.h b/src/lisp.h
index 8affbc76126..371bd0d729d 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2380,7 +2380,6 @@ extern void redisplay P_ ((void));
extern int check_point_in_composition
P_ ((struct buffer *, int, struct buffer *, int));
extern void redisplay_preserve_echo_area P_ ((int));
-extern void mark_window_display_accurate P_ ((Lisp_Object, int));
extern void prepare_menu_bars P_ ((void));
void set_frame_cursor_types P_ ((struct frame *, Lisp_Object));
diff --git a/src/macterm.c b/src/macterm.c
index 90c850c596b..f6269791c51 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -8016,8 +8016,9 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
/* Emacs calls this whenever it wants to read an input event from the
user. */
int
-XTread_socket (struct input_event *bufp, int numchars, int expected)
+XTread_socket (int sd, int expected, struct input_event *hold_quit)
{
+ struct input_event inev;
int count = 0;
#if USE_CARBON_EVENTS
OSStatus rneResult;
@@ -8042,9 +8043,6 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
/* So people can tell when we have read the available input. */
input_signal_count++;
- if (numchars <= 0)
- abort ();
-
/* Don't poll for events to process (specifically updateEvt) if
window update currently already in progress. A call to redisplay
(in do_window_update) can be preempted by another call to
@@ -8063,7 +8061,9 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
event to nil because keyboard.c protects incompletely processed
event from being garbage collected by placing them in the
kbd_buffer_gcpro vector. */
- bufp->arg = Qnil;
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
event_mask = everyEvent;
if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
@@ -8101,18 +8101,17 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
GetEventParameter(eventRef, kEventParamMouseLocation,
typeQDPoint, NULL, sizeof (Point),
NULL, &point);
- bufp->kind = WHEEL_EVENT;
- bufp->code = 0;
- bufp->modifiers = (mac_event_to_emacs_modifiers(eventRef)
- | ((delta < 0) ? down_modifier
- : up_modifier));
+ inev.kind = WHEEL_EVENT;
+ inev.code = 0;
+ inev.modifiers = (mac_event_to_emacs_modifiers(eventRef)
+ | ((delta < 0) ? down_modifier
+ : up_modifier));
SetPort (GetWindowPort (window_ptr));
GlobalToLocal (&point);
- XSETINT (bufp->x, point.h);
- XSETINT (bufp->y, point.v);
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
- bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
- count++;
+ XSETINT (inev.x, point.h);
+ XSETINT (inev.y, point.v);
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
+ inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
}
else
SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
@@ -8161,28 +8160,27 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
GlobalToLocal (&mouse_loc);
#if USE_CARBON_EVENTS
- bufp->code = mac_get_mouse_btn (eventRef);
+ inev.code = mac_get_mouse_btn (eventRef);
#else
- bufp_.code = mac_get_emulate_btn (er.modifiers);
+ inev.code = mac_get_emulate_btn (er.modifiers);
#endif
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = tracked_scroll_bar->window;
- bufp->part = scroll_bar_handle;
+ inev.kind = SCROLL_BAR_CLICK_EVENT;
+ inev.frame_or_window = tracked_scroll_bar->window;
+ inev.part = scroll_bar_handle;
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
- bufp->modifiers |= up_modifier;
- bufp->timestamp = er.when * (1000 / 60);
+ inev.modifiers |= up_modifier;
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
- XSETINT (bufp->x, tracked_scroll_bar->left + 2);
- XSETINT (bufp->y, mouse_loc.v - 24);
+ XSETINT (inev.x, tracked_scroll_bar->left + 2);
+ XSETINT (inev.y, mouse_loc.v - 24);
tracked_scroll_bar->dragging = Qnil;
mouse_tracking_in_progress = mouse_tracking_none;
tracked_scroll_bar = NULL;
- count++;
break;
}
@@ -8196,9 +8194,8 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
struct frame *f = ((mac_output *)
GetWRefCon (FrontWindow ()))->mFP;
saved_menu_event_location = er.where;
- bufp->kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- count++;
+ inev.kind = MENU_BAR_ACTIVATE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
break;
@@ -8229,13 +8226,13 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
#endif
#if USE_CARBON_EVENTS
- bufp->code = mac_get_mouse_btn (eventRef);
+ inev.code = mac_get_mouse_btn (eventRef);
#else
- bufp_.code = mac_get_emulate_btn (er.modifiers);
+ inev.code = mac_get_emulate_btn (er.modifiers);
#endif
- XSETINT (bufp->x, mouse_loc.h);
- XSETINT (bufp->y, mouse_loc.v);
- bufp->timestamp = er.when * (1000 / 60);
+ XSETINT (inev.x, mouse_loc.h);
+ XSETINT (inev.y, mouse_loc.v);
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
#if TARGET_API_MAC_CARBON
@@ -8247,7 +8244,7 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
struct scroll_bar *bar = (struct scroll_bar *)
GetControlReference (ch);
x_scroll_bar_handle_click (bar, control_part_code, &er,
- bufp);
+ &inev);
if (er.what == mouseDown
&& control_part_code == kControlIndicatorPart)
{
@@ -8264,22 +8261,22 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
else
{
Lisp_Object window;
-
- bufp->kind = MOUSE_CLICK_EVENT;
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
+
+ inev.kind = MOUSE_CLICK_EVENT;
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
if (er.what == mouseDown)
mouse_tracking_in_progress
= mouse_tracking_mouse_movement;
else
mouse_tracking_in_progress = mouse_tracking_none;
- window = window_from_coordinates (mwp->mFP, bufp->x, bufp->y, 0, 0, 0, 1);
+ window = window_from_coordinates (mwp->mFP, inev.x, inev.y, 0, 0, 0, 1);
if (EQ (window, mwp->mFP->tool_bar_window))
{
if (er.what == mouseDown)
- handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 1, 0);
+ handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 1, 0);
else
- handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 0,
+ handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 0,
#if USE_CARBON_EVENTS
mac_event_to_emacs_modifiers (eventRef)
#else
@@ -8291,22 +8288,20 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
}
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
switch (er.what)
{
case mouseDown:
- bufp->modifiers |= down_modifier;
+ inev.modifiers |= down_modifier;
break;
case mouseUp:
- bufp->modifiers |= up_modifier;
+ inev.modifiers |= up_modifier;
break;
}
-
- count++;
}
break;
@@ -8327,10 +8322,9 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
case inGoAway:
if (TrackGoAway (window_ptr, er.where))
{
- bufp->kind = DELETE_WINDOW_EVENT;
- XSETFRAME (bufp->frame_or_window,
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window,
((mac_output *) GetWRefCon (window_ptr))->mFP);
- count++;
}
break;
@@ -8399,8 +8393,8 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
if (keycode_to_xkeysym (keycode, &xkeysym))
{
- bufp->code = 0xff00 | xkeysym;
- bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = 0xff00 | xkeysym;
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
}
else
{
@@ -8419,12 +8413,12 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
int new_keycode = keycode | new_modifiers;
Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
unsigned long some_state = 0;
- bufp->code = KeyTranslate (kchr_ptr, new_keycode,
- &some_state) & 0xff;
+ inev.code = KeyTranslate (kchr_ptr, new_keycode,
+ &some_state) & 0xff;
}
else
- bufp->code = er.message & charCodeMask;
- bufp->kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = er.message & charCodeMask;
+ inev.kind = ASCII_KEYSTROKE_EVENT;
}
}
@@ -8435,7 +8429,7 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
Mac keyboard to be used to enter non-ASCII iso-latin-1
characters directly. */
if (mac_keyboard_text_encoding != kTextEncodingMacRoman
- && bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
+ && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
{
static TECObjectRef converter = NULL;
OSStatus the_err = noErr;
@@ -8464,7 +8458,7 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
if (the_err == noErr)
{
- unsigned char ch = bufp->code;
+ unsigned char ch = inev.code;
ByteCount actual_input_length, actual_output_length;
unsigned char outch;
@@ -8475,25 +8469,23 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
if (convert_status == noErr
&& actual_input_length == 1
&& actual_output_length == 1)
- bufp->code = outch;
+ inev.code = outch;
}
}
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
{
mac_output *mwp
= (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
}
- bufp->timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-
- count++;
+ inev.timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
break;
case kHighLevelEvent:
@@ -8521,21 +8513,21 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
if (wp && is_emacs_window(wp))
f = ((mac_output *) GetWRefCon (wp))->mFP;
- bufp->kind = DRAG_N_DROP_EVENT;
- bufp->code = 0;
- bufp->timestamp = er.when * (1000 / 60);
+ inev.kind = DRAG_N_DROP_EVENT;
+ inev.code = 0;
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
- XSETINT (bufp->x, 0);
- XSETINT (bufp->y, 0);
+ XSETINT (inev.x, 0);
+ XSETINT (inev.y, 0);
XSETFRAME (frame, f);
- bufp->frame_or_window = Fcons (frame, drag_and_drop_file_list);
+ inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
/* Regardless of whether Emacs was suspended or in the
foreground, ask it to redraw its entire screen.
@@ -8552,8 +8544,6 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
#else /* not TARGET_API_MAC_CARBON */
InvalRect (&(wp->portRect));
#endif /* not TARGET_API_MAC_CARBON */
-
- count++;
}
default:
break;
@@ -8622,8 +8612,13 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
}
}
- UNBLOCK_INPUT;
+ if (inev.kind != NO_EVENT)
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ UNBLOCK_INPUT;
return count;
}
diff --git a/src/sysdep.c b/src/sysdep.c
index d4693f99a94..20d57b6a6a3 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2711,13 +2711,6 @@ sys_select (nfds, rfds, wfds, efds, timeout)
/* Read keyboard input into the standard buffer,
waiting for at least one character. */
-/* Make all keyboard buffers much bigger when using a window system. */
-#ifdef HAVE_WINDOW_SYSTEM
-#define BUFFER_SIZE_FACTOR 16
-#else
-#define BUFFER_SIZE_FACTOR 1
-#endif
-
void
read_input_waiting ()
{
@@ -2728,26 +2721,19 @@ read_input_waiting ()
if (read_socket_hook)
{
- struct input_event buf[256];
- for (i = 0; i < 256; i++)
- EVENT_INIT (buf[i]);
-
+ struct input_event hold_quit;
+
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
+
read_alarm_should_throw = 0;
if (! setjmp (read_alarm_throw))
- nread = (*read_socket_hook) (0, buf, 256, 1);
+ nread = (*read_socket_hook) (0, 1, &hold_quit);
else
nread = -1;
- /* 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;
- }
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
}
else
{
diff --git a/src/termhooks.h b/src/termhooks.h
index 6b2b0d07867..49a0cbac85b 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -489,10 +489,11 @@ struct display
there is available input on at least one of the currently opened
display devices -- but not necessarily on this device.
Therefore, in most cases EXPECTED should be simply ignored.
- */
+
+ XXX This documentation needs to be updated. */
int (*read_socket_hook) P_ ((struct display *display,
- struct input_event *buf,
- int size, int expected));
+ int expected,
+ struct input_event *hold_quit));
/* Called when a frame's display becomes entirely up to date. */
void (*frame_up_to_date_hook) P_ ((struct frame *));
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 24295e122d0..168a0fb87b3 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -642,8 +642,7 @@ maybe_generate_resize_event ()
}
int
-w32_console_read_socket (struct input_event *bufp, int numchars,
- int expected)
+w32_console_read_socket (int sd, int expected, struct input_event *hold_quit)
{
BOOL no_events = TRUE;
int nev, ret = 0, add;
@@ -670,27 +669,31 @@ w32_console_read_socket (struct input_event *bufp, int numchars,
return nev;
}
- while (nev > 0 && numchars > 0)
+ while (nev > 0)
{
+ struct input_event inev;
+
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
+
switch (queue_ptr->EventType)
{
case KEY_EVENT:
- add = key_event (&queue_ptr->Event.KeyEvent, bufp, &isdead);
+ add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead);
if (add == -1) /* 95.7.25 by himi */
{
queue_ptr--;
add = 1;
}
- bufp += add;
- ret += add;
- numchars -= add;
+ if (add)
+ kbd_buffer_store_event_hold (&inev, hold_quit);
break;
case MOUSE_EVENT:
- add = do_mouse_event (&queue_ptr->Event.MouseEvent, bufp);
- bufp += add;
- ret += add;
- numchars -= add;
+ add = do_mouse_event (&queue_ptr->Event.MouseEvent, &inev);
+ if (add)
+ kbd_buffer_store_event_hold (&inev, hold_quit);
break;
case WINDOW_BUFFER_SIZE_EVENT:
diff --git a/src/w32inevt.h b/src/w32inevt.h
index 0b3c70a141e..fb61cb0ef55 100644
--- a/src/w32inevt.h
+++ b/src/w32inevt.h
@@ -21,8 +21,8 @@ Boston, MA 02111-1307, USA. */
#ifndef EMACS_W32INEVT_H
#define EMACS_W32INEVT_H
-extern int w32_console_read_socket (int sd, struct input_event *bufp,
- int numchars, int expected);
+extern int w32_console_read_socket (int sd, int numchars,
+ struct input_event *hold_quit);
extern void w32_console_mouse_position (FRAME_PTR *f, int insist,
Lisp_Object *bar_window,
enum scroll_bar_part *part,
diff --git a/src/w32term.c b/src/w32term.c
index 92d508691cd..c59dabc27b0 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -4122,8 +4122,6 @@ static short temp_buffer[100];
This routine is called by the SIGIO handler.
We return as soon as there are no more events to be read.
- Events representing keys are stored in buffer BUFP,
- which can hold up to NUMCHARS characters.
We return the number of characters stored into the buffer,
thus pretending to be `read'.
@@ -4139,10 +4137,10 @@ static short temp_buffer[100];
*/
int
-w32_read_socket (bufp, numchars, expected)
- /* register */ struct input_event *bufp;
- /* register */ int numchars;
+w32_read_socket (sd, expected, hold_quit)
+ register int sd;
int expected;
+ struct input_event *hold_quit;
{
int count = 0;
int check_visibility = 0;
@@ -4162,13 +4160,17 @@ w32_read_socket (bufp, numchars, expected)
/* So people can tell when we have read the available input. */
input_signal_count++;
- if (numchars <= 0)
- abort (); /* Don't think this happens. */
-
/* TODO: tool-bars, ghostscript integration, mouse
cursors. */
while (get_next_msg (&msg, FALSE))
{
+ struct input_event inev;
+ int do_help = 0;
+
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
+
switch (msg.msg.message)
{
case WM_PAINT:
@@ -4197,12 +4199,8 @@ w32_read_socket (bufp, numchars, expected)
visibility changes properly. */
if (f->iconified)
{
- bufp->kind = DEICONIFY_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
@@ -4232,17 +4230,10 @@ w32_read_socket (bufp, numchars, expected)
if (f)
{
- if (numchars == 0)
- abort ();
-
- bufp->kind = LANGUAGE_CHANGE_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->code = msg.msg.wParam;
- bufp->modifiers = msg.msg.lParam & 0xffff;
- bufp++;
- count++;
- numchars--;
+ inev.kind = LANGUAGE_CHANGE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ inev.code = msg.msg.wParam;
+ inev.modifiers = msg.msg.lParam & 0xffff;
}
break;
@@ -4261,15 +4252,11 @@ w32_read_socket (bufp, numchars, expected)
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
temp_buffer[temp_index++] = msg.msg.wParam;
- bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
- bufp->code = msg.msg.wParam;
- bufp->modifiers = msg.dwModifiers;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->timestamp = msg.msg.time;
- bufp++;
- numchars--;
- count++;
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = msg.msg.wParam;
+ inev.modifiers = msg.dwModifiers;
+ XSETFRAME (inev.frame_or_window, f);
+ inev.timestamp = msg.msg.time;
}
break;
@@ -4288,15 +4275,11 @@ w32_read_socket (bufp, numchars, expected)
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
temp_buffer[temp_index++] = msg.msg.wParam;
- bufp->kind = ASCII_KEYSTROKE_EVENT;
- bufp->code = msg.msg.wParam;
- bufp->modifiers = msg.dwModifiers;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->timestamp = msg.msg.time;
- bufp++;
- numchars--;
- count++;
+ inev.kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = msg.msg.wParam;
+ inev.modifiers = msg.dwModifiers;
+ XSETFRAME (inev.frame_or_window, f);
+ inev.timestamp = msg.msg.time;
}
break;
@@ -4342,13 +4325,10 @@ w32_read_socket (bufp, numchars, expected)
iff it is active. */
if (WINDOWP(window)
&& !EQ (window, last_window)
- && !EQ (window, selected_window)
- && numchars > 0)
+ && !EQ (window, selected_window))
{
- bufp->kind = SELECT_WINDOW_EVENT;
- bufp->frame_or_window = window;
- bufp->arg = Qnil;
- ++bufp, ++count, --numchars;
+ inev.kind = SELECT_WINDOW_EVENT;
+ inev.frame_or_window = window;
}
last_window=window;
@@ -4366,27 +4346,8 @@ w32_read_socket (bufp, numchars, expected)
has changed, generate a HELP_EVENT. */
if (help_echo_string != previous_help_echo_string ||
(!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
- {
- Lisp_Object frame;
- int n;
-
- if (help_echo_string == Qnil)
- {
- help_echo_object = help_echo_window = Qnil;
- help_echo_pos = -1;
- }
-
- if (f)
- XSETFRAME (frame, f);
- else
- frame = Qnil;
+ do_help = 1;
- any_help_event_p = 1;
- n = gen_help_event (bufp, numchars, help_echo_string, frame,
- help_echo_window, help_echo_object,
- help_echo_pos);
- bufp += n, count += n, numchars -= n;
- }
break;
case WM_LBUTTONDOWN:
@@ -4400,13 +4361,10 @@ w32_read_socket (bufp, numchars, expected)
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
- struct input_event emacs_event;
int tool_bar_p = 0;
int button;
int up;
- emacs_event.kind = NO_EVENT;
-
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
@@ -4415,35 +4373,29 @@ w32_read_socket (bufp, numchars, expected)
if (f)
{
- construct_mouse_click (&emacs_event, &msg, f);
+ construct_mouse_click (&inev, &msg, f);
/* Is this in the tool-bar? */
if (WINDOWP (f->tool_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
{
Lisp_Object window;
- int x = XFASTINT (emacs_event.x);
- int y = XFASTINT (emacs_event.y);
+ int x = XFASTINT (inev.x);
+ int y = XFASTINT (inev.y);
window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
if (EQ (window, f->tool_bar_window))
{
- w32_handle_tool_bar_click (f, &emacs_event);
+ w32_handle_tool_bar_click (f, &inev);
tool_bar_p = 1;
}
}
- if (!tool_bar_p)
- if (!dpyinfo->w32_focus_frame
- || f == dpyinfo->w32_focus_frame
- && (numchars >= 1))
- {
- construct_mouse_click (bufp, &msg, f);
- bufp++;
- count++;
- numchars--;
- }
+ if (tool_bar_p
+ || (dpyinfo->w32_focus_frame
+ && f == dpyinfo->w32_focus_frame))
+ inev.kind = NO_EVENT;
}
parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
@@ -4481,15 +4433,11 @@ w32_read_socket (bufp, numchars, expected)
if (f)
{
- if ((!dpyinfo->w32_focus_frame
- || f == dpyinfo->w32_focus_frame)
- && (numchars >= 1))
+ if (!dpyinfo->w32_focus_frame
+ || f == dpyinfo->w32_focus_frame)
{
/* Emit an Emacs wheel-up/down event. */
- construct_mouse_wheel (bufp, &msg, f);
- bufp++;
- count++;
- numchars--;
+ construct_mouse_wheel (&inev, &msg, f);
}
/* Ignore any mouse motion that happened before this
event; any subsequent mouse-movement Emacs events
@@ -4506,12 +4454,7 @@ w32_read_socket (bufp, numchars, expected)
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
- {
- construct_drag_n_drop (bufp, &msg, f);
- bufp++;
- count++;
- numchars--;
- }
+ construct_drag_n_drop (&inev, &msg, f);
break;
case WM_VSCROLL:
@@ -4519,15 +4462,8 @@ w32_read_socket (bufp, numchars, expected)
struct scroll_bar *bar =
x_window_to_scroll_bar ((HWND)msg.msg.lParam);
- if (bar && numchars >= 1)
- {
- if (w32_scroll_bar_handle_click (bar, &msg, bufp))
- {
- bufp++;
- count++;
- numchars--;
- }
- }
+ if (bar)
+ w32_scroll_bar_handle_click (bar, &msg, &inev);
break;
}
@@ -4603,12 +4539,8 @@ w32_read_socket (bufp, numchars, expected)
f->async_visible = 0;
f->async_iconified = 1;
- bufp->kind = ICONIFY_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = ICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
break;
case SIZE_MAXIMIZED:
@@ -4633,12 +4565,8 @@ w32_read_socket (bufp, numchars, expected)
f->left_pos = x;
f->top_pos = y;
- bufp->kind = DEICONIFY_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
@@ -4706,16 +4634,7 @@ w32_read_socket (bufp, numchars, expected)
Otherwise, the startup message is cleared when
the mouse leaves the frame. */
if (any_help_event_p)
- {
- Lisp_Object frame;
- int n;
-
- XSETFRAME (frame, f);
- help_echo_string = Qnil;
- n = gen_help_event (bufp, numchars,
- Qnil, frame, Qnil, Qnil, 0);
- bufp += n, count += n, numchars -= n;
- }
+ do_help = -1;
}
break;
@@ -4765,16 +4684,7 @@ w32_read_socket (bufp, numchars, expected)
Otherwise, the startup message is cleared when
the mouse leaves the frame. */
if (any_help_event_p)
- {
- Lisp_Object frame;
- int n;
-
- XSETFRAME (frame, f);
- help_echo_string = Qnil;
- n = gen_help_event (bufp, numchars,
- Qnil, frame, Qnil, Qnil, 0);
- bufp += n, count += n, numchars -=n;
- }
+ do_help = -1;
}
dpyinfo->grabbed = 0;
@@ -4786,15 +4696,8 @@ w32_read_socket (bufp, numchars, expected)
if (f)
{
- if (numchars == 0)
- abort ();
-
- bufp->kind = DELETE_WINDOW_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
break;
@@ -4803,15 +4706,8 @@ w32_read_socket (bufp, numchars, expected)
if (f)
{
- if (numchars == 0)
- abort ();
-
- bufp->kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = MENU_BAR_ACTIVATE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
break;
@@ -4853,6 +4749,42 @@ w32_read_socket (bufp, numchars, expected)
}
break;
}
+
+ if (inev.kind != NO_EVENT)
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+
+ if (do_help
+ && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object frame;
+
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+
+ if (do_help > 0)
+ {
+ if (help_echo_string == Qnil)
+ {
+ help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
+ }
+
+ any_help_event_p = 1;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+ else
+ {
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ }
+ count++;
+ }
}
/* If the focus was just given to an autoraising frame,
@@ -5144,6 +5076,9 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
cursor remains invisible. */
if (w32_use_visible_system_caret)
{
+ /* Call to erase_phys_cursor here seems to use the
+ wrong values of w->phys_cursor, as they have been
+ overwritten before this function was called. */
if (w->phys_cursor_type != NO_CURSOR)
erase_phys_cursor (w);
diff --git a/src/window.c b/src/window.c
index 8f971ab0260..7419239752a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2046,6 +2046,9 @@ window_loop (type, obj, mini, frames)
if (EQ (w->buffer, obj))
{
mark_window_display_accurate (window, 0);
+ w->update_mode_line = Qt;
+ XBUFFER (obj)->prevent_redisplay_optimizations_p = 1;
+ ++update_mode_lines;
best_window = window;
}
break;
@@ -3464,12 +3467,18 @@ displaying that buffer. */)
if (NILP (object))
{
windows_or_buffers_changed++;
+ update_mode_lines++;
return Qt;
}
if (WINDOWP (object))
{
+ struct window *w = XWINDOW (object);
mark_window_display_accurate (object, 0);
+ w->update_mode_line = Qt;
+ if (BUFFERP (w->buffer))
+ XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ ++update_mode_lines;
return Qt;
}
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 88ee0a78188..35c7429b66b 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -107,13 +107,10 @@ Lisp_Object Vx_session_previous_id;
/* Handle any messages from the session manager. If no connection is
open to a session manager, just return 0.
- Otherwise returns the number of events stored in buffer BUFP,
- which can hold up to *NUMCHARS characters. At most one event is
- stored, a SAVE_SESSION_EVENT. */
+ Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP. */
int
-x_session_check_input (bufp, numchars)
+x_session_check_input (bufp)
struct input_event *bufp;
- int *numchars;
{
SELECT_TYPE read_fds;
EMACS_TIME tmout;
@@ -147,16 +144,11 @@ x_session_check_input (bufp, numchars)
/* Check if smc_interact_CB was called and we shall generate a
SAVE_SESSION_EVENT. */
- if (*numchars > 0 && emacs_event.kind != NO_EVENT)
- {
- bcopy (&emacs_event, bufp, sizeof (struct input_event));
- bufp++;
- (*numchars)--;
-
- return 1;
- }
+ if (emacs_event.kind == NO_EVENT)
+ return 0;
- return 0;
+ bcopy (&emacs_event, bufp, sizeof (struct input_event));
+ return 1;
}
/* Return non-zero if we have a connection to a session manager.*/
diff --git a/src/xterm.c b/src/xterm.c
index 546c93600d4..6100eaacffa 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -337,16 +337,10 @@ static void x_clear_frame P_ ((void));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
-static int x_focus_changed P_ ((int,
- int,
- struct x_display_info *,
- struct frame *,
- struct input_event *,
- int));
-static int x_detect_focus_change P_ ((struct x_display_info *,
- XEvent *,
- struct input_event *,
- int));
+static void x_focus_changed P_ ((int, int, struct x_display_info *,
+ struct frame *, struct input_event *));
+static void x_detect_focus_change P_ ((struct x_display_info *,
+ XEvent *, struct input_event *));
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
@@ -365,11 +359,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
unsigned long *));
static void x_check_fullscreen P_ ((struct frame *));
static void x_check_expected_move P_ ((struct frame *));
-static int handle_one_xevent P_ ((struct x_display_info *,
- XEvent *,
- struct input_event **,
- int *,
- int *));
+static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
+ int *, struct input_event *));
/* Flush display of frame F, or of all frames if F is null. */
@@ -3169,20 +3160,16 @@ x_new_focus_frame (dpyinfo, frame)
/* Handle FocusIn and FocusOut state changes for FRAME.
If FRAME has focus and there exists more than one frame, puts
- a FOCUS_IN_EVENT into BUFP.
- Returns number of events inserted into BUFP. */
+ a FOCUS_IN_EVENT into *BUFP. */
-static int
-x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
+static void
+x_focus_changed (type, state, dpyinfo, frame, bufp)
int type;
int state;
struct x_display_info *dpyinfo;
struct frame *frame;
struct input_event *bufp;
- int numchars;
{
- int nr_events = 0;
-
if (type == FocusIn)
{
if (dpyinfo->x_focus_event_frame != frame)
@@ -3192,17 +3179,12 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
/* Don't stop displaying the initial startup message
for a switch-frame event we don't need. */
- if (numchars > 0
- && GC_NILP (Vterminal_frame)
+ if (GC_NILP (Vterminal_frame)
&& GC_CONSP (Vframe_list)
&& !GC_NILP (XCDR (Vframe_list)))
{
bufp->kind = FOCUS_IN_EVENT;
XSETFRAME (bufp->frame_or_window, frame);
- bufp->arg = Qnil;
- ++bufp;
- numchars--;
- ++nr_events;
}
}
@@ -3228,27 +3210,25 @@ x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
XUnsetICFocus (FRAME_XIC (frame));
#endif
}
-
- return nr_events;
}
/* The focus may have changed. Figure out if it is a real focus change,
by checking both FocusIn/Out and Enter/LeaveNotify events.
- Returns number of events inserted into BUFP. */
+ Returns FOCUS_IN_EVENT event in *BUFP. */
-static int
-x_detect_focus_change (dpyinfo, event, bufp, numchars)
+static void
+x_detect_focus_change (dpyinfo, event, bufp)
struct x_display_info *dpyinfo;
XEvent *event;
struct input_event *bufp;
- int numchars;
{
struct frame *frame;
int nr_events = 0;
frame = x_any_window_to_frame (dpyinfo, event->xany.window);
- if (! frame) return nr_events;
+ if (! frame)
+ return;
switch (event->type)
{
@@ -3262,29 +3242,20 @@ x_detect_focus_change (dpyinfo, event, bufp, numchars)
if (event->xcrossing.detail != NotifyInferior
&& event->xcrossing.focus
&& ! (focus_state & FOCUS_EXPLICIT))
- nr_events = x_focus_changed ((event->type == EnterNotify
- ? FocusIn : FocusOut),
- FOCUS_IMPLICIT,
- dpyinfo,
- frame,
- bufp,
- numchars);
+ x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
+ FOCUS_IMPLICIT,
+ dpyinfo, frame, bufp);
}
break;
case FocusIn:
case FocusOut:
- nr_events = x_focus_changed (event->type,
- (event->xfocus.detail == NotifyPointer
- ? FOCUS_IMPLICIT : FOCUS_EXPLICIT),
- dpyinfo,
- frame,
- bufp,
- numchars);
+ x_focus_changed (event->type,
+ (event->xfocus.detail == NotifyPointer ?
+ FOCUS_IMPLICIT : FOCUS_EXPLICIT),
+ dpyinfo, frame, bufp);
break;
}
-
- return nr_events;
}
@@ -3629,35 +3600,39 @@ glyph_rect (f, x, y, rect)
XRectangle *rect;
{
Lisp_Object window;
- int found = 0;
+ struct window *w;
+ struct glyph_row *r, *end_row;
window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
- if (!NILP (window))
- {
- struct window *w = XWINDOW (window);
- struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- struct glyph_row *end = r + w->current_matrix->nrows - 1;
+ if (NILP (window))
+ return 0;
- for (; !found && r < end && r->enabled_p; ++r)
- if (r->y >= y)
- {
- struct glyph *g = r->glyphs[TEXT_AREA];
- struct glyph *end = g + r->used[TEXT_AREA];
- int gx;
+ w = XWINDOW (window);
+ r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ end_row = r + w->current_matrix->nrows - 1;
- for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g)
- if (gx >= x)
- {
- rect->width = g->pixel_width;
- rect->height = r->height;
- rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx);
- rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
- found = 1;
- }
- }
+ for (; r < end_row && r->enabled_p; ++r)
+ {
+ if (r->y >= y)
+ {
+ struct glyph *g = r->glyphs[TEXT_AREA];
+ struct glyph *end = g + r->used[TEXT_AREA];
+ int gx = r->x;
+ while (g < end && gx < x)
+ gx += g->pixel_width, ++g;
+ if (g < end)
+ {
+ rect->width = g->pixel_width;
+ rect->height = r->height;
+ rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx);
+ rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
+ return 1;
+ }
+ break;
+ }
}
- return found;
+ return 0;
}
@@ -5657,6 +5632,11 @@ static XComposeStatus compose_status;
static int temp_index;
static short temp_buffer[100];
+#define STORE_KEYSYM_FOR_DEBUG(keysym) \
+ if (temp_index == sizeof temp_buffer / sizeof (short)) \
+ temp_index = 0; \
+ temp_buffer[temp_index++] = (keysym)
+
/* Set this to nonzero to fake an "X I/O error"
on a particular display. */
@@ -5676,15 +5656,8 @@ static struct x_display_info *next_noop_dpyinfo;
f->output_data.x->saved_menu_event \
= (XEvent *) xmalloc (sizeof (XEvent)); \
bcopy (&event, f->output_data.x->saved_menu_event, size); \
- if (numchars >= 1) \
- { \
- bufp->kind = MENU_BAR_ACTIVATE_EVENT; \
- XSETFRAME (bufp->frame_or_window, f); \
- bufp->arg = Qnil; \
- bufp++; \
- count++; \
- numchars--; \
- } \
+ inev.kind = MENU_BAR_ACTIVATE_EVENT; \
+ XSETFRAME (inev.frame_or_window, f); \
} \
while (0)
@@ -5726,14 +5699,13 @@ x_filter_event (dpyinfo, event)
#endif
#ifdef USE_GTK
-static struct input_event **current_bufp;
-static int *current_numcharsp;
static int current_count;
static int current_finish;
+static struct input_event *current_hold_quit;
/* This is the filter function invoked by the GTK event loop.
It is invoked before the XEvent is translated to a GdkEvent,
- so we have a chanse to act on the event before GTK. */
+ so we have a chance to act on the event before GTK. */
static GdkFilterReturn
event_handler_gdk (gxev, ev, data)
GdkXEvent *gxev;
@@ -5742,7 +5714,7 @@ event_handler_gdk (gxev, ev, data)
{
XEvent *xev = (XEvent *) gxev;
- if (current_numcharsp)
+ if (current_count >= 0)
{
struct x_display_info *dpyinfo;
@@ -5760,11 +5732,11 @@ event_handler_gdk (gxev, ev, data)
if (! dpyinfo)
current_finish = X_EVENT_NORMAL;
else
- current_count += handle_one_xevent (dpyinfo,
- xev,
- current_bufp,
- current_numcharsp,
- &current_finish);
+ {
+ current_count +=
+ handle_one_xevent (dpyinfo, xev, &current_finish,
+ current_hold_quit);
+ }
}
else
current_finish = x_dispatch_event (xev, xev->xany.display);
@@ -5783,28 +5755,29 @@ event_handler_gdk (gxev, ev, data)
*FINISH is zero if caller should continue reading events.
*FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
- Events representing keys are stored in buffer *BUFP_R,
- which can hold up to *NUMCHARSP characters.
We return the number of characters stored into the buffer. */
static int
-handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
+handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
struct x_display_info *dpyinfo;
XEvent *eventp;
- /* register */ struct input_event **bufp_r;
- /* register */ int *numcharsp;
int *finish;
+ struct input_event *hold_quit;
{
+ struct input_event inev;
int count = 0;
+ int do_help = 0;
int nbytes = 0;
struct frame *f;
struct coding_system coding;
- struct input_event *bufp = *bufp_r;
- int numchars = *numcharsp;
XEvent event = *eventp;
*finish = X_EVENT_NORMAL;
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
+
switch (event.type)
{
case ClientMessage:
@@ -5859,8 +5832,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
}
/* Not certain about handling scroll bars here */
#endif /* 0 */
+ goto done;
}
- else if (event.xclient.data.l[0]
+
+ if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_save_yourself)
{
/* Save state modify the WM_COMMAND property to
@@ -5871,11 +5846,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
/* If we have a session manager, don't set this.
KDE will then start two Emacsen, one for the
session manager and one for this. */
- if (numchars > 0
#ifdef HAVE_X_SM
- && ! x_session_have_connection ()
+ if (! x_session_have_connection ())
#endif
- )
{
f = x_top_window_to_frame (dpyinfo,
event.xclient.window);
@@ -5890,41 +5863,36 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
event.xclient.window,
0, 0);
}
+ goto done;
}
- else if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_delete_window)
+
+ if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_delete_window)
{
- struct frame *f
- = x_any_window_to_frame (dpyinfo,
+ f = x_any_window_to_frame (dpyinfo,
event.xclient.window);
+ if (!f)
+ goto OTHER; /* May be a dialog that is to be removed */
- if (f)
- {
- if (numchars == 0)
- abort ();
-
- bufp->kind = DELETE_WINDOW_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
-
- count += 1;
- numchars -= 1;
- }
- else
- goto OTHER; /* May be a dialog that is to be removed */
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ goto done;
}
+
+ goto done;
}
- else if (event.xclient.message_type
+
+ if (event.xclient.message_type
== dpyinfo->Xatom_wm_configure_denied)
{
+ goto done;
}
- else if (event.xclient.message_type
- == dpyinfo->Xatom_wm_window_moved)
+
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_window_moved)
{
int new_x, new_y;
- struct frame *f
- = x_window_to_frame (dpyinfo, event.xclient.window);
+ f = x_window_to_frame (dpyinfo, event.xclient.window);
new_x = event.xclient.data.s[0];
new_y = event.xclient.data.s[1];
@@ -5934,63 +5902,55 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
f->left_pos = new_x;
f->top_pos = new_y;
}
+ goto done;
}
+
#ifdef HACK_EDITRES
- else if (event.xclient.message_type
- == dpyinfo->Xatom_editres)
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_editres)
{
- struct frame *f
- = x_any_window_to_frame (dpyinfo, event.xclient.window);
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
_XEditResCheckMessages (f->output_data.x->widget, NULL,
&event, NULL);
+ goto done;
}
#endif /* HACK_EDITRES */
- else if ((event.xclient.message_type
- == dpyinfo->Xatom_DONE)
- || (event.xclient.message_type
- == dpyinfo->Xatom_PAGE))
+
+ if ((event.xclient.message_type
+ == dpyinfo->Xatom_DONE)
+ || (event.xclient.message_type
+ == dpyinfo->Xatom_PAGE))
{
/* Ghostview job completed. Kill it. We could
reply with "Next" if we received "Page", but we
currently never do because we are interested in
images, only, which should have 1 page. */
Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
- struct frame *f
- = x_window_to_frame (dpyinfo, event.xclient.window);
+ f = x_window_to_frame (dpyinfo, event.xclient.window);
x_kill_gs_process (pixmap, f);
expose_frame (f, 0, 0, 0, 0);
+ goto done;
}
+
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Scroll bar callbacks send a ClientMessage from which
we construct an input_event. */
- else if (event.xclient.message_type
- == dpyinfo->Xatom_Scrollbar)
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_Scrollbar)
{
- x_scroll_bar_to_input_event (&event, bufp);
- ++bufp, ++count, --numchars;
- goto out;
+ x_scroll_bar_to_input_event (&event, &inev);
+ *finish = X_EVENT_GOTO_OUT;
+ goto done;
}
#endif /* USE_TOOLKIT_SCROLL_BARS */
- else
- {
- struct frame *f
- = x_any_window_to_frame (dpyinfo, event.xclient.window);
- if (f)
- {
- int ret = x_handle_dnd_message (f, &event.xclient,
- dpyinfo, bufp);
- if (ret > 0)
- {
- ++bufp, ++count, --numchars;
- }
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
- if (ret != 0)
- *finish = X_EVENT_DROP;
- }
- else
- goto OTHER;
- }
+ if (!f)
+ goto OTHER;
+
+ if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
+ *finish = X_EVENT_DROP;
}
break;
@@ -6010,19 +5970,11 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{
XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
- if (numchars == 0)
- abort ();
-
- bufp->kind = SELECTION_CLEAR_EVENT;
- SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
- SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
- SELECTION_EVENT_TIME (bufp) = eventp->time;
- bufp->frame_or_window = Qnil;
- bufp->arg = Qnil;
- bufp++;
-
- count += 1;
- numchars -= 1;
+ inev.kind = SELECTION_CLEAR_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
+ SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
+ SELECTION_EVENT_TIME (&inev) = eventp->time;
+ inev.frame_or_window = Qnil;
}
break;
@@ -6039,22 +5991,14 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
XSelectionRequestEvent *eventp
= (XSelectionRequestEvent *) &event;
- if (numchars == 0)
- abort ();
-
- bufp->kind = SELECTION_REQUEST_EVENT;
- SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
- SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
- SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
- SELECTION_EVENT_TARGET (bufp) = eventp->target;
- SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
- SELECTION_EVENT_TIME (bufp) = eventp->time;
- bufp->frame_or_window = Qnil;
- bufp->arg = Qnil;
- bufp++;
-
- count += 1;
- numchars -= 1;
+ inev.kind = SELECTION_REQUEST_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
+ SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
+ SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
+ SELECTION_EVENT_TARGET (&inev) = eventp->target;
+ SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
+ SELECTION_EVENT_TIME (&inev) = eventp->time;
+ inev.frame_or_window = Qnil;
}
break;
@@ -6084,7 +6028,6 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
}
goto OTHER;
- break;
case Expose:
f = x_window_to_frame (dpyinfo, event.xexpose.window);
@@ -6186,12 +6129,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{
f->async_iconified = 1;
- bufp->kind = ICONIFY_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = ICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
}
goto OTHER;
@@ -6223,12 +6162,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
if (f->iconified)
{
- bufp->kind = DEICONIFY_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp++;
- count++;
- numchars--;
+ inev.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
@@ -6289,6 +6224,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
int copy_bufsiz = sizeof (copy_buffer);
int modifiers;
Lisp_Object coding_system = Qlatin_1;
+ Lisp_Object c;
event.xkey.state
|= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
@@ -6382,49 +6318,37 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
orig_keysym = keysym;
- if (numchars > 0)
- {
- Lisp_Object c;
-
- /* First deal with keysyms which have defined
- translations to characters. */
- if (keysym >= 32 && keysym < 128)
- /* Avoid explicitly decoding each ASCII character. */
- {
- bufp->kind = ASCII_KEYSTROKE_EVENT;
- bufp->code = keysym;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- modifiers);
- bufp->timestamp = event.xkey.time;
- bufp++;
- count++;
- numchars--;
- }
- /* Now non-ASCII. */
- else if (HASH_TABLE_P (Vx_keysym_table)
- && (NATNUMP (c = Fgethash (make_number (keysym),
- Vx_keysym_table,
- Qnil))))
- {
- bufp->kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- bufp->code = XFASTINT (c);
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- modifiers);
- bufp->timestamp = event.xkey.time;
- bufp++;
- count++;
- numchars--;
- }
- /* Random non-modifier sorts of keysyms. */
- else if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+ /* Common for all keysym input events. */
+ XSETFRAME (inev.frame_or_window, f);
+ inev.modifiers
+ = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+ inev.timestamp = event.xkey.time;
+
+ /* First deal with keysyms which have defined
+ translations to characters. */
+ if (keysym >= 32 && keysym < 128)
+ /* Avoid explicitly decoding each ASCII character. */
+ {
+ inev.kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = keysym;
+ goto done_keysym;
+ }
+
+ /* Now non-ASCII. */
+ if (HASH_TABLE_P (Vx_keysym_table)
+ && (NATNUMP (c = Fgethash (make_number (keysym),
+ Vx_keysym_table,
+ Qnil))))
+ {
+ inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.code = XFASTINT (c);
+ goto done_keysym;
+ }
+
+ /* Random non-modifier sorts of keysyms. */
+ if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
|| keysym == XK_Delete
#ifdef XK_ISO_Left_Tab
|| (keysym >= XK_ISO_Left_Tab
@@ -6505,104 +6429,80 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
<= XK_ISO_Last_Group_Lock)
#endif
))
- {
- if (temp_index == sizeof temp_buffer / sizeof (short))
- temp_index = 0;
- temp_buffer[temp_index++] = keysym;
- /* make_lispy_event will convert this to a symbolic
- key. */
- bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
- bufp->code = keysym;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- modifiers);
- bufp->timestamp = event.xkey.time;
- bufp++;
- count++;
- numchars--;
- }
- else if (numchars > nbytes)
- { /* Raw bytes, not keysym. */
- register int i;
- register int c;
- int nchars, len;
-
- /* The input should be decoded with `coding_system'
- which depends on which X*LookupString function
- we used just above and the locale. */
- setup_coding_system (coding_system, &coding);
- coding.src_multibyte = 0;
- coding.dst_multibyte = 1;
- /* The input is converted to events, thus we can't
- handle composition. Anyway, there's no XIM that
- gives us composition information. */
- coding.composing = COMPOSITION_DISABLED;
-
- for (i = 0; i < nbytes; i++)
- {
- if (temp_index == (sizeof temp_buffer
- / sizeof (short)))
- temp_index = 0;
- temp_buffer[temp_index++] = copy_bufptr[i];
- }
+ {
+ STORE_KEYSYM_FOR_DEBUG (keysym);
+ /* make_lispy_event will convert this to a symbolic
+ key. */
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = keysym;
+ goto done_keysym;
+ }
- {
- /* Decode the input data. */
- int require;
- unsigned char *p;
-
- require = decoding_buffer_size (&coding, nbytes);
- p = (unsigned char *) alloca (require);
- coding.mode |= CODING_MODE_LAST_BLOCK;
- /* We explicitly disable composition
- handling because key data should
- not contain any composition
- sequence. */
- coding.composing = COMPOSITION_DISABLED;
- decode_coding (&coding, copy_bufptr, p,
- nbytes, require);
- nbytes = coding.produced;
- nchars = coding.produced_char;
- copy_bufptr = p;
- }
+ { /* Raw bytes, not keysym. */
+ register int i;
+ register int c;
+ int nchars, len;
+
+ /* The input should be decoded with `coding_system'
+ which depends on which X*LookupString function
+ we used just above and the locale. */
+ setup_coding_system (coding_system, &coding);
+ coding.src_multibyte = 0;
+ coding.dst_multibyte = 1;
+ /* The input is converted to events, thus we can't
+ handle composition. Anyway, there's no XIM that
+ gives us composition information. */
+ coding.composing = COMPOSITION_DISABLED;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
+ }
- /* Convert the input data to a sequence of
- character events. */
- for (i = 0; i < nbytes; i += len)
- {
- if (nchars == nbytes)
- c = copy_bufptr[i], len = 1;
- else
- c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
- nbytes - i, len);
-
- bufp->kind = (SINGLE_BYTE_CHAR_P (c)
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- bufp->code = c;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- bufp->modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- modifiers);
- bufp->timestamp = event.xkey.time;
- bufp++;
- }
+ {
+ /* Decode the input data. */
+ int require;
+ unsigned char *p;
+
+ require = decoding_buffer_size (&coding, nbytes);
+ p = (unsigned char *) alloca (require);
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ /* We explicitly disable composition handling because
+ key data should not contain any composition sequence. */
+ coding.composing = COMPOSITION_DISABLED;
+ decode_coding (&coding, copy_bufptr, p, nbytes, require);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+ copy_bufptr = p;
+ }
- count += nchars;
- numchars -= nchars;
+ /* Convert the input data to a sequence of
+ character events. */
+ for (i = 0; i < nbytes; i += len)
+ {
+ if (nchars == nbytes)
+ c = copy_bufptr[i], len = 1;
+ else
+ c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
+ nbytes - i, len);
+ inev.kind = (SINGLE_BYTE_CHAR_P (c)
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.code = c;
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ }
- if (keysym == NoSymbol)
- break;
- }
- else
- abort ();
- }
- else
- abort ();
+ /* Previous code updated count by nchars rather than nbytes,
+ but that seems bogus to me. ++kfs */
+ count += nbytes;
+
+ inev.kind = NO_EVENT; /* Already stored above. */
+
+ if (keysym == NoSymbol)
+ break;
+ }
}
+ done_keysym:
#ifdef HAVE_X_I18N
/* Don't dispatch this event since XtDispatchEvent calls
XFilterEvent, and two calls in a row may freeze the
@@ -6623,63 +6523,38 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
#endif
case EnterNotify:
- {
- int n;
-
- n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
- if (n > 0)
- {
- bufp += n, count += n, numchars -= n;
- }
+ x_detect_focus_change (dpyinfo, &event, &inev);
- f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
+ f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
#if 0
- if (event.xcrossing.focus)
- {
- /* Avoid nasty pop/raise loops. */
- if (f && (!(f->auto_raise)
- || !(f->auto_lower)
- || (event.xcrossing.time - enter_timestamp) > 500))
- {
- x_new_focus_frame (dpyinfo, f);
- enter_timestamp = event.xcrossing.time;
- }
- }
- else if (f == dpyinfo->x_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
+ if (event.xcrossing.focus)
+ {
+ /* Avoid nasty pop/raise loops. */
+ if (f && (!(f->auto_raise)
+ || !(f->auto_lower)
+ || (event.xcrossing.time - enter_timestamp) > 500))
+ {
+ x_new_focus_frame (dpyinfo, f);
+ enter_timestamp = event.xcrossing.time;
+ }
+ }
+ else if (f == dpyinfo->x_focus_frame)
+ x_new_focus_frame (dpyinfo, 0);
#endif
- /* EnterNotify counts as mouse movement,
- so update things that depend on mouse position. */
- if (f && !f->output_data.x->hourglass_p)
- note_mouse_movement (f, &event.xmotion);
- goto OTHER;
- }
+ /* EnterNotify counts as mouse movement,
+ so update things that depend on mouse position. */
+ if (f && !f->output_data.x->hourglass_p)
+ note_mouse_movement (f, &event.xmotion);
+ goto OTHER;
case FocusIn:
- {
- int n;
-
- n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
- if (n > 0)
- {
- bufp += n, count += n, numchars -= n;
- }
- }
-
+ x_detect_focus_change (dpyinfo, &event, &inev);
goto OTHER;
case LeaveNotify:
- {
- int n;
-
- n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
- if (n > 0)
- {
- bufp += n, count += n, numchars -= n;
- }
- }
+ x_detect_focus_change (dpyinfo, &event, &inev);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
@@ -6697,31 +6572,12 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
Otherwise, the startup message is cleared when
the mouse leaves the frame. */
if (any_help_event_p)
- {
- Lisp_Object frame;
- int n;
-
- XSETFRAME (frame, f);
- help_echo_string = Qnil;
- n = gen_help_event (bufp, numchars,
- Qnil, frame, Qnil, Qnil, 0);
- bufp += n, count += n, numchars -= n;
- }
-
+ do_help = -1;
}
goto OTHER;
case FocusOut:
- {
- int n;
-
- n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
- if (n > 0)
- {
- bufp += n, count += n, numchars -= n;
- }
- }
-
+ x_detect_focus_change (dpyinfo, &event, &inev);
goto OTHER;
case MotionNotify:
@@ -6759,13 +6615,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
will be selected iff it is active. */
if (WINDOWP (window)
&& !EQ (window, last_window)
- && !EQ (window, selected_window)
- && numchars > 0)
+ && !EQ (window, selected_window))
{
- bufp->kind = SELECT_WINDOW_EVENT;
- bufp->frame_or_window = window;
- bufp->arg = Qnil;
- ++bufp, ++count, --numchars;
+ inev.kind = SELECT_WINDOW_EVENT;
+ inev.frame_or_window = window;
}
last_window=window;
@@ -6792,22 +6645,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
has changed, generate a HELP_EVENT. */
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
- {
- Lisp_Object frame;
- int n;
-
- if (f)
- XSETFRAME (frame, f);
- else
- frame = Qnil;
-
- any_help_event_p = 1;
- n = gen_help_event (bufp, numchars, help_echo_string, frame,
- help_echo_window, help_echo_object,
- help_echo_pos);
- bufp += n, count += n, numchars -= n;
- }
-
+ do_help = 1;
goto OTHER;
}
@@ -6891,10 +6729,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
- struct input_event emacs_event;
int tool_bar_p = 0;
- emacs_event.kind = NO_EVENT;
bzero (&compose_status, sizeof (compose_status));
if (dpyinfo->grabbed
@@ -6934,7 +6770,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (! popup_activated ())
#endif
- construct_mouse_click (&emacs_event, &event, f);
+ construct_mouse_click (&inev, &event, f);
}
}
else
@@ -6948,12 +6784,12 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
scroll bars. */
if (bar && event.xbutton.state & ControlMask)
{
- x_scroll_bar_handle_click (bar, &event, &emacs_event);
+ x_scroll_bar_handle_click (bar, &event, &inev);
*finish = X_EVENT_DROP;
}
#else /* not USE_TOOLKIT_SCROLL_BARS */
if (bar)
- x_scroll_bar_handle_click (bar, &event, &emacs_event);
+ x_scroll_bar_handle_click (bar, &event, &inev);
#endif /* not USE_TOOLKIT_SCROLL_BARS */
}
@@ -6974,14 +6810,6 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
else
dpyinfo->grabbed &= ~(1 << event.xbutton.button);
- if (numchars >= 1 && emacs_event.kind != NO_EVENT)
- {
- bcopy (&emacs_event, bufp, sizeof (struct input_event));
- bufp++;
- count++;
- numchars--;
- }
-
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
/* For a down-event in the menu bar,
@@ -7068,16 +6896,38 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
break;
}
- goto ret;
+ done:
+ if (inev.kind != NO_EVENT)
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
- out:
- *finish = X_EVENT_GOTO_OUT;
+ if (do_help
+ && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object frame;
- ret:
- *bufp_r = bufp;
- *numcharsp = numchars;
- *eventp = event;
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+
+ if (do_help > 0)
+ {
+ any_help_event_p = 1;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+ else
+ {
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ }
+ count++;
+ }
+ *eventp = event;
return count;
}
@@ -7093,28 +6943,12 @@ x_dispatch_event (event, display)
Display *display;
{
struct x_display_info *dpyinfo;
- struct input_event bufp[10];
- struct input_event *bufpp;
- int numchars = 10;
int finish = X_EVENT_NORMAL;
- for (bufpp = bufp; bufpp != bufp + 10; bufpp++)
- EVENT_INIT (*bufpp);
- bufpp = bufp;
-
dpyinfo = x_display_info_for_display (display);
if (dpyinfo)
- {
- int i, events;
- events = handle_one_xevent (dpyinfo,
- event,
- &bufpp,
- &numchars,
- &finish);
- for (i = 0; i < events; ++i)
- kbd_buffer_store_event (&bufp[i]);
- }
+ handle_one_xevent (dpyinfo, event, &finish, 0);
return finish;
}
@@ -7124,19 +6958,16 @@ x_dispatch_event (event, display)
This routine is called by the SIGIO handler.
We return as soon as there are no more events to be read.
- Events representing keys are stored in buffer BUFP,
- which can hold up to NUMCHARS characters.
We return the number of characters stored into the buffer,
thus pretending to be `read'.
EXPECTED is nonzero if the caller knows input is available. */
static int
-XTread_socket (display, bufp, numchars, expected)
+XTread_socket (display, expected, hold_quit)
struct display *display;
- struct input_event *bufp;
- int numchars;
int expected;
+ struct input_event *hold_quit;
{
int count = 0;
XEvent event;
@@ -7155,9 +6986,6 @@ XTread_socket (display, bufp, numchars, expected)
/* So people can tell when we have read the available input. */
input_signal_count++;
- if (numchars <= 0)
- abort (); /* Don't think this happens. */
-
++handling_signal;
/* Find the display we are supposed to read input for.
@@ -7199,13 +7027,22 @@ XTread_socket (display, bufp, numchars, expected)
}
#ifdef HAVE_X_SM
- BLOCK_INPUT;
- count += x_session_check_input (bufp, &numchars);
- UNBLOCK_INPUT;
+ {
+ struct input_event inev;
+ BLOCK_INPUT;
+ /* We don't need to EVENT_INIT (inev) here, as
+ x_session_check_input copies an entire input_event. */
+ if (x_session_check_input (&inev))
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ UNBLOCK_INPUT;
+ }
#endif
#ifndef USE_GTK
- while (numchars > 0 && XPending (dpyinfo->display))
+ while (XPending (dpyinfo->display))
{
int finish;
@@ -7218,11 +7055,7 @@ XTread_socket (display, bufp, numchars, expected)
#endif
event_found = 1;
- count += handle_one_xevent (dpyinfo,
- &event,
- &bufp,
- &numchars,
- &finish);
+ count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
if (finish == X_EVENT_GOTO_OUT)
goto out;
@@ -7243,14 +7076,13 @@ XTread_socket (display, bufp, numchars, expected)
while (gtk_events_pending ())
{
current_count = count;
- current_numcharsp = &numchars;
- current_bufp = &bufp;
+ current_hold_quit = hold_quit;
gtk_main_iteration ();
count = current_count;
- current_bufp = 0;
- current_numcharsp = 0;
+ current_count = -1;
+ current_hold_quit = 0;
if (current_finish == X_EVENT_GOTO_OUT)
break;
@@ -7290,8 +7122,9 @@ XTread_socket (display, bufp, numchars, expected)
pending_autoraise_frame = 0;
}
- UNBLOCK_INPUT;
--handling_signal;
+ UNBLOCK_INPUT;
+
return count;
}
@@ -11000,6 +10833,10 @@ x_initialize ()
last_tool_bar_item = -1;
any_help_event_p = 0;
+#ifdef USE_GTK
+ current_count = -1;
+#endif
+
/* Try to use interrupt input; if we can't, then start polling. */
Fset_input_mode (Qt, Qnil, Qt, Qnil);
diff --git a/src/xterm.h b/src/xterm.h
index 45de640f165..4a19d2c0d56 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1089,8 +1089,7 @@ extern void widget_store_internal_border P_ ((Widget));
/* Defined in xsmfns.c */
#ifdef HAVE_X_SM
extern void x_session_initialize P_ ((struct x_display_info *dpyinfo));
-extern int x_session_check_input P_ ((struct input_event *bufp,
- int *numchars));
+extern int x_session_check_input P_ ((struct input_event *bufp));
extern int x_session_have_connection P_ ((void));
#endif