comparison src/event-Xt.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
63 63
64 #if defined (HAVE_OFFIX_DND) 64 #if defined (HAVE_OFFIX_DND)
65 #include "offix.h" 65 #include "offix.h"
66 #endif 66 #endif
67 67
68 #ifdef WINDOWSNT
69 /* Hmm, under unix we want X modifiers, under NT we want X modifiers if
70 we are running X and Windows modifiers otherwise.
71 gak. This is a kludge until we support multiple native GUIs!
72 */
73 #undef MOD_ALT
74 #undef MOD_CONTROL
75 #undef MOD_SHIFT
76 #endif
77
68 #include "events-mod.h" 78 #include "events-mod.h"
69 79
70 static void handle_focus_event_1 (struct frame *f, int in_p); 80 static void enqueue_Xt_dispatch_event (Lisp_Object event);
71 81
72 static struct event_stream *Xt_event_stream; 82 static struct event_stream *Xt_event_stream;
73 83
74 /* With the new event model, all events go through XtDispatchEvent() 84 /* With the new event model, all events go through XtDispatchEvent()
75 and are picked up by an event handler that is added to each frame 85 and are picked up by an event handler that is added to each frame
84 XtAppContext Xt_app_con; 94 XtAppContext Xt_app_con;
85 95
86 /* Do we accept events sent by other clients? */ 96 /* Do we accept events sent by other clients? */
87 int x_allow_sendevents; 97 int x_allow_sendevents;
88 98
99 int modifier_keys_are_sticky;
100
89 #ifdef DEBUG_XEMACS 101 #ifdef DEBUG_XEMACS
90 int x_debug_events; 102 int x_debug_events;
91 #endif 103 #endif
92 104
93 static int process_events_occurred; 105 static int process_events_occurred;
94 static int tty_events_occurred; 106 static int tty_events_occurred;
95 107
96 /* Mask of bits indicating the descriptors that we wait for input on */ 108 /* Mask of bits indicating the descriptors that we wait for input on */
97 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; 109 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
98 110
99 static const String x_fallback_resources[] = 111 static CONST String x_fallback_resources[] =
100 { 112 {
101 /* This file is automatically generated from the app-defaults file 113 /* This file is automatically generated from the app-defaults file
102 in ../etc/Emacs.ad. These resources are consulted only if no 114 in ../etc/Emacs.ad. These resources are consulted only if no
103 app-defaults file is found at all. 115 app-defaults file is found at all.
104 */ 116 */
106 0 118 0
107 }; 119 };
108 120
109 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p); 121 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
110 void emacs_Xt_mapping_action (Widget w, XEvent *event); 122 void emacs_Xt_mapping_action (Widget w, XEvent *event);
111 void debug_process_finalization (Lisp_Process *p); 123 void debug_process_finalization (struct Lisp_Process *p);
112 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event, 124 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
113 Boolean *continue_to_dispatch); 125 Boolean *continue_to_dispatch);
114 126
115 static int last_quit_check_signal_tick_count; 127 static int last_quit_check_signal_tick_count;
116 128
159 171
160 Emacs detects keyboard configurations which violate the above rules, and 172 Emacs detects keyboard configurations which violate the above rules, and
161 prints an error message on the standard-error-output. (Perhaps it should 173 prints an error message on the standard-error-output. (Perhaps it should
162 use a pop-up-window instead.) 174 use a pop-up-window instead.)
163 */ 175 */
164
165 /* For every key on the keyboard that has a known character correspondence,
166 we define the ascii-character property of the keysym, and make the
167 default binding for the key be self-insert-command.
168
169 The following magic is basically intimate knowledge of X11/keysymdef.h.
170 The keysym mappings defined by X11 are based on the iso8859 standards,
171 except for Cyrillic and Greek.
172
173 In a non-Mule world, a user can still have a multi-lingual editor, by doing
174 (set-face-font "...-iso8859-2" (current-buffer))
175 for all their Latin-2 buffers, etc. */
176
177 static Lisp_Object
178 x_keysym_to_character (KeySym keysym)
179 {
180 #ifdef MULE
181 Lisp_Object charset = Qzero;
182 #define USE_CHARSET(var,cs) \
183 ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
184 #else
185 #define USE_CHARSET(var,lb)
186 #endif /* MULE */
187 int code = 0;
188
189 if ((keysym & 0xff) < 0xa0)
190 return Qnil;
191
192 switch (keysym >> 8)
193 {
194 case 0: /* ASCII + Latin1 */
195 USE_CHARSET (charset, LATIN_ISO8859_1);
196 code = keysym & 0x7f;
197 break;
198 case 1: /* Latin2 */
199 USE_CHARSET (charset, LATIN_ISO8859_2);
200 code = keysym & 0x7f;
201 break;
202 case 2: /* Latin3 */
203 USE_CHARSET (charset, LATIN_ISO8859_3);
204 code = keysym & 0x7f;
205 break;
206 case 3: /* Latin4 */
207 USE_CHARSET (charset, LATIN_ISO8859_4);
208 code = keysym & 0x7f;
209 break;
210 case 4: /* Katakana */
211 USE_CHARSET (charset, KATAKANA_JISX0201);
212 if ((keysym & 0xff) > 0xa0)
213 code = keysym & 0x7f;
214 break;
215 case 5: /* Arabic */
216 USE_CHARSET (charset, ARABIC_ISO8859_6);
217 code = keysym & 0x7f;
218 break;
219 case 6: /* Cyrillic */
220 {
221 static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
222 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
223 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
224 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
225 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
226 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
227 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
228 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
229 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
230 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
231 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
232 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
233 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
234 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
235 code = cyrillic[(keysym & 0x7f) - 0x20];
236 break;
237 }
238 case 7: /* Greek */
239 {
240 static unsigned char const greek[] = /* 0x20 - 0x7f */
241 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
242 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
243 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
244 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
246 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
247 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
248 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
250 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
251 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
252 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
253 USE_CHARSET (charset, GREEK_ISO8859_7);
254 code = greek[(keysym & 0x7f) - 0x20];
255 break;
256 }
257 case 8: /* Technical */
258 break;
259 case 9: /* Special */
260 break;
261 case 10: /* Publishing */
262 break;
263 case 11: /* APL */
264 break;
265 case 12: /* Hebrew */
266 USE_CHARSET (charset, HEBREW_ISO8859_8);
267 code = keysym & 0x7f;
268 break;
269 case 13: /* Thai */
270 /* #### This needs to deal with character composition. */
271 USE_CHARSET (charset, THAI_TIS620);
272 code = keysym & 0x7f;
273 break;
274 case 14: /* Korean Hangul */
275 break;
276 case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
277 break;
278 case 32: /* Currency */
279 break;
280 default:
281 break;
282 }
283
284 if (code == 0)
285 return Qnil;
286
287 #ifdef MULE
288 return make_char (MAKE_CHAR (charset, code, 0));
289 #else
290 return make_char (code + 0x80);
291 #endif
292 }
293
294 /* #### The way that keysym correspondence to characters should work:
295 - a Lisp_Event should contain a keysym AND a character slot.
296 - keybindings are tried with the keysym. If no binding can be found,
297 and there is a corresponding character, call self-insert-command.
298
299 #### Nuke x-iso8859-1.el.
300 #### Nuke the Qascii_character property.
301 #### Nuke Vcharacter_set_property.
302 */
303 static void
304 maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
305 {
306 Lisp_Object character = x_keysym_to_character (keysym);
307
308 if (CHARP (character))
309 {
310 extern Lisp_Object Vcurrent_global_map;
311 extern Lisp_Object Qascii_character;
312 Fput (symbol, Qascii_character, character);
313 if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
314 Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
315 }
316 }
317
318 static void
319 x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
320 {
321 KeySym upper_lower[2];
322 int j;
323
324 if (keysym < 0x80) /* Optimize for ASCII keysyms */
325 return;
326
327 /* If you execute:
328 xmodmap -e 'keysym NN = scaron'
329 and then press (Shift scaron), X11 will return the different
330 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'.
331 So we "register" both `scaron' and `Scaron'. */
332 #ifdef HAVE_XCONVERTCASE
333 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
334 #else
335 upper_lower[0] = upper_lower[1] = keysym;
336 #endif
337
338 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
339 {
340 char *name;
341 keysym = upper_lower[j];
342
343 name = XKeysymToString (keysym);
344 if (name)
345 {
346 /* X guarantees NAME to be in the Host Portable Character Encoding */
347 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
348 Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
349 Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
350
351 if (! EQ (old_value, new_value)
352 && ! (EQ (old_value, Qsans_modifiers) &&
353 EQ (new_value, Qt)))
354 {
355 maybe_define_x_key_as_self_inserting_character (keysym, sym);
356 Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
357 Fputhash (sym, new_value, hash_table);
358 }
359 }
360 }
361 }
362 176
363 static void 177 static void
364 x_reset_key_mapping (struct device *d) 178 x_reset_key_mapping (struct device *d)
365 { 179 {
366 Display *display = DEVICE_X_DISPLAY (d); 180 Display *display = DEVICE_X_DISPLAY (d);
395 int j; 209 int j;
396 210
397 if (keysym[0] == NoSymbol) 211 if (keysym[0] == NoSymbol)
398 continue; 212 continue;
399 213
400 x_has_keysym (keysym[0], hash_table, 0); 214 {
215 char *name = XKeysymToString (keysym[0]);
216 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[0], 0);
217 if (name)
218 {
219 Fputhash (build_string (name), Qsans_modifiers, hash_table);
220 Fputhash (sym, Qsans_modifiers, hash_table);
221 }
222 }
401 223
402 for (j = 1; j < keysyms_per_code; j++) 224 for (j = 1; j < keysyms_per_code; j++)
403 { 225 {
404 if (keysym[j] != keysym[0] && 226 if (keysym[j] != keysym[0] &&
405 keysym[j] != NoSymbol) 227 keysym[j] != NoSymbol)
406 x_has_keysym (keysym[j], hash_table, 1); 228 {
229 char *name = XKeysymToString (keysym[j]);
230 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[j], 0);
231 if (name && NILP (Fgethash (sym, hash_table, Qnil)))
232 {
233 Fputhash (build_string (name), Qt, hash_table);
234 Fputhash (sym, Qt, hash_table);
235 }
236 }
407 } 237 }
408 } 238 }
409 } 239 }
410 240
411 static const char * 241 static CONST char *
412 index_to_name (int indice) 242 index_to_name (int indice)
413 { 243 {
414 switch (indice) 244 switch (indice)
415 { 245 {
416 case ShiftMapIndex: return "ModShift"; 246 case ShiftMapIndex: return "ModShift";
561 interpret that bit as Meta, because we can't make XLookupString() 391 interpret that bit as Meta, because we can't make XLookupString()
562 not interpret it as Mode_switch; and interpreting it as both would 392 not interpret it as Mode_switch; and interpreting it as both would
563 be totally wrong. */ 393 be totally wrong. */
564 if (mode_bit) 394 if (mode_bit)
565 { 395 {
566 const char *warn = 0; 396 CONST char *warn = 0;
567 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; 397 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
568 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; 398 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
569 else if (mode_bit == super_bit) warn = "Super", super_bit = 0; 399 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
570 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0; 400 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
571 if (warn) 401 if (warn)
975 Lookup_String: /* Come-From XBufferOverflow */ 805 Lookup_String: /* Come-From XBufferOverflow */
976 #ifdef XIM_MOTIF 806 #ifdef XIM_MOTIF
977 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window), 807 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
978 event, bufptr, bufsiz, &keysym, &status); 808 event, bufptr, bufsiz, &keysym, &status);
979 #else /* XIM_XLIB */ 809 #else /* XIM_XLIB */
980 if (xic) 810 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
981 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
982 #endif /* HAVE_XIM */ 811 #endif /* HAVE_XIM */
983 812
984 #ifdef DEBUG_XEMACS 813 #ifdef DEBUG_XEMACS
985 if (x_debug_events > 0) 814 if (x_debug_events > 0)
986 { 815 {
1027 Emchar ch; 856 Emchar ch;
1028 Lisp_Object instream, fb_instream; 857 Lisp_Object instream, fb_instream;
1029 Lstream *istr; 858 Lstream *istr;
1030 struct gcpro gcpro1, gcpro2; 859 struct gcpro gcpro1, gcpro2;
1031 860
1032 fb_instream = make_fixed_buffer_input_stream (bufptr, len); 861 fb_instream =
1033 862 make_fixed_buffer_input_stream ((unsigned char *) bufptr, len);
1034 /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */ 863
864 /* ### Use Fget_coding_system (Vcomposed_input_coding_system) */
1035 instream = 865 instream =
1036 make_decoding_input_stream (XLSTREAM (fb_instream), 866 make_decoding_input_stream (XLSTREAM (fb_instream),
1037 Fget_coding_system (Qundecided)); 867 Fget_coding_system (Qundecided));
1038 868
1039 istr = XLSTREAM (instream); 869 istr = XLSTREAM (instream);
1040 870
1041 GCPRO2 (instream, fb_instream); 871 GCPRO2 (instream, fb_instream);
1042 while ((ch = Lstream_get_emchar (istr)) != EOF) 872 while ((ch = Lstream_get_emchar (istr)) != EOF)
1043 { 873 {
1044 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); 874 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1045 Lisp_Event *ev = XEVENT (emacs_event); 875 struct Lisp_Event *ev = XEVENT (emacs_event);
1046 ev->channel = DEVICE_CONSOLE (d); 876 ev->channel = DEVICE_CONSOLE (d);
1047 ev->event_type = key_press_event; 877 ev->event_type = key_press_event;
1048 ev->timestamp = event->time; 878 ev->timestamp = event->time;
1049 ev->event.key.modifiers = 0; 879 ev->event.key.modifiers = 0;
1050 ev->event.key.keysym = make_char (ch); 880 ev->event.key.keysym = make_char (ch);
1087 } 917 }
1088 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t; 918 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t;
1089 } 919 }
1090 920
1091 static int 921 static int
1092 x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event) 922 x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event)
1093 { 923 {
1094 Display *display = x_event->xany.display; 924 Display *display = x_event->xany.display;
1095 struct device *d = get_device_from_display (display); 925 struct device *d = get_device_from_display (display);
1096 struct x_device *xd = DEVICE_X_DATA (d); 926 struct x_device *xd = DEVICE_X_DATA (d);
1097 927
1109 939
1110 case KeyPress: 940 case KeyPress:
1111 case ButtonPress: 941 case ButtonPress:
1112 case ButtonRelease: 942 case ButtonRelease:
1113 { 943 {
1114 int modifiers = 0; 944 unsigned int modifiers = 0;
1115 int shift_p, lock_p; 945 int shift_p, lock_p;
1116 Bool key_event_p = (x_event->type == KeyPress); 946 Bool key_event_p = (x_event->type == KeyPress);
1117 unsigned int *state = 947 unsigned int *state =
1118 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; 948 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state;
1119 949
1136 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = 966 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) =
1137 key_event_p ? x_event->xkey.time : x_event->xbutton.time; 967 key_event_p ? x_event->xkey.time : x_event->xbutton.time;
1138 968
1139 x_handle_sticky_modifiers (x_event, d); 969 x_handle_sticky_modifiers (x_event, d);
1140 970
1141 if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; 971 if (*state & ControlMask) modifiers |= MOD_CONTROL;
1142 if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META; 972 if (*state & xd->MetaMask) modifiers |= MOD_META;
1143 if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; 973 if (*state & xd->SuperMask) modifiers |= MOD_SUPER;
1144 if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; 974 if (*state & xd->HyperMask) modifiers |= MOD_HYPER;
1145 if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; 975 if (*state & xd->AltMask) modifiers |= MOD_ALT;
1146 976
1147 /* Ignore the Caps_Lock key if: 977 /* Ignore the Caps_Lock key if:
1148 - any other modifiers are down, so that Caps_Lock doesn't 978 - any other modifiers are down, so that Caps_Lock doesn't
1149 turn C-x into C-X, which would suck. 979 turn C-x into C-X, which would suck.
1150 - the event was a mouse event. */ 980 - the event was a mouse event. */
1153 983
1154 shift_p = *state & ShiftMask; 984 shift_p = *state & ShiftMask;
1155 lock_p = *state & LockMask; 985 lock_p = *state & LockMask;
1156 986
1157 if (shift_p || lock_p) 987 if (shift_p || lock_p)
1158 modifiers |= XEMACS_MOD_SHIFT; 988 modifiers |= MOD_SHIFT;
1159 989
1160 if (key_event_p) 990 if (key_event_p)
1161 { 991 {
1162 Lisp_Object keysym; 992 Lisp_Object keysym;
1163 XKeyEvent *ev = &x_event->xkey; 993 XKeyEvent *ev = &x_event->xkey;
1185 /* !!#### maybe fix for Mule */ 1015 /* !!#### maybe fix for Mule */
1186 if (lock_p && !shift_p && 1016 if (lock_p && !shift_p &&
1187 ! (CHAR_OR_CHAR_INTP (keysym) 1017 ! (CHAR_OR_CHAR_INTP (keysym)
1188 && keysym_obeys_caps_lock_p 1018 && keysym_obeys_caps_lock_p
1189 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) 1019 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
1190 modifiers &= (~XEMACS_MOD_SHIFT); 1020 modifiers &= (~MOD_SHIFT);
1191 1021
1192 /* If this key contains two distinct keysyms, that is, 1022 /* If this key contains two distinct keysyms, that is,
1193 "shift" generates a different keysym than the 1023 "shift" generates a different keysym than the
1194 non-shifted key, then don't apply the shift modifier 1024 non-shifted key, then don't apply the shift modifier
1195 bit: it's implicit. Otherwise, if there would be no 1025 bit: it's implicit. Otherwise, if there would be no
1197 and unshifted version of this key, apply the shift bit. 1027 and unshifted version of this key, apply the shift bit.
1198 Non-graphics, like Backspace and F1 get the shift bit 1028 Non-graphics, like Backspace and F1 get the shift bit
1199 in the modifiers slot. Neither the characters "a", 1029 in the modifiers slot. Neither the characters "a",
1200 "A", "2", nor "@" normally have the shift bit set. 1030 "A", "2", nor "@" normally have the shift bit set.
1201 However, "F1" normally does. */ 1031 However, "F1" normally does. */
1202 if (modifiers & XEMACS_MOD_SHIFT) 1032 if (modifiers & MOD_SHIFT)
1203 { 1033 {
1204 int Mode_switch_p = *state & xd->ModeMask; 1034 int Mode_switch_p = *state & xd->ModeMask;
1205 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); 1035 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
1206 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); 1036 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1);
1207 if (top && bot && top != bot) 1037 if (top && bot && top != bot)
1208 modifiers &= ~XEMACS_MOD_SHIFT; 1038 modifiers &= ~MOD_SHIFT;
1209 } 1039 }
1210 emacs_event->event_type = key_press_event; 1040 emacs_event->event_type = key_press_event;
1211 emacs_event->timestamp = ev->time; 1041 emacs_event->timestamp = ev->time;
1212 emacs_event->event.key.modifiers = modifiers; 1042 emacs_event->event.key.modifiers = modifiers;
1213 emacs_event->event.key.keysym = keysym; 1043 emacs_event->event.key.keysym = keysym;
1214 } 1044 }
1215 else /* Mouse press/release event */ 1045 else /* Mouse press/release event */
1216 { 1046 {
1217 XButtonEvent *ev = &x_event->xbutton; 1047 XButtonEvent *ev = &x_event->xbutton;
1218 struct frame *frame = x_window_to_frame (d, ev->window); 1048 struct frame *frame = x_window_to_frame (d, ev->window);
1219
1220 if (! frame) 1049 if (! frame)
1221 return 0; /* not for us */ 1050 return 0; /* not for us */
1222 XSETFRAME (emacs_event->channel, frame); 1051 XSETFRAME (emacs_event->channel, frame);
1223 1052
1224 emacs_event->event_type = (x_event->type == ButtonPress) ? 1053 emacs_event->event_type = (x_event->type == ButtonPress) ?
1227 emacs_event->event.button.modifiers = modifiers; 1056 emacs_event->event.button.modifiers = modifiers;
1228 emacs_event->timestamp = ev->time; 1057 emacs_event->timestamp = ev->time;
1229 emacs_event->event.button.button = ev->button; 1058 emacs_event->event.button.button = ev->button;
1230 emacs_event->event.button.x = ev->x; 1059 emacs_event->event.button.x = ev->x;
1231 emacs_event->event.button.y = ev->y; 1060 emacs_event->event.button.y = ev->y;
1232 /* because we don't seem to get a FocusIn event for button clicks 1061
1233 when a widget-glyph is selected we will assume that we want the
1234 focus if a button gets pressed. */
1235 if (x_event->type == ButtonPress)
1236 handle_focus_event_1 (frame, 1);
1237 } 1062 }
1238 } 1063 }
1239 break; 1064 break;
1240 1065
1241 case MotionNotify: 1066 case MotionNotify:
1242 { 1067 {
1243 XMotionEvent *ev = &x_event->xmotion; 1068 XMotionEvent *ev = &x_event->xmotion;
1244 struct frame *frame = x_window_to_frame (d, ev->window); 1069 struct frame *frame = x_window_to_frame (d, ev->window);
1245 int modifiers = 0; 1070 unsigned int modifiers = 0;
1246 XMotionEvent event2; 1071 XMotionEvent event2;
1247 1072
1248 if (! frame) 1073 if (! frame)
1249 return 0; /* not for us */ 1074 return 0; /* not for us */
1250 1075
1269 XSETFRAME (emacs_event->channel, frame); 1094 XSETFRAME (emacs_event->channel, frame);
1270 emacs_event->event_type = pointer_motion_event; 1095 emacs_event->event_type = pointer_motion_event;
1271 emacs_event->timestamp = ev->time; 1096 emacs_event->timestamp = ev->time;
1272 emacs_event->event.motion.x = ev->x; 1097 emacs_event->event.motion.x = ev->x;
1273 emacs_event->event.motion.y = ev->y; 1098 emacs_event->event.motion.y = ev->y;
1274 if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; 1099 if (ev->state & ShiftMask) modifiers |= MOD_SHIFT;
1275 if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; 1100 if (ev->state & ControlMask) modifiers |= MOD_CONTROL;
1276 if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META; 1101 if (ev->state & xd->MetaMask) modifiers |= MOD_META;
1277 if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; 1102 if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER;
1278 if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; 1103 if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER;
1279 if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; 1104 if (ev->state & xd->AltMask) modifiers |= MOD_ALT;
1280 /* Currently ignores Shift_Lock but probably shouldn't 1105 /* Currently ignores Shift_Lock but probably shouldn't
1281 (but it definitely should ignore Caps_Lock). */ 1106 (but it definitely should ignore Caps_Lock). */
1282 emacs_event->event.motion.modifiers = modifiers; 1107 emacs_event->event.motion.modifiers = modifiers;
1283 } 1108 }
1284 break; 1109 break;
1290 explicitly prohibits. */ 1115 explicitly prohibits. */
1291 XClientMessageEvent *ev = &x_event->xclient; 1116 XClientMessageEvent *ev = &x_event->xclient;
1292 #ifdef HAVE_OFFIX_DND 1117 #ifdef HAVE_OFFIX_DND
1293 if (DndIsDropMessage(x_event)) 1118 if (DndIsDropMessage(x_event))
1294 { 1119 {
1295 unsigned int state; 1120 unsigned int state, modifiers = 0, button=0;
1296 int modifiers = 0;
1297 unsigned int button=0;
1298 struct frame *frame = x_any_window_to_frame (d, ev->window); 1121 struct frame *frame = x_any_window_to_frame (d, ev->window);
1299 Extbyte *data; 1122 Extbyte *data;
1300 unsigned long size, dtype; 1123 unsigned long size, dtype;
1301 Lisp_Object l_type = Qnil, l_data = Qnil; 1124 Lisp_Object l_type = Qnil, l_data = Qnil;
1302 Lisp_Object l_dndlist = Qnil, l_item = Qnil; 1125 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
1311 emacs_event->event_type = misc_user_event; 1134 emacs_event->event_type = misc_user_event;
1312 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d); 1135 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1313 1136
1314 state=DndDragButtons(x_event); 1137 state=DndDragButtons(x_event);
1315 1138
1316 if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; 1139 if (state & ShiftMask) modifiers |= MOD_SHIFT;
1317 if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; 1140 if (state & ControlMask) modifiers |= MOD_CONTROL;
1318 if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META; 1141 if (state & xd->MetaMask) modifiers |= MOD_META;
1319 if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; 1142 if (state & xd->SuperMask) modifiers |= MOD_SUPER;
1320 if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; 1143 if (state & xd->HyperMask) modifiers |= MOD_HYPER;
1321 if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; 1144 if (state & xd->AltMask) modifiers |= MOD_ALT;
1322 1145
1323 if (state & Button5Mask) button = Button5; 1146 if (state & Button5Mask) button = Button5;
1324 if (state & Button4Mask) button = Button4; 1147 if (state & Button4Mask) button = Button4;
1325 if (state & Button3Mask) button = Button3; 1148 if (state & Button3Mask) button = Button3;
1326 if (state & Button2Mask) button = Button2; 1149 if (state & Button2Mask) button = Button2;
1359 l_type = Qdragdrop_MIME; 1182 l_type = Qdragdrop_MIME;
1360 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ), 1183 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
1361 make_string ((Bufbyte *)"8bit", 4), 1184 make_string ((Bufbyte *)"8bit", 4),
1362 make_ext_string ((Extbyte *)data, 1185 make_ext_string ((Extbyte *)data,
1363 strlen((char *)data), 1186 strlen((char *)data),
1364 Qctext) ) ); 1187 FORMAT_CTEXT) ) );
1365 break; 1188 break;
1366 case DndMIME: 1189 case DndMIME:
1367 /* we have to parse this in some way to extract 1190 /* we have to parse this in some way to extract
1368 content-type and params (in the tm way) and 1191 content-type and params (in the tm way) and
1369 content encoding. 1192 content encoding.
1372 to tm... 1195 to tm...
1373 */ 1196 */
1374 l_type = Qdragdrop_MIME; 1197 l_type = Qdragdrop_MIME;
1375 l_dndlist = list1 ( make_ext_string ((Extbyte *)data, 1198 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1376 strlen((char *)data), 1199 strlen((char *)data),
1377 Qbinary) ); 1200 FORMAT_BINARY) );
1378 break; 1201 break;
1379 case DndFile: 1202 case DndFile:
1380 case DndDir: 1203 case DndDir:
1381 case DndLink: 1204 case DndLink:
1382 case DndExe: 1205 case DndExe:
1393 case DndURL: 1216 case DndURL:
1394 /* as it is a real URL it should already be escaped 1217 /* as it is a real URL it should already be escaped
1395 and escaping again will break them (cause % is unsave) */ 1218 and escaping again will break them (cause % is unsave) */
1396 l_dndlist = list1 ( make_ext_string ((Extbyte *)data, 1219 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1397 strlen ((char *)data), 1220 strlen ((char *)data),
1398 Qfile_name) ); 1221 FORMAT_FILENAME) );
1399 l_type = Qdragdrop_URL; 1222 l_type = Qdragdrop_URL;
1400 break; 1223 break;
1401 default: /* Unknown, RawData and any other type */ 1224 default: /* Unknown, RawData and any other type */
1402 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ), 1225 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ),
1403 make_string ((Bufbyte *)"8bit", 4), 1226 make_string ((Bufbyte *)"8bit", 4),
1404 make_ext_string ((Extbyte *)data, 1227 make_ext_string ((Extbyte *)data,
1405 size, 1228 size,
1406 Qbinary) ) ); 1229 FORMAT_BINARY) ) );
1407 l_type = Qdragdrop_MIME; 1230 l_type = Qdragdrop_MIME;
1408 break; 1231 break;
1409 } 1232 }
1410 1233
1411 emacs_event->event.misc.function = Qdragdrop_drop_dispatch; 1234 emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
1450 case EnterNotify: 1273 case EnterNotify:
1451 case LeaveNotify: FROB(xcrossing, window); break; 1274 case LeaveNotify: FROB(xcrossing, window); break;
1452 case FocusIn: 1275 case FocusIn:
1453 case FocusOut: FROB(xfocus, window); break; 1276 case FocusOut: FROB(xfocus, window); break;
1454 case VisibilityNotify: FROB(xvisibility, window); break; 1277 case VisibilityNotify: FROB(xvisibility, window); break;
1455 case CreateNotify: FROB(xcreatewindow, window); break;
1456 default: 1278 default:
1457 w = x_event->xany.window; 1279 w = x_event->xany.window;
1458 *x_event_copy = *x_event; 1280 *x_event_copy = *x_event;
1459 break; 1281 break;
1460 } 1282 }
1480 /************************************************************************/ 1302 /************************************************************************/
1481 1303
1482 static void 1304 static void
1483 handle_focus_event_1 (struct frame *f, int in_p) 1305 handle_focus_event_1 (struct frame *f, int in_p)
1484 { 1306 {
1485 #if XtSpecificationRelease > 5
1486 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
1487 #endif
1488 #ifdef HAVE_XIM 1307 #ifdef HAVE_XIM
1489 XIM_focus_event (f, in_p); 1308 XIM_focus_event (f, in_p);
1490 #endif /* HAVE_XIM */ 1309 #endif /* HAVE_XIM */
1310
1491 /* On focus change, clear all memory of sticky modifiers 1311 /* On focus change, clear all memory of sticky modifiers
1492 to avoid non-intuitive behavior. */ 1312 to avoid non-intuitive behavior. */
1493 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f))); 1313 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f)));
1494 1314
1495 /* We don't want to handle the focus change now, because we might 1315 /* We don't want to handle the focus change now, because we might
1497 we enqueue it. 1317 we enqueue it.
1498 1318
1499 Actually, we half handle it: we handle it as far as changing the 1319 Actually, we half handle it: we handle it as far as changing the
1500 box cursor for redisplay, but we don't call any hooks or do any 1320 box cursor for redisplay, but we don't call any hooks or do any
1501 select-frame stuff until after the sit-for. 1321 select-frame stuff until after the sit-for.
1502 1322 */
1503 Unfortunately native widgets break the model because they grab
1504 the keyboard focus and nothing sets it back again. I cannot find
1505 any reasonable way to do this elsewhere so we assert here that
1506 the keyboard focus is on the emacs text widget. Menus and dialogs
1507 do this in their selection callback, but we don't want that since
1508 a button having focus is legitimate. An edit field having focus
1509 is mandatory. Weirdly you get a FocusOut event when you click in
1510 a widget-glyph but you don't get a correspondng FocusIn when you
1511 click in the frame. Why is this? */
1512 if (in_p
1513 #if XtSpecificationRelease > 5
1514 && FRAME_X_TEXT_WIDGET (f) != focus_widget
1515 #endif
1516 )
1517 {
1518 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
1519 FRAME_X_TEXT_WIDGET (f));
1520 }
1521 /* do the generic event-stream stuff. */
1522 { 1323 {
1523 Lisp_Object frm; 1324 Lisp_Object frm;
1524 Lisp_Object conser; 1325 Lisp_Object conser;
1525 struct gcpro gcpro1; 1326 struct gcpro gcpro1;
1526 1327
1601 { 1402 {
1602 XWindowAttributes xwa; 1403 XWindowAttributes xwa;
1603 1404
1604 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM) 1405 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
1605 send synthetic MapNotify events when a window is first 1406 send synthetic MapNotify events when a window is first
1606 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE. 1407 created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE.
1607 Or something like that. We initially tried a different 1408 Or something like that. We initially tried a different
1608 solution below, but that ran into a different window- 1409 solution below, but that ran into a different window-
1609 manager bug. 1410 manager bug.
1610 1411
1611 It seems that the only reliable way is to treat a 1412 It seems that the only reliable way is to treat a
1709 #endif 1510 #endif
1710 } 1511 }
1711 } 1512 }
1712 1513
1713 static void 1514 static void
1714 emacs_Xt_force_event_pending (struct frame* f) 1515 emacs_Xt_handle_magic_event (struct Lisp_Event *emacs_event)
1715 {
1716 XEvent event;
1717
1718 Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f)));
1719 event.xclient.type = ClientMessage;
1720 event.xclient.display = dpy;
1721 event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False);
1722 event.xclient.format = 32;
1723 event.xclient.window = 0;
1724
1725 /* Send the drop message */
1726 XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)),
1727 True, NoEventMask, &event);
1728 /* Force event pending to check the X queue. */
1729 quit_check_signal_tick_count++;
1730 }
1731
1732 static void
1733 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
1734 { 1516 {
1735 /* This function can GC */ 1517 /* This function can GC */
1736 XEvent *event = &emacs_event->event.magic.underlying_x_event; 1518 XEvent *event = &emacs_event->event.magic.underlying_x_event;
1737 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event)); 1519 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
1738 1520
1756 case PropertyNotify: 1538 case PropertyNotify:
1757 x_handle_property_notify (&event->xproperty); 1539 x_handle_property_notify (&event->xproperty);
1758 break; 1540 break;
1759 1541
1760 case Expose: 1542 case Expose:
1761 if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y, 1543 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1762 event->xexpose.width, event->xexpose.height) 1544 event->xexpose.width, event->xexpose.height);
1763 &&
1764 !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
1765 event->xexpose.width, event->xexpose.height))
1766 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1767 event->xexpose.width, event->xexpose.height);
1768 break; 1545 break;
1769 1546
1770 case GraphicsExpose: /* This occurs when an XCopyArea's source area was 1547 case GraphicsExpose: /* This occurs when an XCopyArea's source area was
1771 obscured or not available. */ 1548 obscured or not available. */
1772 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, 1549 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1800 } 1577 }
1801 break; 1578 break;
1802 1579
1803 case FocusIn: 1580 case FocusIn:
1804 case FocusOut: 1581 case FocusOut:
1805
1806 #ifdef EXTERNAL_WIDGET 1582 #ifdef EXTERNAL_WIDGET
1807 /* External widget lossage: Ben said: 1583 /* External widget lossage: Ben said:
1808 YUCK. The only way to make focus changes work properly is to 1584 YUCK. The only way to make focus changes work properly is to
1809 completely ignore all FocusIn/FocusOut events and depend only 1585 completely ignore all FocusIn/FocusOut events and depend only
1810 on notifications from the ExternalClient widget. */ 1586 on notifications from the ExternalClient widget. */
1840 #ifdef HAVE_XIM 1616 #ifdef HAVE_XIM
1841 XIM_SetGeometry (f); 1617 XIM_SetGeometry (f);
1842 #endif 1618 #endif
1843 break; 1619 break;
1844 1620
1845 case CreateNotify:
1846 break;
1847
1848 default: 1621 default:
1849 break; 1622 break;
1850 } 1623 }
1851 } 1624 }
1852 1625
1858 static int timeout_id_tick; 1631 static int timeout_id_tick;
1859 1632
1860 /* Xt interval id's might not fit into an int (they're pointers, as it 1633 /* Xt interval id's might not fit into an int (they're pointers, as it
1861 happens), so we need to provide a conversion list. */ 1634 happens), so we need to provide a conversion list. */
1862 1635
1863 static struct Xt_timeout 1636 struct Xt_timeout
1864 { 1637 {
1865 int id; 1638 int id;
1866 XtIntervalId interval_id; 1639 XtIntervalId interval_id;
1867 struct Xt_timeout *next; 1640 struct Xt_timeout *next;
1868 } *pending_timeouts, *completed_timeouts; 1641 } *pending_timeouts, *completed_timeouts;
1869 1642
1870 static struct Xt_timeout_blocktype 1643 struct Xt_timeout_blocktype
1871 { 1644 {
1872 Blocktype_declare (struct Xt_timeout); 1645 Blocktype_declare (struct Xt_timeout);
1873 } *the_Xt_timeout_blocktype; 1646 } *the_Xt_timeout_blocktype;
1874 1647
1875 /* called by XtAppNextEvent() */ 1648 /* called by XtAppNextEvent() */
1972 if (timeout) 1745 if (timeout)
1973 Blocktype_free (the_Xt_timeout_blocktype, timeout); 1746 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1974 } 1747 }
1975 1748
1976 static void 1749 static void
1977 Xt_timeout_to_emacs_event (Lisp_Event *emacs_event) 1750 Xt_timeout_to_emacs_event (struct Lisp_Event *emacs_event)
1978 { 1751 {
1979 struct Xt_timeout *timeout = completed_timeouts; 1752 struct Xt_timeout *timeout = completed_timeouts;
1980 assert (timeout); 1753 assert (timeout);
1981 completed_timeouts = completed_timeouts->next; 1754 completed_timeouts = completed_timeouts->next;
1982 emacs_event->event_type = timeout_event; 1755 emacs_event->event_type = timeout_event;
2139 xfree (closure); 1912 xfree (closure);
2140 filedesc_to_what_closure[fd] = 0; 1913 filedesc_to_what_closure[fd] = 0;
2141 } 1914 }
2142 1915
2143 static void 1916 static void
2144 emacs_Xt_select_process (Lisp_Process *p) 1917 emacs_Xt_select_process (struct Lisp_Process *p)
2145 { 1918 {
2146 Lisp_Object process; 1919 Lisp_Object process;
2147 int infd = event_stream_unixoid_select_process (p); 1920 int infd = event_stream_unixoid_select_process (p);
2148 1921
2149 XSETPROCESS (process, p); 1922 XSETPROCESS (process, p);
2150 select_filedesc (infd, process); 1923 select_filedesc (infd, process);
2151 } 1924 }
2152 1925
2153 static void 1926 static void
2154 emacs_Xt_unselect_process (Lisp_Process *p) 1927 emacs_Xt_unselect_process (struct Lisp_Process *p)
2155 { 1928 {
2156 int infd = event_stream_unixoid_unselect_process (p); 1929 int infd = event_stream_unixoid_unselect_process (p);
2157 1930
2158 unselect_filedesc (infd); 1931 unselect_filedesc (infd);
2159 } 1932 }
2178 1951
2179 /* This is called from GC when a process object is about to be freed. 1952 /* This is called from GC when a process object is about to be freed.
2180 If we've still got pointers to it in this file, we're gonna lose hard. 1953 If we've still got pointers to it in this file, we're gonna lose hard.
2181 */ 1954 */
2182 void 1955 void
2183 debug_process_finalization (Lisp_Process *p) 1956 debug_process_finalization (struct Lisp_Process *p)
2184 { 1957 {
2185 #if 0 /* #### */ 1958 #if 0 /* #### */
2186 int i; 1959 int i;
2187 Lisp_Object instr, outstr; 1960 Lisp_Object instr, outstr;
2188 1961
2198 } 1971 }
2199 #endif 1972 #endif
2200 } 1973 }
2201 1974
2202 static void 1975 static void
2203 Xt_process_to_emacs_event (Lisp_Event *emacs_event) 1976 Xt_process_to_emacs_event (struct Lisp_Event *emacs_event)
2204 { 1977 {
2205 int i; 1978 int i;
1979 Lisp_Object process;
2206 1980
2207 assert (process_events_occurred > 0); 1981 assert (process_events_occurred > 0);
2208
2209 for (i = 0; i < MAXDESC; i++) 1982 for (i = 0; i < MAXDESC; i++)
2210 { 1983 {
2211 Lisp_Object process = filedesc_with_input[i]; 1984 process = filedesc_with_input[i];
2212 if (PROCESSP (process)) 1985 if (PROCESSP (process))
2213 { 1986 break;
2214 filedesc_with_input[i] = Qnil; 1987 }
2215 process_events_occurred--; 1988 assert (i < MAXDESC);
2216 /* process events have nil as channel */ 1989 filedesc_with_input[i] = Qnil;
2217 emacs_event->event_type = process_event; 1990 process_events_occurred--;
2218 emacs_event->timestamp = 0; /* #### */ 1991 /* process events have nil as channel */
2219 emacs_event->event.process.process = process; 1992 emacs_event->event_type = process_event;
2220 return; 1993 emacs_event->timestamp = 0; /* #### */
2221 } 1994 emacs_event->event.process.process = process;
2222 }
2223 abort ();
2224 } 1995 }
2225 1996
2226 static void 1997 static void
2227 emacs_Xt_select_console (struct console *con) 1998 emacs_Xt_select_console (struct console *con)
2228 { 1999 {
2229 Lisp_Object console; 2000 Lisp_Object console;
2230 int infd; 2001 int infd;
2002 #ifdef HAVE_GPM
2003 int mousefd;
2004 #endif
2231 2005
2232 if (CONSOLE_X_P (con)) 2006 if (CONSOLE_X_P (con))
2233 return; /* X consoles are automatically selected for when we 2007 return; /* X consoles are automatically selected for when we
2234 initialize them in Xt */ 2008 initialize them in Xt */
2235 infd = event_stream_unixoid_select_console (con); 2009 infd = event_stream_unixoid_select_console (con);
2236 XSETCONSOLE (console, con); 2010 XSETCONSOLE (console, con);
2237 select_filedesc (infd, console); 2011 select_filedesc (infd, console);
2012 #ifdef HAVE_GPM
2013 /* On a stream device (ie: noninteractive), bad things can happen. */
2014 if (EQ (CONSOLE_TYPE (con), Qtty)) {
2015 mousefd = CONSOLE_TTY_MOUSE_FD (con);
2016 /* We check filedesc_to_what_closure[fd] here because if you run
2017 ** XEmacs from a TTY, it will fire up GPM, select the mouse fd, then
2018 ** if you run gnuattach to connect to another TTY, it will fire up
2019 ** GPM again, and try to reselect the mouse fd. GPM uses the same
2020 ** fd for every connection apparently, and select_filedesc will
2021 ** fail its assertion if we try to select it twice.
2022 */
2023 if ((mousefd >= 0) && !filedesc_to_what_closure[mousefd]) {
2024 select_filedesc (mousefd, console);
2025 }
2026 }
2027 #endif
2238 } 2028 }
2239 2029
2240 static void 2030 static void
2241 emacs_Xt_unselect_console (struct console *con) 2031 emacs_Xt_unselect_console (struct console *con)
2242 { 2032 {
2243 Lisp_Object console; 2033 Lisp_Object console;
2244 int infd; 2034 int infd;
2035 #ifdef HAVE_GPM
2036 int mousefd;
2037 #endif
2245 2038
2246 if (CONSOLE_X_P (con)) 2039 if (CONSOLE_X_P (con))
2247 return; /* X consoles are automatically selected for when we 2040 return; /* X consoles are automatically selected for when we
2248 initialize them in Xt */ 2041 initialize them in Xt */
2249 infd = event_stream_unixoid_unselect_console (con); 2042 infd = event_stream_unixoid_unselect_console (con);
2250 XSETCONSOLE (console, con); 2043 XSETCONSOLE (console, con);
2251 unselect_filedesc (infd); 2044 unselect_filedesc (infd);
2045 #ifdef HAVE_GPM
2046 /* On a stream device (ie: noninteractive), bad things can happen. */
2047 if (EQ (CONSOLE_TYPE (con), Qtty)) {
2048 mousefd = CONSOLE_TTY_MOUSE_FD (con);
2049 if (mousefd >= 0) {
2050 unselect_filedesc (mousefd);
2051 }
2052 }
2053 #endif
2252 } 2054 }
2253 2055
2254 /* read an event from a tty, if one is available. Returns non-zero 2056 /* read an event from a tty, if one is available. Returns non-zero
2255 if an event was available. Note that when this function is 2057 if an event was available. Note that when this function is
2256 called, there should always be a tty marked as ready for input. 2058 called, there should always be a tty marked as ready for input.
2258 may not really be any input available. (In this case, 2060 may not really be any input available. (In this case,
2259 read_event_from_tty_or_stream_desc() will arrange for the TTY device 2061 read_event_from_tty_or_stream_desc() will arrange for the TTY device
2260 to be deleted.) */ 2062 to be deleted.) */
2261 2063
2262 static int 2064 static int
2263 Xt_tty_to_emacs_event (Lisp_Event *emacs_event) 2065 Xt_tty_to_emacs_event (struct Lisp_Event *emacs_event)
2264 { 2066 {
2265 int i; 2067 int i;
2266 2068
2267 assert (tty_events_occurred > 0); 2069 assert (tty_events_occurred > 0);
2268 for (i = 0; i < MAXDESC; i++) 2070 for (i = 0; i < MAXDESC; i++)
2304 if (f) 2106 if (f)
2305 { 2107 {
2306 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4); 2108 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
2307 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name)); 2109 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
2308 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0, 2110 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
2309 strlen (buf), Qterminal, 1); 2111 strlen (buf), FORMAT_TERMINAL);
2310 } 2112 }
2311 stderr_out ("\n"); 2113 stderr_out ("\n");
2312 } 2114 }
2313 2115
2314 static const char * 2116 static CONST char *
2315 XEvent_mode_to_string (int mode) 2117 XEvent_mode_to_string (int mode)
2316 { 2118 {
2317 switch (mode) 2119 switch (mode)
2318 { 2120 {
2319 case NotifyNormal: return "Normal"; 2121 case NotifyNormal: return "Normal";
2322 case NotifyWhileGrabbed: return "WhileGrabbed"; 2124 case NotifyWhileGrabbed: return "WhileGrabbed";
2323 default: return "???"; 2125 default: return "???";
2324 } 2126 }
2325 } 2127 }
2326 2128
2327 static const char * 2129 static CONST char *
2328 XEvent_detail_to_string (int detail) 2130 XEvent_detail_to_string (int detail)
2329 { 2131 {
2330 switch (detail) 2132 switch (detail)
2331 { 2133 {
2332 case NotifyAncestor: return "Ancestor"; 2134 case NotifyAncestor: return "Ancestor";
2338 case NotifyDetailNone: return "DetailNone"; 2140 case NotifyDetailNone: return "DetailNone";
2339 default: return "???"; 2141 default: return "???";
2340 } 2142 }
2341 } 2143 }
2342 2144
2343 static const char * 2145 static CONST char *
2344 XEvent_visibility_to_string (int state) 2146 XEvent_visibility_to_string (int state)
2345 { 2147 {
2346 switch (state) 2148 switch (state)
2347 { 2149 {
2348 case VisibilityFullyObscured: return "FullyObscured"; 2150 case VisibilityFullyObscured: return "FullyObscured";
2507 /* get the next event from Xt */ 2309 /* get the next event from Xt */
2508 /************************************************************************/ 2310 /************************************************************************/
2509 2311
2510 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail; 2312 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail;
2511 2313
2512 void 2314 static void
2513 enqueue_Xt_dispatch_event (Lisp_Object event) 2315 enqueue_Xt_dispatch_event (Lisp_Object event)
2514 { 2316 {
2515 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); 2317 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail);
2516 } 2318 }
2517 2319
2543 2345
2544 enqueue_Xt_dispatch_event (event); 2346 enqueue_Xt_dispatch_event (event);
2545 } 2347 }
2546 2348
2547 static void 2349 static void
2548 emacs_Xt_next_event (Lisp_Event *emacs_event) 2350 emacs_Xt_next_event (struct Lisp_Event *emacs_event)
2549 { 2351 {
2550 we_didnt_get_an_event: 2352 we_didnt_get_an_event:
2551 2353
2552 while (NILP (dispatch_event_queue) && 2354 while (NILP (dispatch_event_queue) &&
2553 !completed_timeouts && 2355 !completed_timeouts &&
2928 /* This is exported by the Xt library (at least by mine). If this 2730 /* This is exported by the Xt library (at least by mine). If this
2929 isn't the case somewhere, rename this appropriately and remove 2731 isn't the case somewhere, rename this appropriately and remove
2930 the '#if 0'. Note, however, that I got "unknown structure" 2732 the '#if 0'. Note, however, that I got "unknown structure"
2931 errors when I tried this. */ 2733 errors when I tried this. */
2932 XtConvertArgRec Const colorConvertArgs[] = { 2734 XtConvertArgRec Const colorConvertArgs[] = {
2933 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), 2735 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
2934 sizeof (Screen *) }, 2736 sizeof(Screen *)},
2935 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), 2737 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
2936 sizeof (Colormap) } 2738 sizeof(Colormap)}
2937 }; 2739 };
2938 2740
2939 #endif 2741 #endif
2940 2742
2941 #define done(type, value) \ 2743 #define done(type, value) \
3073 } 2875 }
3074 } 2876 }
3075 2877
3076 2878
3077 /************************************************************************/ 2879 /************************************************************************/
3078 /* handle focus changes for native widgets */
3079 /************************************************************************/
3080 static void
3081 emacs_Xt_event_widget_focus_in (Widget w,
3082 XEvent *event,
3083 String *params,
3084 Cardinal *num_params)
3085 {
3086 struct frame* f =
3087 x_any_widget_or_parent_to_frame (get_device_from_display (event->xany.display), w);
3088
3089 XtSetKeyboardFocus (FRAME_X_SHELL_WIDGET (f), w);
3090 }
3091
3092 static void
3093 emacs_Xt_event_widget_focus_out (Widget w,
3094 XEvent *event,
3095 String *params,
3096 Cardinal *num_params)
3097 {
3098 }
3099
3100 static XtActionsRec widgetActionsList[] =
3101 {
3102 {"widget-focus-in", emacs_Xt_event_widget_focus_in },
3103 {"widget-focus-out", emacs_Xt_event_widget_focus_out },
3104 };
3105
3106 static void
3107 emacs_Xt_event_add_widget_actions (XtAppContext ctx)
3108 {
3109 XtAppAddActions (ctx, widgetActionsList, 2);
3110 }
3111
3112
3113 /************************************************************************/
3114 /* initialization */ 2880 /* initialization */
3115 /************************************************************************/ 2881 /************************************************************************/
3116 2882
3117 void 2883 void
3118 syms_of_event_Xt (void) 2884 syms_of_event_Xt (void)
3119 { 2885 {
3120 defsymbol (&Qkey_mapping, "key-mapping"); 2886 defsymbol (&Qkey_mapping, "key-mapping");
3121 defsymbol (&Qsans_modifiers, "sans-modifiers"); 2887 defsymbol (&Qsans_modifiers, "sans-modifiers");
3122 defsymbol (&Qself_insert_command, "self-insert-command");
3123 } 2888 }
3124 2889
3125 void 2890 void
3126 reinit_vars_of_event_Xt (void) 2891 vars_of_event_Xt (void)
3127 { 2892 {
2893 dispatch_event_queue = Qnil;
2894 staticpro (&dispatch_event_queue);
2895 dispatch_event_queue_tail = Qnil;
2896
2897 /* this function only makes safe calls */
2898 init_what_input_once ();
2899
3128 Xt_event_stream = xnew (struct event_stream); 2900 Xt_event_stream = xnew (struct event_stream);
3129 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p; 2901 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
3130 Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending;
3131 Xt_event_stream->next_event_cb = emacs_Xt_next_event; 2902 Xt_event_stream->next_event_cb = emacs_Xt_next_event;
3132 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event; 2903 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
3133 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout; 2904 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
3134 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout; 2905 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout;
3135 Xt_event_stream->select_console_cb = emacs_Xt_select_console; 2906 Xt_event_stream->select_console_cb = emacs_Xt_select_console;
3138 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process; 2909 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process;
3139 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p; 2910 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
3140 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair; 2911 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
3141 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair; 2912 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
3142 2913
3143 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype); 2914 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
3144 2915 *Non-nil makes modifier keys sticky.
3145 last_quit_check_signal_tick_count = 0; 2916 This means that you can release the modifier key before pressing down
3146 2917 the key that you wish to be modified. Although this is non-standard
3147 /* this function only makes safe calls */ 2918 behavior, it is recommended because it reduces the strain on your hand,
3148 init_what_input_once (); 2919 thus reducing the incidence of the dreaded Emacs-pinky syndrome.
3149 } 2920 */ );
3150 2921 modifier_keys_are_sticky = 0;
3151 void
3152 vars_of_event_Xt (void)
3153 {
3154 reinit_vars_of_event_Xt ();
3155
3156 dispatch_event_queue = Qnil;
3157 staticpro (&dispatch_event_queue);
3158 dispatch_event_queue_tail = Qnil;
3159 pdump_wire (&dispatch_event_queue_tail);
3160 2922
3161 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /* 2923 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /*
3162 *Non-nil means to allow synthetic events. Nil means they are ignored. 2924 *Non-nil means to allow synthetic events. Nil means they are ignored.
3163 Beware: allowing emacs to process SendEvents opens a big security hole. 2925 Beware: allowing emacs to process SendEvents opens a big security hole.
3164 */ ); 2926 */ );
3172 1 == non-verbose output 2934 1 == non-verbose output
3173 2 == verbose output 2935 2 == verbose output
3174 */ ); 2936 */ );
3175 x_debug_events = 0; 2937 x_debug_events = 0;
3176 #endif 2938 #endif
2939
2940 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
2941
2942 last_quit_check_signal_tick_count = 0;
3177 } 2943 }
3178 2944
3179 /* This mess is a hack that patches the shell widget to treat visual inheritance 2945 /* This mess is a hack that patches the shell widget to treat visual inheritance
3180 the same as colormap and depth inheritance */ 2946 the same as colormap and depth inheritance */
3181 2947
3218 /* In xselect.c */ 2984 /* In xselect.c */
3219 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000); 2985 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000);
3220 XSetErrorHandler (x_error_handler); 2986 XSetErrorHandler (x_error_handler);
3221 XSetIOErrorHandler (x_IO_error_handler); 2987 XSetIOErrorHandler (x_IO_error_handler);
3222 2988
3223 #ifndef WIN32_NATIVE 2989 #ifndef WINDOWSNT
3224 XtAppAddInput (Xt_app_con, signal_event_pipe[0], 2990 XtAppAddInput (Xt_app_con, signal_event_pipe[0],
3225 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */), 2991 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
3226 Xt_what_callback, 0); 2992 Xt_what_callback, 0);
3227 #endif 2993 #endif
3228 2994
3235 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles, 3001 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles,
3236 EmacsXtCvtStringToXIMStyles, 3002 EmacsXtCvtStringToXIMStyles,
3237 NULL, 0, 3003 NULL, 0,
3238 XtCacheByDisplay, EmacsFreeXIMStyles); 3004 XtCacheByDisplay, EmacsFreeXIMStyles);
3239 #endif /* XIM_XLIB */ 3005 #endif /* XIM_XLIB */
3240 /* Add extra actions to native widgets to handle focus and friends. */
3241 emacs_Xt_event_add_widget_actions (Xt_app_con);
3242 3006
3243 /* insert the visual inheritance patch/hack described above */ 3007 /* insert the visual inheritance patch/hack described above */
3244 orig_shell_init_proc = shellClassRec.core_class.initialize; 3008 orig_shell_init_proc = shellClassRec.core_class.initialize;
3245 shellClassRec.core_class.initialize = ShellVisualPatch; 3009 shellClassRec.core_class.initialize = ShellVisualPatch;
3246 3010