aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog19
-rw-r--r--src/xfns.c12
-rw-r--r--src/xterm.c2346
-rw-r--r--src/xterm.h13
4 files changed, 1234 insertions, 1156 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index eb37f99e63e..be555fb495c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,22 @@
12003-01-08 Jan D. <jan.h.d@swipnet.se>
2
3 * xfns.c (Fx_file_dialog): Call XtAppNextEvent and x_dispatch_event
4 instead of XtAppProcessEvent.
5
6 * xterm.c (handle_one_xevent): New function
7 (x_dispatch_event): New function
8 (XTread_socket): Call handle_one_xevent.
9
10 * xterm.h (FRAME_OUTER_TO_INNER_DIFF_X/Y): Added
11
12 * xmenu.c (Fx_popup_menu): If popping up at mouse position,
13 call XQueryPointer to get coordinates.
14 (popup_get_selection): Do not set popup_activated_flag to zero,
15 let popup_deactivate_callback do that. Needed for Motif.
16 Call x_dispatch_event instead of XtDispatchEvent.
17 (xmenu_show): Calculate root coordinate from frame top/left position.
18
19
12003-01-08 Kim F. Storm <storm@cua.dk> 202003-01-08 Kim F. Storm <storm@cua.dk>
2 21
3 * process.c (server_accept_connection): Fixed recording of new 22 * process.c (server_accept_connection): Fixed recording of new
diff --git a/src/xfns.c b/src/xfns.c
index 7f777527157..85f402befb0 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -11649,18 +11649,14 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
11649 XmListSetPos (list, item_pos); 11649 XmListSetPos (list, item_pos);
11650 } 11650 }
11651 11651
11652 /* Process events until the user presses Cancel or OK. Block 11652 /* Process events until the user presses Cancel or OK. */
11653 and unblock input here so that we get a chance of processing
11654 expose events. */
11655 UNBLOCK_INPUT;
11656 result = 0; 11653 result = 0;
11657 while (result == 0) 11654 while (result == 0)
11658 { 11655 {
11659 BLOCK_INPUT; 11656 XEvent event;
11660 XtAppProcessEvent (Xt_app_con, XtIMAll); 11657 XtAppNextEvent (Xt_app_con, &event);
11661 UNBLOCK_INPUT; 11658 x_dispatch_event (&event, FRAME_X_DISPLAY (f) );
11662 } 11659 }
11663 BLOCK_INPUT;
11664 11660
11665 /* Get the result. */ 11661 /* Get the result. */
11666 if (result == XmCR_OK) 11662 if (result == XmCR_OK)
diff --git a/src/xterm.c b/src/xterm.c
index 8c021ca895f..220c45e648c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9934,51 +9934,6 @@ x_scroll_bar_clear (f)
9934#endif /* not USE_TOOLKIT_SCROLL_BARS */ 9934#endif /* not USE_TOOLKIT_SCROLL_BARS */
9935} 9935}
9936 9936
9937/* This processes Expose events from the menu-bar specific X event
9938 loop in xmenu.c. This allows to redisplay the frame if necessary
9939 when handling menu-bar or pop-up items. */
9940
9941int
9942process_expose_from_menu (event)
9943 XEvent event;
9944{
9945 FRAME_PTR f;
9946 struct x_display_info *dpyinfo;
9947 int frame_exposed_p = 0;
9948
9949 BLOCK_INPUT;
9950
9951 dpyinfo = x_display_info_for_display (event.xexpose.display);
9952 f = x_window_to_frame (dpyinfo, event.xexpose.window);
9953 if (f)
9954 {
9955 if (f->async_visible == 0)
9956 {
9957 f->async_visible = 1;
9958 f->async_iconified = 0;
9959 f->output_data.x->has_been_visible = 1;
9960 SET_FRAME_GARBAGED (f);
9961 }
9962 else
9963 {
9964 expose_frame (x_window_to_frame (dpyinfo, event.xexpose.window),
9965 event.xexpose.x, event.xexpose.y,
9966 event.xexpose.width, event.xexpose.height);
9967 frame_exposed_p = 1;
9968 }
9969 }
9970 else
9971 {
9972 struct scroll_bar *bar
9973 = x_window_to_scroll_bar (event.xexpose.window);
9974
9975 if (bar)
9976 x_scroll_bar_expose (bar, &event);
9977 }
9978
9979 UNBLOCK_INPUT;
9980 return frame_exposed_p;
9981}
9982 9937
9983/* Define a queue to save up SelectionRequest events for later handling. */ 9938/* Define a queue to save up SelectionRequest events for later handling. */
9984 9939
@@ -10107,131 +10062,61 @@ static struct x_display_info *next_noop_dpyinfo;
10107#define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent)) 10062#define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
10108#define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent)) 10063#define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
10109 10064
10110/* Read events coming from the X server.
10111 This routine is called by the SIGIO handler.
10112 We return as soon as there are no more events to be read.
10113 10065
10114 Events representing keys are stored in buffer BUFP, 10066enum
10115 which can hold up to NUMCHARS characters. 10067{
10116 We return the number of characters stored into the buffer, 10068 X_EVENT_NORMAL,
10117 thus pretending to be `read'. 10069 X_EVENT_GOTO_OUT,
10070 X_EVENT_DROP
10071};
10118 10072
10119 EXPECTED is nonzero if the caller knows input is available. */ 10073/* Handles the XEvent EVENT on display DPYINFO.
10074
10075 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
10076 *FINISH is zero if caller should continue reading events.
10077 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
10078
10079 Events representing keys are stored in buffer *BUFP_R,
10080 which can hold up to *NUMCHARSP characters.
10081 We return the number of characters stored into the buffer. */
10120 10082
10121static int 10083static int
10122XTread_socket (sd, bufp, numchars, expected) 10084handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10123 register int sd; 10085 struct x_display_info *dpyinfo;
10124 /* register */ struct input_event *bufp; 10086 XEvent *eventp;
10125 /* register */ int numchars; 10087 /* register */ struct input_event **bufp_r;
10126 int expected; 10088 /* register */ int *numcharsp;
10089 int *finish;
10127{ 10090{
10128 int count = 0; 10091 int count = 0;
10129 int nbytes = 0; 10092 int nbytes = 0;
10130 XEvent event;
10131 struct frame *f; 10093 struct frame *f;
10132 int event_found = 0;
10133 struct x_display_info *dpyinfo;
10134 struct coding_system coding; 10094 struct coding_system coding;
10095 struct input_event *bufp = *bufp_r;
10096 int numchars = *numcharsp;
10097 XEvent event = *eventp;
10135 10098
10136 if (interrupt_input_blocked) 10099 *finish = X_EVENT_NORMAL;
10137 {
10138 interrupt_input_pending = 1;
10139 return -1;
10140 }
10141
10142 interrupt_input_pending = 0;
10143 BLOCK_INPUT;
10144
10145 /* So people can tell when we have read the available input. */
10146 input_signal_count++;
10147
10148 if (numchars <= 0)
10149 abort (); /* Don't think this happens. */
10150
10151 ++handling_signal;
10152 10100
10153 /* Find the display we are supposed to read input for. 10101 switch (event.type)
10154 It's the one communicating on descriptor SD. */
10155 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
10156 { 10102 {
10157#if 0 /* This ought to be unnecessary; let's verify it. */ 10103 case ClientMessage:
10158#ifdef FIOSNBIO 10104 {
10159 /* If available, Xlib uses FIOSNBIO to make the socket 10105 if (event.xclient.message_type
10160 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set, 10106 == dpyinfo->Xatom_wm_protocols
10161 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK, 10107 && event.xclient.format == 32)
10162 a read returns 0, which Xlib interprets as equivalent to EPIPE. */ 10108 {
10163 fcntl (dpyinfo->connection, F_SETFL, 0); 10109 if (event.xclient.data.l[0]
10164#endif /* ! defined (FIOSNBIO) */ 10110 == dpyinfo->Xatom_wm_take_focus)
10165#endif 10111 {
10166 10112 /* Use x_any_window_to_frame because this
10167#if 0 /* This code can't be made to work, with multiple displays, 10113 could be the shell widget window
10168 and appears not to be used on any system any more. 10114 if the frame has no title bar. */
10169 Also keyboard.c doesn't turn O_NDELAY on and off 10115 f = x_any_window_to_frame (dpyinfo, event.xclient.window);
10170 for X connections. */
10171#ifndef SIGIO
10172#ifndef HAVE_SELECT
10173 if (! (fcntl (dpyinfo->connection, F_GETFL, 0) & O_NDELAY))
10174 {
10175 extern int read_alarm_should_throw;
10176 read_alarm_should_throw = 1;
10177 XPeekEvent (dpyinfo->display, &event);
10178 read_alarm_should_throw = 0;
10179 }
10180#endif /* HAVE_SELECT */
10181#endif /* SIGIO */
10182#endif
10183
10184 /* For debugging, this gives a way to fake an I/O error. */
10185 if (dpyinfo == XTread_socket_fake_io_error)
10186 {
10187 XTread_socket_fake_io_error = 0;
10188 x_io_error_quitter (dpyinfo->display);
10189 }
10190
10191#ifdef HAVE_X_SM
10192 BLOCK_INPUT;
10193 count += x_session_check_input (bufp, &numchars);
10194 UNBLOCK_INPUT;
10195#endif
10196
10197 while (XPending (dpyinfo->display))
10198 {
10199 XNextEvent (dpyinfo->display, &event);
10200
10201#ifdef HAVE_X_I18N
10202 {
10203 /* Filter events for the current X input method.
10204 XFilterEvent returns non-zero if the input method has
10205 consumed the event. We pass the frame's X window to
10206 XFilterEvent because that's the one for which the IC
10207 was created. */
10208 struct frame *f1 = x_any_window_to_frame (dpyinfo,
10209 event.xclient.window);
10210 if (XFilterEvent (&event, f1 ? FRAME_X_WINDOW (f1) : None))
10211 break;
10212 }
10213#endif
10214 event_found = 1;
10215
10216 switch (event.type)
10217 {
10218 case ClientMessage:
10219 {
10220 if (event.xclient.message_type
10221 == dpyinfo->Xatom_wm_protocols
10222 && event.xclient.format == 32)
10223 {
10224 if (event.xclient.data.l[0]
10225 == dpyinfo->Xatom_wm_take_focus)
10226 {
10227 /* Use x_any_window_to_frame because this
10228 could be the shell widget window
10229 if the frame has no title bar. */
10230 f = x_any_window_to_frame (dpyinfo, event.xclient.window);
10231#ifdef HAVE_X_I18N 10116#ifdef HAVE_X_I18N
10232 /* Not quite sure this is needed -pd */ 10117 /* Not quite sure this is needed -pd */
10233 if (f && FRAME_XIC (f)) 10118 if (f && FRAME_XIC (f))
10234 XSetICFocus (FRAME_XIC (f)); 10119 XSetICFocus (FRAME_XIC (f));
10235#endif 10120#endif
10236#if 0 /* Emacs sets WM hints whose `input' field is `true'. This 10121#if 0 /* Emacs sets WM hints whose `input' field is `true'. This
10237 instructs the WM to set the input focus automatically for 10122 instructs the WM to set the input focus automatically for
@@ -10246,1165 +10131,1332 @@ XTread_socket (sd, bufp, numchars, expected)
10246 below can generate additional FocusIn events which confuse 10131 below can generate additional FocusIn events which confuse
10247 Emacs. */ 10132 Emacs. */
10248 10133
10249 /* Since we set WM_TAKE_FOCUS, we must call 10134 /* Since we set WM_TAKE_FOCUS, we must call
10250 XSetInputFocus explicitly. But not if f is null, 10135 XSetInputFocus explicitly. But not if f is null,
10251 since that might be an event for a deleted frame. */ 10136 since that might be an event for a deleted frame. */
10252 if (f) 10137 if (f)
10253 { 10138 {
10254 Display *d = event.xclient.display; 10139 Display *d = event.xclient.display;
10255 /* Catch and ignore errors, in case window has been 10140 /* Catch and ignore errors, in case window has been
10256 iconified by a window manager such as GWM. */ 10141 iconified by a window manager such as GWM. */
10257 int count = x_catch_errors (d); 10142 int count = x_catch_errors (d);
10258 XSetInputFocus (d, event.xclient.window, 10143 XSetInputFocus (d, event.xclient.window,
10259 /* The ICCCM says this is 10144 /* The ICCCM says this is
10260 the only valid choice. */ 10145 the only valid choice. */
10261 RevertToParent, 10146 RevertToParent,
10262 event.xclient.data.l[1]); 10147 event.xclient.data.l[1]);
10263 /* This is needed to detect the error 10148 /* This is needed to detect the error
10264 if there is an error. */ 10149 if there is an error. */
10265 XSync (d, False); 10150 XSync (d, False);
10266 x_uncatch_errors (d, count); 10151 x_uncatch_errors (d, count);
10267 } 10152 }
10268 /* Not certain about handling scroll bars here */ 10153 /* Not certain about handling scroll bars here */
10269#endif /* 0 */ 10154#endif /* 0 */
10270 } 10155 }
10271 else if (event.xclient.data.l[0] 10156 else if (event.xclient.data.l[0]
10272 == dpyinfo->Xatom_wm_save_yourself) 10157 == dpyinfo->Xatom_wm_save_yourself)
10273 { 10158 {
10274 /* Save state modify the WM_COMMAND property to 10159 /* Save state modify the WM_COMMAND property to
10275 something which can reinstate us. This notifies 10160 something which can reinstate us. This notifies
10276 the session manager, who's looking for such a 10161 the session manager, who's looking for such a
10277 PropertyNotify. Can restart processing when 10162 PropertyNotify. Can restart processing when
10278 a keyboard or mouse event arrives. */ 10163 a keyboard or mouse event arrives. */
10279 /* If we have a session manager, don't set this. 10164 /* If we have a session manager, don't set this.
10280 KDE will then start two Emacsen, one for the 10165 KDE will then start two Emacsen, one for the
10281 session manager and one for this. */ 10166 session manager and one for this. */
10282 if (numchars > 0 10167 if (numchars > 0
10283#ifdef HAVE_X_SM 10168#ifdef HAVE_X_SM
10284 && ! x_session_have_connection () 10169 && ! x_session_have_connection ()
10285#endif 10170#endif
10286 ) 10171 )
10287 { 10172 {
10288 f = x_top_window_to_frame (dpyinfo, 10173 f = x_top_window_to_frame (dpyinfo,
10289 event.xclient.window); 10174 event.xclient.window);
10290 /* This is just so we only give real data once 10175 /* This is just so we only give real data once
10291 for a single Emacs process. */ 10176 for a single Emacs process. */
10292 if (f == SELECTED_FRAME ()) 10177 if (f == SELECTED_FRAME ())
10293 XSetCommand (FRAME_X_DISPLAY (f), 10178 XSetCommand (FRAME_X_DISPLAY (f),
10294 event.xclient.window, 10179 event.xclient.window,
10295 initial_argv, initial_argc); 10180 initial_argv, initial_argc);
10296 else if (f) 10181 else if (f)
10297 XSetCommand (FRAME_X_DISPLAY (f), 10182 XSetCommand (FRAME_X_DISPLAY (f),
10298 event.xclient.window, 10183 event.xclient.window,
10299 0, 0); 10184 0, 0);
10300 } 10185 }
10301 } 10186 }
10302 else if (event.xclient.data.l[0] 10187 else if (event.xclient.data.l[0]
10303 == dpyinfo->Xatom_wm_delete_window) 10188 == dpyinfo->Xatom_wm_delete_window)
10304 { 10189 {
10305 struct frame *f 10190 struct frame *f
10306 = x_any_window_to_frame (dpyinfo, 10191 = x_any_window_to_frame (dpyinfo,
10307 event.xclient.window); 10192 event.xclient.window);
10308
10309 if (f)
10310 {
10311 if (numchars == 0)
10312 abort ();
10313
10314 bufp->kind = DELETE_WINDOW_EVENT;
10315 XSETFRAME (bufp->frame_or_window, f);
10316 bufp->arg = Qnil;
10317 bufp++;
10318 10193
10319 count += 1; 10194 if (f)
10320 numchars -= 1; 10195 {
10321 } 10196 if (numchars == 0)
10322 } 10197 abort ();
10323 }
10324 else if (event.xclient.message_type
10325 == dpyinfo->Xatom_wm_configure_denied)
10326 {
10327 }
10328 else if (event.xclient.message_type
10329 == dpyinfo->Xatom_wm_window_moved)
10330 {
10331 int new_x, new_y;
10332 struct frame *f
10333 = x_window_to_frame (dpyinfo, event.xclient.window);
10334 10198
10335 new_x = event.xclient.data.s[0]; 10199 bufp->kind = DELETE_WINDOW_EVENT;
10336 new_y = event.xclient.data.s[1]; 10200 XSETFRAME (bufp->frame_or_window, f);
10201 bufp->arg = Qnil;
10202 bufp++;
10337 10203
10338 if (f) 10204 count += 1;
10339 { 10205 numchars -= 1;
10340 f->output_data.x->left_pos = new_x; 10206 }
10341 f->output_data.x->top_pos = new_y; 10207 else
10342 } 10208 goto OTHER; /* May be a dialog that is to be removed */
10343 } 10209 }
10210 }
10211 else if (event.xclient.message_type
10212 == dpyinfo->Xatom_wm_configure_denied)
10213 {
10214 }
10215 else if (event.xclient.message_type
10216 == dpyinfo->Xatom_wm_window_moved)
10217 {
10218 int new_x, new_y;
10219 struct frame *f
10220 = x_window_to_frame (dpyinfo, event.xclient.window);
10221
10222 new_x = event.xclient.data.s[0];
10223 new_y = event.xclient.data.s[1];
10224
10225 if (f)
10226 {
10227 f->output_data.x->left_pos = new_x;
10228 f->output_data.x->top_pos = new_y;
10229 }
10230 }
10344#ifdef HACK_EDITRES 10231#ifdef HACK_EDITRES
10345 else if (event.xclient.message_type 10232 else if (event.xclient.message_type
10346 == dpyinfo->Xatom_editres) 10233 == dpyinfo->Xatom_editres)
10347 { 10234 {
10348 struct frame *f 10235 struct frame *f
10349 = x_any_window_to_frame (dpyinfo, event.xclient.window); 10236 = x_any_window_to_frame (dpyinfo, event.xclient.window);
10350 _XEditResCheckMessages (f->output_data.x->widget, NULL, 10237 _XEditResCheckMessages (f->output_data.x->widget, NULL,
10351 &event, NULL); 10238 &event, NULL);
10352 } 10239 }
10353#endif /* HACK_EDITRES */ 10240#endif /* HACK_EDITRES */
10354 else if ((event.xclient.message_type 10241 else if ((event.xclient.message_type
10355 == dpyinfo->Xatom_DONE) 10242 == dpyinfo->Xatom_DONE)
10356 || (event.xclient.message_type 10243 || (event.xclient.message_type
10357 == dpyinfo->Xatom_PAGE)) 10244 == dpyinfo->Xatom_PAGE))
10358 { 10245 {
10359 /* Ghostview job completed. Kill it. We could 10246 /* Ghostview job completed. Kill it. We could
10360 reply with "Next" if we received "Page", but we 10247 reply with "Next" if we received "Page", but we
10361 currently never do because we are interested in 10248 currently never do because we are interested in
10362 images, only, which should have 1 page. */ 10249 images, only, which should have 1 page. */
10363 Pixmap pixmap = (Pixmap) event.xclient.data.l[1]; 10250 Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
10364 struct frame *f 10251 struct frame *f
10365 = x_window_to_frame (dpyinfo, event.xclient.window); 10252 = x_window_to_frame (dpyinfo, event.xclient.window);
10366 x_kill_gs_process (pixmap, f); 10253 x_kill_gs_process (pixmap, f);
10367 expose_frame (f, 0, 0, 0, 0); 10254 expose_frame (f, 0, 0, 0, 0);
10368 } 10255 }
10369#ifdef USE_TOOLKIT_SCROLL_BARS 10256#ifdef USE_TOOLKIT_SCROLL_BARS
10370 /* Scroll bar callbacks send a ClientMessage from which 10257 /* Scroll bar callbacks send a ClientMessage from which
10371 we construct an input_event. */ 10258 we construct an input_event. */
10372 else if (event.xclient.message_type 10259 else if (event.xclient.message_type
10373 == dpyinfo->Xatom_Scrollbar) 10260 == dpyinfo->Xatom_Scrollbar)
10374 { 10261 {
10375 x_scroll_bar_to_input_event (&event, bufp); 10262 x_scroll_bar_to_input_event (&event, bufp);
10376 ++bufp, ++count, --numchars; 10263 ++bufp, ++count, --numchars;
10377 goto out; 10264 goto out;
10378 } 10265 }
10379#endif /* USE_TOOLKIT_SCROLL_BARS */ 10266#endif /* USE_TOOLKIT_SCROLL_BARS */
10380 else 10267 else
10381 goto OTHER; 10268 goto OTHER;
10382 } 10269 }
10383 break; 10270 break;
10384 10271
10385 case SelectionNotify: 10272 case SelectionNotify:
10386#ifdef USE_X_TOOLKIT 10273#ifdef USE_X_TOOLKIT
10387 if (! x_window_to_frame (dpyinfo, event.xselection.requestor)) 10274 if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
10388 goto OTHER; 10275 goto OTHER;
10389#endif /* not USE_X_TOOLKIT */ 10276#endif /* not USE_X_TOOLKIT */
10390 x_handle_selection_notify (&event.xselection); 10277 x_handle_selection_notify (&event.xselection);
10391 break; 10278 break;
10392 10279
10393 case SelectionClear: /* Someone has grabbed ownership. */ 10280 case SelectionClear: /* Someone has grabbed ownership. */
10394#ifdef USE_X_TOOLKIT 10281#ifdef USE_X_TOOLKIT
10395 if (! x_window_to_frame (dpyinfo, event.xselectionclear.window)) 10282 if (! x_window_to_frame (dpyinfo, event.xselectionclear.window))
10396 goto OTHER; 10283 goto OTHER;
10397#endif /* USE_X_TOOLKIT */ 10284#endif /* USE_X_TOOLKIT */
10398 { 10285 {
10399 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; 10286 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
10400 10287
10401 if (numchars == 0) 10288 if (numchars == 0)
10402 abort (); 10289 abort ();
10403 10290
10404 bufp->kind = SELECTION_CLEAR_EVENT; 10291 bufp->kind = SELECTION_CLEAR_EVENT;
10405 SELECTION_EVENT_DISPLAY (bufp) = eventp->display; 10292 SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
10406 SELECTION_EVENT_SELECTION (bufp) = eventp->selection; 10293 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
10407 SELECTION_EVENT_TIME (bufp) = eventp->time; 10294 SELECTION_EVENT_TIME (bufp) = eventp->time;
10408 bufp->frame_or_window = Qnil; 10295 bufp->frame_or_window = Qnil;
10409 bufp->arg = Qnil; 10296 bufp->arg = Qnil;
10410 bufp++; 10297 bufp++;
10411 10298
10412 count += 1; 10299 count += 1;
10413 numchars -= 1; 10300 numchars -= 1;
10414 } 10301 }
10415 break; 10302 break;
10416 10303
10417 case SelectionRequest: /* Someone wants our selection. */ 10304 case SelectionRequest: /* Someone wants our selection. */
10418#ifdef USE_X_TOOLKIT 10305#ifdef USE_X_TOOLKIT
10419 if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner)) 10306 if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
10420 goto OTHER; 10307 goto OTHER;
10421#endif /* USE_X_TOOLKIT */ 10308#endif /* USE_X_TOOLKIT */
10422 if (x_queue_selection_requests) 10309 if (x_queue_selection_requests)
10423 x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner), 10310 x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner),
10424 &event); 10311 &event);
10425 else 10312 else
10426 { 10313 {
10427 XSelectionRequestEvent *eventp 10314 XSelectionRequestEvent *eventp
10428 = (XSelectionRequestEvent *) &event; 10315 = (XSelectionRequestEvent *) &event;
10429 10316
10430 if (numchars == 0) 10317 if (numchars == 0)
10431 abort (); 10318 abort ();
10432 10319
10433 bufp->kind = SELECTION_REQUEST_EVENT; 10320 bufp->kind = SELECTION_REQUEST_EVENT;
10434 SELECTION_EVENT_DISPLAY (bufp) = eventp->display; 10321 SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
10435 SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor; 10322 SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
10436 SELECTION_EVENT_SELECTION (bufp) = eventp->selection; 10323 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
10437 SELECTION_EVENT_TARGET (bufp) = eventp->target; 10324 SELECTION_EVENT_TARGET (bufp) = eventp->target;
10438 SELECTION_EVENT_PROPERTY (bufp) = eventp->property; 10325 SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
10439 SELECTION_EVENT_TIME (bufp) = eventp->time; 10326 SELECTION_EVENT_TIME (bufp) = eventp->time;
10440 bufp->frame_or_window = Qnil; 10327 bufp->frame_or_window = Qnil;
10441 bufp->arg = Qnil; 10328 bufp->arg = Qnil;
10442 bufp++; 10329 bufp++;
10443 10330
10444 count += 1; 10331 count += 1;
10445 numchars -= 1; 10332 numchars -= 1;
10446 } 10333 }
10447 break; 10334 break;
10448 10335
10449 case PropertyNotify: 10336 case PropertyNotify:
10450#if 0 /* This is plain wrong. In the case that we are waiting for a 10337#if 0 /* This is plain wrong. In the case that we are waiting for a
10451 PropertyNotify used as an ACK in incremental selection 10338 PropertyNotify used as an ACK in incremental selection
10452 transfer, the property will be on the receiver's window. */ 10339 transfer, the property will be on the receiver's window. */
10453#if defined USE_X_TOOLKIT 10340#if defined USE_X_TOOLKIT
10454 if (!x_any_window_to_frame (dpyinfo, event.xproperty.window)) 10341 if (!x_any_window_to_frame (dpyinfo, event.xproperty.window))
10455 goto OTHER; 10342 goto OTHER;
10456#endif 10343#endif
10457#endif 10344#endif
10458 x_handle_property_notify (&event.xproperty); 10345 x_handle_property_notify (&event.xproperty);
10459 goto OTHER; 10346 goto OTHER;
10460 10347
10461 case ReparentNotify: 10348 case ReparentNotify:
10462 f = x_top_window_to_frame (dpyinfo, event.xreparent.window); 10349 f = x_top_window_to_frame (dpyinfo, event.xreparent.window);
10463 if (f) 10350 if (f)
10464 { 10351 {
10465 int x, y; 10352 int x, y;
10466 f->output_data.x->parent_desc = event.xreparent.parent; 10353 f->output_data.x->parent_desc = event.xreparent.parent;
10467 x_real_positions (f, &x, &y); 10354 x_real_positions (f, &x, &y);
10468 f->output_data.x->left_pos = x; 10355 f->output_data.x->left_pos = x;
10469 f->output_data.x->top_pos = y; 10356 f->output_data.x->top_pos = y;
10470 goto OTHER; 10357 goto OTHER;
10471 } 10358 }
10472 break; 10359 break;
10473 10360
10474 case Expose: 10361 case Expose:
10475 f = x_window_to_frame (dpyinfo, event.xexpose.window); 10362 f = x_window_to_frame (dpyinfo, event.xexpose.window);
10476 if (f) 10363 if (f)
10477 { 10364 {
10478 x_check_fullscreen (f); 10365 x_check_fullscreen (f);
10479 10366
10480 if (f->async_visible == 0) 10367 if (f->async_visible == 0)
10481 { 10368 {
10482 f->async_visible = 1; 10369 f->async_visible = 1;
10483 f->async_iconified = 0; 10370 f->async_iconified = 0;
10484 f->output_data.x->has_been_visible = 1; 10371 f->output_data.x->has_been_visible = 1;
10485 SET_FRAME_GARBAGED (f); 10372 SET_FRAME_GARBAGED (f);
10486 } 10373 }
10487 else 10374 else
10488 expose_frame (x_window_to_frame (dpyinfo, 10375 expose_frame (x_window_to_frame (dpyinfo,
10489 event.xexpose.window), 10376 event.xexpose.window),
10490 event.xexpose.x, event.xexpose.y, 10377 event.xexpose.x, event.xexpose.y,
10491 event.xexpose.width, event.xexpose.height); 10378 event.xexpose.width, event.xexpose.height);
10492 } 10379 }
10493 else 10380 else
10494 { 10381 {
10495#ifndef USE_TOOLKIT_SCROLL_BARS 10382#ifndef USE_TOOLKIT_SCROLL_BARS
10496 struct scroll_bar *bar; 10383 struct scroll_bar *bar;
10497#endif 10384#endif
10498#if defined USE_LUCID 10385#if defined USE_LUCID
10499 /* Submenus of the Lucid menu bar aren't widgets 10386 /* Submenus of the Lucid menu bar aren't widgets
10500 themselves, so there's no way to dispatch events 10387 themselves, so there's no way to dispatch events
10501 to them. Recognize this case separately. */ 10388 to them. Recognize this case separately. */
10502 { 10389 {
10503 Widget widget 10390 Widget widget
10504 = x_window_to_menu_bar (event.xexpose.window); 10391 = x_window_to_menu_bar (event.xexpose.window);
10505 if (widget) 10392 if (widget)
10506 xlwmenu_redisplay (widget); 10393 xlwmenu_redisplay (widget);
10507 } 10394 }
10508#endif /* USE_LUCID */ 10395#endif /* USE_LUCID */
10509 10396
10510#ifdef USE_TOOLKIT_SCROLL_BARS 10397#ifdef USE_TOOLKIT_SCROLL_BARS
10511 /* Dispatch event to the widget. */ 10398 /* Dispatch event to the widget. */
10512 goto OTHER; 10399 goto OTHER;
10513#else /* not USE_TOOLKIT_SCROLL_BARS */ 10400#else /* not USE_TOOLKIT_SCROLL_BARS */
10514 bar = x_window_to_scroll_bar (event.xexpose.window); 10401 bar = x_window_to_scroll_bar (event.xexpose.window);
10515 10402
10516 if (bar) 10403 if (bar)
10517 x_scroll_bar_expose (bar, &event); 10404 x_scroll_bar_expose (bar, &event);
10518#ifdef USE_X_TOOLKIT 10405#ifdef USE_X_TOOLKIT
10519 else 10406 else
10520 goto OTHER; 10407 goto OTHER;
10521#endif /* USE_X_TOOLKIT */ 10408#endif /* USE_X_TOOLKIT */
10522#endif /* not USE_TOOLKIT_SCROLL_BARS */ 10409#endif /* not USE_TOOLKIT_SCROLL_BARS */
10523 } 10410 }
10524 break; 10411 break;
10525 10412
10526 case GraphicsExpose: /* This occurs when an XCopyArea's 10413 case GraphicsExpose: /* This occurs when an XCopyArea's
10527 source area was obscured or not 10414 source area was obscured or not
10528 available. */ 10415 available. */
10529 f = x_window_to_frame (dpyinfo, event.xgraphicsexpose.drawable); 10416 f = x_window_to_frame (dpyinfo, event.xgraphicsexpose.drawable);
10530 if (f) 10417 if (f)
10531 { 10418 {
10532 expose_frame (f, 10419 expose_frame (f,
10533 event.xgraphicsexpose.x, event.xgraphicsexpose.y, 10420 event.xgraphicsexpose.x, event.xgraphicsexpose.y,
10534 event.xgraphicsexpose.width, 10421 event.xgraphicsexpose.width,
10535 event.xgraphicsexpose.height); 10422 event.xgraphicsexpose.height);
10536 } 10423 }
10537#ifdef USE_X_TOOLKIT 10424#ifdef USE_X_TOOLKIT
10538 else 10425 else
10539 goto OTHER; 10426 goto OTHER;
10540#endif /* USE_X_TOOLKIT */ 10427#endif /* USE_X_TOOLKIT */
10541 break; 10428 break;
10542
10543 case NoExpose: /* This occurs when an XCopyArea's
10544 source area was completely
10545 available. */
10546 break;
10547
10548 case UnmapNotify:
10549 /* Redo the mouse-highlight after the tooltip has gone. */
10550 if (event.xmap.window == tip_window)
10551 {
10552 tip_window = 0;
10553 redo_mouse_highlight ();
10554 }
10555 10429
10556 f = x_top_window_to_frame (dpyinfo, event.xunmap.window); 10430 case NoExpose: /* This occurs when an XCopyArea's
10557 if (f) /* F may no longer exist if 10431 source area was completely
10558 the frame was deleted. */ 10432 available. */
10559 { 10433 break;
10560 /* While a frame is unmapped, display generation is
10561 disabled; you don't want to spend time updating a
10562 display that won't ever be seen. */
10563 f->async_visible = 0;
10564 /* We can't distinguish, from the event, whether the window
10565 has become iconified or invisible. So assume, if it
10566 was previously visible, than now it is iconified.
10567 But x_make_frame_invisible clears both
10568 the visible flag and the iconified flag;
10569 and that way, we know the window is not iconified now. */
10570 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
10571 {
10572 f->async_iconified = 1;
10573
10574 bufp->kind = ICONIFY_EVENT;
10575 XSETFRAME (bufp->frame_or_window, f);
10576 bufp->arg = Qnil;
10577 bufp++;
10578 count++;
10579 numchars--;
10580 }
10581 }
10582 goto OTHER;
10583
10584 case MapNotify:
10585 if (event.xmap.window == tip_window)
10586 /* The tooltip has been drawn already. Avoid
10587 the SET_FRAME_GARBAGED below. */
10588 goto OTHER;
10589
10590 /* We use x_top_window_to_frame because map events can
10591 come for sub-windows and they don't mean that the
10592 frame is visible. */
10593 f = x_top_window_to_frame (dpyinfo, event.xmap.window);
10594 if (f)
10595 {
10596 f->async_visible = 1;
10597 f->async_iconified = 0;
10598 f->output_data.x->has_been_visible = 1;
10599 10434
10600 /* wait_reading_process_input will notice this and update 10435 case UnmapNotify:
10601 the frame's display structures. */ 10436 /* Redo the mouse-highlight after the tooltip has gone. */
10602 SET_FRAME_GARBAGED (f); 10437 if (event.xmap.window == tip_window)
10438 {
10439 tip_window = 0;
10440 redo_mouse_highlight ();
10441 }
10603 10442
10604 if (f->iconified) 10443 f = x_top_window_to_frame (dpyinfo, event.xunmap.window);
10605 { 10444 if (f) /* F may no longer exist if
10606 bufp->kind = DEICONIFY_EVENT; 10445 the frame was deleted. */
10607 XSETFRAME (bufp->frame_or_window, f); 10446 {
10608 bufp->arg = Qnil; 10447 /* While a frame is unmapped, display generation is
10609 bufp++; 10448 disabled; you don't want to spend time updating a
10610 count++; 10449 display that won't ever be seen. */
10611 numchars--; 10450 f->async_visible = 0;
10612 } 10451 /* We can't distinguish, from the event, whether the window
10613 else if (! NILP (Vframe_list) 10452 has become iconified or invisible. So assume, if it
10614 && ! NILP (XCDR (Vframe_list))) 10453 was previously visible, than now it is iconified.
10615 /* Force a redisplay sooner or later 10454 But x_make_frame_invisible clears both
10616 to update the frame titles 10455 the visible flag and the iconified flag;
10617 in case this is the second frame. */ 10456 and that way, we know the window is not iconified now. */
10618 record_asynch_buffer_change (); 10457 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
10619 } 10458 {
10620 goto OTHER; 10459 f->async_iconified = 1;
10621 10460
10622 case KeyPress: 10461 bufp->kind = ICONIFY_EVENT;
10462 XSETFRAME (bufp->frame_or_window, f);
10463 bufp->arg = Qnil;
10464 bufp++;
10465 count++;
10466 numchars--;
10467 }
10468 }
10469 goto OTHER;
10470
10471 case MapNotify:
10472 if (event.xmap.window == tip_window)
10473 /* The tooltip has been drawn already. Avoid
10474 the SET_FRAME_GARBAGED below. */
10475 goto OTHER;
10476
10477 /* We use x_top_window_to_frame because map events can
10478 come for sub-windows and they don't mean that the
10479 frame is visible. */
10480 f = x_top_window_to_frame (dpyinfo, event.xmap.window);
10481 if (f)
10482 {
10483 /* wait_reading_process_input will notice this and update
10484 the frame's display structures.
10485 If we where iconified, we should not set garbaged,
10486 because that stops redrawing on Expose events. This looks
10487 bad if we are called from a recursive event loop
10488 (x_dispatch_event), for example when a dialog is up. */
10489 if (! f->async_iconified)
10490 SET_FRAME_GARBAGED (f);
10491
10492 f->async_visible = 1;
10493 f->async_iconified = 0;
10494 f->output_data.x->has_been_visible = 1;
10495
10496 if (f->iconified)
10497 {
10498 bufp->kind = DEICONIFY_EVENT;
10499 XSETFRAME (bufp->frame_or_window, f);
10500 bufp->arg = Qnil;
10501 bufp++;
10502 count++;
10503 numchars--;
10504 }
10505 else if (! NILP (Vframe_list)
10506 && ! NILP (XCDR (Vframe_list)))
10507 /* Force a redisplay sooner or later
10508 to update the frame titles
10509 in case this is the second frame. */
10510 record_asynch_buffer_change ();
10511 }
10512 goto OTHER;
10623 10513
10624 /* Dispatch KeyPress events when in menu. */ 10514 case KeyPress:
10625 if (popup_activated_flag)
10626 goto OTHER;
10627 10515
10628 f = x_any_window_to_frame (dpyinfo, event.xkey.window); 10516 /* Dispatch KeyPress events when in menu. */
10517 if (popup_activated_flag)
10518 goto OTHER;
10519 f = x_any_window_to_frame (dpyinfo, event.xkey.window);
10629 10520
10630 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) 10521 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
10631 { 10522 {
10632 dpyinfo->mouse_face_hidden = 1; 10523 dpyinfo->mouse_face_hidden = 1;
10633 clear_mouse_face (dpyinfo); 10524 clear_mouse_face (dpyinfo);
10634 } 10525 }
10635 10526
10636#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS 10527#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10637 if (f == 0) 10528 if (f == 0)
10638 { 10529 {
10639 /* Scroll bars consume key events, but we want 10530 /* Scroll bars consume key events, but we want
10640 the keys to go to the scroll bar's frame. */ 10531 the keys to go to the scroll bar's frame. */
10641 Widget widget = XtWindowToWidget (dpyinfo->display, 10532 Widget widget = XtWindowToWidget (dpyinfo->display,
10642 event.xkey.window); 10533 event.xkey.window);
10643 if (widget && XmIsScrollBar (widget)) 10534 if (widget && XmIsScrollBar (widget))
10644 { 10535 {
10645 widget = XtParent (widget); 10536 widget = XtParent (widget);
10646 f = x_any_window_to_frame (dpyinfo, XtWindow (widget)); 10537 f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
10647 } 10538 }
10648 } 10539 }
10649#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */ 10540#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10650 10541
10651 if (f != 0) 10542 if (f != 0)
10652 { 10543 {
10653 KeySym keysym, orig_keysym; 10544 KeySym keysym, orig_keysym;
10654 /* al%imercury@uunet.uu.net says that making this 81 10545 /* al%imercury@uunet.uu.net says that making this 81
10655 instead of 80 fixed a bug whereby meta chars made 10546 instead of 80 fixed a bug whereby meta chars made
10656 his Emacs hang. 10547 his Emacs hang.
10657 10548
10658 It seems that some version of XmbLookupString has 10549 It seems that some version of XmbLookupString has
10659 a bug of not returning XBufferOverflow in 10550 a bug of not returning XBufferOverflow in
10660 status_return even if the input is too long to 10551 status_return even if the input is too long to
10661 fit in 81 bytes. So, we must prepare sufficient 10552 fit in 81 bytes. So, we must prepare sufficient
10662 bytes for copy_buffer. 513 bytes (256 chars for 10553 bytes for copy_buffer. 513 bytes (256 chars for
10663 two-byte character set) seems to be a fairly good 10554 two-byte character set) seems to be a fairly good
10664 approximation. -- 2000.8.10 handa@etl.go.jp */ 10555 approximation. -- 2000.8.10 handa@etl.go.jp */
10665 unsigned char copy_buffer[513]; 10556 unsigned char copy_buffer[513];
10666 unsigned char *copy_bufptr = copy_buffer; 10557 unsigned char *copy_bufptr = copy_buffer;
10667 int copy_bufsiz = sizeof (copy_buffer); 10558 int copy_bufsiz = sizeof (copy_buffer);
10668 int modifiers; 10559 int modifiers;
10669 Lisp_Object coding_system = Qlatin_1; 10560 Lisp_Object coding_system = Qlatin_1;
10670 10561
10671 event.xkey.state 10562 event.xkey.state
10672 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f), 10563 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
10673 extra_keyboard_modifiers); 10564 extra_keyboard_modifiers);
10674 modifiers = event.xkey.state; 10565 modifiers = event.xkey.state;
10675 10566
10676 /* This will have to go some day... */ 10567 /* This will have to go some day... */
10677 10568
10678 /* make_lispy_event turns chars into control chars. 10569 /* make_lispy_event turns chars into control chars.
10679 Don't do it here because XLookupString is too eager. */ 10570 Don't do it here because XLookupString is too eager. */
10680 event.xkey.state &= ~ControlMask; 10571 event.xkey.state &= ~ControlMask;
10681 event.xkey.state &= ~(dpyinfo->meta_mod_mask 10572 event.xkey.state &= ~(dpyinfo->meta_mod_mask
10682 | dpyinfo->super_mod_mask 10573 | dpyinfo->super_mod_mask
10683 | dpyinfo->hyper_mod_mask 10574 | dpyinfo->hyper_mod_mask
10684 | dpyinfo->alt_mod_mask); 10575 | dpyinfo->alt_mod_mask);
10685 10576
10686 /* In case Meta is ComposeCharacter, 10577 /* In case Meta is ComposeCharacter,
10687 clear its status. According to Markus Ehrnsperger 10578 clear its status. According to Markus Ehrnsperger
10688 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de 10579 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10689 this enables ComposeCharacter to work whether or 10580 this enables ComposeCharacter to work whether or
10690 not it is combined with Meta. */ 10581 not it is combined with Meta. */
10691 if (modifiers & dpyinfo->meta_mod_mask) 10582 if (modifiers & dpyinfo->meta_mod_mask)
10692 bzero (&compose_status, sizeof (compose_status)); 10583 bzero (&compose_status, sizeof (compose_status));
10693 10584
10694#ifdef HAVE_X_I18N 10585#ifdef HAVE_X_I18N
10695 if (FRAME_XIC (f)) 10586 if (FRAME_XIC (f))
10696 { 10587 {
10697 Status status_return; 10588 Status status_return;
10698 10589
10699 coding_system = Vlocale_coding_system; 10590 coding_system = Vlocale_coding_system;
10700 nbytes = XmbLookupString (FRAME_XIC (f), 10591 nbytes = XmbLookupString (FRAME_XIC (f),
10701 &event.xkey, copy_bufptr, 10592 &event.xkey, copy_bufptr,
10702 copy_bufsiz, &keysym, 10593 copy_bufsiz, &keysym,
10703 &status_return); 10594 &status_return);
10704 if (status_return == XBufferOverflow) 10595 if (status_return == XBufferOverflow)
10705 { 10596 {
10706 copy_bufsiz = nbytes + 1; 10597 copy_bufsiz = nbytes + 1;
10707 copy_bufptr = (char *) alloca (copy_bufsiz); 10598 copy_bufptr = (char *) alloca (copy_bufsiz);
10708 nbytes = XmbLookupString (FRAME_XIC (f), 10599 nbytes = XmbLookupString (FRAME_XIC (f),
10709 &event.xkey, copy_bufptr, 10600 &event.xkey, copy_bufptr,
10710 copy_bufsiz, &keysym, 10601 copy_bufsiz, &keysym,
10711 &status_return); 10602 &status_return);
10712 } 10603 }
10713/* Xutf8LookupString is a new but already deprecated interface. -stef */ 10604 /* Xutf8LookupString is a new but already deprecated interface. -stef */
10714#if 0 && defined X_HAVE_UTF8_STRING 10605#if 0 && defined X_HAVE_UTF8_STRING
10715 else if (status_return == XLookupKeySym) 10606 else if (status_return == XLookupKeySym)
10716 { /* Try again but with utf-8. */ 10607 { /* Try again but with utf-8. */
10717 coding_system = Qutf_8; 10608 coding_system = Qutf_8;
10718 nbytes = Xutf8LookupString (FRAME_XIC (f), 10609 nbytes = Xutf8LookupString (FRAME_XIC (f),
10719 &event.xkey, copy_bufptr, 10610 &event.xkey, copy_bufptr,
10720 copy_bufsiz, &keysym, 10611 copy_bufsiz, &keysym,
10721 &status_return); 10612 &status_return);
10722 if (status_return == XBufferOverflow) 10613 if (status_return == XBufferOverflow)
10723 { 10614 {
10724 copy_bufsiz = nbytes + 1; 10615 copy_bufsiz = nbytes + 1;
10725 copy_bufptr = (char *) alloca (copy_bufsiz); 10616 copy_bufptr = (char *) alloca (copy_bufsiz);
10726 nbytes = Xutf8LookupString (FRAME_XIC (f), 10617 nbytes = Xutf8LookupString (FRAME_XIC (f),
10727 &event.xkey, 10618 &event.xkey,
10728 copy_bufptr, 10619 copy_bufptr,
10729 copy_bufsiz, &keysym, 10620 copy_bufsiz, &keysym,
10730 &status_return); 10621 &status_return);
10731 } 10622 }
10732 } 10623 }
10733#endif 10624#endif
10734 10625
10735 if (status_return == XLookupNone) 10626 if (status_return == XLookupNone)
10736 break; 10627 break;
10737 else if (status_return == XLookupChars) 10628 else if (status_return == XLookupChars)
10738 { 10629 {
10739 keysym = NoSymbol; 10630 keysym = NoSymbol;
10740 modifiers = 0; 10631 modifiers = 0;
10741 } 10632 }
10742 else if (status_return != XLookupKeySym 10633 else if (status_return != XLookupKeySym
10743 && status_return != XLookupBoth) 10634 && status_return != XLookupBoth)
10744 abort (); 10635 abort ();
10745 } 10636 }
10746 else 10637 else
10747 nbytes = XLookupString (&event.xkey, copy_bufptr, 10638 nbytes = XLookupString (&event.xkey, copy_bufptr,
10748 copy_bufsiz, &keysym, 10639 copy_bufsiz, &keysym,
10749 &compose_status); 10640 &compose_status);
10750#else 10641#else
10751 nbytes = XLookupString (&event.xkey, copy_bufptr, 10642 nbytes = XLookupString (&event.xkey, copy_bufptr,
10752 copy_bufsiz, &keysym, 10643 copy_bufsiz, &keysym,
10753 &compose_status); 10644 &compose_status);
10754#endif 10645#endif
10755 10646
10756 orig_keysym = keysym; 10647 orig_keysym = keysym;
10757 10648
10758 if (numchars > 1) 10649 if (numchars > 1)
10759 { 10650 {
10760 Lisp_Object c; 10651 Lisp_Object c;
10761 10652
10762 /* First deal with keysyms which have defined 10653 /* First deal with keysyms which have defined
10763 translations to characters. */ 10654 translations to characters. */
10764 if (keysym >= 32 && keysym < 128) 10655 if (keysym >= 32 && keysym < 128)
10765 /* Avoid explicitly decoding each ASCII character. */ 10656 /* Avoid explicitly decoding each ASCII character. */
10766 { 10657 {
10767 bufp->kind = ASCII_KEYSTROKE_EVENT; 10658 bufp->kind = ASCII_KEYSTROKE_EVENT;
10768 bufp->code = keysym; 10659 bufp->code = keysym;
10769 XSETFRAME (bufp->frame_or_window, f); 10660 XSETFRAME (bufp->frame_or_window, f);
10770 bufp->arg = Qnil; 10661 bufp->arg = Qnil;
10771 bufp->modifiers 10662 bufp->modifiers
10772 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 10663 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
10773 modifiers); 10664 modifiers);
10774 bufp->timestamp = event.xkey.time; 10665 bufp->timestamp = event.xkey.time;
10775 bufp++; 10666 bufp++;
10776 count++; 10667 count++;
10777 numchars--; 10668 numchars--;
10778 } 10669 }
10779 /* Now non-ASCII. */ 10670 /* Now non-ASCII. */
10780 else if (HASH_TABLE_P (Vx_keysym_table) 10671 else if (HASH_TABLE_P (Vx_keysym_table)
10781 && (NATNUMP (c = Fgethash (make_number (keysym), 10672 && (NATNUMP (c = Fgethash (make_number (keysym),
10782 Vx_keysym_table, 10673 Vx_keysym_table,
10783 Qnil)))) 10674 Qnil))))
10784 { 10675 {
10785 bufp->kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) 10676 bufp->kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
10786 ? ASCII_KEYSTROKE_EVENT 10677 ? ASCII_KEYSTROKE_EVENT
10787 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 10678 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
10788 bufp->code = XFASTINT (c); 10679 bufp->code = XFASTINT (c);
10789 XSETFRAME (bufp->frame_or_window, f); 10680 XSETFRAME (bufp->frame_or_window, f);
10790 bufp->arg = Qnil; 10681 bufp->arg = Qnil;
10791 bufp->modifiers 10682 bufp->modifiers
10792 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 10683 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
10793 modifiers); 10684 modifiers);
10794 bufp->timestamp = event.xkey.time; 10685 bufp->timestamp = event.xkey.time;
10795 bufp++; 10686 bufp++;
10796 count++; 10687 count++;
10797 numchars--; 10688 numchars--;
10798 } 10689 }
10799 /* Random non-modifier sorts of keysyms. */ 10690 /* Random non-modifier sorts of keysyms. */
10800 else if (((keysym >= XK_BackSpace && keysym <= XK_Escape) 10691 else if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
10801 || keysym == XK_Delete 10692 || keysym == XK_Delete
10802#ifdef XK_ISO_Left_Tab 10693#ifdef XK_ISO_Left_Tab
10803 || (keysym >= XK_ISO_Left_Tab 10694 || (keysym >= XK_ISO_Left_Tab
10804 && keysym <= XK_ISO_Enter) 10695 && keysym <= XK_ISO_Enter)
10805#endif 10696#endif
10806 || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */ 10697 || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
10807 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */ 10698 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
10808#ifdef HPUX 10699#ifdef HPUX
10809 /* This recognizes the "extended function 10700 /* This recognizes the "extended function
10810 keys". It seems there's no cleaner way. 10701 keys". It seems there's no cleaner way.
10811 Test IsModifierKey to avoid handling 10702 Test IsModifierKey to avoid handling
10812 mode_switch incorrectly. */ 10703 mode_switch incorrectly. */
10813 || ((unsigned) (keysym) >= XK_Select 10704 || ((unsigned) (keysym) >= XK_Select
10814 && (unsigned)(keysym) < XK_KP_Space) 10705 && (unsigned)(keysym) < XK_KP_Space)
10815#endif 10706#endif
10816#ifdef XK_dead_circumflex 10707#ifdef XK_dead_circumflex
10817 || orig_keysym == XK_dead_circumflex 10708 || orig_keysym == XK_dead_circumflex
10818#endif 10709#endif
10819#ifdef XK_dead_grave 10710#ifdef XK_dead_grave
10820 || orig_keysym == XK_dead_grave 10711 || orig_keysym == XK_dead_grave
10821#endif 10712#endif
10822#ifdef XK_dead_tilde 10713#ifdef XK_dead_tilde
10823 || orig_keysym == XK_dead_tilde 10714 || orig_keysym == XK_dead_tilde
10824#endif 10715#endif
10825#ifdef XK_dead_diaeresis 10716#ifdef XK_dead_diaeresis
10826 || orig_keysym == XK_dead_diaeresis 10717 || orig_keysym == XK_dead_diaeresis
10827#endif 10718#endif
10828#ifdef XK_dead_macron 10719#ifdef XK_dead_macron
10829 || orig_keysym == XK_dead_macron 10720 || orig_keysym == XK_dead_macron
10830#endif 10721#endif
10831#ifdef XK_dead_degree 10722#ifdef XK_dead_degree
10832 || orig_keysym == XK_dead_degree 10723 || orig_keysym == XK_dead_degree
10833#endif 10724#endif
10834#ifdef XK_dead_acute 10725#ifdef XK_dead_acute
10835 || orig_keysym == XK_dead_acute 10726 || orig_keysym == XK_dead_acute
10836#endif 10727#endif
10837#ifdef XK_dead_cedilla 10728#ifdef XK_dead_cedilla
10838 || orig_keysym == XK_dead_cedilla 10729 || orig_keysym == XK_dead_cedilla
10839#endif 10730#endif
10840#ifdef XK_dead_breve 10731#ifdef XK_dead_breve
10841 || orig_keysym == XK_dead_breve 10732 || orig_keysym == XK_dead_breve
10842#endif 10733#endif
10843#ifdef XK_dead_ogonek 10734#ifdef XK_dead_ogonek
10844 || orig_keysym == XK_dead_ogonek 10735 || orig_keysym == XK_dead_ogonek
10845#endif 10736#endif
10846#ifdef XK_dead_caron 10737#ifdef XK_dead_caron
10847 || orig_keysym == XK_dead_caron 10738 || orig_keysym == XK_dead_caron
10848#endif 10739#endif
10849#ifdef XK_dead_doubleacute 10740#ifdef XK_dead_doubleacute
10850 || orig_keysym == XK_dead_doubleacute 10741 || orig_keysym == XK_dead_doubleacute
10851#endif 10742#endif
10852#ifdef XK_dead_abovedot 10743#ifdef XK_dead_abovedot
10853 || orig_keysym == XK_dead_abovedot 10744 || orig_keysym == XK_dead_abovedot
10854#endif 10745#endif
10855 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ 10746 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
10856 || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */ 10747 || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
10857 /* Any "vendor-specific" key is ok. */ 10748 /* Any "vendor-specific" key is ok. */
10858 || (orig_keysym & (1 << 28)) 10749 || (orig_keysym & (1 << 28))
10859 || (keysym != NoSymbol && nbytes == 0)) 10750 || (keysym != NoSymbol && nbytes == 0))
10860 && ! (IsModifierKey (orig_keysym) 10751 && ! (IsModifierKey (orig_keysym)
10861#ifndef HAVE_X11R5 10752#ifndef HAVE_X11R5
10862#ifdef XK_Mode_switch 10753#ifdef XK_Mode_switch
10863 || ((unsigned)(orig_keysym) == XK_Mode_switch) 10754 || ((unsigned)(orig_keysym) == XK_Mode_switch)
10864#endif 10755#endif
10865#ifdef XK_Num_Lock 10756#ifdef XK_Num_Lock
10866 || ((unsigned)(orig_keysym) == XK_Num_Lock) 10757 || ((unsigned)(orig_keysym) == XK_Num_Lock)
10867#endif 10758#endif
10868#endif /* not HAVE_X11R5 */ 10759#endif /* not HAVE_X11R5 */
10869 /* The symbols from XK_ISO_Lock 10760 /* The symbols from XK_ISO_Lock
10870 to XK_ISO_Last_Group_Lock 10761 to XK_ISO_Last_Group_Lock
10871 don't have real modifiers but 10762 don't have real modifiers but
10872 should be treated similarly to 10763 should be treated similarly to
10873 Mode_switch by Emacs. */ 10764 Mode_switch by Emacs. */
10874#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock 10765#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
10875 || ((unsigned)(orig_keysym) 10766 || ((unsigned)(orig_keysym)
10876 >= XK_ISO_Lock 10767 >= XK_ISO_Lock
10877 && (unsigned)(orig_keysym) 10768 && (unsigned)(orig_keysym)
10878 <= XK_ISO_Last_Group_Lock) 10769 <= XK_ISO_Last_Group_Lock)
10879#endif 10770#endif
10880 )) 10771 ))
10881 { 10772 {
10882 if (temp_index == sizeof temp_buffer / sizeof (short)) 10773 if (temp_index == sizeof temp_buffer / sizeof (short))
10883 temp_index = 0; 10774 temp_index = 0;
10884 temp_buffer[temp_index++] = keysym; 10775 temp_buffer[temp_index++] = keysym;
10885 /* make_lispy_event will convert this to a symbolic 10776 /* make_lispy_event will convert this to a symbolic
10886 key. */ 10777 key. */
10887 bufp->kind = NON_ASCII_KEYSTROKE_EVENT; 10778 bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
10888 bufp->code = keysym; 10779 bufp->code = keysym;
10889 XSETFRAME (bufp->frame_or_window, f); 10780 XSETFRAME (bufp->frame_or_window, f);
10890 bufp->arg = Qnil; 10781 bufp->arg = Qnil;
10891 bufp->modifiers 10782 bufp->modifiers
10892 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 10783 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
10893 modifiers); 10784 modifiers);
10894 bufp->timestamp = event.xkey.time; 10785 bufp->timestamp = event.xkey.time;
10895 bufp++; 10786 bufp++;
10896 count++; 10787 count++;
10897 numchars--; 10788 numchars--;
10898 } 10789 }
10899 else if (numchars > nbytes) 10790 else if (numchars > nbytes)
10900 { /* Raw bytes, not keysym. */ 10791 { /* Raw bytes, not keysym. */
10901 register int i; 10792 register int i;
10902 register int c; 10793 register int c;
10903 int nchars, len; 10794 int nchars, len;
10904 10795
10905 /* The input should be decoded with `coding_system' 10796 /* The input should be decoded with `coding_system'
10906 which depends on which X*LookupString function 10797 which depends on which X*LookupString function
10907 we used just above and the locale. */ 10798 we used just above and the locale. */
10908 setup_coding_system (coding_system, &coding); 10799 setup_coding_system (coding_system, &coding);
10909 coding.src_multibyte = 0; 10800 coding.src_multibyte = 0;
10910 coding.dst_multibyte = 1; 10801 coding.dst_multibyte = 1;
10911 /* The input is converted to events, thus we can't 10802 /* The input is converted to events, thus we can't
10912 handle composition. Anyway, there's no XIM that 10803 handle composition. Anyway, there's no XIM that
10913 gives us composition information. */ 10804 gives us composition information. */
10914 coding.composing = COMPOSITION_DISABLED; 10805 coding.composing = COMPOSITION_DISABLED;
10915 10806
10916 for (i = 0; i < nbytes; i++) 10807 for (i = 0; i < nbytes; i++)
10917 { 10808 {
10918 if (temp_index == (sizeof temp_buffer 10809 if (temp_index == (sizeof temp_buffer
10919 / sizeof (short))) 10810 / sizeof (short)))
10920 temp_index = 0; 10811 temp_index = 0;
10921 temp_buffer[temp_index++] = copy_bufptr[i]; 10812 temp_buffer[temp_index++] = copy_bufptr[i];
10922 } 10813 }
10923 10814
10924 { 10815 {
10925 /* Decode the input data. */ 10816 /* Decode the input data. */
10926 int require; 10817 int require;
10927 unsigned char *p; 10818 unsigned char *p;
10928 10819
10929 require = decoding_buffer_size (&coding, nbytes); 10820 require = decoding_buffer_size (&coding, nbytes);
10930 p = (unsigned char *) alloca (require); 10821 p = (unsigned char *) alloca (require);
10931 coding.mode |= CODING_MODE_LAST_BLOCK; 10822 coding.mode |= CODING_MODE_LAST_BLOCK;
10932 /* We explicitely disable composition 10823 /* We explicitely disable composition
10933 handling because key data should 10824 handling because key data should
10934 not contain any composition 10825 not contain any composition
10935 sequence. */ 10826 sequence. */
10936 coding.composing = COMPOSITION_DISABLED; 10827 coding.composing = COMPOSITION_DISABLED;
10937 decode_coding (&coding, copy_bufptr, p, 10828 decode_coding (&coding, copy_bufptr, p,
10938 nbytes, require); 10829 nbytes, require);
10939 nbytes = coding.produced; 10830 nbytes = coding.produced;
10940 nchars = coding.produced_char; 10831 nchars = coding.produced_char;
10941 copy_bufptr = p; 10832 copy_bufptr = p;
10942 } 10833 }
10943 10834
10944 /* Convert the input data to a sequence of 10835 /* Convert the input data to a sequence of
10945 character events. */ 10836 character events. */
10946 for (i = 0; i < nbytes; i += len) 10837 for (i = 0; i < nbytes; i += len)
10947 { 10838 {
10948 if (nchars == nbytes) 10839 if (nchars == nbytes)
10949 c = copy_bufptr[i], len = 1; 10840 c = copy_bufptr[i], len = 1;
10950 else 10841 else
10951 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, 10842 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
10952 nbytes - i, len); 10843 nbytes - i, len);
10953 10844
10954 bufp->kind = (SINGLE_BYTE_CHAR_P (c) 10845 bufp->kind = (SINGLE_BYTE_CHAR_P (c)
10955 ? ASCII_KEYSTROKE_EVENT 10846 ? ASCII_KEYSTROKE_EVENT
10956 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 10847 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
10957 bufp->code = c; 10848 bufp->code = c;
10958 XSETFRAME (bufp->frame_or_window, f); 10849 XSETFRAME (bufp->frame_or_window, f);
10959 bufp->arg = Qnil; 10850 bufp->arg = Qnil;
10960 bufp->modifiers 10851 bufp->modifiers
10961 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 10852 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
10962 modifiers); 10853 modifiers);
10963 bufp->timestamp = event.xkey.time; 10854 bufp->timestamp = event.xkey.time;
10964 bufp++; 10855 bufp++;
10965 } 10856 }
10966 10857
10967 count += nchars; 10858 count += nchars;
10968 numchars -= nchars; 10859 numchars -= nchars;
10969 10860
10970 if (keysym == NoSymbol) 10861 if (keysym == NoSymbol)
10971 break; 10862 break;
10972 } 10863 }
10973 else 10864 else
10974 abort (); 10865 abort ();
10975 } 10866 }
10976 else 10867 else
10977 abort (); 10868 abort ();
10978 } 10869 }
10979#ifdef HAVE_X_I18N 10870#ifdef HAVE_X_I18N
10980 /* Don't dispatch this event since XtDispatchEvent calls 10871 /* Don't dispatch this event since XtDispatchEvent calls
10981 XFilterEvent, and two calls in a row may freeze the 10872 XFilterEvent, and two calls in a row may freeze the
10982 client. */ 10873 client. */
10983 break; 10874 break;
10984#else 10875#else
10985 goto OTHER; 10876 goto OTHER;
10986#endif 10877#endif
10987 10878
10988 case KeyRelease: 10879 case KeyRelease:
10989#ifdef HAVE_X_I18N 10880#ifdef HAVE_X_I18N
10990 /* Don't dispatch this event since XtDispatchEvent calls 10881 /* Don't dispatch this event since XtDispatchEvent calls
10991 XFilterEvent, and two calls in a row may freeze the 10882 XFilterEvent, and two calls in a row may freeze the
10992 client. */ 10883 client. */
10993 break; 10884 break;
10994#else 10885#else
10995 goto OTHER; 10886 goto OTHER;
10996#endif 10887#endif
10997 10888
10998 case EnterNotify: 10889 case EnterNotify:
10999 { 10890 {
11000 int n; 10891 int n;
11001 10892
11002 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); 10893 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
11003 if (n > 0) 10894 if (n > 0)
11004 { 10895 {
11005 bufp += n, count += n, numchars -= n; 10896 bufp += n, count += n, numchars -= n;
11006 } 10897 }
11007 10898
11008 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); 10899 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
11009 10900
11010#if 0 10901#if 0
11011 if (event.xcrossing.focus) 10902 if (event.xcrossing.focus)
11012 { 10903 {
11013 /* Avoid nasty pop/raise loops. */ 10904 /* Avoid nasty pop/raise loops. */
11014 if (f && (!(f->auto_raise) 10905 if (f && (!(f->auto_raise)
11015 || !(f->auto_lower) 10906 || !(f->auto_lower)
11016 || (event.xcrossing.time - enter_timestamp) > 500)) 10907 || (event.xcrossing.time - enter_timestamp) > 500))
11017 {
11018 x_new_focus_frame (dpyinfo, f);
11019 enter_timestamp = event.xcrossing.time;
11020 }
11021 }
11022 else if (f == dpyinfo->x_focus_frame)
11023 x_new_focus_frame (dpyinfo, 0);
11024#endif
11025
11026 /* EnterNotify counts as mouse movement,
11027 so update things that depend on mouse position. */
11028 if (f && !f->output_data.x->hourglass_p)
11029 note_mouse_movement (f, &event.xmotion);
11030 goto OTHER;
11031 }
11032
11033 case FocusIn:
11034 { 10908 {
11035 int n; 10909 x_new_focus_frame (dpyinfo, f);
11036 10910 enter_timestamp = event.xcrossing.time;
11037 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
11038 if (n > 0)
11039 {
11040 bufp += n, count += n, numchars -= n;
11041 }
11042 } 10911 }
10912 }
10913 else if (f == dpyinfo->x_focus_frame)
10914 x_new_focus_frame (dpyinfo, 0);
10915#endif
11043 10916
11044 goto OTHER; 10917 /* EnterNotify counts as mouse movement,
10918 so update things that depend on mouse position. */
10919 if (f && !f->output_data.x->hourglass_p)
10920 note_mouse_movement (f, &event.xmotion);
10921 goto OTHER;
10922 }
11045 10923
11046 case LeaveNotify: 10924 case FocusIn:
11047 { 10925 {
11048 int n; 10926 int n;
11049 10927
11050 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); 10928 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
11051 if (n > 0) 10929 if (n > 0)
11052 { 10930 {
11053 bufp += n, count += n, numchars -= n; 10931 bufp += n, count += n, numchars -= n;
11054 } 10932 }
11055 } 10933 }
11056 10934
11057 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); 10935 goto OTHER;
11058 if (f)
11059 {
11060 if (f == dpyinfo->mouse_face_mouse_frame)
11061 {
11062 /* If we move outside the frame, then we're
11063 certainly no longer on any text in the frame. */
11064 clear_mouse_face (dpyinfo);
11065 dpyinfo->mouse_face_mouse_frame = 0;
11066 }
11067 10936
11068 /* Generate a nil HELP_EVENT to cancel a help-echo. 10937 case LeaveNotify:
11069 Do it only if there's something to cancel. 10938 {
11070 Otherwise, the startup message is cleared when 10939 int n;
11071 the mouse leaves the frame. */
11072 if (any_help_event_p)
11073 {
11074 Lisp_Object frame;
11075 int n;
11076
11077 XSETFRAME (frame, f);
11078 help_echo = Qnil;
11079 n = gen_help_event (bufp, numchars,
11080 Qnil, frame, Qnil, Qnil, 0);
11081 bufp += n, count += n, numchars -= n;
11082 }
11083 10940
11084 } 10941 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
11085 goto OTHER; 10942 if (n > 0)
10943 {
10944 bufp += n, count += n, numchars -= n;
10945 }
10946 }
11086 10947
11087 case FocusOut: 10948 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
11088 { 10949 if (f)
11089 int n; 10950 {
10951 if (f == dpyinfo->mouse_face_mouse_frame)
10952 {
10953 /* If we move outside the frame, then we're
10954 certainly no longer on any text in the frame. */
10955 clear_mouse_face (dpyinfo);
10956 dpyinfo->mouse_face_mouse_frame = 0;
10957 }
11090 10958
11091 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); 10959 /* Generate a nil HELP_EVENT to cancel a help-echo.
11092 if (n > 0) 10960 Do it only if there's something to cancel.
11093 { 10961 Otherwise, the startup message is cleared when
11094 bufp += n, count += n, numchars -= n; 10962 the mouse leaves the frame. */
11095 } 10963 if (any_help_event_p)
11096 } 10964 {
10965 Lisp_Object frame;
10966 int n;
10967
10968 XSETFRAME (frame, f);
10969 help_echo = Qnil;
10970 n = gen_help_event (bufp, numchars,
10971 Qnil, frame, Qnil, Qnil, 0);
10972 bufp += n, count += n, numchars -= n;
10973 }
11097 10974
11098 goto OTHER; 10975 }
10976 goto OTHER;
11099 10977
11100 case MotionNotify: 10978 case FocusOut:
11101 { 10979 {
11102 previous_help_echo = help_echo; 10980 int n;
11103 help_echo = help_echo_object = help_echo_window = Qnil;
11104 help_echo_pos = -1;
11105 10981
11106 if (dpyinfo->grabbed && last_mouse_frame 10982 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
11107 && FRAME_LIVE_P (last_mouse_frame)) 10983 if (n > 0)
11108 f = last_mouse_frame; 10984 {
11109 else 10985 bufp += n, count += n, numchars -= n;
11110 f = x_window_to_frame (dpyinfo, event.xmotion.window); 10986 }
10987 }
11111 10988
11112 if (dpyinfo->mouse_face_hidden) 10989 goto OTHER;
11113 {
11114 dpyinfo->mouse_face_hidden = 0;
11115 clear_mouse_face (dpyinfo);
11116 }
11117 10990
11118 if (f) 10991 case MotionNotify:
11119 { 10992 {
11120 10993 previous_help_echo = help_echo;
11121 /* Generate SELECT_WINDOW_EVENTs when needed. */ 10994 help_echo = help_echo_object = help_echo_window = Qnil;
11122 if (mouse_autoselect_window) 10995 help_echo_pos = -1;
11123 { 10996
11124 Lisp_Object window; 10997 if (dpyinfo->grabbed && last_mouse_frame
11125 int area; 10998 && FRAME_LIVE_P (last_mouse_frame))
11126 10999 f = last_mouse_frame;
11127 window = window_from_coordinates (f, 11000 else
11128 event.xmotion.x, event.xmotion.y, 11001 f = x_window_to_frame (dpyinfo, event.xmotion.window);
11129 &area, 0); 11002
11130 11003 if (dpyinfo->mouse_face_hidden)
11131 /* Window will be selected only when it is not selected now and 11004 {
11132 last mouse movement event was not in it. Minibuffer window 11005 dpyinfo->mouse_face_hidden = 0;
11133 will be selected iff it is active. */ 11006 clear_mouse_face (dpyinfo);
11134 if (WINDOWP(window) 11007 }
11135 && !EQ (window, last_window) 11008
11136 && !EQ (window, selected_window) 11009 if (f)
11137 && numchars > 0) 11010 {
11138 { 11011
11139 bufp->kind = SELECT_WINDOW_EVENT; 11012 /* Generate SELECT_WINDOW_EVENTs when needed. */
11140 bufp->frame_or_window = window; 11013 if (mouse_autoselect_window)
11141 bufp->arg = Qnil; 11014 {
11142 ++bufp, ++count, --numchars; 11015 Lisp_Object window;
11143 } 11016 int area;
11017
11018 window = window_from_coordinates (f,
11019 event.xmotion.x, event.xmotion.y,
11020 &area, 0);
11021
11022 /* Window will be selected only when it is not selected now and
11023 last mouse movement event was not in it. Minibuffer window
11024 will be selected iff it is active. */
11025 if (WINDOWP(window)
11026 && !EQ (window, last_window)
11027 && !EQ (window, selected_window)
11028 && numchars > 0)
11029 {
11030 bufp->kind = SELECT_WINDOW_EVENT;
11031 bufp->frame_or_window = window;
11032 bufp->arg = Qnil;
11033 ++bufp, ++count, --numchars;
11034 }
11144 11035
11145 last_window=window; 11036 last_window=window;
11146 } 11037 }
11147 note_mouse_movement (f, &event.xmotion); 11038 note_mouse_movement (f, &event.xmotion);
11148 } 11039 }
11149 else 11040 else
11150 { 11041 {
11151#ifndef USE_TOOLKIT_SCROLL_BARS 11042#ifndef USE_TOOLKIT_SCROLL_BARS
11152 struct scroll_bar *bar 11043 struct scroll_bar *bar
11153 = x_window_to_scroll_bar (event.xmotion.window); 11044 = x_window_to_scroll_bar (event.xmotion.window);
11154 11045
11155 if (bar) 11046 if (bar)
11156 x_scroll_bar_note_movement (bar, &event); 11047 x_scroll_bar_note_movement (bar, &event);
11157#endif /* USE_TOOLKIT_SCROLL_BARS */ 11048#endif /* USE_TOOLKIT_SCROLL_BARS */
11158 11049
11159 /* If we move outside the frame, then we're 11050 /* If we move outside the frame, then we're
11160 certainly no longer on any text in the frame. */ 11051 certainly no longer on any text in the frame. */
11161 clear_mouse_face (dpyinfo); 11052 clear_mouse_face (dpyinfo);
11162 } 11053 }
11163 11054
11164 /* If the contents of the global variable help_echo 11055 /* If the contents of the global variable help_echo
11165 has changed, generate a HELP_EVENT. */ 11056 has changed, generate a HELP_EVENT. */
11166 if (!NILP (help_echo) 11057 if (!NILP (help_echo)
11167 || !NILP (previous_help_echo)) 11058 || !NILP (previous_help_echo))
11168 { 11059 {
11169 Lisp_Object frame; 11060 Lisp_Object frame;
11170 int n; 11061 int n;
11171 11062
11172 if (f) 11063 if (f)
11173 XSETFRAME (frame, f); 11064 XSETFRAME (frame, f);
11174 else 11065 else
11175 frame = Qnil; 11066 frame = Qnil;
11176 11067
11177 any_help_event_p = 1; 11068 any_help_event_p = 1;
11178 n = gen_help_event (bufp, numchars, help_echo, frame, 11069 n = gen_help_event (bufp, numchars, help_echo, frame,
11179 help_echo_window, help_echo_object, 11070 help_echo_window, help_echo_object,
11180 help_echo_pos); 11071 help_echo_pos);
11181 bufp += n, count += n, numchars -= n; 11072 bufp += n, count += n, numchars -= n;
11182 } 11073 }
11183 11074
11184 goto OTHER; 11075 goto OTHER;
11185 } 11076 }
11186 11077
11187 case ConfigureNotify: 11078 case ConfigureNotify:
11188 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window); 11079 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
11189 if (f) 11080 if (f)
11190 { 11081 {
11191#ifndef USE_X_TOOLKIT 11082#ifndef USE_X_TOOLKIT
11192 /* If there is a pending resize for fullscreen, don't 11083 /* If there is a pending resize for fullscreen, don't
11193 do this one, the right one will come later. 11084 do this one, the right one will come later.
11194 The toolkit version doesn't seem to need this, but we 11085 The toolkit version doesn't seem to need this, but we
11195 need to reset it below. */ 11086 need to reset it below. */
11196 int dont_resize = 11087 int dont_resize =
11197 ((f->output_data.x->want_fullscreen & FULLSCREEN_WAIT) 11088 ((f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
11198 && FRAME_NEW_WIDTH (f) != 0); 11089 && FRAME_NEW_WIDTH (f) != 0);
11199 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height); 11090 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
11200 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width); 11091 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
11201 if (dont_resize) 11092 if (dont_resize)
11202 goto OTHER; 11093 goto OTHER;
11203 11094
11204 /* In the toolkit version, change_frame_size 11095 /* In the toolkit version, change_frame_size
11205 is called by the code that handles resizing 11096 is called by the code that handles resizing
11206 of the EmacsFrame widget. */ 11097 of the EmacsFrame widget. */
11207 11098
11208 /* Even if the number of character rows and columns has 11099 /* Even if the number of character rows and columns has
11209 not changed, the font size may have changed, so we need 11100 not changed, the font size may have changed, so we need
11210 to check the pixel dimensions as well. */ 11101 to check the pixel dimensions as well. */
11211 if (columns != f->width 11102 if (columns != f->width
11212 || rows != f->height 11103 || rows != f->height
11213 || event.xconfigure.width != f->output_data.x->pixel_width 11104 || event.xconfigure.width != f->output_data.x->pixel_width
11214 || event.xconfigure.height != f->output_data.x->pixel_height) 11105 || event.xconfigure.height != f->output_data.x->pixel_height)
11215 { 11106 {
11216 change_frame_size (f, rows, columns, 0, 1, 0); 11107 change_frame_size (f, rows, columns, 0, 1, 0);
11217 SET_FRAME_GARBAGED (f); 11108 SET_FRAME_GARBAGED (f);
11218 cancel_mouse_face (f); 11109 cancel_mouse_face (f);
11219 } 11110 }
11220#endif 11111#endif
11221 11112
11222 f->output_data.x->pixel_width = event.xconfigure.width; 11113 f->output_data.x->pixel_width = event.xconfigure.width;
11223 f->output_data.x->pixel_height = event.xconfigure.height; 11114 f->output_data.x->pixel_height = event.xconfigure.height;
11224 11115
11225 /* What we have now is the position of Emacs's own window. 11116 /* What we have now is the position of Emacs's own window.
11226 Convert that to the position of the window manager window. */ 11117 Convert that to the position of the window manager window. */
11227 x_real_positions (f, &f->output_data.x->left_pos, 11118 x_real_positions (f, &f->output_data.x->left_pos,
11228 &f->output_data.x->top_pos); 11119 &f->output_data.x->top_pos);
11229 11120
11230 x_check_fullscreen_move(f); 11121 x_check_fullscreen_move(f);
11231 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT) 11122 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
11232 f->output_data.x->want_fullscreen &= 11123 f->output_data.x->want_fullscreen &=
11233 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); 11124 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
11234#ifdef HAVE_X_I18N 11125#ifdef HAVE_X_I18N
11235 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) 11126 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
11236 xic_set_statusarea (f); 11127 xic_set_statusarea (f);
11237#endif 11128#endif
11238 11129
11239 if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window) 11130 if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
11240 { 11131 {
11241 /* Since the WM decorations come below top_pos now, 11132 /* Since the WM decorations come below top_pos now,
11242 we must put them below top_pos in the future. */ 11133 we must put them below top_pos in the future. */
11243 f->output_data.x->win_gravity = NorthWestGravity; 11134 f->output_data.x->win_gravity = NorthWestGravity;
11244 x_wm_set_size_hint (f, (long) 0, 0); 11135 x_wm_set_size_hint (f, (long) 0, 0);
11245 } 11136 }
11246 } 11137 }
11247 goto OTHER; 11138 goto OTHER;
11248 11139
11249 case ButtonPress: 11140 case ButtonPress:
11250 case ButtonRelease: 11141 case ButtonRelease:
11251 { 11142 {
11252 /* If we decide we want to generate an event to be seen 11143 /* If we decide we want to generate an event to be seen
11253 by the rest of Emacs, we put it here. */ 11144 by the rest of Emacs, we put it here. */
11254 struct input_event emacs_event; 11145 struct input_event emacs_event;
11255 int tool_bar_p = 0; 11146 int tool_bar_p = 0;
11256 11147
11257 emacs_event.kind = NO_EVENT; 11148 emacs_event.kind = NO_EVENT;
11258 bzero (&compose_status, sizeof (compose_status)); 11149 bzero (&compose_status, sizeof (compose_status));
11259 11150
11260 if (dpyinfo->grabbed 11151 if (dpyinfo->grabbed
11261 && last_mouse_frame 11152 && last_mouse_frame
11262 && FRAME_LIVE_P (last_mouse_frame)) 11153 && FRAME_LIVE_P (last_mouse_frame))
11263 f = last_mouse_frame; 11154 f = last_mouse_frame;
11264 else 11155 else
11265 f = x_window_to_frame (dpyinfo, event.xbutton.window); 11156 f = x_window_to_frame (dpyinfo, event.xbutton.window);
11266 11157
11267 if (f) 11158 if (f)
11268 { 11159 {
11269 /* Is this in the tool-bar? */ 11160 /* Is this in the tool-bar? */
11270 if (WINDOWP (f->tool_bar_window) 11161 if (WINDOWP (f->tool_bar_window)
11271 && XFASTINT (XWINDOW (f->tool_bar_window)->height)) 11162 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
11272 { 11163 {
11273 Lisp_Object window; 11164 Lisp_Object window;
11274 int p, x, y; 11165 int p, x, y;
11275 11166
11276 x = event.xbutton.x; 11167 x = event.xbutton.x;
11277 y = event.xbutton.y; 11168 y = event.xbutton.y;
11278 11169
11279 /* Set x and y. */ 11170 /* Set x and y. */
11280 window = window_from_coordinates (f, x, y, &p, 1); 11171 window = window_from_coordinates (f, x, y, &p, 1);
11281 if (EQ (window, f->tool_bar_window)) 11172 if (EQ (window, f->tool_bar_window))
11282 { 11173 {
11283 x_handle_tool_bar_click (f, &event.xbutton); 11174 x_handle_tool_bar_click (f, &event.xbutton);
11284 tool_bar_p = 1; 11175 tool_bar_p = 1;
11285 } 11176 }
11286 } 11177 }
11287 11178
11288 if (!tool_bar_p) 11179 if (!tool_bar_p)
11289 if (!dpyinfo->x_focus_frame 11180 if (!dpyinfo->x_focus_frame
11290 || f == dpyinfo->x_focus_frame) 11181 || f == dpyinfo->x_focus_frame)
11291 construct_mouse_click (&emacs_event, &event, f); 11182 construct_mouse_click (&emacs_event, &event, f);
11292 } 11183 }
11293 else 11184 else
11294 { 11185 {
11295#ifndef USE_TOOLKIT_SCROLL_BARS 11186#ifndef USE_TOOLKIT_SCROLL_BARS
11296 struct scroll_bar *bar 11187 struct scroll_bar *bar
11297 = x_window_to_scroll_bar (event.xbutton.window); 11188 = x_window_to_scroll_bar (event.xbutton.window);
11298 11189
11299 if (bar) 11190 if (bar)
11300 x_scroll_bar_handle_click (bar, &event, &emacs_event); 11191 x_scroll_bar_handle_click (bar, &event, &emacs_event);
11301#endif /* not USE_TOOLKIT_SCROLL_BARS */ 11192#endif /* not USE_TOOLKIT_SCROLL_BARS */
11302 } 11193 }
11303 11194
11304 if (event.type == ButtonPress) 11195 if (event.type == ButtonPress)
11305 { 11196 {
11306 dpyinfo->grabbed |= (1 << event.xbutton.button); 11197 dpyinfo->grabbed |= (1 << event.xbutton.button);
11307 last_mouse_frame = f; 11198 last_mouse_frame = f;
11308 /* Ignore any mouse motion that happened 11199 /* Ignore any mouse motion that happened
11309 before this event; any subsequent mouse-movement 11200 before this event; any subsequent mouse-movement
11310 Emacs events should reflect only motion after 11201 Emacs events should reflect only motion after
11311 the ButtonPress. */ 11202 the ButtonPress. */
11312 if (f != 0) 11203 if (f != 0)
11313 f->mouse_moved = 0; 11204 f->mouse_moved = 0;
11314 11205
11315 if (!tool_bar_p) 11206 if (!tool_bar_p)
11316 last_tool_bar_item = -1; 11207 last_tool_bar_item = -1;
11317 } 11208 }
11318 else 11209 else
11319 { 11210 {
11320 dpyinfo->grabbed &= ~(1 << event.xbutton.button); 11211 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
11321 } 11212 }
11322 11213
11323 if (numchars >= 1 && emacs_event.kind != NO_EVENT) 11214 if (numchars >= 1 && emacs_event.kind != NO_EVENT)
11324 { 11215 {
11325 bcopy (&emacs_event, bufp, sizeof (struct input_event)); 11216 bcopy (&emacs_event, bufp, sizeof (struct input_event));
11326 bufp++; 11217 bufp++;
11327 count++; 11218 count++;
11328 numchars--; 11219 numchars--;
11329 } 11220 }
11330 11221
11331#ifdef USE_X_TOOLKIT 11222#ifdef USE_X_TOOLKIT
11332 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window); 11223 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
11333 /* For a down-event in the menu bar, 11224 /* For a down-event in the menu bar,
11334 don't pass it to Xt right now. 11225 don't pass it to Xt right now.
11335 Instead, save it away 11226 Instead, save it away
11336 and we will pass it to Xt from kbd_buffer_get_event. 11227 and we will pass it to Xt from kbd_buffer_get_event.
11337 That way, we can run some Lisp code first. */ 11228 That way, we can run some Lisp code first. */
11338 if (f && event.type == ButtonPress 11229 if (f && event.type == ButtonPress
11339 /* Verify the event is really within the menu bar 11230 /* Verify the event is really within the menu bar
11340 and not just sent to it due to grabbing. */ 11231 and not just sent to it due to grabbing. */
11341 && event.xbutton.x >= 0 11232 && event.xbutton.x >= 0
11342 && event.xbutton.x < f->output_data.x->pixel_width 11233 && event.xbutton.x < f->output_data.x->pixel_width
11343 && event.xbutton.y >= 0 11234 && event.xbutton.y >= 0
11344 && event.xbutton.y < f->output_data.x->menubar_height 11235 && event.xbutton.y < f->output_data.x->menubar_height
11345 && event.xbutton.same_screen) 11236 && event.xbutton.same_screen)
11346 { 11237 {
11347 SET_SAVED_BUTTON_EVENT; 11238 SET_SAVED_BUTTON_EVENT;
11348 XSETFRAME (last_mouse_press_frame, f); 11239 XSETFRAME (last_mouse_press_frame, f);
11349 } 11240 }
11350 else if (event.type == ButtonPress) 11241 else if (event.type == ButtonPress)
11351 { 11242 {
11352 last_mouse_press_frame = Qnil; 11243 last_mouse_press_frame = Qnil;
11353 goto OTHER; 11244 goto OTHER;
11354 } 11245 }
11355 11246
11356#ifdef USE_MOTIF /* This should do not harm for Lucid, 11247#ifdef USE_MOTIF /* This should do not harm for Lucid,
11357 but I am trying to be cautious. */ 11248 but I am trying to be cautious. */
11358 else if (event.type == ButtonRelease) 11249 else if (event.type == ButtonRelease)
11359 { 11250 {
11360 if (!NILP (last_mouse_press_frame)) 11251 if (!NILP (last_mouse_press_frame))
11361 { 11252 {
11362 f = XFRAME (last_mouse_press_frame); 11253 f = XFRAME (last_mouse_press_frame);
11363 if (f->output_data.x) 11254 if (f->output_data.x)
11364 SET_SAVED_BUTTON_EVENT; 11255 SET_SAVED_BUTTON_EVENT;
11365 } 11256 }
11366 else 11257 else
11367 goto OTHER; 11258 goto OTHER;
11368 } 11259 }
11369#endif /* USE_MOTIF */ 11260#endif /* USE_MOTIF */
11370 else 11261 else
11371 goto OTHER; 11262 goto OTHER;
11372#endif /* USE_X_TOOLKIT */ 11263#endif /* USE_X_TOOLKIT */
11373 } 11264 }
11374 break; 11265 break;
11375 11266
11376 case CirculateNotify: 11267 case CirculateNotify:
11377 goto OTHER; 11268 goto OTHER;
11378 11269
11379 case CirculateRequest: 11270 case CirculateRequest:
11380 goto OTHER; 11271 goto OTHER;
11381 11272
11382 case VisibilityNotify: 11273 case VisibilityNotify:
11383 goto OTHER; 11274 goto OTHER;
11384 11275
11385 case MappingNotify: 11276 case MappingNotify:
11386 /* Someone has changed the keyboard mapping - update the 11277 /* Someone has changed the keyboard mapping - update the
11387 local cache. */ 11278 local cache. */
11388 switch (event.xmapping.request) 11279 switch (event.xmapping.request)
11389 { 11280 {
11390 case MappingModifier: 11281 case MappingModifier:
11391 x_find_modifier_meanings (dpyinfo); 11282 x_find_modifier_meanings (dpyinfo);
11392 /* This is meant to fall through. */ 11283 /* This is meant to fall through. */
11393 case MappingKeyboard: 11284 case MappingKeyboard:
11394 XRefreshKeyboardMapping (&event.xmapping); 11285 XRefreshKeyboardMapping (&event.xmapping);
11395 } 11286 }
11396 goto OTHER; 11287 goto OTHER;
11397 11288
11398 default: 11289 default:
11399 OTHER: 11290 OTHER:
11400#ifdef USE_X_TOOLKIT 11291#ifdef USE_X_TOOLKIT
11401 BLOCK_INPUT; 11292 BLOCK_INPUT;
11402 XtDispatchEvent (&event); 11293 XtDispatchEvent (&event);
11403 UNBLOCK_INPUT; 11294 UNBLOCK_INPUT;
11404#endif /* USE_X_TOOLKIT */ 11295#endif /* USE_X_TOOLKIT */
11405 break; 11296 break;
11406 } 11297 }
11298
11299 goto ret;
11300
11301 out:
11302 *finish = X_EVENT_GOTO_OUT;
11303
11304 ret:
11305 *bufp_r = bufp;
11306 *numcharsp = numchars;
11307 *eventp = event;
11308
11309 return count;
11310}
11311
11312
11313/* Handles the XEvent EVENT on display DISPLAY.
11314 This is used for event loops outside the normal event handling,
11315 i.e. looping while a popup menu or a dialog is posted. */
11316void
11317x_dispatch_event (event, display)
11318 XEvent *event;
11319 Display *display;
11320{
11321 struct x_display_info *dpyinfo;
11322 struct input_event bufp[10];
11323 struct input_event *bufpp = bufp;
11324 int numchars = 10;
11325 int finish;
11326
11327 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
11328 if (dpyinfo->display == display)
11329 break;
11330
11331 if (dpyinfo)
11332 {
11333 int i, events;
11334 events = handle_one_xevent (dpyinfo,
11335 event,
11336 &bufpp,
11337 &numchars,
11338 &finish);
11339 for (i = 0; i < events; ++i)
11340 kbd_buffer_store_event (&bufp[i]);
11341 }
11342}
11343
11344
11345/* Read events coming from the X server.
11346 This routine is called by the SIGIO handler.
11347 We return as soon as there are no more events to be read.
11348
11349 Events representing keys are stored in buffer BUFP,
11350 which can hold up to NUMCHARS characters.
11351 We return the number of characters stored into the buffer,
11352 thus pretending to be `read'.
11353
11354 EXPECTED is nonzero if the caller knows input is available. */
11355
11356static int
11357XTread_socket (sd, bufp, numchars, expected)
11358 register int sd;
11359 /* register */ struct input_event *bufp;
11360 /* register */ int numchars;
11361 int expected;
11362{
11363 int count = 0;
11364 int nbytes = 0;
11365 XEvent event;
11366 int event_found = 0;
11367 struct x_display_info *dpyinfo;
11368
11369 if (interrupt_input_blocked)
11370 {
11371 interrupt_input_pending = 1;
11372 return -1;
11373 }
11374
11375 interrupt_input_pending = 0;
11376 BLOCK_INPUT;
11377
11378 /* So people can tell when we have read the available input. */
11379 input_signal_count++;
11380
11381 if (numchars <= 0)
11382 abort (); /* Don't think this happens. */
11383
11384 ++handling_signal;
11385
11386 /* Find the display we are supposed to read input for.
11387 It's the one communicating on descriptor SD. */
11388 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
11389 {
11390#if 0 /* This ought to be unnecessary; let's verify it. */
11391#ifdef FIOSNBIO
11392 /* If available, Xlib uses FIOSNBIO to make the socket
11393 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
11394 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
11395 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
11396 fcntl (dpyinfo->connection, F_SETFL, 0);
11397#endif /* ! defined (FIOSNBIO) */
11398#endif
11399
11400#if 0 /* This code can't be made to work, with multiple displays,
11401 and appears not to be used on any system any more.
11402 Also keyboard.c doesn't turn O_NDELAY on and off
11403 for X connections. */
11404#ifndef SIGIO
11405#ifndef HAVE_SELECT
11406 if (! (fcntl (dpyinfo->connection, F_GETFL, 0) & O_NDELAY))
11407 {
11408 extern int read_alarm_should_throw;
11409 read_alarm_should_throw = 1;
11410 XPeekEvent (dpyinfo->display, &event);
11411 read_alarm_should_throw = 0;
11412 }
11413#endif /* HAVE_SELECT */
11414#endif /* SIGIO */
11415#endif
11416
11417 /* For debugging, this gives a way to fake an I/O error. */
11418 if (dpyinfo == XTread_socket_fake_io_error)
11419 {
11420 XTread_socket_fake_io_error = 0;
11421 x_io_error_quitter (dpyinfo->display);
11407 } 11422 }
11423
11424#ifdef HAVE_X_SM
11425 BLOCK_INPUT;
11426 count += x_session_check_input (bufp, &numchars);
11427 UNBLOCK_INPUT;
11428#endif
11429
11430 while (XPending (dpyinfo->display))
11431 {
11432 int finish;
11433
11434 XNextEvent (dpyinfo->display, &event);
11435
11436#ifdef HAVE_X_I18N
11437 {
11438 /* Filter events for the current X input method.
11439 XFilterEvent returns non-zero if the input method has
11440 consumed the event. We pass the frame's X window to
11441 XFilterEvent because that's the one for which the IC
11442 was created. */
11443 struct frame *f1 = x_any_window_to_frame (dpyinfo,
11444 event.xclient.window);
11445 if (XFilterEvent (&event, f1 ? FRAME_X_WINDOW (f1) : None))
11446 break;
11447 }
11448#endif
11449 event_found = 1;
11450
11451 count += handle_one_xevent (dpyinfo,
11452 &event,
11453 &bufp,
11454 &numchars,
11455 &finish);
11456
11457 if (finish == X_EVENT_GOTO_OUT)
11458 goto out;
11459 }
11408 } 11460 }
11409 11461
11410 out:; 11462 out:;
diff --git a/src/xterm.h b/src/xterm.h
index d9f185f7adf..9e8779bf55d 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -619,7 +619,7 @@ enum
619enum 619enum
620{ 620{
621 /* Values for focus_state, used as bit mask. 621 /* Values for focus_state, used as bit mask.
622 EXPLICIT means if we received a FocusIn for the frame and know it has 622 EXPLICIT means we received a FocusIn for the frame and know it has
623 the focus. IMPLICIT means we recevied an EnterNotify and the frame 623 the focus. IMPLICIT means we recevied an EnterNotify and the frame
624 may have the focus if no window manager is running. 624 may have the focus if no window manager is running.
625 FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */ 625 FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
@@ -674,6 +674,16 @@ enum
674#define PIXEL_WIDTH(f) ((f)->output_data.x->pixel_width) 674#define PIXEL_WIDTH(f) ((f)->output_data.x->pixel_width)
675#define PIXEL_HEIGHT(f) ((f)->output_data.x->pixel_height) 675#define PIXEL_HEIGHT(f) ((f)->output_data.x->pixel_height)
676 676
677/* The difference in pixels between the top left corner of the
678 Emacs window (including possible window manager decorations)
679 and FRAME_X_WINDOW (f). */
680#define FRAME_OUTER_TO_INNER_DIFF_X(f) \
681 ((f)->output_data.x->x_pixels_outer_diff)
682#define FRAME_OUTER_TO_INNER_DIFF_Y(f) \
683 ((f)->output_data.x->y_pixels_outer_diff \
684 + (f)->output_data.x->menubar_height)
685
686
677#define FRAME_XIC(f) ((f)->output_data.x->xic) 687#define FRAME_XIC(f) ((f)->output_data.x->xic)
678#define FRAME_X_XIM(f) (FRAME_X_DISPLAY_INFO (f)->xim) 688#define FRAME_X_XIM(f) (FRAME_X_DISPLAY_INFO (f)->xim)
679#define FRAME_X_XIM_STYLES(f) (FRAME_X_DISPLAY_INFO (f)->xim_styles) 689#define FRAME_X_XIM_STYLES(f) (FRAME_X_DISPLAY_INFO (f)->xim_styles)
@@ -1029,6 +1039,7 @@ extern void x_clear_area P_ ((Display *, Window, int, int, int, int, int));
1029extern void x_fullscreen_adjust P_ ((struct frame *f, int *, int *, 1039extern void x_fullscreen_adjust P_ ((struct frame *f, int *, int *,
1030 int *, int *)); 1040 int *, int *));
1031 1041
1042extern void x_dispatch_event P_ ((XEvent *, Display *));
1032 1043
1033/* Defined in xselect.c */ 1044/* Defined in xselect.c */
1034 1045