comparison src/xterm.c @ 54173:03cb01738926

(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.
author Kim F. Storm <storm@cua.dk>
date Fri, 27 Feb 2004 23:49:48 +0000
parents 869ca316cdda
children f6e4e454800a b44978264e1d
comparison
equal deleted inserted replaced
54172:6851117e8d89 54173:03cb01738926
334 static void XTreset_terminal_modes P_ ((void)); 334 static void XTreset_terminal_modes P_ ((void));
335 static void x_clear_frame P_ ((void)); 335 static void x_clear_frame P_ ((void));
336 static void frame_highlight P_ ((struct frame *)); 336 static void frame_highlight P_ ((struct frame *));
337 static void frame_unhighlight P_ ((struct frame *)); 337 static void frame_unhighlight P_ ((struct frame *));
338 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 338 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
339 static int x_focus_changed P_ ((int, 339 static void x_focus_changed P_ ((int, int, struct x_display_info *,
340 int, 340 struct frame *, struct input_event *));
341 struct x_display_info *, 341 static void x_detect_focus_change P_ ((struct x_display_info *,
342 struct frame *, 342 XEvent *, struct input_event *));
343 struct input_event *,
344 int));
345 static int x_detect_focus_change P_ ((struct x_display_info *,
346 XEvent *,
347 struct input_event *,
348 int));
349 static void XTframe_rehighlight P_ ((struct frame *)); 343 static void XTframe_rehighlight P_ ((struct frame *));
350 static void x_frame_rehighlight P_ ((struct x_display_info *)); 344 static void x_frame_rehighlight P_ ((struct x_display_info *));
351 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 345 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
352 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, 346 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
353 enum text_cursor_kinds)); 347 enum text_cursor_kinds));
362 enum scroll_bar_part *, 356 enum scroll_bar_part *,
363 Lisp_Object *, Lisp_Object *, 357 Lisp_Object *, Lisp_Object *,
364 unsigned long *)); 358 unsigned long *));
365 static void x_check_fullscreen P_ ((struct frame *)); 359 static void x_check_fullscreen P_ ((struct frame *));
366 static void x_check_expected_move P_ ((struct frame *)); 360 static void x_check_expected_move P_ ((struct frame *));
367 static int handle_one_xevent P_ ((struct x_display_info *, 361 static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
368 XEvent *, 362 int *, struct input_event *));
369 struct input_event **,
370 int *,
371 int *));
372 363
373 364
374 /* Flush display of frame F, or of all frames if F is null. */ 365 /* Flush display of frame F, or of all frames if F is null. */
375 366
376 static void 367 static void
3165 x_frame_rehighlight (dpyinfo); 3156 x_frame_rehighlight (dpyinfo);
3166 } 3157 }
3167 3158
3168 /* Handle FocusIn and FocusOut state changes for FRAME. 3159 /* Handle FocusIn and FocusOut state changes for FRAME.
3169 If FRAME has focus and there exists more than one frame, puts 3160 If FRAME has focus and there exists more than one frame, puts
3170 a FOCUS_IN_EVENT into BUFP. 3161 a FOCUS_IN_EVENT into *BUFP. */
3171 Returns number of events inserted into BUFP. */ 3162
3172 3163 static void
3173 static int 3164 x_focus_changed (type, state, dpyinfo, frame, bufp)
3174 x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
3175 int type; 3165 int type;
3176 int state; 3166 int state;
3177 struct x_display_info *dpyinfo; 3167 struct x_display_info *dpyinfo;
3178 struct frame *frame; 3168 struct frame *frame;
3179 struct input_event *bufp; 3169 struct input_event *bufp;
3180 int numchars; 3170 {
3181 {
3182 int nr_events = 0;
3183
3184 if (type == FocusIn) 3171 if (type == FocusIn)
3185 { 3172 {
3186 if (dpyinfo->x_focus_event_frame != frame) 3173 if (dpyinfo->x_focus_event_frame != frame)
3187 { 3174 {
3188 x_new_focus_frame (dpyinfo, frame); 3175 x_new_focus_frame (dpyinfo, frame);
3189 dpyinfo->x_focus_event_frame = frame; 3176 dpyinfo->x_focus_event_frame = frame;
3190 3177
3191 /* Don't stop displaying the initial startup message 3178 /* Don't stop displaying the initial startup message
3192 for a switch-frame event we don't need. */ 3179 for a switch-frame event we don't need. */
3193 if (numchars > 0 3180 if (GC_NILP (Vterminal_frame)
3194 && GC_NILP (Vterminal_frame)
3195 && GC_CONSP (Vframe_list) 3181 && GC_CONSP (Vframe_list)
3196 && !GC_NILP (XCDR (Vframe_list))) 3182 && !GC_NILP (XCDR (Vframe_list)))
3197 { 3183 {
3198 bufp->kind = FOCUS_IN_EVENT; 3184 bufp->kind = FOCUS_IN_EVENT;
3199 XSETFRAME (bufp->frame_or_window, frame); 3185 XSETFRAME (bufp->frame_or_window, frame);
3200 bufp->arg = Qnil;
3201 ++bufp;
3202 numchars--;
3203 ++nr_events;
3204 } 3186 }
3205 } 3187 }
3206 3188
3207 frame->output_data.x->focus_state |= state; 3189 frame->output_data.x->focus_state |= state;
3208 3190
3224 #ifdef HAVE_X_I18N 3206 #ifdef HAVE_X_I18N
3225 if (FRAME_XIC (frame)) 3207 if (FRAME_XIC (frame))
3226 XUnsetICFocus (FRAME_XIC (frame)); 3208 XUnsetICFocus (FRAME_XIC (frame));
3227 #endif 3209 #endif
3228 } 3210 }
3229
3230 return nr_events;
3231 } 3211 }
3232 3212
3233 /* The focus may have changed. Figure out if it is a real focus change, 3213 /* The focus may have changed. Figure out if it is a real focus change,
3234 by checking both FocusIn/Out and Enter/LeaveNotify events. 3214 by checking both FocusIn/Out and Enter/LeaveNotify events.
3235 3215
3236 Returns number of events inserted into BUFP. */ 3216 Returns FOCUS_IN_EVENT event in *BUFP. */
3237 3217
3238 static int 3218 static void
3239 x_detect_focus_change (dpyinfo, event, bufp, numchars) 3219 x_detect_focus_change (dpyinfo, event, bufp)
3240 struct x_display_info *dpyinfo; 3220 struct x_display_info *dpyinfo;
3241 XEvent *event; 3221 XEvent *event;
3242 struct input_event *bufp; 3222 struct input_event *bufp;
3243 int numchars;
3244 { 3223 {
3245 struct frame *frame; 3224 struct frame *frame;
3246 int nr_events = 0; 3225 int nr_events = 0;
3247 3226
3248 frame = x_any_window_to_frame (dpyinfo, event->xany.window); 3227 frame = x_any_window_to_frame (dpyinfo, event->xany.window);
3249 if (! frame) return nr_events; 3228 if (! frame)
3229 return;
3250 3230
3251 switch (event->type) 3231 switch (event->type)
3252 { 3232 {
3253 case EnterNotify: 3233 case EnterNotify:
3254 case LeaveNotify: 3234 case LeaveNotify:
3258 = focus_frame ? focus_frame->output_data.x->focus_state : 0; 3238 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
3259 3239
3260 if (event->xcrossing.detail != NotifyInferior 3240 if (event->xcrossing.detail != NotifyInferior
3261 && event->xcrossing.focus 3241 && event->xcrossing.focus
3262 && ! (focus_state & FOCUS_EXPLICIT)) 3242 && ! (focus_state & FOCUS_EXPLICIT))
3263 nr_events = x_focus_changed ((event->type == EnterNotify 3243 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
3264 ? FocusIn : FocusOut), 3244 FOCUS_IMPLICIT,
3265 FOCUS_IMPLICIT, 3245 dpyinfo, frame, bufp);
3266 dpyinfo,
3267 frame,
3268 bufp,
3269 numchars);
3270 } 3246 }
3271 break; 3247 break;
3272 3248
3273 case FocusIn: 3249 case FocusIn:
3274 case FocusOut: 3250 case FocusOut:
3275 nr_events = x_focus_changed (event->type, 3251 x_focus_changed (event->type,
3276 (event->xfocus.detail == NotifyPointer 3252 (event->xfocus.detail == NotifyPointer ?
3277 ? FOCUS_IMPLICIT : FOCUS_EXPLICIT), 3253 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
3278 dpyinfo, 3254 dpyinfo, frame, bufp);
3279 frame,
3280 bufp,
3281 numchars);
3282 break; 3255 break;
3283 } 3256 }
3284
3285 return nr_events;
3286 } 3257 }
3287 3258
3288 3259
3289 /* Handle an event saying the mouse has moved out of an Emacs frame. */ 3260 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3290 3261
3625 struct frame *f; 3596 struct frame *f;
3626 int x, y; 3597 int x, y;
3627 XRectangle *rect; 3598 XRectangle *rect;
3628 { 3599 {
3629 Lisp_Object window; 3600 Lisp_Object window;
3630 int found = 0; 3601 struct window *w;
3602 struct glyph_row *r, *end_row;
3631 3603
3632 window = window_from_coordinates (f, x, y, 0, &x, &y, 0); 3604 window = window_from_coordinates (f, x, y, 0, &x, &y, 0);
3633 if (!NILP (window)) 3605 if (NILP (window))
3634 { 3606 return 0;
3635 struct window *w = XWINDOW (window); 3607
3636 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 3608 w = XWINDOW (window);
3637 struct glyph_row *end = r + w->current_matrix->nrows - 1; 3609 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
3638 3610 end_row = r + w->current_matrix->nrows - 1;
3639 for (; !found && r < end && r->enabled_p; ++r) 3611
3640 if (r->y >= y) 3612 for (; r < end_row && r->enabled_p; ++r)
3641 { 3613 {
3642 struct glyph *g = r->glyphs[TEXT_AREA]; 3614 if (r->y >= y)
3643 struct glyph *end = g + r->used[TEXT_AREA]; 3615 {
3644 int gx; 3616 struct glyph *g = r->glyphs[TEXT_AREA];
3645 3617 struct glyph *end = g + r->used[TEXT_AREA];
3646 for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g) 3618 int gx = r->x;
3647 if (gx >= x) 3619 while (g < end && gx < x)
3648 { 3620 gx += g->pixel_width, ++g;
3649 rect->width = g->pixel_width; 3621 if (g < end)
3650 rect->height = r->height; 3622 {
3651 rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx); 3623 rect->width = g->pixel_width;
3652 rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y); 3624 rect->height = r->height;
3653 found = 1; 3625 rect->x = WINDOW_TO_FRAME_PIXEL_X (w, gx);
3654 } 3626 rect->y = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
3655 } 3627 return 1;
3656 } 3628 }
3657 3629 break;
3658 return found; 3630 }
3631 }
3632
3633 return 0;
3659 } 3634 }
3660 3635
3661 3636
3662 /* Return the current position of the mouse. 3637 /* Return the current position of the mouse.
3663 *FP should be a frame which indicates which display to ask about. 3638 *FP should be a frame which indicates which display to ask about.
5646 to help debug the loss-of-chars-during-GC problem. */ 5621 to help debug the loss-of-chars-during-GC problem. */
5647 5622
5648 static int temp_index; 5623 static int temp_index;
5649 static short temp_buffer[100]; 5624 static short temp_buffer[100];
5650 5625
5626 #define STORE_KEYSYM_FOR_DEBUG(keysym) \
5627 if (temp_index == sizeof temp_buffer / sizeof (short)) \
5628 temp_index = 0; \
5629 temp_buffer[temp_index++] = (keysym)
5630
5651 /* Set this to nonzero to fake an "X I/O error" 5631 /* Set this to nonzero to fake an "X I/O error"
5652 on a particular display. */ 5632 on a particular display. */
5653 5633
5654 struct x_display_info *XTread_socket_fake_io_error; 5634 struct x_display_info *XTread_socket_fake_io_error;
5655 5635
5665 { \ 5645 { \
5666 if (f->output_data.x->saved_menu_event == 0) \ 5646 if (f->output_data.x->saved_menu_event == 0) \
5667 f->output_data.x->saved_menu_event \ 5647 f->output_data.x->saved_menu_event \
5668 = (XEvent *) xmalloc (sizeof (XEvent)); \ 5648 = (XEvent *) xmalloc (sizeof (XEvent)); \
5669 bcopy (&event, f->output_data.x->saved_menu_event, size); \ 5649 bcopy (&event, f->output_data.x->saved_menu_event, size); \
5670 if (numchars >= 1) \ 5650 inev.kind = MENU_BAR_ACTIVATE_EVENT; \
5671 { \ 5651 XSETFRAME (inev.frame_or_window, f); \
5672 bufp->kind = MENU_BAR_ACTIVATE_EVENT; \
5673 XSETFRAME (bufp->frame_or_window, f); \
5674 bufp->arg = Qnil; \
5675 bufp++; \
5676 count++; \
5677 numchars--; \
5678 } \
5679 } \ 5652 } \
5680 while (0) 5653 while (0)
5681 5654
5682 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent)) 5655 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
5683 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent)) 5656 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
5715 return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None); 5688 return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
5716 } 5689 }
5717 #endif 5690 #endif
5718 5691
5719 #ifdef USE_GTK 5692 #ifdef USE_GTK
5720 static struct input_event **current_bufp;
5721 static int *current_numcharsp;
5722 static int current_count; 5693 static int current_count;
5723 static int current_finish; 5694 static int current_finish;
5695 static struct input_event *current_hold_quit;
5724 5696
5725 /* This is the filter function invoked by the GTK event loop. 5697 /* This is the filter function invoked by the GTK event loop.
5726 It is invoked before the XEvent is translated to a GdkEvent, 5698 It is invoked before the XEvent is translated to a GdkEvent,
5727 so we have a chanse to act on the event before GTK. */ 5699 so we have a chance to act on the event before GTK. */
5728 static GdkFilterReturn 5700 static GdkFilterReturn
5729 event_handler_gdk (gxev, ev, data) 5701 event_handler_gdk (gxev, ev, data)
5730 GdkXEvent *gxev; 5702 GdkXEvent *gxev;
5731 GdkEvent *ev; 5703 GdkEvent *ev;
5732 gpointer data; 5704 gpointer data;
5733 { 5705 {
5734 XEvent *xev = (XEvent *) gxev; 5706 XEvent *xev = (XEvent *) gxev;
5735 5707
5736 if (current_numcharsp) 5708 if (current_count >= 0)
5737 { 5709 {
5738 struct x_display_info *dpyinfo; 5710 struct x_display_info *dpyinfo;
5739 5711
5740 dpyinfo = x_display_info_for_display (xev->xany.display); 5712 dpyinfo = x_display_info_for_display (xev->xany.display);
5741 5713
5749 #endif 5721 #endif
5750 5722
5751 if (! dpyinfo) 5723 if (! dpyinfo)
5752 current_finish = X_EVENT_NORMAL; 5724 current_finish = X_EVENT_NORMAL;
5753 else 5725 else
5754 current_count += handle_one_xevent (dpyinfo, 5726 {
5755 xev, 5727 current_count +=
5756 current_bufp, 5728 handle_one_xevent (dpyinfo, xev, &current_finish,
5757 current_numcharsp, 5729 current_hold_quit);
5758 &current_finish); 5730 }
5759 } 5731 }
5760 else 5732 else
5761 current_finish = x_dispatch_event (xev, xev->xany.display); 5733 current_finish = x_dispatch_event (xev, xev->xany.display);
5762 5734
5763 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP) 5735 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
5772 5744
5773 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. 5745 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
5774 *FINISH is zero if caller should continue reading events. 5746 *FINISH is zero if caller should continue reading events.
5775 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit. 5747 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
5776 5748
5777 Events representing keys are stored in buffer *BUFP_R,
5778 which can hold up to *NUMCHARSP characters.
5779 We return the number of characters stored into the buffer. */ 5749 We return the number of characters stored into the buffer. */
5780 5750
5781 static int 5751 static int
5782 handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) 5752 handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5783 struct x_display_info *dpyinfo; 5753 struct x_display_info *dpyinfo;
5784 XEvent *eventp; 5754 XEvent *eventp;
5785 /* register */ struct input_event **bufp_r;
5786 /* register */ int *numcharsp;
5787 int *finish; 5755 int *finish;
5788 { 5756 struct input_event *hold_quit;
5757 {
5758 struct input_event inev;
5789 int count = 0; 5759 int count = 0;
5760 int do_help = 0;
5790 int nbytes = 0; 5761 int nbytes = 0;
5791 struct frame *f; 5762 struct frame *f;
5792 struct coding_system coding; 5763 struct coding_system coding;
5793 struct input_event *bufp = *bufp_r;
5794 int numchars = *numcharsp;
5795 XEvent event = *eventp; 5764 XEvent event = *eventp;
5796 5765
5797 *finish = X_EVENT_NORMAL; 5766 *finish = X_EVENT_NORMAL;
5767
5768 EVENT_INIT (inev);
5769 inev.kind = NO_EVENT;
5770 inev.arg = Qnil;
5798 5771
5799 switch (event.type) 5772 switch (event.type)
5800 { 5773 {
5801 case ClientMessage: 5774 case ClientMessage:
5802 { 5775 {
5848 XSync (d, False); 5821 XSync (d, False);
5849 x_uncatch_errors (d, count); 5822 x_uncatch_errors (d, count);
5850 } 5823 }
5851 /* Not certain about handling scroll bars here */ 5824 /* Not certain about handling scroll bars here */
5852 #endif /* 0 */ 5825 #endif /* 0 */
5826 goto done;
5853 } 5827 }
5854 else if (event.xclient.data.l[0] 5828
5829 if (event.xclient.data.l[0]
5855 == dpyinfo->Xatom_wm_save_yourself) 5830 == dpyinfo->Xatom_wm_save_yourself)
5856 { 5831 {
5857 /* Save state modify the WM_COMMAND property to 5832 /* Save state modify the WM_COMMAND property to
5858 something which can reinstate us. This notifies 5833 something which can reinstate us. This notifies
5859 the session manager, who's looking for such a 5834 the session manager, who's looking for such a
5860 PropertyNotify. Can restart processing when 5835 PropertyNotify. Can restart processing when
5861 a keyboard or mouse event arrives. */ 5836 a keyboard or mouse event arrives. */
5862 /* If we have a session manager, don't set this. 5837 /* If we have a session manager, don't set this.
5863 KDE will then start two Emacsen, one for the 5838 KDE will then start two Emacsen, one for the
5864 session manager and one for this. */ 5839 session manager and one for this. */
5865 if (numchars > 0
5866 #ifdef HAVE_X_SM 5840 #ifdef HAVE_X_SM
5867 && ! x_session_have_connection () 5841 if (! x_session_have_connection ())
5868 #endif 5842 #endif
5869 )
5870 { 5843 {
5871 f = x_top_window_to_frame (dpyinfo, 5844 f = x_top_window_to_frame (dpyinfo,
5872 event.xclient.window); 5845 event.xclient.window);
5873 /* This is just so we only give real data once 5846 /* This is just so we only give real data once
5874 for a single Emacs process. */ 5847 for a single Emacs process. */
5879 else if (f) 5852 else if (f)
5880 XSetCommand (FRAME_X_DISPLAY (f), 5853 XSetCommand (FRAME_X_DISPLAY (f),
5881 event.xclient.window, 5854 event.xclient.window,
5882 0, 0); 5855 0, 0);
5883 } 5856 }
5857 goto done;
5884 } 5858 }
5885 else if (event.xclient.data.l[0] 5859
5886 == dpyinfo->Xatom_wm_delete_window) 5860 if (event.xclient.data.l[0]
5861 == dpyinfo->Xatom_wm_delete_window)
5887 { 5862 {
5888 struct frame *f 5863 f = x_any_window_to_frame (dpyinfo,
5889 = x_any_window_to_frame (dpyinfo,
5890 event.xclient.window); 5864 event.xclient.window);
5891 5865 if (!f)
5892 if (f) 5866 goto OTHER; /* May be a dialog that is to be removed */
5893 { 5867
5894 if (numchars == 0) 5868 inev.kind = DELETE_WINDOW_EVENT;
5895 abort (); 5869 XSETFRAME (inev.frame_or_window, f);
5896 5870 goto done;
5897 bufp->kind = DELETE_WINDOW_EVENT;
5898 XSETFRAME (bufp->frame_or_window, f);
5899 bufp->arg = Qnil;
5900 bufp++;
5901
5902 count += 1;
5903 numchars -= 1;
5904 }
5905 else
5906 goto OTHER; /* May be a dialog that is to be removed */
5907 } 5871 }
5872
5873 goto done;
5908 } 5874 }
5909 else if (event.xclient.message_type 5875
5876 if (event.xclient.message_type
5910 == dpyinfo->Xatom_wm_configure_denied) 5877 == dpyinfo->Xatom_wm_configure_denied)
5911 { 5878 {
5879 goto done;
5912 } 5880 }
5913 else if (event.xclient.message_type 5881
5914 == dpyinfo->Xatom_wm_window_moved) 5882 if (event.xclient.message_type
5883 == dpyinfo->Xatom_wm_window_moved)
5915 { 5884 {
5916 int new_x, new_y; 5885 int new_x, new_y;
5917 struct frame *f 5886 f = x_window_to_frame (dpyinfo, event.xclient.window);
5918 = x_window_to_frame (dpyinfo, event.xclient.window);
5919 5887
5920 new_x = event.xclient.data.s[0]; 5888 new_x = event.xclient.data.s[0];
5921 new_y = event.xclient.data.s[1]; 5889 new_y = event.xclient.data.s[1];
5922 5890
5923 if (f) 5891 if (f)
5924 { 5892 {
5925 f->left_pos = new_x; 5893 f->left_pos = new_x;
5926 f->top_pos = new_y; 5894 f->top_pos = new_y;
5927 } 5895 }
5896 goto done;
5928 } 5897 }
5898
5929 #ifdef HACK_EDITRES 5899 #ifdef HACK_EDITRES
5930 else if (event.xclient.message_type 5900 if (event.xclient.message_type
5931 == dpyinfo->Xatom_editres) 5901 == dpyinfo->Xatom_editres)
5932 { 5902 {
5933 struct frame *f 5903 f = x_any_window_to_frame (dpyinfo, event.xclient.window);
5934 = x_any_window_to_frame (dpyinfo, event.xclient.window);
5935 _XEditResCheckMessages (f->output_data.x->widget, NULL, 5904 _XEditResCheckMessages (f->output_data.x->widget, NULL,
5936 &event, NULL); 5905 &event, NULL);
5906 goto done;
5937 } 5907 }
5938 #endif /* HACK_EDITRES */ 5908 #endif /* HACK_EDITRES */
5939 else if ((event.xclient.message_type 5909
5940 == dpyinfo->Xatom_DONE) 5910 if ((event.xclient.message_type
5941 || (event.xclient.message_type 5911 == dpyinfo->Xatom_DONE)
5942 == dpyinfo->Xatom_PAGE)) 5912 || (event.xclient.message_type
5913 == dpyinfo->Xatom_PAGE))
5943 { 5914 {
5944 /* Ghostview job completed. Kill it. We could 5915 /* Ghostview job completed. Kill it. We could
5945 reply with "Next" if we received "Page", but we 5916 reply with "Next" if we received "Page", but we
5946 currently never do because we are interested in 5917 currently never do because we are interested in
5947 images, only, which should have 1 page. */ 5918 images, only, which should have 1 page. */
5948 Pixmap pixmap = (Pixmap) event.xclient.data.l[1]; 5919 Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
5949 struct frame *f 5920 f = x_window_to_frame (dpyinfo, event.xclient.window);
5950 = x_window_to_frame (dpyinfo, event.xclient.window);
5951 x_kill_gs_process (pixmap, f); 5921 x_kill_gs_process (pixmap, f);
5952 expose_frame (f, 0, 0, 0, 0); 5922 expose_frame (f, 0, 0, 0, 0);
5923 goto done;
5953 } 5924 }
5925
5954 #ifdef USE_TOOLKIT_SCROLL_BARS 5926 #ifdef USE_TOOLKIT_SCROLL_BARS
5955 /* Scroll bar callbacks send a ClientMessage from which 5927 /* Scroll bar callbacks send a ClientMessage from which
5956 we construct an input_event. */ 5928 we construct an input_event. */
5957 else if (event.xclient.message_type 5929 if (event.xclient.message_type
5958 == dpyinfo->Xatom_Scrollbar) 5930 == dpyinfo->Xatom_Scrollbar)
5959 { 5931 {
5960 x_scroll_bar_to_input_event (&event, bufp); 5932 x_scroll_bar_to_input_event (&event, &inev);
5961 ++bufp, ++count, --numchars; 5933 *finish = X_EVENT_GOTO_OUT;
5962 goto out; 5934 goto done;
5963 } 5935 }
5964 #endif /* USE_TOOLKIT_SCROLL_BARS */ 5936 #endif /* USE_TOOLKIT_SCROLL_BARS */
5965 else 5937
5966 { 5938 f = x_any_window_to_frame (dpyinfo, event.xclient.window);
5967 struct frame *f 5939
5968 = x_any_window_to_frame (dpyinfo, event.xclient.window); 5940 if (!f)
5969 5941 goto OTHER;
5970 if (f) 5942
5971 { 5943 if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
5972 int ret = x_handle_dnd_message (f, &event.xclient, 5944 *finish = X_EVENT_DROP;
5973 dpyinfo, bufp);
5974 if (ret > 0)
5975 {
5976 ++bufp, ++count, --numchars;
5977 }
5978
5979 if (ret != 0)
5980 *finish = X_EVENT_DROP;
5981 }
5982 else
5983 goto OTHER;
5984 }
5985 } 5945 }
5986 break; 5946 break;
5987 5947
5988 case SelectionNotify: 5948 case SelectionNotify:
5989 #ifdef USE_X_TOOLKIT 5949 #ifdef USE_X_TOOLKIT
5999 goto OTHER; 5959 goto OTHER;
6000 #endif /* USE_X_TOOLKIT */ 5960 #endif /* USE_X_TOOLKIT */
6001 { 5961 {
6002 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; 5962 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
6003 5963
6004 if (numchars == 0) 5964 inev.kind = SELECTION_CLEAR_EVENT;
6005 abort (); 5965 SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
6006 5966 SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
6007 bufp->kind = SELECTION_CLEAR_EVENT; 5967 SELECTION_EVENT_TIME (&inev) = eventp->time;
6008 SELECTION_EVENT_DISPLAY (bufp) = eventp->display; 5968 inev.frame_or_window = Qnil;
6009 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
6010 SELECTION_EVENT_TIME (bufp) = eventp->time;
6011 bufp->frame_or_window = Qnil;
6012 bufp->arg = Qnil;
6013 bufp++;
6014
6015 count += 1;
6016 numchars -= 1;
6017 } 5969 }
6018 break; 5970 break;
6019 5971
6020 case SelectionRequest: /* Someone wants our selection. */ 5972 case SelectionRequest: /* Someone wants our selection. */
6021 #ifdef USE_X_TOOLKIT 5973 #ifdef USE_X_TOOLKIT
6028 else 5980 else
6029 { 5981 {
6030 XSelectionRequestEvent *eventp 5982 XSelectionRequestEvent *eventp
6031 = (XSelectionRequestEvent *) &event; 5983 = (XSelectionRequestEvent *) &event;
6032 5984
6033 if (numchars == 0) 5985 inev.kind = SELECTION_REQUEST_EVENT;
6034 abort (); 5986 SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
6035 5987 SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
6036 bufp->kind = SELECTION_REQUEST_EVENT; 5988 SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
6037 SELECTION_EVENT_DISPLAY (bufp) = eventp->display; 5989 SELECTION_EVENT_TARGET (&inev) = eventp->target;
6038 SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor; 5990 SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
6039 SELECTION_EVENT_SELECTION (bufp) = eventp->selection; 5991 SELECTION_EVENT_TIME (&inev) = eventp->time;
6040 SELECTION_EVENT_TARGET (bufp) = eventp->target; 5992 inev.frame_or_window = Qnil;
6041 SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
6042 SELECTION_EVENT_TIME (bufp) = eventp->time;
6043 bufp->frame_or_window = Qnil;
6044 bufp->arg = Qnil;
6045 bufp++;
6046
6047 count += 1;
6048 numchars -= 1;
6049 } 5993 }
6050 break; 5994 break;
6051 5995
6052 case PropertyNotify: 5996 case PropertyNotify:
6053 #if 0 /* This is plain wrong. In the case that we are waiting for a 5997 #if 0 /* This is plain wrong. In the case that we are waiting for a
6073 6017
6074 /* Perhaps reparented due to a WM restart. Reset this. */ 6018 /* Perhaps reparented due to a WM restart. Reset this. */
6075 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; 6019 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
6076 } 6020 }
6077 goto OTHER; 6021 goto OTHER;
6078 break;
6079 6022
6080 case Expose: 6023 case Expose:
6081 f = x_window_to_frame (dpyinfo, event.xexpose.window); 6024 f = x_window_to_frame (dpyinfo, event.xexpose.window);
6082 if (f) 6025 if (f)
6083 { 6026 {
6175 and that way, we know the window is not iconified now. */ 6118 and that way, we know the window is not iconified now. */
6176 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)) 6119 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
6177 { 6120 {
6178 f->async_iconified = 1; 6121 f->async_iconified = 1;
6179 6122
6180 bufp->kind = ICONIFY_EVENT; 6123 inev.kind = ICONIFY_EVENT;
6181 XSETFRAME (bufp->frame_or_window, f); 6124 XSETFRAME (inev.frame_or_window, f);
6182 bufp->arg = Qnil;
6183 bufp++;
6184 count++;
6185 numchars--;
6186 } 6125 }
6187 } 6126 }
6188 goto OTHER; 6127 goto OTHER;
6189 6128
6190 case MapNotify: 6129 case MapNotify:
6212 f->async_iconified = 0; 6151 f->async_iconified = 0;
6213 f->output_data.x->has_been_visible = 1; 6152 f->output_data.x->has_been_visible = 1;
6214 6153
6215 if (f->iconified) 6154 if (f->iconified)
6216 { 6155 {
6217 bufp->kind = DEICONIFY_EVENT; 6156 inev.kind = DEICONIFY_EVENT;
6218 XSETFRAME (bufp->frame_or_window, f); 6157 XSETFRAME (inev.frame_or_window, f);
6219 bufp->arg = Qnil;
6220 bufp++;
6221 count++;
6222 numchars--;
6223 } 6158 }
6224 else if (! NILP (Vframe_list) 6159 else if (! NILP (Vframe_list)
6225 && ! NILP (XCDR (Vframe_list))) 6160 && ! NILP (XCDR (Vframe_list)))
6226 /* Force a redisplay sooner or later 6161 /* Force a redisplay sooner or later
6227 to update the frame titles 6162 to update the frame titles
6278 unsigned char copy_buffer[513]; 6213 unsigned char copy_buffer[513];
6279 unsigned char *copy_bufptr = copy_buffer; 6214 unsigned char *copy_bufptr = copy_buffer;
6280 int copy_bufsiz = sizeof (copy_buffer); 6215 int copy_bufsiz = sizeof (copy_buffer);
6281 int modifiers; 6216 int modifiers;
6282 Lisp_Object coding_system = Qlatin_1; 6217 Lisp_Object coding_system = Qlatin_1;
6218 Lisp_Object c;
6283 6219
6284 event.xkey.state 6220 event.xkey.state
6285 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f), 6221 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
6286 extra_keyboard_modifiers); 6222 extra_keyboard_modifiers);
6287 modifiers = event.xkey.state; 6223 modifiers = event.xkey.state;
6371 if (compose_status.chars_matched > 0 && nbytes == 0) 6307 if (compose_status.chars_matched > 0 && nbytes == 0)
6372 break; 6308 break;
6373 6309
6374 orig_keysym = keysym; 6310 orig_keysym = keysym;
6375 6311
6376 if (numchars > 1) 6312 /* Common for all keysym input events. */
6377 { 6313 XSETFRAME (inev.frame_or_window, f);
6378 Lisp_Object c; 6314 inev.modifiers
6379 6315 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
6380 /* First deal with keysyms which have defined 6316 inev.timestamp = event.xkey.time;
6381 translations to characters. */ 6317
6382 if (keysym >= 32 && keysym < 128) 6318 /* First deal with keysyms which have defined
6383 /* Avoid explicitly decoding each ASCII character. */ 6319 translations to characters. */
6384 { 6320 if (keysym >= 32 && keysym < 128)
6385 bufp->kind = ASCII_KEYSTROKE_EVENT; 6321 /* Avoid explicitly decoding each ASCII character. */
6386 bufp->code = keysym; 6322 {
6387 XSETFRAME (bufp->frame_or_window, f); 6323 inev.kind = ASCII_KEYSTROKE_EVENT;
6388 bufp->arg = Qnil; 6324 inev.code = keysym;
6389 bufp->modifiers 6325 goto done_keysym;
6390 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 6326 }
6391 modifiers); 6327
6392 bufp->timestamp = event.xkey.time; 6328 /* Now non-ASCII. */
6393 bufp++; 6329 if (HASH_TABLE_P (Vx_keysym_table)
6394 count++; 6330 && (NATNUMP (c = Fgethash (make_number (keysym),
6395 numchars--; 6331 Vx_keysym_table,
6396 } 6332 Qnil))))
6397 /* Now non-ASCII. */ 6333 {
6398 else if (HASH_TABLE_P (Vx_keysym_table) 6334 inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
6399 && (NATNUMP (c = Fgethash (make_number (keysym), 6335 ? ASCII_KEYSTROKE_EVENT
6400 Vx_keysym_table, 6336 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
6401 Qnil)))) 6337 inev.code = XFASTINT (c);
6402 { 6338 goto done_keysym;
6403 bufp->kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) 6339 }
6404 ? ASCII_KEYSTROKE_EVENT 6340
6405 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 6341 /* Random non-modifier sorts of keysyms. */
6406 bufp->code = XFASTINT (c); 6342 if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
6407 XSETFRAME (bufp->frame_or_window, f);
6408 bufp->arg = Qnil;
6409 bufp->modifiers
6410 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
6411 modifiers);
6412 bufp->timestamp = event.xkey.time;
6413 bufp++;
6414 count++;
6415 numchars--;
6416 }
6417 /* Random non-modifier sorts of keysyms. */
6418 else if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
6419 || keysym == XK_Delete 6343 || keysym == XK_Delete
6420 #ifdef XK_ISO_Left_Tab 6344 #ifdef XK_ISO_Left_Tab
6421 || (keysym >= XK_ISO_Left_Tab 6345 || (keysym >= XK_ISO_Left_Tab
6422 && keysym <= XK_ISO_Enter) 6346 && keysym <= XK_ISO_Enter)
6423 #endif 6347 #endif
6494 >= XK_ISO_Lock 6418 >= XK_ISO_Lock
6495 && (unsigned)(orig_keysym) 6419 && (unsigned)(orig_keysym)
6496 <= XK_ISO_Last_Group_Lock) 6420 <= XK_ISO_Last_Group_Lock)
6497 #endif 6421 #endif
6498 )) 6422 ))
6499 { 6423 {
6500 if (temp_index == sizeof temp_buffer / sizeof (short)) 6424 STORE_KEYSYM_FOR_DEBUG (keysym);
6501 temp_index = 0; 6425 /* make_lispy_event will convert this to a symbolic
6502 temp_buffer[temp_index++] = keysym; 6426 key. */
6503 /* make_lispy_event will convert this to a symbolic 6427 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
6504 key. */ 6428 inev.code = keysym;
6505 bufp->kind = NON_ASCII_KEYSTROKE_EVENT; 6429 goto done_keysym;
6506 bufp->code = keysym; 6430 }
6507 XSETFRAME (bufp->frame_or_window, f); 6431
6508 bufp->arg = Qnil; 6432 { /* Raw bytes, not keysym. */
6509 bufp->modifiers 6433 register int i;
6510 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 6434 register int c;
6511 modifiers); 6435 int nchars, len;
6512 bufp->timestamp = event.xkey.time; 6436
6513 bufp++; 6437 /* The input should be decoded with `coding_system'
6514 count++; 6438 which depends on which X*LookupString function
6515 numchars--; 6439 we used just above and the locale. */
6516 } 6440 setup_coding_system (coding_system, &coding);
6517 else if (numchars > nbytes) 6441 coding.src_multibyte = 0;
6518 { /* Raw bytes, not keysym. */ 6442 coding.dst_multibyte = 1;
6519 register int i; 6443 /* The input is converted to events, thus we can't
6520 register int c; 6444 handle composition. Anyway, there's no XIM that
6521 int nchars, len; 6445 gives us composition information. */
6522 6446 coding.composing = COMPOSITION_DISABLED;
6523 /* The input should be decoded with `coding_system' 6447
6524 which depends on which X*LookupString function 6448 for (i = 0; i < nbytes; i++)
6525 we used just above and the locale. */ 6449 {
6526 setup_coding_system (coding_system, &coding); 6450 STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
6527 coding.src_multibyte = 0; 6451 }
6528 coding.dst_multibyte = 1; 6452
6529 /* The input is converted to events, thus we can't 6453 {
6530 handle composition. Anyway, there's no XIM that 6454 /* Decode the input data. */
6531 gives us composition information. */ 6455 int require;
6532 coding.composing = COMPOSITION_DISABLED; 6456 unsigned char *p;
6533 6457
6534 for (i = 0; i < nbytes; i++) 6458 require = decoding_buffer_size (&coding, nbytes);
6535 { 6459 p = (unsigned char *) alloca (require);
6536 if (temp_index == (sizeof temp_buffer 6460 coding.mode |= CODING_MODE_LAST_BLOCK;
6537 / sizeof (short))) 6461 /* We explicitly disable composition handling because
6538 temp_index = 0; 6462 key data should not contain any composition sequence. */
6539 temp_buffer[temp_index++] = copy_bufptr[i]; 6463 coding.composing = COMPOSITION_DISABLED;
6540 } 6464 decode_coding (&coding, copy_bufptr, p, nbytes, require);
6541 6465 nbytes = coding.produced;
6542 { 6466 nchars = coding.produced_char;
6543 /* Decode the input data. */ 6467 copy_bufptr = p;
6544 int require; 6468 }
6545 unsigned char *p; 6469
6546 6470 /* Convert the input data to a sequence of
6547 require = decoding_buffer_size (&coding, nbytes); 6471 character events. */
6548 p = (unsigned char *) alloca (require); 6472 for (i = 0; i < nbytes; i += len)
6549 coding.mode |= CODING_MODE_LAST_BLOCK; 6473 {
6550 /* We explicitly disable composition 6474 if (nchars == nbytes)
6551 handling because key data should 6475 c = copy_bufptr[i], len = 1;
6552 not contain any composition 6476 else
6553 sequence. */ 6477 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
6554 coding.composing = COMPOSITION_DISABLED; 6478 nbytes - i, len);
6555 decode_coding (&coding, copy_bufptr, p, 6479 inev.kind = (SINGLE_BYTE_CHAR_P (c)
6556 nbytes, require); 6480 ? ASCII_KEYSTROKE_EVENT
6557 nbytes = coding.produced; 6481 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
6558 nchars = coding.produced_char; 6482 inev.code = c;
6559 copy_bufptr = p; 6483 kbd_buffer_store_event_hold (&inev, hold_quit);
6560 } 6484 }
6561 6485
6562 /* Convert the input data to a sequence of 6486 /* Previous code updated count by nchars rather than nbytes,
6563 character events. */ 6487 but that seems bogus to me. ++kfs */
6564 for (i = 0; i < nbytes; i += len) 6488 count += nbytes;
6565 { 6489
6566 if (nchars == nbytes) 6490 inev.kind = NO_EVENT; /* Already stored above. */
6567 c = copy_bufptr[i], len = 1; 6491
6568 else 6492 if (keysym == NoSymbol)
6569 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, 6493 break;
6570 nbytes - i, len); 6494 }
6571
6572 bufp->kind = (SINGLE_BYTE_CHAR_P (c)
6573 ? ASCII_KEYSTROKE_EVENT
6574 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
6575 bufp->code = c;
6576 XSETFRAME (bufp->frame_or_window, f);
6577 bufp->arg = Qnil;
6578 bufp->modifiers
6579 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
6580 modifiers);
6581 bufp->timestamp = event.xkey.time;
6582 bufp++;
6583 }
6584
6585 count += nchars;
6586 numchars -= nchars;
6587
6588 if (keysym == NoSymbol)
6589 break;
6590 }
6591 else
6592 abort ();
6593 }
6594 else
6595 abort ();
6596 } 6495 }
6496 done_keysym:
6597 #ifdef HAVE_X_I18N 6497 #ifdef HAVE_X_I18N
6598 /* Don't dispatch this event since XtDispatchEvent calls 6498 /* Don't dispatch this event since XtDispatchEvent calls
6599 XFilterEvent, and two calls in a row may freeze the 6499 XFilterEvent, and two calls in a row may freeze the
6600 client. */ 6500 client. */
6601 break; 6501 break;
6612 #else 6512 #else
6613 goto OTHER; 6513 goto OTHER;
6614 #endif 6514 #endif
6615 6515
6616 case EnterNotify: 6516 case EnterNotify:
6617 { 6517 x_detect_focus_change (dpyinfo, &event, &inev);
6618 int n; 6518
6619 6519 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
6620 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
6621 if (n > 0)
6622 {
6623 bufp += n, count += n, numchars -= n;
6624 }
6625
6626 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
6627 6520
6628 #if 0 6521 #if 0
6629 if (event.xcrossing.focus) 6522 if (event.xcrossing.focus)
6630 { 6523 {
6631 /* Avoid nasty pop/raise loops. */ 6524 /* Avoid nasty pop/raise loops. */
6632 if (f && (!(f->auto_raise) 6525 if (f && (!(f->auto_raise)
6633 || !(f->auto_lower) 6526 || !(f->auto_lower)
6634 || (event.xcrossing.time - enter_timestamp) > 500)) 6527 || (event.xcrossing.time - enter_timestamp) > 500))
6635 { 6528 {
6636 x_new_focus_frame (dpyinfo, f); 6529 x_new_focus_frame (dpyinfo, f);
6637 enter_timestamp = event.xcrossing.time; 6530 enter_timestamp = event.xcrossing.time;
6638 } 6531 }
6639 } 6532 }
6640 else if (f == dpyinfo->x_focus_frame) 6533 else if (f == dpyinfo->x_focus_frame)
6641 x_new_focus_frame (dpyinfo, 0); 6534 x_new_focus_frame (dpyinfo, 0);
6642 #endif 6535 #endif
6643 6536
6644 /* EnterNotify counts as mouse movement, 6537 /* EnterNotify counts as mouse movement,
6645 so update things that depend on mouse position. */ 6538 so update things that depend on mouse position. */
6646 if (f && !f->output_data.x->hourglass_p) 6539 if (f && !f->output_data.x->hourglass_p)
6647 note_mouse_movement (f, &event.xmotion); 6540 note_mouse_movement (f, &event.xmotion);
6648 goto OTHER; 6541 goto OTHER;
6649 }
6650 6542
6651 case FocusIn: 6543 case FocusIn:
6652 { 6544 x_detect_focus_change (dpyinfo, &event, &inev);
6653 int n;
6654
6655 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
6656 if (n > 0)
6657 {
6658 bufp += n, count += n, numchars -= n;
6659 }
6660 }
6661
6662 goto OTHER; 6545 goto OTHER;
6663 6546
6664 case LeaveNotify: 6547 case LeaveNotify:
6665 { 6548 x_detect_focus_change (dpyinfo, &event, &inev);
6666 int n;
6667
6668 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
6669 if (n > 0)
6670 {
6671 bufp += n, count += n, numchars -= n;
6672 }
6673 }
6674 6549
6675 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); 6550 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
6676 if (f) 6551 if (f)
6677 { 6552 {
6678 if (f == dpyinfo->mouse_face_mouse_frame) 6553 if (f == dpyinfo->mouse_face_mouse_frame)
6686 /* Generate a nil HELP_EVENT to cancel a help-echo. 6561 /* Generate a nil HELP_EVENT to cancel a help-echo.
6687 Do it only if there's something to cancel. 6562 Do it only if there's something to cancel.
6688 Otherwise, the startup message is cleared when 6563 Otherwise, the startup message is cleared when
6689 the mouse leaves the frame. */ 6564 the mouse leaves the frame. */
6690 if (any_help_event_p) 6565 if (any_help_event_p)
6691 { 6566 do_help = -1;
6692 Lisp_Object frame;
6693 int n;
6694
6695 XSETFRAME (frame, f);
6696 help_echo_string = Qnil;
6697 n = gen_help_event (bufp, numchars,
6698 Qnil, frame, Qnil, Qnil, 0);
6699 bufp += n, count += n, numchars -= n;
6700 }
6701
6702 } 6567 }
6703 goto OTHER; 6568 goto OTHER;
6704 6569
6705 case FocusOut: 6570 case FocusOut:
6706 { 6571 x_detect_focus_change (dpyinfo, &event, &inev);
6707 int n;
6708
6709 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
6710 if (n > 0)
6711 {
6712 bufp += n, count += n, numchars -= n;
6713 }
6714 }
6715
6716 goto OTHER; 6572 goto OTHER;
6717 6573
6718 case MotionNotify: 6574 case MotionNotify:
6719 { 6575 {
6720 previous_help_echo_string = help_echo_string; 6576 previous_help_echo_string = help_echo_string;
6748 /* Window will be selected only when it is not selected now and 6604 /* Window will be selected only when it is not selected now and
6749 last mouse movement event was not in it. Minibuffer window 6605 last mouse movement event was not in it. Minibuffer window
6750 will be selected iff it is active. */ 6606 will be selected iff it is active. */
6751 if (WINDOWP (window) 6607 if (WINDOWP (window)
6752 && !EQ (window, last_window) 6608 && !EQ (window, last_window)
6753 && !EQ (window, selected_window) 6609 && !EQ (window, selected_window))
6754 && numchars > 0)
6755 { 6610 {
6756 bufp->kind = SELECT_WINDOW_EVENT; 6611 inev.kind = SELECT_WINDOW_EVENT;
6757 bufp->frame_or_window = window; 6612 inev.frame_or_window = window;
6758 bufp->arg = Qnil;
6759 ++bufp, ++count, --numchars;
6760 } 6613 }
6761 6614
6762 last_window=window; 6615 last_window=window;
6763 } 6616 }
6764 note_mouse_movement (f, &event.xmotion); 6617 note_mouse_movement (f, &event.xmotion);
6781 6634
6782 /* If the contents of the global variable help_echo_string 6635 /* If the contents of the global variable help_echo_string
6783 has changed, generate a HELP_EVENT. */ 6636 has changed, generate a HELP_EVENT. */
6784 if (!NILP (help_echo_string) 6637 if (!NILP (help_echo_string)
6785 || !NILP (previous_help_echo_string)) 6638 || !NILP (previous_help_echo_string))
6786 { 6639 do_help = 1;
6787 Lisp_Object frame;
6788 int n;
6789
6790 if (f)
6791 XSETFRAME (frame, f);
6792 else
6793 frame = Qnil;
6794
6795 any_help_event_p = 1;
6796 n = gen_help_event (bufp, numchars, help_echo_string, frame,
6797 help_echo_window, help_echo_object,
6798 help_echo_pos);
6799 bufp += n, count += n, numchars -= n;
6800 }
6801
6802 goto OTHER; 6640 goto OTHER;
6803 } 6641 }
6804 6642
6805 case ConfigureNotify: 6643 case ConfigureNotify:
6806 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window); 6644 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
6880 case ButtonRelease: 6718 case ButtonRelease:
6881 case ButtonPress: 6719 case ButtonPress:
6882 { 6720 {
6883 /* If we decide we want to generate an event to be seen 6721 /* If we decide we want to generate an event to be seen
6884 by the rest of Emacs, we put it here. */ 6722 by the rest of Emacs, we put it here. */
6885 struct input_event emacs_event;
6886 int tool_bar_p = 0; 6723 int tool_bar_p = 0;
6887 6724
6888 emacs_event.kind = NO_EVENT;
6889 bzero (&compose_status, sizeof (compose_status)); 6725 bzero (&compose_status, sizeof (compose_status));
6890 6726
6891 if (dpyinfo->grabbed 6727 if (dpyinfo->grabbed
6892 && last_mouse_frame 6728 && last_mouse_frame
6893 && FRAME_LIVE_P (last_mouse_frame)) 6729 && FRAME_LIVE_P (last_mouse_frame))
6923 || f == dpyinfo->x_focus_frame) 6759 || f == dpyinfo->x_focus_frame)
6924 { 6760 {
6925 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) 6761 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
6926 if (! popup_activated ()) 6762 if (! popup_activated ())
6927 #endif 6763 #endif
6928 construct_mouse_click (&emacs_event, &event, f); 6764 construct_mouse_click (&inev, &event, f);
6929 } 6765 }
6930 } 6766 }
6931 else 6767 else
6932 { 6768 {
6933 struct scroll_bar *bar 6769 struct scroll_bar *bar
6937 #ifdef USE_TOOLKIT_SCROLL_BARS 6773 #ifdef USE_TOOLKIT_SCROLL_BARS
6938 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit 6774 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
6939 scroll bars. */ 6775 scroll bars. */
6940 if (bar && event.xbutton.state & ControlMask) 6776 if (bar && event.xbutton.state & ControlMask)
6941 { 6777 {
6942 x_scroll_bar_handle_click (bar, &event, &emacs_event); 6778 x_scroll_bar_handle_click (bar, &event, &inev);
6943 *finish = X_EVENT_DROP; 6779 *finish = X_EVENT_DROP;
6944 } 6780 }
6945 #else /* not USE_TOOLKIT_SCROLL_BARS */ 6781 #else /* not USE_TOOLKIT_SCROLL_BARS */
6946 if (bar) 6782 if (bar)
6947 x_scroll_bar_handle_click (bar, &event, &emacs_event); 6783 x_scroll_bar_handle_click (bar, &event, &inev);
6948 #endif /* not USE_TOOLKIT_SCROLL_BARS */ 6784 #endif /* not USE_TOOLKIT_SCROLL_BARS */
6949 } 6785 }
6950 6786
6951 if (event.type == ButtonPress) 6787 if (event.type == ButtonPress)
6952 { 6788 {
6962 if (!tool_bar_p) 6798 if (!tool_bar_p)
6963 last_tool_bar_item = -1; 6799 last_tool_bar_item = -1;
6964 } 6800 }
6965 else 6801 else
6966 dpyinfo->grabbed &= ~(1 << event.xbutton.button); 6802 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
6967
6968 if (numchars >= 1 && emacs_event.kind != NO_EVENT)
6969 {
6970 bcopy (&emacs_event, bufp, sizeof (struct input_event));
6971 bufp++;
6972 count++;
6973 numchars--;
6974 }
6975 6803
6976 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) 6804 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
6977 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window); 6805 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
6978 /* For a down-event in the menu bar, 6806 /* For a down-event in the menu bar,
6979 don't pass it to Xt right now. 6807 don't pass it to Xt right now.
7057 UNBLOCK_INPUT; 6885 UNBLOCK_INPUT;
7058 #endif /* USE_X_TOOLKIT */ 6886 #endif /* USE_X_TOOLKIT */
7059 break; 6887 break;
7060 } 6888 }
7061 6889
7062 goto ret; 6890 done:
7063 6891 if (inev.kind != NO_EVENT)
7064 out: 6892 {
7065 *finish = X_EVENT_GOTO_OUT; 6893 kbd_buffer_store_event_hold (&inev, hold_quit);
7066 6894 count++;
7067 ret: 6895 }
7068 *bufp_r = bufp; 6896
7069 *numcharsp = numchars; 6897 if (do_help
6898 && !(hold_quit && hold_quit->kind != NO_EVENT))
6899 {
6900 Lisp_Object frame;
6901
6902 if (f)
6903 XSETFRAME (frame, f);
6904 else
6905 frame = Qnil;
6906
6907 if (do_help > 0)
6908 {
6909 any_help_event_p = 1;
6910 gen_help_event (help_echo_string, frame, help_echo_window,
6911 help_echo_object, help_echo_pos);
6912 }
6913 else
6914 {
6915 help_echo_string = Qnil;
6916 gen_help_event (Qnil, frame, Qnil, Qnil, 0);
6917 }
6918 count++;
6919 }
6920
7070 *eventp = event; 6921 *eventp = event;
7071
7072 return count; 6922 return count;
7073 } 6923 }
7074 6924
7075 6925
7076 /* Handles the XEvent EVENT on display DISPLAY. 6926 /* Handles the XEvent EVENT on display DISPLAY.
7082 x_dispatch_event (event, display) 6932 x_dispatch_event (event, display)
7083 XEvent *event; 6933 XEvent *event;
7084 Display *display; 6934 Display *display;
7085 { 6935 {
7086 struct x_display_info *dpyinfo; 6936 struct x_display_info *dpyinfo;
7087 struct input_event bufp[10];
7088 struct input_event *bufpp;
7089 int numchars = 10;
7090 int finish = X_EVENT_NORMAL; 6937 int finish = X_EVENT_NORMAL;
7091 6938
7092 for (bufpp = bufp; bufpp != bufp + 10; bufpp++)
7093 EVENT_INIT (*bufpp);
7094 bufpp = bufp;
7095
7096 dpyinfo = x_display_info_for_display (display); 6939 dpyinfo = x_display_info_for_display (display);
7097 6940
7098 if (dpyinfo) 6941 if (dpyinfo)
7099 { 6942 handle_one_xevent (dpyinfo, event, &finish, 0);
7100 int i, events;
7101 events = handle_one_xevent (dpyinfo,
7102 event,
7103 &bufpp,
7104 &numchars,
7105 &finish);
7106 for (i = 0; i < events; ++i)
7107 kbd_buffer_store_event (&bufp[i]);
7108 }
7109 6943
7110 return finish; 6944 return finish;
7111 } 6945 }
7112 6946
7113 6947
7114 /* Read events coming from the X server. 6948 /* Read events coming from the X server.
7115 This routine is called by the SIGIO handler. 6949 This routine is called by the SIGIO handler.
7116 We return as soon as there are no more events to be read. 6950 We return as soon as there are no more events to be read.
7117 6951
7118 Events representing keys are stored in buffer BUFP,
7119 which can hold up to NUMCHARS characters.
7120 We return the number of characters stored into the buffer, 6952 We return the number of characters stored into the buffer,
7121 thus pretending to be `read'. 6953 thus pretending to be `read'.
7122 6954
7123 EXPECTED is nonzero if the caller knows input is available. */ 6955 EXPECTED is nonzero if the caller knows input is available. */
7124 6956
7125 static int 6957 static int
7126 XTread_socket (sd, bufp, numchars, expected) 6958 XTread_socket (sd, expected, hold_quit)
7127 register int sd; 6959 register int sd;
7128 /* register */ struct input_event *bufp;
7129 /* register */ int numchars;
7130 int expected; 6960 int expected;
6961 struct input_event *hold_quit;
7131 { 6962 {
7132 int count = 0; 6963 int count = 0;
7133 XEvent event; 6964 XEvent event;
7134 int event_found = 0; 6965 int event_found = 0;
7135 struct x_display_info *dpyinfo; 6966 struct x_display_info *dpyinfo;
7143 interrupt_input_pending = 0; 6974 interrupt_input_pending = 0;
7144 BLOCK_INPUT; 6975 BLOCK_INPUT;
7145 6976
7146 /* So people can tell when we have read the available input. */ 6977 /* So people can tell when we have read the available input. */
7147 input_signal_count++; 6978 input_signal_count++;
7148
7149 if (numchars <= 0)
7150 abort (); /* Don't think this happens. */
7151 6979
7152 ++handling_signal; 6980 ++handling_signal;
7153 6981
7154 /* Find the display we are supposed to read input for. 6982 /* Find the display we are supposed to read input for.
7155 It's the one communicating on descriptor SD. */ 6983 It's the one communicating on descriptor SD. */
7188 XTread_socket_fake_io_error = 0; 7016 XTread_socket_fake_io_error = 0;
7189 x_io_error_quitter (dpyinfo->display); 7017 x_io_error_quitter (dpyinfo->display);
7190 } 7018 }
7191 7019
7192 #ifdef HAVE_X_SM 7020 #ifdef HAVE_X_SM
7193 BLOCK_INPUT; 7021 {
7194 count += x_session_check_input (bufp, &numchars); 7022 struct input_event inev;
7195 UNBLOCK_INPUT; 7023 BLOCK_INPUT;
7024 /* We don't need to EVENT_INIT (inev) here, as
7025 x_session_check_input copies an entire input_event. */
7026 if (x_session_check_input (&inev))
7027 {
7028 kbd_buffer_store_event_hold (&inev, hold_quit);
7029 count++;
7030 }
7031 UNBLOCK_INPUT;
7032 }
7196 #endif 7033 #endif
7197 7034
7198 #ifndef USE_GTK 7035 #ifndef USE_GTK
7199 while (XPending (dpyinfo->display)) 7036 while (XPending (dpyinfo->display))
7200 { 7037 {
7207 if (x_filter_event (dpyinfo, &event)) 7044 if (x_filter_event (dpyinfo, &event))
7208 break; 7045 break;
7209 #endif 7046 #endif
7210 event_found = 1; 7047 event_found = 1;
7211 7048
7212 count += handle_one_xevent (dpyinfo, 7049 count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
7213 &event,
7214 &bufp,
7215 &numchars,
7216 &finish);
7217 7050
7218 if (finish == X_EVENT_GOTO_OUT) 7051 if (finish == X_EVENT_GOTO_OUT)
7219 goto out; 7052 goto out;
7220 } 7053 }
7221 #endif /* not USE_GTK */ 7054 #endif /* not USE_GTK */
7232 from all displays. */ 7065 from all displays. */
7233 7066
7234 while (gtk_events_pending ()) 7067 while (gtk_events_pending ())
7235 { 7068 {
7236 current_count = count; 7069 current_count = count;
7237 current_numcharsp = &numchars; 7070 current_hold_quit = hold_quit;
7238 current_bufp = &bufp;
7239 7071
7240 gtk_main_iteration (); 7072 gtk_main_iteration ();
7241 7073
7242 count = current_count; 7074 count = current_count;
7243 current_bufp = 0; 7075 current_count = -1;
7244 current_numcharsp = 0; 7076 current_hold_quit = 0;
7245 7077
7246 if (current_finish == X_EVENT_GOTO_OUT) 7078 if (current_finish == X_EVENT_GOTO_OUT)
7247 break; 7079 break;
7248 } 7080 }
7249 #endif /* USE_GTK */ 7081 #endif /* USE_GTK */
7279 { 7111 {
7280 x_raise_frame (pending_autoraise_frame); 7112 x_raise_frame (pending_autoraise_frame);
7281 pending_autoraise_frame = 0; 7113 pending_autoraise_frame = 0;
7282 } 7114 }
7283 7115
7116 --handling_signal;
7284 UNBLOCK_INPUT; 7117 UNBLOCK_INPUT;
7285 --handling_signal; 7118
7286 return count; 7119 return count;
7287 } 7120 }
7288 7121
7289 7122
7290 7123
10943 10776
10944 x_noop_count = 0; 10777 x_noop_count = 0;
10945 last_tool_bar_item = -1; 10778 last_tool_bar_item = -1;
10946 any_help_event_p = 0; 10779 any_help_event_p = 0;
10947 10780
10781 #ifdef USE_GTK
10782 current_count = -1;
10783 #endif
10784
10948 /* Try to use interrupt input; if we can't, then start polling. */ 10785 /* Try to use interrupt input; if we can't, then start polling. */
10949 Fset_input_mode (Qt, Qnil, Qt, Qnil); 10786 Fset_input_mode (Qt, Qnil, Qt, Qnil);
10950 10787
10951 #ifdef USE_X_TOOLKIT 10788 #ifdef USE_X_TOOLKIT
10952 XtToolkitInitialize (); 10789 XtToolkitInitialize ();