comparison src/event-Xt.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents 064ab7fed2e0
children 2f8bb876ab1d
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
76 #endif 76 #endif
77 77
78 #include "events-mod.h" 78 #include "events-mod.h"
79 79
80 static void enqueue_Xt_dispatch_event (Lisp_Object event); 80 static void enqueue_Xt_dispatch_event (Lisp_Object event);
81 static void handle_focus_event_1 (struct frame *f, int in_p);
81 82
82 static struct event_stream *Xt_event_stream; 83 static struct event_stream *Xt_event_stream;
83 84
84 /* With the new event model, all events go through XtDispatchEvent() 85 /* With the new event model, all events go through XtDispatchEvent()
85 and are picked up by an event handler that is added to each frame 86 and are picked up by an event handler that is added to each frame
106 static int tty_events_occurred; 107 static int tty_events_occurred;
107 108
108 /* Mask of bits indicating the descriptors that we wait for input on */ 109 /* Mask of bits indicating the descriptors that we wait for input on */
109 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; 110 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
110 111
111 static CONST String x_fallback_resources[] = 112 static const String x_fallback_resources[] =
112 { 113 {
113 /* This file is automatically generated from the app-defaults file 114 /* This file is automatically generated from the app-defaults file
114 in ../etc/Emacs.ad. These resources are consulted only if no 115 in ../etc/Emacs.ad. These resources are consulted only if no
115 app-defaults file is found at all. 116 app-defaults file is found at all.
116 */ 117 */
118 0 119 0
119 }; 120 };
120 121
121 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p); 122 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
122 void emacs_Xt_mapping_action (Widget w, XEvent *event); 123 void emacs_Xt_mapping_action (Widget w, XEvent *event);
123 void debug_process_finalization (struct Lisp_Process *p); 124 void debug_process_finalization (Lisp_Process *p);
124 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event, 125 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
125 Boolean *continue_to_dispatch); 126 Boolean *continue_to_dispatch);
126 127
127 static int last_quit_check_signal_tick_count; 128 static int last_quit_check_signal_tick_count;
128 129
171 172
172 Emacs detects keyboard configurations which violate the above rules, and 173 Emacs detects keyboard configurations which violate the above rules, and
173 prints an error message on the standard-error-output. (Perhaps it should 174 prints an error message on the standard-error-output. (Perhaps it should
174 use a pop-up-window instead.) 175 use a pop-up-window instead.)
175 */ 176 */
177
178 /* For every key on the keyboard that has a known character correspondence,
179 we define the ascii-character property of the keysym, and make the
180 default binding for the key be self-insert-command.
181
182 The following magic is basically intimate knowledge of X11/keysymdef.h.
183 The keysym mappings defined by X11 are based on the iso8859 standards,
184 except for Cyrillic and Greek.
185
186 In a non-Mule world, a user can still have a multi-lingual editor, by doing
187 (set-face-font "...-iso8859-2" (current-buffer))
188 for all their Latin-2 buffers, etc. */
189
190 static Lisp_Object
191 x_keysym_to_character (KeySym keysym)
192 {
193 #ifdef MULE
194 Lisp_Object charset = Qzero;
195 #define USE_CHARSET(var,cs) \
196 ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
197 #else
198 #define USE_CHARSET(var,lb)
199 #endif /* MULE */
200 int code = 0;
201
202 if ((keysym & 0xff) < 0xa0)
203 return Qnil;
204
205 switch (keysym >> 8)
206 {
207 case 0: /* ASCII + Latin1 */
208 USE_CHARSET (charset, LATIN_ISO8859_1);
209 code = keysym & 0x7f;
210 break;
211 case 1: /* Latin2 */
212 USE_CHARSET (charset, LATIN_ISO8859_2);
213 code = keysym & 0x7f;
214 break;
215 case 2: /* Latin3 */
216 USE_CHARSET (charset, LATIN_ISO8859_3);
217 code = keysym & 0x7f;
218 break;
219 case 3: /* Latin4 */
220 USE_CHARSET (charset, LATIN_ISO8859_4);
221 code = keysym & 0x7f;
222 break;
223 case 4: /* Katakana */
224 USE_CHARSET (charset, KATAKANA_JISX0201);
225 if ((keysym & 0xff) > 0xa0)
226 code = keysym & 0x7f;
227 break;
228 case 5: /* Arabic */
229 USE_CHARSET (charset, ARABIC_ISO8859_6);
230 code = keysym & 0x7f;
231 break;
232 case 6: /* Cyrillic */
233 {
234 static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
235 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
236 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
237 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
238 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
239 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
240 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
241 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
242 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
243 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
244 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
245 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
246 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
247 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
248 code = cyrillic[(keysym & 0x7f) - 0x20];
249 break;
250 }
251 case 7: /* Greek */
252 {
253 static unsigned char const greek[] = /* 0x20 - 0x7f */
254 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
255 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
256 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
257 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
259 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
260 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
261 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
263 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
264 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
265 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
266 USE_CHARSET (charset, GREEK_ISO8859_7);
267 code = greek[(keysym & 0x7f) - 0x20];
268 break;
269 }
270 case 8: /* Technical */
271 break;
272 case 9: /* Special */
273 break;
274 case 10: /* Publishing */
275 break;
276 case 11: /* APL */
277 break;
278 case 12: /* Hebrew */
279 USE_CHARSET (charset, HEBREW_ISO8859_8);
280 code = keysym & 0x7f;
281 break;
282 case 13: /* Thai */
283 /* #### This needs to deal with character composition. */
284 USE_CHARSET (charset, THAI_TIS620);
285 code = keysym & 0x7f;
286 break;
287 case 14: /* Korean Hangul */
288 break;
289 case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
290 break;
291 case 32: /* Currency */
292 break;
293 default:
294 break;
295 }
296
297 if (code == 0)
298 return Qnil;
299
300 #ifdef MULE
301 return make_char (MAKE_CHAR (charset, code, 0));
302 #else
303 return make_char (code + 0x80);
304 #endif
305 }
306
307 /* #### The way that keysym correspondence to characters should work:
308 - a Lisp_Event should contain a keysym AND a character slot.
309 - keybindings are tried with the keysym. If no binding can be found,
310 and there is a corresponding character, call self-insert-command.
311
312 #### Nuke x-iso8859-1.el.
313 #### Nuke the Qascii_character property.
314 #### Nuke Vcharacter_set_property.
315 */
316 static void
317 maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
318 {
319 Lisp_Object character = x_keysym_to_character (keysym);
320
321 if (CHARP (character))
322 {
323 extern Lisp_Object Vcurrent_global_map;
324 extern Lisp_Object Qascii_character;
325 Fput (symbol, Qascii_character, character);
326 if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
327 Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
328 }
329 }
330
331 static void
332 x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
333 {
334 KeySym upper_lower[2];
335 int j;
336
337 if (keysym < 0x80) /* Optimize for ASCII keysyms */
338 return;
339
340 /* If you execute:
341 xmodmap -e 'keysym NN = scaron'
342 and then press (Shift scaron), X11 will return the different
343 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'.
344 So we "register" both `scaron' and `Scaron'. */
345 #ifdef HAVE_XCONVERTCASE
346 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
347 #else
348 upper_lower[0] = upper_lower[1] = keysym;
349 #endif
350
351 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
352 {
353 char *name;
354 keysym = upper_lower[j];
355
356 name = XKeysymToString (keysym);
357 if (name)
358 {
359 /* X guarantees NAME to be in the Host Portable Character Encoding */
360 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
361 Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
362 Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
363
364 if (! EQ (old_value, new_value)
365 && ! (EQ (old_value, Qsans_modifiers) &&
366 EQ (new_value, Qt)))
367 {
368 maybe_define_x_key_as_self_inserting_character (keysym, sym);
369 Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
370 Fputhash (sym, new_value, hash_table);
371 }
372 }
373 }
374 }
176 375
177 static void 376 static void
178 x_reset_key_mapping (struct device *d) 377 x_reset_key_mapping (struct device *d)
179 { 378 {
180 Display *display = DEVICE_X_DISPLAY (d); 379 Display *display = DEVICE_X_DISPLAY (d);
209 int j; 408 int j;
210 409
211 if (keysym[0] == NoSymbol) 410 if (keysym[0] == NoSymbol)
212 continue; 411 continue;
213 412
214 { 413 x_has_keysym (keysym[0], hash_table, 0);
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 }
223 414
224 for (j = 1; j < keysyms_per_code; j++) 415 for (j = 1; j < keysyms_per_code; j++)
225 { 416 {
226 if (keysym[j] != keysym[0] && 417 if (keysym[j] != keysym[0] &&
227 keysym[j] != NoSymbol) 418 keysym[j] != NoSymbol)
228 { 419 x_has_keysym (keysym[j], hash_table, 1);
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 }
237 } 420 }
238 } 421 }
239 } 422 }
240 423
241 static CONST char * 424 static const char *
242 index_to_name (int indice) 425 index_to_name (int indice)
243 { 426 {
244 switch (indice) 427 switch (indice)
245 { 428 {
246 case ShiftMapIndex: return "ModShift"; 429 case ShiftMapIndex: return "ModShift";
391 interpret that bit as Meta, because we can't make XLookupString() 574 interpret that bit as Meta, because we can't make XLookupString()
392 not interpret it as Mode_switch; and interpreting it as both would 575 not interpret it as Mode_switch; and interpreting it as both would
393 be totally wrong. */ 576 be totally wrong. */
394 if (mode_bit) 577 if (mode_bit)
395 { 578 {
396 CONST char *warn = 0; 579 const char *warn = 0;
397 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; 580 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
398 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; 581 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
399 else if (mode_bit == super_bit) warn = "Super", super_bit = 0; 582 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
400 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0; 583 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
401 if (warn) 584 if (warn)
805 Lookup_String: /* Come-From XBufferOverflow */ 988 Lookup_String: /* Come-From XBufferOverflow */
806 #ifdef XIM_MOTIF 989 #ifdef XIM_MOTIF
807 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window), 990 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
808 event, bufptr, bufsiz, &keysym, &status); 991 event, bufptr, bufsiz, &keysym, &status);
809 #else /* XIM_XLIB */ 992 #else /* XIM_XLIB */
810 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status); 993 if (xic)
994 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
811 #endif /* HAVE_XIM */ 995 #endif /* HAVE_XIM */
812 996
813 #ifdef DEBUG_XEMACS 997 #ifdef DEBUG_XEMACS
814 if (x_debug_events > 0) 998 if (x_debug_events > 0)
815 { 999 {
856 Emchar ch; 1040 Emchar ch;
857 Lisp_Object instream, fb_instream; 1041 Lisp_Object instream, fb_instream;
858 Lstream *istr; 1042 Lstream *istr;
859 struct gcpro gcpro1, gcpro2; 1043 struct gcpro gcpro1, gcpro2;
860 1044
861 fb_instream = 1045 fb_instream = make_fixed_buffer_input_stream (bufptr, len);
862 make_fixed_buffer_input_stream ((unsigned char *) bufptr, len); 1046
863 1047 /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */
864 /* ### Use Fget_coding_system (Vcomposed_input_coding_system) */
865 instream = 1048 instream =
866 make_decoding_input_stream (XLSTREAM (fb_instream), 1049 make_decoding_input_stream (XLSTREAM (fb_instream),
867 Fget_coding_system (Qundecided)); 1050 Fget_coding_system (Qundecided));
868 1051
869 istr = XLSTREAM (instream); 1052 istr = XLSTREAM (instream);
870 1053
871 GCPRO2 (instream, fb_instream); 1054 GCPRO2 (instream, fb_instream);
872 while ((ch = Lstream_get_emchar (istr)) != EOF) 1055 while ((ch = Lstream_get_emchar (istr)) != EOF)
873 { 1056 {
874 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); 1057 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
875 struct Lisp_Event *ev = XEVENT (emacs_event); 1058 Lisp_Event *ev = XEVENT (emacs_event);
876 ev->channel = DEVICE_CONSOLE (d); 1059 ev->channel = DEVICE_CONSOLE (d);
877 ev->event_type = key_press_event; 1060 ev->event_type = key_press_event;
878 ev->timestamp = event->time; 1061 ev->timestamp = event->time;
879 ev->event.key.modifiers = 0; 1062 ev->event.key.modifiers = 0;
880 ev->event.key.keysym = make_char (ch); 1063 ev->event.key.keysym = make_char (ch);
917 } 1100 }
918 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t; 1101 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t;
919 } 1102 }
920 1103
921 static int 1104 static int
922 x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event) 1105 x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
923 { 1106 {
924 Display *display = x_event->xany.display; 1107 Display *display = x_event->xany.display;
925 struct device *d = get_device_from_display (display); 1108 struct device *d = get_device_from_display (display);
926 struct x_device *xd = DEVICE_X_DATA (d); 1109 struct x_device *xd = DEVICE_X_DATA (d);
927 1110
1044 } 1227 }
1045 else /* Mouse press/release event */ 1228 else /* Mouse press/release event */
1046 { 1229 {
1047 XButtonEvent *ev = &x_event->xbutton; 1230 XButtonEvent *ev = &x_event->xbutton;
1048 struct frame *frame = x_window_to_frame (d, ev->window); 1231 struct frame *frame = x_window_to_frame (d, ev->window);
1232
1049 if (! frame) 1233 if (! frame)
1050 return 0; /* not for us */ 1234 return 0; /* not for us */
1051 XSETFRAME (emacs_event->channel, frame); 1235 XSETFRAME (emacs_event->channel, frame);
1052 1236
1053 emacs_event->event_type = (x_event->type == ButtonPress) ? 1237 emacs_event->event_type = (x_event->type == ButtonPress) ?
1056 emacs_event->event.button.modifiers = modifiers; 1240 emacs_event->event.button.modifiers = modifiers;
1057 emacs_event->timestamp = ev->time; 1241 emacs_event->timestamp = ev->time;
1058 emacs_event->event.button.button = ev->button; 1242 emacs_event->event.button.button = ev->button;
1059 emacs_event->event.button.x = ev->x; 1243 emacs_event->event.button.x = ev->x;
1060 emacs_event->event.button.y = ev->y; 1244 emacs_event->event.button.y = ev->y;
1061 1245 /* because we don't seem to get a FocusIn event for button clicks
1246 when a widget-glyph is selected we will assume that we want the
1247 focus if a button gets pressed. */
1248 if (x_event->type == ButtonPress)
1249 handle_focus_event_1 (frame, 1);
1062 } 1250 }
1063 } 1251 }
1064 break; 1252 break;
1065 1253
1066 case MotionNotify: 1254 case MotionNotify:
1182 l_type = Qdragdrop_MIME; 1370 l_type = Qdragdrop_MIME;
1183 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ), 1371 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
1184 make_string ((Bufbyte *)"8bit", 4), 1372 make_string ((Bufbyte *)"8bit", 4),
1185 make_ext_string ((Extbyte *)data, 1373 make_ext_string ((Extbyte *)data,
1186 strlen((char *)data), 1374 strlen((char *)data),
1187 FORMAT_CTEXT) ) ); 1375 Qctext) ) );
1188 break; 1376 break;
1189 case DndMIME: 1377 case DndMIME:
1190 /* we have to parse this in some way to extract 1378 /* we have to parse this in some way to extract
1191 content-type and params (in the tm way) and 1379 content-type and params (in the tm way) and
1192 content encoding. 1380 content encoding.
1195 to tm... 1383 to tm...
1196 */ 1384 */
1197 l_type = Qdragdrop_MIME; 1385 l_type = Qdragdrop_MIME;
1198 l_dndlist = list1 ( make_ext_string ((Extbyte *)data, 1386 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1199 strlen((char *)data), 1387 strlen((char *)data),
1200 FORMAT_BINARY) ); 1388 Qbinary) );
1201 break; 1389 break;
1202 case DndFile: 1390 case DndFile:
1203 case DndDir: 1391 case DndDir:
1204 case DndLink: 1392 case DndLink:
1205 case DndExe: 1393 case DndExe:
1216 case DndURL: 1404 case DndURL:
1217 /* as it is a real URL it should already be escaped 1405 /* as it is a real URL it should already be escaped
1218 and escaping again will break them (cause % is unsave) */ 1406 and escaping again will break them (cause % is unsave) */
1219 l_dndlist = list1 ( make_ext_string ((Extbyte *)data, 1407 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1220 strlen ((char *)data), 1408 strlen ((char *)data),
1221 FORMAT_FILENAME) ); 1409 Qfile_name) );
1222 l_type = Qdragdrop_URL; 1410 l_type = Qdragdrop_URL;
1223 break; 1411 break;
1224 default: /* Unknown, RawData and any other type */ 1412 default: /* Unknown, RawData and any other type */
1225 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ), 1413 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ),
1226 make_string ((Bufbyte *)"8bit", 4), 1414 make_string ((Bufbyte *)"8bit", 4),
1227 make_ext_string ((Extbyte *)data, 1415 make_ext_string ((Extbyte *)data,
1228 size, 1416 size,
1229 FORMAT_BINARY) ) ); 1417 Qbinary) ) );
1230 l_type = Qdragdrop_MIME; 1418 l_type = Qdragdrop_MIME;
1231 break; 1419 break;
1232 } 1420 }
1233 1421
1234 emacs_event->event.misc.function = Qdragdrop_drop_dispatch; 1422 emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
1302 /************************************************************************/ 1490 /************************************************************************/
1303 1491
1304 static void 1492 static void
1305 handle_focus_event_1 (struct frame *f, int in_p) 1493 handle_focus_event_1 (struct frame *f, int in_p)
1306 { 1494 {
1495 #if XtSpecificationRelease > 5
1496 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
1497 #endif
1307 #ifdef HAVE_XIM 1498 #ifdef HAVE_XIM
1308 XIM_focus_event (f, in_p); 1499 XIM_focus_event (f, in_p);
1309 #endif /* HAVE_XIM */ 1500 #endif /* HAVE_XIM */
1310 1501
1311 /* On focus change, clear all memory of sticky modifiers 1502 /* On focus change, clear all memory of sticky modifiers
1317 we enqueue it. 1508 we enqueue it.
1318 1509
1319 Actually, we half handle it: we handle it as far as changing the 1510 Actually, we half handle it: we handle it as far as changing the
1320 box cursor for redisplay, but we don't call any hooks or do any 1511 box cursor for redisplay, but we don't call any hooks or do any
1321 select-frame stuff until after the sit-for. 1512 select-frame stuff until after the sit-for.
1322 */ 1513
1514 Unfortunately native widgets break the model because they grab
1515 the keyboard focus and nothing sets it back again. I cannot find
1516 any reasonable way to do this elsewhere so we assert here that
1517 the keyboard focus is on the emacs text widget. Menus and dialogs
1518 do this in their selection callback, but we don't want that since
1519 a button having focus is legitimate. An edit field having focus
1520 is mandatory. Weirdly you get a FocusOut event when you click in
1521 a widget-glyph but you don't get a correspondng FocusIn when you
1522 click in the frame. Why is this? */
1523 if (in_p
1524 #if XtSpecificationRelease > 5
1525 && FRAME_X_TEXT_WIDGET (f) != focus_widget
1526 #endif
1527 )
1528 {
1529 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
1530 FRAME_X_TEXT_WIDGET (f));
1531 }
1532 /* do the generic event-stream stuff. */
1323 { 1533 {
1324 Lisp_Object frm; 1534 Lisp_Object frm;
1325 Lisp_Object conser; 1535 Lisp_Object conser;
1326 struct gcpro gcpro1; 1536 struct gcpro gcpro1;
1327 1537
1402 { 1612 {
1403 XWindowAttributes xwa; 1613 XWindowAttributes xwa;
1404 1614
1405 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM) 1615 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
1406 send synthetic MapNotify events when a window is first 1616 send synthetic MapNotify events when a window is first
1407 created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE. 1617 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
1408 Or something like that. We initially tried a different 1618 Or something like that. We initially tried a different
1409 solution below, but that ran into a different window- 1619 solution below, but that ran into a different window-
1410 manager bug. 1620 manager bug.
1411 1621
1412 It seems that the only reliable way is to treat a 1622 It seems that the only reliable way is to treat a
1510 #endif 1720 #endif
1511 } 1721 }
1512 } 1722 }
1513 1723
1514 static void 1724 static void
1515 emacs_Xt_handle_magic_event (struct Lisp_Event *emacs_event) 1725 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
1516 { 1726 {
1517 /* This function can GC */ 1727 /* This function can GC */
1518 XEvent *event = &emacs_event->event.magic.underlying_x_event; 1728 XEvent *event = &emacs_event->event.magic.underlying_x_event;
1519 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event)); 1729 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
1520 1730
1538 case PropertyNotify: 1748 case PropertyNotify:
1539 x_handle_property_notify (&event->xproperty); 1749 x_handle_property_notify (&event->xproperty);
1540 break; 1750 break;
1541 1751
1542 case Expose: 1752 case Expose:
1543 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, 1753 if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
1544 event->xexpose.width, event->xexpose.height); 1754 event->xexpose.width, event->xexpose.height)
1755 &&
1756 !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
1757 event->xexpose.width, event->xexpose.height))
1758 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1759 event->xexpose.width, event->xexpose.height);
1545 break; 1760 break;
1546 1761
1547 case GraphicsExpose: /* This occurs when an XCopyArea's source area was 1762 case GraphicsExpose: /* This occurs when an XCopyArea's source area was
1548 obscured or not available. */ 1763 obscured or not available. */
1549 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, 1764 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1577 } 1792 }
1578 break; 1793 break;
1579 1794
1580 case FocusIn: 1795 case FocusIn:
1581 case FocusOut: 1796 case FocusOut:
1797
1582 #ifdef EXTERNAL_WIDGET 1798 #ifdef EXTERNAL_WIDGET
1583 /* External widget lossage: Ben said: 1799 /* External widget lossage: Ben said:
1584 YUCK. The only way to make focus changes work properly is to 1800 YUCK. The only way to make focus changes work properly is to
1585 completely ignore all FocusIn/FocusOut events and depend only 1801 completely ignore all FocusIn/FocusOut events and depend only
1586 on notifications from the ExternalClient widget. */ 1802 on notifications from the ExternalClient widget. */
1631 static int timeout_id_tick; 1847 static int timeout_id_tick;
1632 1848
1633 /* Xt interval id's might not fit into an int (they're pointers, as it 1849 /* Xt interval id's might not fit into an int (they're pointers, as it
1634 happens), so we need to provide a conversion list. */ 1850 happens), so we need to provide a conversion list. */
1635 1851
1636 struct Xt_timeout 1852 static struct Xt_timeout
1637 { 1853 {
1638 int id; 1854 int id;
1639 XtIntervalId interval_id; 1855 XtIntervalId interval_id;
1640 struct Xt_timeout *next; 1856 struct Xt_timeout *next;
1641 } *pending_timeouts, *completed_timeouts; 1857 } *pending_timeouts, *completed_timeouts;
1642 1858
1643 struct Xt_timeout_blocktype 1859 static struct Xt_timeout_blocktype
1644 { 1860 {
1645 Blocktype_declare (struct Xt_timeout); 1861 Blocktype_declare (struct Xt_timeout);
1646 } *the_Xt_timeout_blocktype; 1862 } *the_Xt_timeout_blocktype;
1647 1863
1648 /* called by XtAppNextEvent() */ 1864 /* called by XtAppNextEvent() */
1745 if (timeout) 1961 if (timeout)
1746 Blocktype_free (the_Xt_timeout_blocktype, timeout); 1962 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1747 } 1963 }
1748 1964
1749 static void 1965 static void
1750 Xt_timeout_to_emacs_event (struct Lisp_Event *emacs_event) 1966 Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
1751 { 1967 {
1752 struct Xt_timeout *timeout = completed_timeouts; 1968 struct Xt_timeout *timeout = completed_timeouts;
1753 assert (timeout); 1969 assert (timeout);
1754 completed_timeouts = completed_timeouts->next; 1970 completed_timeouts = completed_timeouts->next;
1755 emacs_event->event_type = timeout_event; 1971 emacs_event->event_type = timeout_event;
1912 xfree (closure); 2128 xfree (closure);
1913 filedesc_to_what_closure[fd] = 0; 2129 filedesc_to_what_closure[fd] = 0;
1914 } 2130 }
1915 2131
1916 static void 2132 static void
1917 emacs_Xt_select_process (struct Lisp_Process *p) 2133 emacs_Xt_select_process (Lisp_Process *p)
1918 { 2134 {
1919 Lisp_Object process; 2135 Lisp_Object process;
1920 int infd = event_stream_unixoid_select_process (p); 2136 int infd = event_stream_unixoid_select_process (p);
1921 2137
1922 XSETPROCESS (process, p); 2138 XSETPROCESS (process, p);
1923 select_filedesc (infd, process); 2139 select_filedesc (infd, process);
1924 } 2140 }
1925 2141
1926 static void 2142 static void
1927 emacs_Xt_unselect_process (struct Lisp_Process *p) 2143 emacs_Xt_unselect_process (Lisp_Process *p)
1928 { 2144 {
1929 int infd = event_stream_unixoid_unselect_process (p); 2145 int infd = event_stream_unixoid_unselect_process (p);
1930 2146
1931 unselect_filedesc (infd); 2147 unselect_filedesc (infd);
1932 } 2148 }
1951 2167
1952 /* This is called from GC when a process object is about to be freed. 2168 /* This is called from GC when a process object is about to be freed.
1953 If we've still got pointers to it in this file, we're gonna lose hard. 2169 If we've still got pointers to it in this file, we're gonna lose hard.
1954 */ 2170 */
1955 void 2171 void
1956 debug_process_finalization (struct Lisp_Process *p) 2172 debug_process_finalization (Lisp_Process *p)
1957 { 2173 {
1958 #if 0 /* #### */ 2174 #if 0 /* #### */
1959 int i; 2175 int i;
1960 Lisp_Object instr, outstr; 2176 Lisp_Object instr, outstr;
1961 2177
1971 } 2187 }
1972 #endif 2188 #endif
1973 } 2189 }
1974 2190
1975 static void 2191 static void
1976 Xt_process_to_emacs_event (struct Lisp_Event *emacs_event) 2192 Xt_process_to_emacs_event (Lisp_Event *emacs_event)
1977 { 2193 {
1978 int i; 2194 int i;
1979 Lisp_Object process;
1980 2195
1981 assert (process_events_occurred > 0); 2196 assert (process_events_occurred > 0);
2197
1982 for (i = 0; i < MAXDESC; i++) 2198 for (i = 0; i < MAXDESC; i++)
1983 { 2199 {
1984 process = filedesc_with_input[i]; 2200 Lisp_Object process = filedesc_with_input[i];
1985 if (PROCESSP (process)) 2201 if (PROCESSP (process))
1986 break; 2202 {
1987 } 2203 filedesc_with_input[i] = Qnil;
1988 assert (i < MAXDESC); 2204 process_events_occurred--;
1989 filedesc_with_input[i] = Qnil; 2205 /* process events have nil as channel */
1990 process_events_occurred--; 2206 emacs_event->event_type = process_event;
1991 /* process events have nil as channel */ 2207 emacs_event->timestamp = 0; /* #### */
1992 emacs_event->event_type = process_event; 2208 emacs_event->event.process.process = process;
1993 emacs_event->timestamp = 0; /* #### */ 2209 return;
1994 emacs_event->event.process.process = process; 2210 }
2211 }
2212 abort ();
1995 } 2213 }
1996 2214
1997 static void 2215 static void
1998 emacs_Xt_select_console (struct console *con) 2216 emacs_Xt_select_console (struct console *con)
1999 { 2217 {
2000 Lisp_Object console; 2218 Lisp_Object console;
2001 int infd; 2219 int infd;
2002 #ifdef HAVE_GPM
2003 int mousefd;
2004 #endif
2005 2220
2006 if (CONSOLE_X_P (con)) 2221 if (CONSOLE_X_P (con))
2007 return; /* X consoles are automatically selected for when we 2222 return; /* X consoles are automatically selected for when we
2008 initialize them in Xt */ 2223 initialize them in Xt */
2009 infd = event_stream_unixoid_select_console (con); 2224 infd = event_stream_unixoid_select_console (con);
2010 XSETCONSOLE (console, con); 2225 XSETCONSOLE (console, con);
2011 select_filedesc (infd, console); 2226 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
2028 } 2227 }
2029 2228
2030 static void 2229 static void
2031 emacs_Xt_unselect_console (struct console *con) 2230 emacs_Xt_unselect_console (struct console *con)
2032 { 2231 {
2033 Lisp_Object console; 2232 Lisp_Object console;
2034 int infd; 2233 int infd;
2035 #ifdef HAVE_GPM
2036 int mousefd;
2037 #endif
2038 2234
2039 if (CONSOLE_X_P (con)) 2235 if (CONSOLE_X_P (con))
2040 return; /* X consoles are automatically selected for when we 2236 return; /* X consoles are automatically selected for when we
2041 initialize them in Xt */ 2237 initialize them in Xt */
2042 infd = event_stream_unixoid_unselect_console (con); 2238 infd = event_stream_unixoid_unselect_console (con);
2043 XSETCONSOLE (console, con); 2239 XSETCONSOLE (console, con);
2044 unselect_filedesc (infd); 2240 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
2054 } 2241 }
2055 2242
2056 /* read an event from a tty, if one is available. Returns non-zero 2243 /* read an event from a tty, if one is available. Returns non-zero
2057 if an event was available. Note that when this function is 2244 if an event was available. Note that when this function is
2058 called, there should always be a tty marked as ready for input. 2245 called, there should always be a tty marked as ready for input.
2060 may not really be any input available. (In this case, 2247 may not really be any input available. (In this case,
2061 read_event_from_tty_or_stream_desc() will arrange for the TTY device 2248 read_event_from_tty_or_stream_desc() will arrange for the TTY device
2062 to be deleted.) */ 2249 to be deleted.) */
2063 2250
2064 static int 2251 static int
2065 Xt_tty_to_emacs_event (struct Lisp_Event *emacs_event) 2252 Xt_tty_to_emacs_event (Lisp_Event *emacs_event)
2066 { 2253 {
2067 int i; 2254 int i;
2068 2255
2069 assert (tty_events_occurred > 0); 2256 assert (tty_events_occurred > 0);
2070 for (i = 0; i < MAXDESC; i++) 2257 for (i = 0; i < MAXDESC; i++)
2106 if (f) 2293 if (f)
2107 { 2294 {
2108 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4); 2295 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
2109 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name)); 2296 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
2110 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0, 2297 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
2111 strlen (buf), FORMAT_TERMINAL); 2298 strlen (buf), Qterminal);
2112 } 2299 }
2113 stderr_out ("\n"); 2300 stderr_out ("\n");
2114 } 2301 }
2115 2302
2116 static CONST char * 2303 static const char *
2117 XEvent_mode_to_string (int mode) 2304 XEvent_mode_to_string (int mode)
2118 { 2305 {
2119 switch (mode) 2306 switch (mode)
2120 { 2307 {
2121 case NotifyNormal: return "Normal"; 2308 case NotifyNormal: return "Normal";
2124 case NotifyWhileGrabbed: return "WhileGrabbed"; 2311 case NotifyWhileGrabbed: return "WhileGrabbed";
2125 default: return "???"; 2312 default: return "???";
2126 } 2313 }
2127 } 2314 }
2128 2315
2129 static CONST char * 2316 static const char *
2130 XEvent_detail_to_string (int detail) 2317 XEvent_detail_to_string (int detail)
2131 { 2318 {
2132 switch (detail) 2319 switch (detail)
2133 { 2320 {
2134 case NotifyAncestor: return "Ancestor"; 2321 case NotifyAncestor: return "Ancestor";
2140 case NotifyDetailNone: return "DetailNone"; 2327 case NotifyDetailNone: return "DetailNone";
2141 default: return "???"; 2328 default: return "???";
2142 } 2329 }
2143 } 2330 }
2144 2331
2145 static CONST char * 2332 static const char *
2146 XEvent_visibility_to_string (int state) 2333 XEvent_visibility_to_string (int state)
2147 { 2334 {
2148 switch (state) 2335 switch (state)
2149 { 2336 {
2150 case VisibilityFullyObscured: return "FullyObscured"; 2337 case VisibilityFullyObscured: return "FullyObscured";
2345 2532
2346 enqueue_Xt_dispatch_event (event); 2533 enqueue_Xt_dispatch_event (event);
2347 } 2534 }
2348 2535
2349 static void 2536 static void
2350 emacs_Xt_next_event (struct Lisp_Event *emacs_event) 2537 emacs_Xt_next_event (Lisp_Event *emacs_event)
2351 { 2538 {
2352 we_didnt_get_an_event: 2539 we_didnt_get_an_event:
2353 2540
2354 while (NILP (dispatch_event_queue) && 2541 while (NILP (dispatch_event_queue) &&
2355 !completed_timeouts && 2542 !completed_timeouts &&
2730 /* This is exported by the Xt library (at least by mine). If this 2917 /* This is exported by the Xt library (at least by mine). If this
2731 isn't the case somewhere, rename this appropriately and remove 2918 isn't the case somewhere, rename this appropriately and remove
2732 the '#if 0'. Note, however, that I got "unknown structure" 2919 the '#if 0'. Note, however, that I got "unknown structure"
2733 errors when I tried this. */ 2920 errors when I tried this. */
2734 XtConvertArgRec Const colorConvertArgs[] = { 2921 XtConvertArgRec Const colorConvertArgs[] = {
2735 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), 2922 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
2736 sizeof(Screen *)}, 2923 sizeof (Screen *) },
2737 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), 2924 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
2738 sizeof(Colormap)} 2925 sizeof (Colormap) }
2739 }; 2926 };
2740 2927
2741 #endif 2928 #endif
2742 2929
2743 #define done(type, value) \ 2930 #define done(type, value) \
2883 void 3070 void
2884 syms_of_event_Xt (void) 3071 syms_of_event_Xt (void)
2885 { 3072 {
2886 defsymbol (&Qkey_mapping, "key-mapping"); 3073 defsymbol (&Qkey_mapping, "key-mapping");
2887 defsymbol (&Qsans_modifiers, "sans-modifiers"); 3074 defsymbol (&Qsans_modifiers, "sans-modifiers");
3075 defsymbol (&Qself_insert_command, "self-insert-command");
2888 } 3076 }
2889 3077
2890 void 3078 void
2891 vars_of_event_Xt (void) 3079 reinit_vars_of_event_Xt (void)
2892 { 3080 {
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
2900 Xt_event_stream = xnew (struct event_stream); 3081 Xt_event_stream = xnew (struct event_stream);
2901 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p; 3082 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
2902 Xt_event_stream->next_event_cb = emacs_Xt_next_event; 3083 Xt_event_stream->next_event_cb = emacs_Xt_next_event;
2903 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event; 3084 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
2904 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout; 3085 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
2909 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process; 3090 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process;
2910 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p; 3091 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
2911 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair; 3092 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
2912 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair; 3093 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
2913 3094
3095 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
3096
3097 last_quit_check_signal_tick_count = 0;
3098
3099 /* this function only makes safe calls */
3100 init_what_input_once ();
3101 }
3102
3103 void
3104 vars_of_event_Xt (void)
3105 {
3106 reinit_vars_of_event_Xt ();
3107
3108 dispatch_event_queue = Qnil;
3109 staticpro (&dispatch_event_queue);
3110 dispatch_event_queue_tail = Qnil;
3111 pdump_wire (&dispatch_event_queue_tail);
3112
2914 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /* 3113 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
2915 *Non-nil makes modifier keys sticky. 3114 *Non-nil makes modifier keys sticky.
2916 This means that you can release the modifier key before pressing down 3115 This means that you can release the modifier key before pressing down
2917 the key that you wish to be modified. Although this is non-standard 3116 the key that you wish to be modified. Although this is non-standard
2918 behavior, it is recommended because it reduces the strain on your hand, 3117 behavior, it is recommended because it reduces the strain on your hand,
2934 1 == non-verbose output 3133 1 == non-verbose output
2935 2 == verbose output 3134 2 == verbose output
2936 */ ); 3135 */ );
2937 x_debug_events = 0; 3136 x_debug_events = 0;
2938 #endif 3137 #endif
2939
2940 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
2941
2942 last_quit_check_signal_tick_count = 0;
2943 } 3138 }
2944 3139
2945 /* This mess is a hack that patches the shell widget to treat visual inheritance 3140 /* This mess is a hack that patches the shell widget to treat visual inheritance
2946 the same as colormap and depth inheritance */ 3141 the same as colormap and depth inheritance */
2947 3142