diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 19 | ||||
| -rw-r--r-- | src/xfns.c | 12 | ||||
| -rw-r--r-- | src/xterm.c | 2346 | ||||
| -rw-r--r-- | src/xterm.h | 13 |
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 @@ | |||
| 1 | 2003-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 | |||
| 1 | 2003-01-08 Kim F. Storm <storm@cua.dk> | 20 | 2003-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 | |||
| 9941 | int | ||
| 9942 | process_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, | 10066 | enum |
| 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 | ||
| 10121 | static int | 10083 | static int |
| 10122 | XTread_socket (sd, bufp, numchars, expected) | 10084 | handle_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. */ | ||
| 11316 | void | ||
| 11317 | x_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 | |||
| 11356 | static int | ||
| 11357 | XTread_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 | |||
| 619 | enum | 619 | enum |
| 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)); | |||
| 1029 | extern void x_fullscreen_adjust P_ ((struct frame *f, int *, int *, | 1039 | extern void x_fullscreen_adjust P_ ((struct frame *f, int *, int *, |
| 1030 | int *, int *)); | 1040 | int *, int *)); |
| 1031 | 1041 | ||
| 1042 | extern void x_dispatch_event P_ ((XEvent *, Display *)); | ||
| 1032 | 1043 | ||
| 1033 | /* Defined in xselect.c */ | 1044 | /* Defined in xselect.c */ |
| 1034 | 1045 | ||