1 /* The event_stream interface for X11 with Xt, and/or tty frames.
2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1996 Ben Wing.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: Not in FSF. */
28 #include "console-x.h"
29 #include "../lwlib/lwlib.h"
30 #include "EmacsFrame.h"
32 #include "blocktype.h"
35 #include "console-tty.h"
38 #include "objects-x.h"
40 #include "redisplay.h"
44 #include "sysproc.h" /* for MAXDESC */
46 #include "xintrinsicp.h" /* CoreP.h needs this */
47 #include <X11/CoreP.h> /* Numerous places access the fields of
48 a core widget directly. We could
49 use XtGetValues(), but ... */
50 #include <X11/ShellP.h>
57 #include "file-coding.h"
64 #if defined (HAVE_OFFIX_DND)
68 #include "events-mod.h"
70 void enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p);
71 static void handle_focus_event_1 (struct frame *f, int in_p);
72 static void handle_focus_event_2 (Window w, struct frame *f, int in_p);
74 static struct event_stream *Xt_event_stream;
76 /* With the new event model, all events go through XtDispatchEvent()
77 and are picked up by an event handler that is added to each frame
78 widget. (This is how it's supposed to be.) In the old method,
79 Emacs sucks out events directly from XtNextEvent() and only
80 dispatches the events that it doesn't need to deal with. This
81 old way has lots of corresponding junk that is no longer
82 necessary: lwlib extensions, synthetic XAnyEvents, unnecessary
85 /* The one and only one application context that Emacs uses. */
86 XtAppContext Xt_app_con;
88 /* Do we accept events sent by other clients? */
89 int x_allow_sendevents;
92 Fixnum debug_x_events;
95 static int process_events_occurred;
96 static int tty_events_occurred;
97 static Widget widget_with_focus;
99 /* Mask of bits indicating the descriptors that we wait for input on */
100 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
102 static const String x_fallback_resources[] =
104 /* This file is automatically generated from the app-defaults file
105 in ../etc/Emacs.ad. These resources are consulted only if no
106 app-defaults file is found at all.
108 #include <Emacs.ad.h>
112 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
113 void emacs_Xt_mapping_action (Widget w, XEvent *event);
114 void debug_process_finalization (Lisp_Process *p);
115 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
116 Boolean *continue_to_dispatch);
118 static int last_quit_check_signal_tick_count;
120 Lisp_Object Qkey_mapping;
121 Lisp_Object Qsans_modifiers;
124 /************************************************************************/
125 /* keymap handling */
126 /************************************************************************/
128 /* X bogusly doesn't define the interpretations of any bits besides
129 ModControl, ModShift, and ModLock; so the Interclient Communication
130 Conventions Manual says that we have to bend over backwards to figure
131 out what the other modifier bits mean. According to ICCCM:
133 - Any keycode which is assigned ModControl is a "control" key.
135 - Any modifier bit which is assigned to a keycode which generates Meta_L
136 or Meta_R is the modifier bit meaning "meta". Likewise for Super, Hyper,
139 - Any keypress event which contains ModControl in its state should be
140 interpreted as a "control" character.
142 - Any keypress event which contains a modifier bit in its state which is
143 generated by a keycode whose corresponding keysym is Meta_L or Meta_R
144 should be interpreted as a "meta" character. Likewise for Super, Hyper,
147 - It is illegal for a keysym to be associated with more than one modifier
150 This means that the only thing that emacs can reasonably interpret as a
151 "meta" key is a key whose keysym is Meta_L or Meta_R, and which generates
152 one of the modifier bits Mod1-Mod5.
154 Unfortunately, many keyboards don't have Meta keys in their default
155 configuration. So, if there are no Meta keys, but there are "Alt" keys,
156 emacs will interpret Alt as Meta. If there are both Meta and Alt keys,
157 then the Meta keys mean "Meta", and the Alt keys mean "Alt" (it used to
158 mean "Symbol," but that just confused the hell out of way too many people).
160 This works with the default configurations of the 19 keyboard-types I've
163 Emacs detects keyboard configurations which violate the above rules, and
164 prints an error message on the standard-error-output. (Perhaps it should
165 use a pop-up-window instead.)
168 /* For every key on the keyboard that has a known character correspondence,
169 we define the ascii-character property of the keysym, and make the
170 default binding for the key be self-insert-command.
172 The following magic is basically intimate knowledge of X11/keysymdef.h.
173 The keysym mappings defined by X11 are based on the iso8859 standards,
174 except for Cyrillic and Greek.
176 In a non-Mule world, a user can still have a multi-lingual editor, by doing
177 (set-face-font "...-iso8859-2" (current-buffer))
178 for all their Latin-2 buffers, etc. */
181 x_keysym_to_character (KeySym keysym)
184 Lisp_Object charset = Qzero;
185 #define USE_CHARSET(var,cs) \
186 ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
188 #define USE_CHARSET(var,lb)
192 if ((keysym & 0xff) < 0xa0)
197 case 0: /* ASCII + Latin1 */
198 USE_CHARSET (charset, LATIN_ISO8859_1);
199 code = keysym & 0x7f;
202 USE_CHARSET (charset, LATIN_ISO8859_2);
203 code = keysym & 0x7f;
206 USE_CHARSET (charset, LATIN_ISO8859_3);
207 code = keysym & 0x7f;
210 USE_CHARSET (charset, LATIN_ISO8859_4);
211 code = keysym & 0x7f;
213 case 4: /* Katakana */
214 USE_CHARSET (charset, KATAKANA_JISX0201);
215 if ((keysym & 0xff) > 0xa0)
216 code = keysym & 0x7f;
219 USE_CHARSET (charset, ARABIC_ISO8859_6);
220 code = keysym & 0x7f;
222 case 6: /* Cyrillic */
224 static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
225 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
226 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
227 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
228 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
229 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
230 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
231 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
232 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
233 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
234 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
235 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
236 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
237 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
238 code = cyrillic[(keysym & 0x7f) - 0x20];
243 static unsigned char const greek[] = /* 0x20 - 0x7f */
244 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
245 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
246 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
247 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
249 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
250 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
251 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
253 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
254 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
255 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
256 USE_CHARSET (charset, GREEK_ISO8859_7);
257 code = greek[(keysym & 0x7f) - 0x20];
260 case 8: /* Technical */
262 case 9: /* Special */
264 case 10: /* Publishing */
268 case 12: /* Hebrew */
269 USE_CHARSET (charset, HEBREW_ISO8859_8);
270 code = keysym & 0x7f;
273 /* #### This needs to deal with character composition. */
274 USE_CHARSET (charset, THAI_TIS620);
275 code = keysym & 0x7f;
277 case 14: /* Korean Hangul */
279 case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
281 case 32: /* Currency */
291 return make_char (MAKE_CHAR (charset, code, 0));
293 return make_char (code + 0x80);
297 /* #### The way that keysym correspondence to characters should work:
298 - a Lisp_Event should contain a keysym AND a character slot.
299 - keybindings are tried with the keysym. If no binding can be found,
300 and there is a corresponding character, call self-insert-command.
302 #### Nuke x-iso8859-1.el.
303 #### Nuke the Qascii_character property.
304 #### Nuke Vcharacter_set_property.
307 maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
309 Lisp_Object character = x_keysym_to_character (keysym);
311 if (CHARP (character))
313 extern Lisp_Object Vcurrent_global_map;
314 extern Lisp_Object Qascii_character;
315 if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
317 Fput (symbol, Qascii_character, character);
318 Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
324 x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
326 KeySym upper_lower[2];
329 if (keysym < 0x80) /* Optimize for ASCII keysyms */
333 xmodmap -e 'keysym NN = scaron'
334 and then press (Shift scaron), X11 will return the different
335 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'.
336 So we "register" both `scaron' and `Scaron'. */
337 #ifdef HAVE_XCONVERTCASE
338 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
340 upper_lower[0] = upper_lower[1] = keysym;
343 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
346 keysym = upper_lower[j];
348 name = XKeysymToString (keysym);
351 /* X guarantees NAME to be in the Host Portable Character Encoding */
352 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
353 Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
354 Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
356 if (! EQ (old_value, new_value)
357 && ! (EQ (old_value, Qsans_modifiers) &&
360 maybe_define_x_key_as_self_inserting_character (keysym, sym);
361 Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
362 Fputhash (sym, new_value, hash_table);
369 x_reset_key_mapping (struct device *d)
371 Display *display = DEVICE_X_DISPLAY (d);
372 struct x_device *xd = DEVICE_X_DATA (d);
373 KeySym *keysym, *keysym_end;
374 Lisp_Object hash_table;
375 int key_code_count, keysyms_per_code;
377 if (xd->x_keysym_map)
378 XFree ((char *) xd->x_keysym_map);
379 XDisplayKeycodes (display,
380 &xd->x_keysym_map_min_code,
381 &xd->x_keysym_map_max_code);
382 key_code_count = xd->x_keysym_map_max_code - xd->x_keysym_map_min_code + 1;
384 XGetKeyboardMapping (display, xd->x_keysym_map_min_code, key_code_count,
385 &xd->x_keysym_map_keysyms_per_code);
387 hash_table = xd->x_keysym_map_hash_table;
388 if (HASH_TABLEP (hash_table))
389 Fclrhash (hash_table);
391 xd->x_keysym_map_hash_table = hash_table =
392 make_lisp_hash_table (128, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
394 for (keysym = xd->x_keysym_map,
395 keysyms_per_code = xd->x_keysym_map_keysyms_per_code,
396 keysym_end = keysym + (key_code_count * keysyms_per_code);
398 keysym += keysyms_per_code)
402 if (keysym[0] == NoSymbol)
405 x_has_keysym (keysym[0], hash_table, 0);
407 for (j = 1; j < keysyms_per_code; j++)
409 if (keysym[j] != keysym[0] &&
410 keysym[j] != NoSymbol)
411 x_has_keysym (keysym[j], hash_table, 1);
417 index_to_name (int indice)
421 case ShiftMapIndex: return "ModShift";
422 case LockMapIndex: return "ModLock";
423 case ControlMapIndex: return "ModControl";
424 case Mod1MapIndex: return "Mod1";
425 case Mod2MapIndex: return "Mod2";
426 case Mod3MapIndex: return "Mod3";
427 case Mod4MapIndex: return "Mod4";
428 case Mod5MapIndex: return "Mod5";
429 default: return "???";
433 /* Boy, I really wish C had local functions... */
434 struct c_doesnt_have_closures /* #### not yet used */
436 int warned_about_overlapping_modifiers;
437 int warned_about_predefined_modifiers;
438 int warned_about_duplicate_modifiers;
447 x_reset_modifier_mapping (struct device *d)
449 Display *display = DEVICE_X_DISPLAY (d);
450 struct x_device *xd = DEVICE_X_DATA (d);
451 int modifier_index, modifier_key, column, mkpm;
452 int warned_about_overlapping_modifiers = 0;
453 int warned_about_predefined_modifiers = 0;
454 int warned_about_duplicate_modifiers = 0;
461 xd->lock_interpretation = 0;
463 if (xd->x_modifier_keymap)
464 XFreeModifiermap (xd->x_modifier_keymap);
466 x_reset_key_mapping (d);
468 xd->x_modifier_keymap = XGetModifierMapping (display);
470 /* Boy, I really wish C had local functions...
473 /* The call to warn_when_safe must be on the same line as the string or
474 make-msgfile won't pick it up properly (the newline doesn't confuse
475 it, but the backslash does). */
477 #define modwarn(name,old,other) \
478 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is generated by %s.", \
479 name, code, index_to_name (old), other), \
480 warned_about_overlapping_modifiers = 1
482 #define modbarf(name,other) \
483 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
484 name, code, other), \
485 warned_about_predefined_modifiers = 1
487 #define check_modifier(name,mask) \
488 if ((1<<modifier_index) != mask) \
489 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
490 name, code, index_to_name (modifier_index)), \
491 warned_about_predefined_modifiers = 1
493 #define store_modifier(name,old) \
494 if (old && old != modifier_index) \
495 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates both %s and %s, which is nonsensical.",\
496 name, code, index_to_name (old), \
497 index_to_name (modifier_index)), \
498 warned_about_duplicate_modifiers = 1; \
499 if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift"); \
500 else if (modifier_index == LockMapIndex) modbarf (name,"ModLock"); \
501 else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl"); \
502 else if (sym == XK_Mode_switch) \
503 mode_bit = modifier_index; /* Mode_switch is special, see below... */ \
504 else if (modifier_index == meta_bit && old != meta_bit) \
505 modwarn (name, meta_bit, "Meta"); \
506 else if (modifier_index == super_bit && old != super_bit) \
507 modwarn (name, super_bit, "Super"); \
508 else if (modifier_index == hyper_bit && old != hyper_bit) \
509 modwarn (name, hyper_bit, "Hyper"); \
510 else if (modifier_index == alt_bit && old != alt_bit) \
511 modwarn (name, alt_bit, "Alt"); \
513 old = modifier_index;
515 mkpm = xd->x_modifier_keymap->max_keypermod;
516 for (modifier_index = 0; modifier_index < 8; modifier_index++)
517 for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
519 for (column = 0; column < 4; column += 2) {
520 KeyCode code = xd->x_modifier_keymap->modifiermap[modifier_index * mkpm
522 KeySym sym = (code ? XKeycodeToKeysym (display, code, column) : 0);
523 if (sym == last_sym) continue;
526 case XK_Mode_switch:store_modifier ("Mode_switch", mode_bit); break;
527 case XK_Meta_L: store_modifier ("Meta_L", meta_bit); break;
528 case XK_Meta_R: store_modifier ("Meta_R", meta_bit); break;
529 case XK_Super_L: store_modifier ("Super_L", super_bit); break;
530 case XK_Super_R: store_modifier ("Super_R", super_bit); break;
531 case XK_Hyper_L: store_modifier ("Hyper_L", hyper_bit); break;
532 case XK_Hyper_R: store_modifier ("Hyper_R", hyper_bit); break;
533 case XK_Alt_L: store_modifier ("Alt_L", alt_bit); break;
534 case XK_Alt_R: store_modifier ("Alt_R", alt_bit); break;
535 case XK_Control_L: check_modifier ("Control_L", ControlMask); break;
536 case XK_Control_R: check_modifier ("Control_R", ControlMask); break;
537 case XK_Shift_L: check_modifier ("Shift_L", ShiftMask); break;
538 case XK_Shift_R: check_modifier ("Shift_R", ShiftMask); break;
539 case XK_Shift_Lock: check_modifier ("Shift_Lock", LockMask);
540 xd->lock_interpretation = XK_Shift_Lock; break;
541 case XK_Caps_Lock: check_modifier ("Caps_Lock", LockMask);
542 xd->lock_interpretation = XK_Caps_Lock; break;
544 /* It probably doesn't make any sense for a modifier bit to be
545 assigned to a key that is not one of the above, but OpenWindows
546 assigns modifier bits to a couple of random function keys for
547 no reason that I can discern, so printing a warning here would
552 #undef store_modifier
553 #undef check_modifier
557 /* If there was no Meta key, then try using the Alt key instead.
558 If there is both a Meta key and an Alt key, then the Alt key
559 is not disturbed and remains an Alt key. */
560 if (! meta_bit && alt_bit)
561 meta_bit = alt_bit, alt_bit = 0;
563 /* mode_bit overrides everything, since it's processed down inside of
564 XLookupString() instead of by us. If Meta and Mode_switch both
565 generate the same modifier bit (which is an error), then we don't
566 interpret that bit as Meta, because we can't make XLookupString()
567 not interpret it as Mode_switch; and interpreting it as both would
571 const char *warn = 0;
572 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
573 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
574 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
575 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
579 (Qkey_mapping, Qwarning,
580 "XEmacs: %s is being used for both Mode_switch and %s.",
581 index_to_name (mode_bit), warn),
582 warned_about_overlapping_modifiers = 1;
587 xd->MetaMask = (meta_bit ? (1 << meta_bit) : 0);
588 xd->HyperMask = (hyper_bit ? (1 << hyper_bit) : 0);
589 xd->SuperMask = (super_bit ? (1 << super_bit) : 0);
590 xd->AltMask = (alt_bit ? (1 << alt_bit) : 0);
591 xd->ModeMask = (mode_bit ? (1 << mode_bit) : 0); /* unused */
594 if (warned_about_overlapping_modifiers)
595 warn_when_safe (Qkey_mapping, Qwarning, "\n"
596 " Two distinct modifier keys (such as Meta and Hyper) cannot generate\n"
597 " the same modifier bit, because Emacs won't be able to tell which\n"
598 " modifier was actually held down when some other key is pressed. It\n"
599 " won't be able to tell Meta-x and Hyper-x apart, for example. Change\n"
600 " one of these keys to use some other modifier bit. If you intend for\n"
601 " these keys to have the same behavior, then change them to have the\n"
602 " same keysym as well as the same modifier bit.");
604 if (warned_about_predefined_modifiers)
605 warn_when_safe (Qkey_mapping, Qwarning, "\n"
606 " The semantics of the modifier bits ModShift, ModLock, and ModControl\n"
607 " are predefined. It does not make sense to assign ModControl to any\n"
608 " keysym other than Control_L or Control_R, or to assign any modifier\n"
609 " bits to the \"control\" keysyms other than ModControl. You can't\n"
610 " turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n"
611 " assigning the key a different modifier bit. You must also make that\n"
612 " key generate an appropriate keysym (Control_L, Meta_L, etc).");
614 /* No need to say anything more for warned_about_duplicate_modifiers. */
616 if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers)
617 warn_when_safe (Qkey_mapping, Qwarning, "\n"
618 " The meanings of the modifier bits Mod1 through Mod5 are determined\n"
619 " by the keysyms used to control those bits. Mod1 does NOT always\n"
620 " mean Meta, although some non-ICCCM-compliant programs assume that.");
624 x_init_modifier_mapping (struct device *d)
626 struct x_device *xd = DEVICE_X_DATA (d);
627 xd->x_keysym_map_hash_table = Qnil;
628 xd->x_keysym_map = NULL;
629 xd->x_modifier_keymap = NULL;
630 x_reset_modifier_mapping (d);
634 x_key_is_modifier_p (KeyCode keycode, struct device *d)
636 struct x_device *xd = DEVICE_X_DATA (d);
640 if (keycode < xd->x_keysym_map_min_code ||
641 keycode > xd->x_keysym_map_max_code)
644 syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
645 xd->x_keysym_map_keysyms_per_code];
646 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
647 if (IsModifierKey (syms [i]) ||
648 syms [i] == XK_Mode_switch) /* why doesn't IsModifierKey count this? */
653 /* key-handling code is always ugly. It just ends up working out
656 Here are some pointers:
658 -- DOWN_MASK indicates which modifiers should be treated as "down"
659 when the corresponding upstroke happens. It gets reset for
660 a particular modifier when that modifier goes up, and reset
661 for all modifiers when a non-modifier key is pressed. Example:
663 I press Control-A-Shift and then release Control-A-Shift.
664 I want the Shift key to be sticky but not the Control key.
666 -- LAST_DOWNKEY and RELEASE_TIME are used to keep track of
667 auto-repeat -- see below.
669 -- If a modifier key is sticky, I can unstick it by pressing
670 the modifier key again. */
673 x_handle_sticky_modifiers (XEvent *ev, struct device *d)
679 if (!modifier_keys_are_sticky) /* Optimize for non-sticky modifiers */
682 xd = DEVICE_X_DATA (d);
683 keycode = ev->xkey.keycode;
686 if (keycode < xd->x_keysym_map_min_code ||
687 keycode > xd->x_keysym_map_max_code)
690 if (! ((type == KeyPress || type == KeyRelease) &&
691 x_key_is_modifier_p (keycode, d)))
692 { /* Not a modifier key */
693 Bool key_event_p = (type == KeyPress || type == KeyRelease);
695 if (type == ButtonPress
697 && ((xd->last_downkey
698 && ((keycode != xd->last_downkey
699 || ev->xkey.time != xd->release_time)))
700 || (INTP (Vmodifier_keys_sticky_time)
702 > (xd->modifier_release_time
703 + XINT (Vmodifier_keys_sticky_time))))))
705 xd->need_to_add_mask = 0;
706 xd->last_downkey = 0;
708 else if (type == KeyPress && !xd->last_downkey)
709 xd->last_downkey = keycode;
711 if (type == KeyPress)
712 xd->release_time = 0;
713 if (type == KeyPress || type == ButtonPress)
716 xd->modifier_release_time = 0;
720 ev->xkey.state |= xd->need_to_add_mask;
722 ev->xbutton.state |= xd->need_to_add_mask;
724 if (type == KeyRelease && keycode == xd->last_downkey)
725 /* If I hold press-and-release the Control key and then press
726 and hold down the right arrow, I want it to auto-repeat
727 Control-Right. On the other hand, if I do the same but
728 manually press the Right arrow a bunch of times, I want
729 to see one Control-Right and then a bunch of Rights.
730 This means that we need to distinguish between an
731 auto-repeated key and a key pressed and released a bunch
734 Naturally, the designers of the X spec didn't see fit
735 to provide an obvious way to distinguish these cases.
736 So we assume that if the release and the next press
737 occur at the same time, the key was actually auto-
738 repeated. Under Open-Windows, at least, this works. */
739 xd->modifier_release_time = xd->release_time
740 = key_event_p ? ev->xkey.time : ev->xbutton.time;
742 else /* Modifier key pressed */
745 KeySym *syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
746 xd->x_keysym_map_keysyms_per_code];
748 /* If a non-modifier key was pressed in the middle of a bunch
749 of modifiers, then it unsticks all the modifiers that were
750 previously pressed. We cannot unstick the modifiers until
751 now because we want to check for auto-repeat of the
754 if (xd->last_downkey)
756 xd->last_downkey = 0;
757 xd->need_to_add_mask = 0;
760 if (xd->modifier_release_time
761 && INTP (Vmodifier_keys_sticky_time)
763 > xd->modifier_release_time + XINT (Vmodifier_keys_sticky_time)))
765 xd->need_to_add_mask = 0;
771 if (type == KeyPress) \
773 /* If modifier key is already sticky, \
774 then unstick it. Note that we do \
775 not test down_mask to deal with the \
776 unlikely but possible case that the \
777 modifier key auto-repeats. */ \
778 if (xd->need_to_add_mask & mask) \
780 xd->need_to_add_mask &= ~mask; \
781 xd->down_mask &= ~mask; \
784 xd->down_mask |= mask; \
788 if (xd->down_mask & mask) \
790 xd->down_mask &= ~mask; \
791 xd->need_to_add_mask |= mask; \
794 xd->modifier_release_time = ev->xkey.time; \
797 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
800 case XK_Control_L: case XK_Control_R: FROB (ControlMask); break;
801 case XK_Shift_L: case XK_Shift_R: FROB (ShiftMask); break;
802 case XK_Meta_L: case XK_Meta_R: FROB (xd->MetaMask); break;
803 case XK_Super_L: case XK_Super_R: FROB (xd->SuperMask); break;
804 case XK_Hyper_L: case XK_Hyper_R: FROB (xd->HyperMask); break;
805 case XK_Alt_L: case XK_Alt_R: FROB (xd->AltMask); break;
812 clear_sticky_modifiers (struct device *d)
814 struct x_device *xd = DEVICE_X_DATA (d);
816 xd->need_to_add_mask = 0;
817 xd->last_downkey = 0;
818 xd->release_time = 0;
823 keysym_obeys_caps_lock_p (KeySym sym, struct device *d)
825 struct x_device *xd = DEVICE_X_DATA (d);
826 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic
827 characters, where "alphabetic" means something more than simply A-Z.
828 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC.
829 But if shift-lock is down, then it does. */
830 if (xd->lock_interpretation == XK_Shift_Lock)
834 ((sym >= XK_A) && (sym <= XK_Z)) ||
835 ((sym >= XK_a) && (sym <= XK_z)) ||
836 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) ||
837 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) ||
838 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) ||
839 ((sym >= XK_oslash) && (sym <= XK_thorn));
842 /* called from EmacsFrame.c (actually from Xt itself) when a
843 MappingNotify event is received. In its infinite wisdom, Xt
844 decided that Xt event handlers never get MappingNotify events.
845 O'Reilly Xt Programming Manual 9.1.2 says:
847 MappingNotify is automatically handled by Xt, so it isn't passed
848 to event handlers and you don't need to worry about it.
850 Of course, we DO worry about it, so we need a special translation. */
852 emacs_Xt_mapping_action (Widget w, XEvent* event)
854 struct device *d = get_device_from_display (event->xany.display);
856 if (DEVICE_X_BEING_DELETED (d))
859 /* nyet. Now this is handled by Xt. */
860 XRefreshKeyboardMapping (&event->xmapping);
862 /* xmodmap generates about a billion MappingKeyboard events, followed
863 by a single MappingModifier event, so it might be worthwhile to
864 take extra MappingKeyboard events out of the queue before requesting
865 the current keymap from the server. */
866 switch (event->xmapping.request)
868 case MappingKeyboard: x_reset_key_mapping (d); break;
869 case MappingModifier: x_reset_modifier_mapping (d); break;
870 case MappingPointer: /* Do something here? */ break;
876 /************************************************************************/
877 /* X to Emacs event conversion */
878 /************************************************************************/
881 x_keysym_to_emacs_keysym (KeySym keysym, int simple_p)
884 if (keysym >= XK_exclam && keysym <= XK_asciitilde)
885 /* We must assume that the X keysym numbers for the ASCII graphic
886 characters are the same as their ASCII codes. */
887 return make_char (keysym);
891 /* These would be handled correctly by the default case, but by
892 special-casing them here we don't garbage a string or call
894 case XK_BackSpace: return QKbackspace;
895 case XK_Tab: return QKtab;
896 case XK_Linefeed: return QKlinefeed;
897 case XK_Return: return QKreturn;
898 case XK_Escape: return QKescape;
899 case XK_space: return QKspace;
900 case XK_Delete: return QKdelete;
903 if (simple_p) return Qnil;
904 /* !!#### not Mule-ized */
905 name = XKeysymToString (keysym);
906 if (!name || !name[0])
907 /* This happens if there is a mismatch between the Xlib of
908 XEmacs and the Xlib of the X server...
910 Let's hard-code in some knowledge of common keysyms introduced
911 in recent X11 releases. Snarfed from X11/keysymdef.h
913 Probably we should add some stuff here for X11R6. */
916 case 0xFF95: return KEYSYM ("kp-home");
917 case 0xFF96: return KEYSYM ("kp-left");
918 case 0xFF97: return KEYSYM ("kp-up");
919 case 0xFF98: return KEYSYM ("kp-right");
920 case 0xFF99: return KEYSYM ("kp-down");
921 case 0xFF9A: return KEYSYM ("kp-prior");
922 case 0xFF9B: return KEYSYM ("kp-next");
923 case 0xFF9C: return KEYSYM ("kp-end");
924 case 0xFF9D: return KEYSYM ("kp-begin");
925 case 0xFF9E: return KEYSYM ("kp-insert");
926 case 0xFF9F: return KEYSYM ("kp-delete");
928 case 0x1005FF10: return KEYSYM ("SunF36"); /* labeled F11 */
929 case 0x1005FF11: return KEYSYM ("SunF37"); /* labeled F12 */
933 sprintf (buf, "unknown-keysym-0x%X", (int) keysym);
937 /* If it's got a one-character name, that's good enough. */
939 return make_char (name[0]);
941 /* If it's in the "Keyboard" character set, downcase it.
942 The case of those keysyms is too totally random for us to
943 force anyone to remember them.
944 The case of the other character sets is significant, however.
946 if ((((unsigned int) keysym) & (~0x1FF)) == ((unsigned int) 0xFE00))
950 for (s1 = name, s2 = buf; *s1; s1++, s2++) {
954 *s2 = tolower (* (unsigned char *) s1);
960 return KEYSYM (name);
965 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
966 /* simple_p means don't try too hard (ASCII only) */
972 /* Some implementations of XmbLookupString don't return
973 XBufferOverflow correctly, so increase the size of the xim input
974 buffer from 64 to the more reasonable size 513, as Emacs has done.
975 From Kenichi Handa. */
977 char *bufptr = buffer;
978 int bufsiz = sizeof (buffer);
981 XIC xic = FRAME_X_XIC (x_any_window_to_frame
982 (get_device_from_display (event->display),
984 #endif /* XIM_XLIB */
985 #endif /* HAVE_XIM */
987 /* We use XLookupString if we're not using XIM, or are using
988 XIM_XLIB but input context creation failed. */
989 #if ! (defined (HAVE_XIM) && defined (XIM_MOTIF))
990 #if defined (HAVE_XIM) && defined (XIM_XLIB)
992 #endif /* XIM_XLIB */
994 /* Apparently it's necessary to specify a dummy here (rather
995 than passing in 0) to avoid crashes on German IRIX */
997 XLookupString (event, dummy, 200, &keysym, 0);
998 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
999 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
1001 #endif /* ! XIM_MOTIF */
1004 Lookup_String: /* Come-From XBufferOverflow */
1006 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
1007 event, bufptr, bufsiz, &keysym, &status);
1008 #else /* XIM_XLIB */
1010 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
1011 #endif /* HAVE_XIM */
1014 if (debug_x_events > 0)
1016 stderr_out (" status=");
1017 #define print_status_when(S) if (status == S) stderr_out (#S)
1018 print_status_when (XLookupKeySym);
1019 print_status_when (XLookupBoth);
1020 print_status_when (XLookupChars);
1021 print_status_when (XLookupNone);
1022 print_status_when (XBufferOverflow);
1024 if (status == XLookupKeySym || status == XLookupBoth)
1025 stderr_out (" keysym=%s", XKeysymToString (keysym));
1026 if (status == XLookupChars || status == XLookupBoth)
1031 stderr_out (" chars=\"");
1032 for (j=0; j<len; j++)
1033 stderr_out ("%c", bufptr[j]);
1036 else if (bufptr[0] <= 32 || bufptr[0] >= 127)
1037 stderr_out (" char=0x%x", bufptr[0]);
1039 stderr_out (" char=%c", bufptr[0]);
1043 #endif /* DEBUG_XEMACS */
1049 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
1050 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
1054 /* Generate multiple emacs events */
1055 struct device *d = get_device_from_display (event->display);
1057 Lisp_Object instream, fb_instream;
1059 struct gcpro gcpro1, gcpro2;
1061 fb_instream = make_fixed_buffer_input_stream (bufptr, len);
1063 /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */
1065 make_decoding_input_stream (XLSTREAM (fb_instream),
1066 Fget_coding_system (Qundecided));
1068 istr = XLSTREAM (instream);
1070 GCPRO2 (instream, fb_instream);
1071 while ((ch = Lstream_get_emchar (istr)) != EOF)
1073 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1074 Lisp_Event *ev = XEVENT (emacs_event);
1075 ev->channel = DEVICE_CONSOLE (d);
1076 ev->event_type = key_press_event;
1077 ev->timestamp = event->time;
1078 ev->event.key.modifiers = 0;
1079 ev->event.key.keysym = make_char (ch);
1080 enqueue_Xt_dispatch_event (emacs_event);
1082 Lstream_close (istr);
1084 Lstream_delete (istr);
1085 Lstream_delete (XLSTREAM (fb_instream));
1088 case XLookupNone: return Qnil;
1089 case XBufferOverflow:
1090 bufptr = (char *) alloca (len+1);
1094 return Qnil; /* not reached */
1095 #endif /* HAVE_XIM */
1099 set_last_server_timestamp (struct device *d, XEvent *x_event)
1102 switch (x_event->type)
1105 case KeyRelease: t = x_event->xkey.time; break;
1107 case ButtonRelease: t = x_event->xbutton.time; break;
1109 case LeaveNotify: t = x_event->xcrossing.time; break;
1110 case MotionNotify: t = x_event->xmotion.time; break;
1111 case PropertyNotify: t = x_event->xproperty.time; break;
1112 case SelectionClear: t = x_event->xselectionclear.time; break;
1113 case SelectionRequest: t = x_event->xselectionrequest.time; break;
1114 case SelectionNotify: t = x_event->xselection.time; break;
1117 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t;
1121 x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
1123 Display *display = x_event->xany.display;
1124 struct device *d = get_device_from_display (display);
1125 struct x_device *xd = DEVICE_X_DATA (d);
1127 if (DEVICE_X_BEING_DELETED (d))
1128 /* #### Uh, is this 0 correct? */
1131 set_last_server_timestamp (d, x_event);
1133 switch (x_event->type)
1136 x_handle_sticky_modifiers (x_event, d);
1144 int shift_p, lock_p;
1145 Bool key_event_p = (x_event->type == KeyPress);
1146 unsigned int *state =
1147 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state;
1149 /* If this is a synthetic KeyPress or Button event, and the user
1150 has expressed a disinterest in this security hole, then drop
1153 ? x_event->xkey.send_event
1154 : x_event->xbutton.send_event)
1155 #ifdef EXTERNAL_WIDGET
1156 /* ben: events get sent to an ExternalShell using XSendEvent.
1157 This is not a perfect solution. */
1158 && !FRAME_X_EXTERNAL_WINDOW_P
1159 (x_any_window_to_frame (d, x_event->xany.window))
1161 && !x_allow_sendevents)
1164 DEVICE_X_MOUSE_TIMESTAMP (d) =
1165 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) =
1166 key_event_p ? x_event->xkey.time : x_event->xbutton.time;
1168 x_handle_sticky_modifiers (x_event, d);
1170 if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1171 if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1172 if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1173 if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1174 if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1176 int numero_de_botao = -1;
1179 numero_de_botao = x_event->xbutton.button;
1181 /* the button gets noted either in the button or the modifiers
1182 field, but not both. */
1183 if (numero_de_botao != 1 && (*state & Button1Mask))
1184 modifiers |= XEMACS_MOD_BUTTON1;
1185 if (numero_de_botao != 2 && (*state & Button2Mask))
1186 modifiers |= XEMACS_MOD_BUTTON2;
1187 if (numero_de_botao != 3 && (*state & Button3Mask))
1188 modifiers |= XEMACS_MOD_BUTTON3;
1189 if (numero_de_botao != 4 && (*state & Button4Mask))
1190 modifiers |= XEMACS_MOD_BUTTON4;
1191 if (numero_de_botao != 5 && (*state & Button5Mask))
1192 modifiers |= XEMACS_MOD_BUTTON5;
1195 /* Ignore the Caps_Lock key if:
1196 - any other modifiers are down, so that Caps_Lock doesn't
1197 turn C-x into C-X, which would suck.
1198 - the event was a mouse event. */
1199 if (modifiers || ! key_event_p)
1200 *state &= (~LockMask);
1202 shift_p = *state & ShiftMask;
1203 lock_p = *state & LockMask;
1205 if (shift_p || lock_p)
1206 modifiers |= XEMACS_MOD_SHIFT;
1211 XKeyEvent *ev = &x_event->xkey;
1212 /* This used to compute the frame from the given X window and
1213 store it here, but we really don't care about the frame. */
1214 emacs_event->channel = DEVICE_CONSOLE (d);
1215 keysym = x_to_emacs_keysym (&x_event->xkey, 0);
1217 /* If the emacs keysym is nil, then that means that the X
1218 keysym was either a Modifier or NoSymbol, which
1219 probably means that we're in the midst of reading a
1220 Multi_key sequence, or a "dead" key prefix, or XIM
1221 input. Ignore it. */
1225 /* More Caps_Lock garbage: Caps_Lock should *only* add the
1226 shift modifier to two-case keys (that is, A-Z and
1227 related characters). So at this point (after looking up
1228 the keysym) if the keysym isn't a dual-case alphabetic,
1229 and if the caps lock key was down but the shift key
1230 wasn't, then turn off the shift modifier. Gag barf */
1231 /* #### type lossage: assuming equivalence of emacs and
1233 /* !!#### maybe fix for Mule */
1234 if (lock_p && !shift_p &&
1235 ! (CHAR_OR_CHAR_INTP (keysym)
1236 && keysym_obeys_caps_lock_p
1237 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
1238 modifiers &= (~XEMACS_MOD_SHIFT);
1240 /* If this key contains two distinct keysyms, that is,
1241 "shift" generates a different keysym than the
1242 non-shifted key, then don't apply the shift modifier
1243 bit: it's implicit. Otherwise, if there would be no
1244 other way to tell the difference between the shifted
1245 and unshifted version of this key, apply the shift bit.
1246 Non-graphics, like Backspace and F1 get the shift bit
1247 in the modifiers slot. Neither the characters "a",
1248 "A", "2", nor "@" normally have the shift bit set.
1249 However, "F1" normally does. */
1250 if (modifiers & XEMACS_MOD_SHIFT)
1252 int Mode_switch_p = *state & xd->ModeMask;
1253 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
1254 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1);
1255 if (top && bot && top != bot)
1256 modifiers &= ~XEMACS_MOD_SHIFT;
1258 emacs_event->event_type = key_press_event;
1259 emacs_event->timestamp = ev->time;
1260 emacs_event->event.key.modifiers = modifiers;
1261 emacs_event->event.key.keysym = keysym;
1263 else /* Mouse press/release event */
1265 XButtonEvent *ev = &x_event->xbutton;
1266 struct frame *frame = x_window_to_frame (d, ev->window);
1269 return 0; /* not for us */
1270 XSETFRAME (emacs_event->channel, frame);
1272 emacs_event->event_type = (x_event->type == ButtonPress) ?
1273 button_press_event : button_release_event;
1275 emacs_event->event.button.modifiers = modifiers;
1276 emacs_event->timestamp = ev->time;
1277 emacs_event->event.button.button = ev->button;
1278 emacs_event->event.button.x = ev->x;
1279 emacs_event->event.button.y = ev->y;
1280 /* because we don't seem to get a FocusIn event for button clicks
1281 when a widget-glyph is selected we will assume that we want the
1282 focus if a button gets pressed. */
1283 if (x_event->type == ButtonPress)
1284 handle_focus_event_1 (frame, 1);
1291 XMotionEvent *ev = &x_event->xmotion;
1292 struct frame *frame = x_window_to_frame (d, ev->window);
1294 XMotionEvent event2;
1297 return 0; /* not for us */
1299 /* We use MotionHintMask, so we will get only one motion event
1300 until the next time we call XQueryPointer or the user
1301 clicks the mouse. So call XQueryPointer now (meaning that
1302 the event will be in sync with the server just before
1303 Fnext_event() returns). If the mouse is still in motion,
1304 then the server will immediately generate exactly one more
1305 motion event, which will be on the queue waiting for us
1306 next time around. */
1308 if (XQueryPointer (event2.display, event2.window,
1309 &event2.root, &event2.subwindow,
1310 &event2.x_root, &event2.y_root,
1311 &event2.x, &event2.y,
1313 ev = &event2; /* only one structure copy */
1315 DEVICE_X_MOUSE_TIMESTAMP (d) = ev->time;
1317 XSETFRAME (emacs_event->channel, frame);
1318 emacs_event->event_type = pointer_motion_event;
1319 emacs_event->timestamp = ev->time;
1320 emacs_event->event.motion.x = ev->x;
1321 emacs_event->event.motion.y = ev->y;
1322 if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
1323 if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1324 if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1325 if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1326 if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1327 if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1328 if (ev->state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1;
1329 if (ev->state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2;
1330 if (ev->state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3;
1331 if (ev->state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4;
1332 if (ev->state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5;
1333 /* Currently ignores Shift_Lock but probably shouldn't
1334 (but it definitely should ignore Caps_Lock). */
1335 emacs_event->event.motion.modifiers = modifiers;
1341 /* Patch bogus TAKE_FOCUS messages from MWM; CurrentTime is
1342 passed as the timestamp of the TAKE_FOCUS, which the ICCCM
1343 explicitly prohibits. */
1344 XClientMessageEvent *ev = &x_event->xclient;
1345 #ifdef HAVE_OFFIX_DND
1346 if (DndIsDropMessage(x_event))
1350 unsigned int button=0;
1351 struct frame *frame = x_any_window_to_frame (d, ev->window);
1353 unsigned long size, dtype;
1354 Lisp_Object l_type = Qnil, l_data = Qnil;
1355 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
1356 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1359 return 0; /* not for us */
1361 GCPRO4 (l_type, l_data, l_dndlist, l_item);
1362 XSETFRAME (emacs_event->channel, frame);
1364 emacs_event->event_type = misc_user_event;
1365 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1367 state=DndDragButtons(x_event);
1369 if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
1370 if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1371 if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1372 if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1373 if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1374 if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1375 if (state & Button1Mask) modifiers |= XEMACS_MOD_BUTTON1;
1376 if (state & Button2Mask) modifiers |= XEMACS_MOD_BUTTON2;
1377 if (state & Button3Mask) modifiers |= XEMACS_MOD_BUTTON3;
1378 if (state & Button4Mask) modifiers |= XEMACS_MOD_BUTTON4;
1379 if (state & Button5Mask) modifiers |= XEMACS_MOD_BUTTON5;
1381 if (state & Button5Mask) button = Button5;
1382 if (state & Button4Mask) button = Button4;
1383 if (state & Button3Mask) button = Button3;
1384 if (state & Button2Mask) button = Button2;
1385 if (state & Button1Mask) button = Button1;
1387 emacs_event->event.misc.modifiers = modifiers;
1388 emacs_event->event.misc.button = button;
1390 DndDropCoordinates(FRAME_X_TEXT_WIDGET(frame), x_event,
1391 &(emacs_event->event.misc.x),
1392 &(emacs_event->event.misc.y) );
1394 DndGetData(x_event,&data,&size);
1396 dtype=DndDataType(x_event);
1399 case DndFiles: /* null terminated strings, end null */
1406 len = strlen ((char*)data);
1407 hurl = dnd_url_hexify_string ((char *)data, "file:");
1408 l_item = make_string ((Bufbyte *)hurl, strlen (hurl));
1409 l_dndlist = Fcons (l_item, l_dndlist);
1413 l_type = Qdragdrop_URL;
1417 l_type = Qdragdrop_MIME;
1418 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
1419 make_string ((Bufbyte *)"8bit", 4),
1420 make_ext_string ((Extbyte *)data,
1421 strlen((char *)data),
1425 /* we have to parse this in some way to extract
1426 content-type and params (in the tm way) and
1428 OR: if data is string, let tm do the job
1429 if data is list[2], give the first two
1432 l_type = Qdragdrop_MIME;
1433 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1434 strlen((char *)data),
1442 char *hurl = dnd_url_hexify_string ((char *) data, "file:");
1444 l_dndlist = list1 ( make_string ((Bufbyte *)hurl,
1446 l_type = Qdragdrop_URL;
1452 /* as it is a real URL it should already be escaped
1453 and escaping again will break them (cause % is unsave) */
1454 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1455 strlen ((char *)data),
1457 l_type = Qdragdrop_URL;
1459 default: /* Unknown, RawData and any other type */
1460 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ),
1461 make_string ((Bufbyte *)"8bit", 4),
1462 make_ext_string ((Extbyte *)data,
1465 l_type = Qdragdrop_MIME;
1469 emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
1470 emacs_event->event.misc.object = Fcons (l_type, l_dndlist);
1476 #endif /* HAVE_OFFIX_DND */
1477 if (ev->message_type == DEVICE_XATOM_WM_PROTOCOLS (d)
1478 && (Atom) (ev->data.l[0]) == DEVICE_XATOM_WM_TAKE_FOCUS (d)
1479 && (Atom) (ev->data.l[1]) == 0)
1481 ev->data.l[1] = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1486 default: /* it's a magic event */
1488 struct frame *frame;
1490 XEvent *x_event_copy = &emacs_event->event.magic.underlying_x_event;
1492 #define FROB(event_member, window_member) \
1493 x_event_copy->event_member = x_event->event_member; \
1494 w = x_event->event_member.window_member
1496 switch (x_event->type)
1498 case SelectionRequest: FROB(xselectionrequest, owner); break;
1499 case SelectionClear: FROB(xselectionclear, window); break;
1500 case SelectionNotify: FROB(xselection, requestor); break;
1501 case PropertyNotify: FROB(xproperty, window); break;
1502 case ClientMessage: FROB(xclient, window); break;
1503 case ConfigureNotify: FROB(xconfigure, window); break;
1505 case GraphicsExpose: FROB(xexpose, window); break;
1507 case UnmapNotify: FROB(xmap, window); break;
1509 case LeaveNotify: FROB(xcrossing, window); break;
1511 case FocusOut: FROB(xfocus, window); break;
1512 case VisibilityNotify: FROB(xvisibility, window); break;
1513 case CreateNotify: FROB(xcreatewindow, window); break;
1515 w = x_event->xany.window;
1516 *x_event_copy = *x_event;
1520 frame = x_any_window_to_frame (d, w);
1525 emacs_event->event_type = magic_event;
1526 XSETFRAME (emacs_event->channel, frame);
1536 /************************************************************************/
1537 /* magic-event handling */
1538 /************************************************************************/
1541 handle_focus_event_1 (struct frame *f, int in_p)
1543 handle_focus_event_2 (XtWindow (FRAME_X_TEXT_WIDGET (f)), f, in_p);
1547 handle_focus_event_2 (Window win, struct frame *f, int in_p)
1549 /* Although this treats focus differently for all widgets (including
1550 the frame) it seems to work ok. */
1551 Widget needs_it = XtWindowToWidget (FRAME_X_DISPLAY (f), win);
1553 #if XtSpecificationRelease > 5
1554 widget_with_focus = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
1557 XIM_focus_event (f, in_p);
1558 #endif /* HAVE_XIM */
1560 /* On focus change, clear all memory of sticky modifiers
1561 to avoid non-intuitive behavior. */
1562 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f)));
1564 /* We don't want to handle the focus change now, because we might
1565 be in an accept-process-output, sleep-for, or sit-for. So
1568 Actually, we half handle it: we handle it as far as changing the
1569 box cursor for redisplay, but we don't call any hooks or do any
1570 select-frame stuff until after the sit-for.
1572 Unfortunately native widgets break the model because they grab
1573 the keyboard focus and nothing sets it back again. I cannot find
1574 any reasonable way to do this elsewhere so we assert here that
1575 the keyboard focus is on the emacs text widget. Menus and dialogs
1576 do this in their selection callback, but we don't want that since
1577 a button having focus is legitimate. An edit field having focus
1578 is mandatory. Weirdly you get a FocusOut event when you click in
1579 a widget-glyph but you don't get a corresponding FocusIn when you
1580 click in the frame. Why is this? */
1582 #if XtSpecificationRelease > 5
1583 && needs_it != widget_with_focus
1587 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f), needs_it);
1590 /* If we are focusing on a native widget then record and exit. */
1591 if (needs_it != FRAME_X_TEXT_WIDGET (f)) {
1592 widget_with_focus = needs_it;
1596 /* We have the focus now. See comment in
1597 emacs_Xt_handle_widget_losing_focus (). */
1599 widget_with_focus = NULL;
1601 /* do the generic event-stream stuff. */
1605 struct gcpro gcpro1;
1608 conser = Fcons (frm, Fcons (FRAME_DEVICE (f), in_p ? Qt : Qnil));
1610 emacs_handle_focus_change_preliminary (conser);
1611 enqueue_magic_eval_event (emacs_handle_focus_change_final,
1617 /* Create a synthetic X focus event. */
1619 enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p)
1621 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1622 Lisp_Event *ev = XEVENT (emacs_event);
1623 XEvent *x_event = &ev->event.magic.underlying_x_event;
1625 x_event->type = in_p ? FocusIn : FocusOut;
1626 x_event->xfocus.window = XtWindow (wants_it);
1628 ev->channel = frame;
1629 ev->event_type = magic_event;
1631 enqueue_Xt_dispatch_event (emacs_event);
1634 /* The idea here is that when a widget glyph gets unmapped we don't
1635 want the focus to stay with it if it has focus - because it may
1636 well just get deleted next and then we have lost the focus until the
1637 user does something. So handle_focus_event_1 records the widget
1638 with keyboard focus when FocusOut is processed, and then, when a
1639 widget gets unmapped, it calls this function to restore focus if
1641 void emacs_Xt_handle_widget_losing_focus (struct frame* f, Widget losing_widget);
1643 emacs_Xt_handle_widget_losing_focus (struct frame* f, Widget losing_widget)
1645 if (losing_widget == widget_with_focus)
1647 handle_focus_event_1 (f, 1);
1651 /* This is called from the external-widget code */
1653 void emacs_Xt_handle_focus_event (XEvent *event);
1655 emacs_Xt_handle_focus_event (XEvent *event)
1657 struct device *d = get_device_from_display (event->xany.display);
1660 if (DEVICE_X_BEING_DELETED (d))
1664 * It's curious that we're using x_any_window_to_frame() instead
1665 * of x_window_to_frame(). I don't know what the impact of this is.
1667 f = x_any_window_to_frame (d, event->xfocus.window);
1669 /* focus events are sometimes generated just before
1670 a frame is destroyed. */
1672 handle_focus_event_1 (f, event->type == FocusIn);
1675 /* both MapNotify and VisibilityNotify can cause this
1676 JV is_visible has the same semantics as f->visible*/
1678 change_frame_visibility (struct frame *f, int is_visible)
1682 XSETFRAME (frame, f);
1684 if (!FRAME_VISIBLE_P (f) && is_visible)
1686 FRAME_VISIBLE_P (f) = is_visible;
1687 /* This improves the double flicker when uniconifying a frame
1688 some. A lot of it is not showing a buffer which has changed
1689 while the frame was iconified. To fix it further requires
1690 the good 'ol double redisplay structure. */
1691 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1692 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1694 else if (FRAME_VISIBLE_P (f) && !is_visible)
1696 FRAME_VISIBLE_P (f) = 0;
1697 va_run_hook_with_args (Qunmap_frame_hook, 1, frame);
1699 else if (FRAME_VISIBLE_P (f) * is_visible < 0)
1701 FRAME_VISIBLE_P(f) = - FRAME_VISIBLE_P(f);
1702 if (FRAME_REPAINT_P(f))
1703 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1704 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1709 handle_map_event (struct frame *f, XEvent *event)
1713 XSETFRAME (frame, f);
1714 if (event->type == MapNotify)
1716 XWindowAttributes xwa;
1718 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
1719 send synthetic MapNotify events when a window is first
1720 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
1721 Or something like that. We initially tried a different
1722 solution below, but that ran into a different window-
1725 It seems that the only reliable way is to treat a
1726 MapNotify event as a "hint" that the window might or
1727 might not be visible, and check explicitly. */
1729 XGetWindowAttributes (event->xany.display, event->xmap.window,
1731 if (xwa.map_state != IsViewable)
1733 /* Calling Fframe_iconified_p is the only way we have to
1734 correctly update FRAME_ICONIFIED_P */
1735 Fframe_iconified_p (frame);
1739 FRAME_X_TOTALLY_VISIBLE_P (f) = 1;
1741 /* Bleagh again!!!! We initially tried the following hack
1742 around the MWM problem, but it turns out that TWM
1743 has a race condition when you un-iconify, where it maps
1744 the window and then tells the server that the window
1745 is un-iconified. Usually, XEmacs wakes up between
1746 those two occurrences, and thus thinks that un-iconified
1747 windows are still iconified.
1749 Ah, the joys of X. */
1751 /* By Emacs definition, a frame that is iconified is not
1752 visible. Marking a frame as visible will automatically cause
1753 frame-iconified-p to return nil, regardless of whether the
1754 frame is actually iconified. Therefore, we have to ignore
1755 MapNotify events on iconified frames. (It's not obvious
1756 to me why these are being sent, but it happens at startup
1757 with frames that are initially iconified; perhaps they are
1758 synthetic MapNotify events coming from the window manager.)
1759 Note that `frame-iconified-p' queries the server
1760 to determine whether the frame is currently iconified,
1761 rather than consulting some internal (and likely
1762 inaccurate) state flag. Therefore, ignoring the MapNotify
1764 if (!FRAME_VISIBLE_P (f) && NILP (Fframe_iconified_p (frame)))
1766 change_frame_visibility (f, 1);
1770 FRAME_X_TOTALLY_VISIBLE_P (f) = 0;
1771 change_frame_visibility (f, 0);
1772 /* Calling Fframe_iconified_p is the only way we have to
1773 correctly update FRAME_ICONIFIED_P */
1774 Fframe_iconified_p (frame);
1779 handle_client_message (struct frame *f, XEvent *event)
1781 struct device *d = XDEVICE (FRAME_DEVICE (f));
1784 XSETFRAME (frame, f);
1786 if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1787 (Atom) (event->xclient.data.l[0]) == DEVICE_XATOM_WM_DELETE_WINDOW (d))
1789 /* WM_DELETE_WINDOW is a misc-user event, but other ClientMessages,
1790 such as WM_TAKE_FOCUS, are eval events. That's because delete-window
1791 was probably executed with a mouse click, while the others could
1792 have been sent as a result of mouse motion or some other implicit
1793 action. (Call this a "heuristic"...) The reason for caring about
1794 this is so that clicking on the close-box will make emacs prompt
1795 using a dialog box instead of the minibuffer if there are unsaved
1798 enqueue_misc_user_event (frame, Qeval,
1799 list3 (Qdelete_frame, frame, Qt));
1801 else if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1802 (Atom) event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d))
1804 handle_focus_event_1 (f, 1);
1806 /* If there is a dialog box up, focus on it.
1808 #### Actually, we're raising it too, which is wrong. We should
1809 #### just focus on it, but lwlib doesn't currently give us an
1810 #### easy way to do that. This should be fixed.
1812 unsigned long take_focus_timestamp = event->xclient.data.l[1];
1813 Widget widget = lw_raise_all_pop_up_widgets ();
1816 /* kludge: raise_all returns bottommost widget, but we really
1817 want the topmost. So just raise it for now. */
1818 XMapRaised (XtDisplay (widget), XtWindow (widget));
1819 /* Grab the focus with the timestamp of the TAKE_FOCUS. */
1820 XSetInputFocus (XtDisplay (widget), XtWindow (widget),
1821 RevertToParent, take_focus_timestamp);
1827 /* #### I'm struggling to understand how the X event loop really works.
1828 Here is the problem:
1830 When widgets get mapped / changed etc the actual display updates
1831 are done asynchronously via X events being processed - this
1832 normally happens when XtAppProcessEvent() gets called. However, if
1833 we are executing lisp code or even doing redisplay we won't
1834 necessarily process X events for a very long time. This has the
1835 effect of widgets only getting updated when XEmacs only goes into
1836 idle, or some other event causes processing of the X event queue.
1838 XtAppProcessEvent can get called from the following places:
1840 emacs_Xt_next_event () - this is normal event processing, almost
1841 any non-X event will take precedence and this means that we
1842 cannot rely on it to do the right thing at the right time for
1845 drain_X_queue () - this happens when SIGIO gets tripped,
1846 processing the event queue allows C-g to be checked for. It gets
1847 called from emacs_Xt_event_pending_p ().
1849 In order to solve this I have tried introducing a list primitive -
1850 dispatch-non-command-events - which forces processing of X events
1851 related to display. Unfortunately this has a number of problems,
1852 one is that it is possible for event_stream_event_pending_p to
1853 block for ever if there isn't actually an event. I guess this can
1854 happen if we drop the synthetic event for reason. It also relies on
1855 SIGIO processing which makes things rather fragile.
1857 People have seen behaviour whereby XEmacs blocks until you move the
1858 mouse. This seems to indicate that dispatch-non-command-events is
1859 blocking. It may be that in a SIGIO world forcing SIGIO processing
1860 does the wrong thing.
1863 emacs_Xt_force_event_pending (struct frame* f)
1867 Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f)));
1868 event.xclient.type = ClientMessage;
1869 event.xclient.display = dpy;
1870 event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False);
1871 event.xclient.format = 32;
1872 event.xclient.window = 0;
1874 /* Send the drop message */
1875 XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)),
1876 True, NoEventMask, &event);
1877 /* We rely on SIGIO and friends to realise we have generated an
1882 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
1884 /* This function can GC */
1885 XEvent *event = &emacs_event->event.magic.underlying_x_event;
1886 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
1888 if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f))))
1891 switch (event->type)
1893 case SelectionRequest:
1894 x_handle_selection_request (&event->xselectionrequest);
1897 case SelectionClear:
1898 x_handle_selection_clear (&event->xselectionclear);
1901 case SelectionNotify:
1902 x_handle_selection_notify (&event->xselection);
1905 case PropertyNotify:
1906 x_handle_property_notify (&event->xproperty);
1910 if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
1911 event->xexpose.width, event->xexpose.height)
1913 !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
1914 event->xexpose.width, event->xexpose.height))
1915 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1916 event->xexpose.width, event->xexpose.height);
1919 case GraphicsExpose: /* This occurs when an XCopyArea's source area was
1920 obscured or not available. */
1921 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1922 event->xexpose.width, event->xexpose.height);
1927 handle_map_event (f, event);
1931 if (event->xcrossing.detail != NotifyInferior)
1935 XSETFRAME (frame, f);
1936 /* FRAME_X_MOUSE_P (f) = 1; */
1937 va_run_hook_with_args (Qmouse_enter_frame_hook, 1, frame);
1942 if (event->xcrossing.detail != NotifyInferior)
1946 XSETFRAME (frame, f);
1947 /* FRAME_X_MOUSE_P (f) = 0; */
1948 va_run_hook_with_args (Qmouse_leave_frame_hook, 1, frame);
1955 #ifdef EXTERNAL_WIDGET
1956 /* External widget lossage: Ben said:
1957 YUCK. The only way to make focus changes work properly is to
1958 completely ignore all FocusIn/FocusOut events and depend only
1959 on notifications from the ExternalClient widget. */
1960 if (FRAME_X_EXTERNAL_WINDOW_P (f))
1963 handle_focus_event_2 (event->xfocus.window, f, event->type == FocusIn);
1967 handle_client_message (f, event);
1970 case VisibilityNotify: /* window visibility has changed */
1971 if (event->xvisibility.window == XtWindow (FRAME_X_SHELL_WIDGET (f)))
1973 FRAME_X_TOTALLY_VISIBLE_P (f) =
1974 (event->xvisibility.state == VisibilityUnobscured);
1975 /* Note that the fvwm pager only sends VisibilityNotify when
1976 changing pages. Is this all we need to do ? JV */
1977 /* Nope. We must at least trigger a redisplay here.
1978 Since this case seems similar to MapNotify, I've
1979 factored out some code to change_frame_visibility().
1980 This triggers the necessary redisplay and runs
1981 (un)map-frame-hook. - dkindred@cs.cmu.edu */
1982 /* Changed it again to support the tristate visibility flag */
1983 change_frame_visibility (f, (event->xvisibility.state
1984 != VisibilityFullyObscured) ? 1 : -1);
1988 case ConfigureNotify:
1990 XIM_SetGeometry (f);
2003 /************************************************************************/
2004 /* timeout events */
2005 /************************************************************************/
2007 static int timeout_id_tick;
2009 /* Xt interval id's might not fit into an int (they're pointers, as it
2010 happens), so we need to provide a conversion list. */
2012 static struct Xt_timeout
2015 XtIntervalId interval_id;
2016 struct Xt_timeout *next;
2017 } *pending_timeouts, *completed_timeouts;
2019 static struct Xt_timeout_blocktype
2021 Blocktype_declare (struct Xt_timeout);
2022 } *the_Xt_timeout_blocktype;
2024 /* called by XtAppNextEvent() */
2026 Xt_timeout_callback (XtPointer closure, XtIntervalId *id)
2028 struct Xt_timeout *timeout = (struct Xt_timeout *) closure;
2029 struct Xt_timeout *t2 = pending_timeouts;
2030 /* Remove this one from the list of pending timeouts */
2032 pending_timeouts = pending_timeouts->next;
2035 while (t2->next && t2->next != timeout) t2 = t2->next;
2037 t2->next = t2->next->next;
2039 /* Add this one to the list of completed timeouts */
2040 timeout->next = completed_timeouts;
2041 completed_timeouts = timeout;
2045 emacs_Xt_add_timeout (EMACS_TIME thyme)
2047 struct Xt_timeout *timeout = Blocktype_alloc (the_Xt_timeout_blocktype);
2048 EMACS_TIME current_time;
2051 timeout->id = timeout_id_tick++;
2052 timeout->next = pending_timeouts;
2053 pending_timeouts = timeout;
2054 EMACS_GET_TIME (current_time);
2055 EMACS_SUB_TIME (thyme, thyme, current_time);
2056 milliseconds = EMACS_SECS (thyme) * 1000 +
2057 EMACS_USECS (thyme) / 1000;
2058 if (milliseconds < 1)
2060 timeout->interval_id = XtAppAddTimeOut (Xt_app_con, milliseconds,
2061 Xt_timeout_callback,
2062 (XtPointer) timeout);
2067 emacs_Xt_remove_timeout (int id)
2069 struct Xt_timeout *timeout, *t2;
2073 /* Find the timeout on the list of pending ones, if it's still there. */
2074 if (pending_timeouts)
2076 if (id == pending_timeouts->id)
2078 timeout = pending_timeouts;
2079 pending_timeouts = pending_timeouts->next;
2083 t2 = pending_timeouts;
2084 while (t2->next && t2->next->id != id) t2 = t2->next;
2085 if ( t2->next) /*found it */
2088 t2->next = t2->next->next;
2091 /* if it was pending, we have removed it from the list */
2093 XtRemoveTimeOut (timeout->interval_id);
2096 /* It could be that the Xt call back was already called but we didn't convert
2097 into an Emacs event yet */
2098 if (!timeout && completed_timeouts)
2100 /* Code duplication! */
2101 if (id == completed_timeouts->id)
2103 timeout = completed_timeouts;
2104 completed_timeouts = completed_timeouts->next;
2108 t2 = completed_timeouts;
2109 while (t2->next && t2->next->id != id) t2 = t2->next;
2110 if ( t2->next) /*found it */
2113 t2->next = t2->next->next;
2118 /* If we found the thing on the lists of timeouts,
2119 and removed it, deallocate
2122 Blocktype_free (the_Xt_timeout_blocktype, timeout);
2126 Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
2128 struct Xt_timeout *timeout = completed_timeouts;
2130 completed_timeouts = completed_timeouts->next;
2131 emacs_event->event_type = timeout_event;
2132 /* timeout events have nil as channel */
2133 emacs_event->timestamp = 0; /* #### wrong!! */
2134 emacs_event->event.timeout.interval_id = timeout->id;
2135 emacs_event->event.timeout.function = Qnil;
2136 emacs_event->event.timeout.object = Qnil;
2137 Blocktype_free (the_Xt_timeout_blocktype, timeout);
2141 /************************************************************************/
2142 /* process and tty events */
2143 /************************************************************************/
2145 struct what_is_ready_closure
2152 static Lisp_Object *filedesc_with_input;
2153 static struct what_is_ready_closure **filedesc_to_what_closure;
2156 init_what_input_once (void)
2160 filedesc_with_input = xnew_array (Lisp_Object, MAXDESC);
2161 filedesc_to_what_closure =
2162 xnew_array (struct what_is_ready_closure *, MAXDESC);
2164 for (i = 0; i < MAXDESC; i++)
2166 filedesc_to_what_closure[i] = 0;
2167 filedesc_with_input[i] = Qnil;
2170 process_events_occurred = 0;
2171 tty_events_occurred = 0;
2175 mark_what_as_being_ready (struct what_is_ready_closure *closure)
2177 if (NILP (filedesc_with_input[closure->fd]))
2179 SELECT_TYPE temp_mask;
2180 FD_ZERO (&temp_mask);
2181 FD_SET (closure->fd, &temp_mask);
2182 /* Check to make sure there's *really* input available.
2183 Sometimes things seem to get confused and this gets called
2184 for the tty fd when there's really only input available
2185 on some process's fd. (It will subsequently get called
2186 for that process's fd, so returning without setting any
2187 flags will take care of it.) To see the problem, uncomment
2188 the stderr_out below, turn NORMAL_QUIT_CHECK_TIMEOUT_MSECS
2189 down to 25, do sh -c 'xemacs -nw -q -f shell 2>/tmp/log'
2190 and press return repeatedly. (Seen under AIX & Linux.)
2191 -dkindred@cs.cmu.edu */
2192 if (!poll_fds_for_input (temp_mask))
2195 stderr_out ("mark_what_as_being_ready: no input available (fd=%d)\n",
2200 filedesc_with_input[closure->fd] = closure->what;
2201 if (PROCESSP (closure->what))
2202 /* Don't increment this if the current process is already marked
2203 * as having input. */
2204 process_events_occurred++;
2206 tty_events_occurred++;
2211 Xt_what_callback (void *closure, int *source, XtInputId *id)
2213 /* If closure is 0, then we got a fake event from a signal handler.
2214 The only purpose of this is to make XtAppProcessEvent() stop
2217 mark_what_as_being_ready ((struct what_is_ready_closure *) closure);
2220 fake_event_occurred++;
2221 drain_signal_event_pipe ();
2226 select_filedesc (int fd, Lisp_Object what)
2228 struct what_is_ready_closure *closure;
2230 /* If somebody is trying to select something that's already selected
2231 for, then something went wrong. The generic routines ought to
2232 detect this and error before here. */
2233 assert (!filedesc_to_what_closure[fd]);
2235 closure = xnew (struct what_is_ready_closure);
2237 closure->what = what;
2239 XtAppAddInput (Xt_app_con, fd,
2240 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
2241 Xt_what_callback, closure);
2242 filedesc_to_what_closure[fd] = closure;
2246 unselect_filedesc (int fd)
2248 struct what_is_ready_closure *closure = filedesc_to_what_closure[fd];
2251 if (!NILP (filedesc_with_input[fd]))
2253 /* We are unselecting this process before we have drained the rest of
2254 the input from it, probably from status_notify() in the command loop.
2255 This can happen like so:
2257 - We are waiting in XtAppNextEvent()
2258 - Process generates output
2259 - Process is marked as being ready
2260 - Process dies, SIGCHLD gets generated before we return (!?)
2261 It could happen I guess.
2262 - sigchld_handler() marks process as dead
2263 - Somehow we end up getting a new KeyPress event on the queue
2264 at the same time (I'm really so sure how that happens but I'm
2265 not sure it can't either so let's assume it can...).
2266 - Key events have priority so we return that instead of the proc.
2267 - Before dispatching the lisp key event we call status_notify()
2268 - Which deselects the process that SIGCHLD marked as dead.
2270 Thus we never remove it from _with_input and turn it into a lisp
2271 event, so we need to do it here. But this does not mean that we're
2272 throwing away the last block of output - status_notify() has already
2273 taken care of running the proc filter or whatever.
2275 filedesc_with_input[fd] = Qnil;
2276 if (PROCESSP (closure->what))
2278 assert (process_events_occurred > 0);
2279 process_events_occurred--;
2283 assert (tty_events_occurred > 0);
2284 tty_events_occurred--;
2287 XtRemoveInput (closure->id);
2289 filedesc_to_what_closure[fd] = 0;
2293 emacs_Xt_select_process (Lisp_Process *p)
2295 Lisp_Object process;
2296 int infd = event_stream_unixoid_select_process (p);
2298 XSETPROCESS (process, p);
2299 select_filedesc (infd, process);
2303 emacs_Xt_unselect_process (Lisp_Process *p)
2305 int infd = event_stream_unixoid_unselect_process (p);
2307 unselect_filedesc (infd);
2311 emacs_Xt_create_stream_pair (void* inhandle, void* outhandle,
2312 Lisp_Object* instream, Lisp_Object* outstream, int flags)
2314 USID u = event_stream_unixoid_create_stream_pair
2315 (inhandle, outhandle, instream, outstream, flags);
2316 if (u != USID_ERROR)
2322 emacs_Xt_delete_stream_pair (Lisp_Object instream, Lisp_Object outstream)
2324 event_stream_unixoid_delete_stream_pair (instream, outstream);
2325 return USID_DONTHASH;
2328 /* This is called from GC when a process object is about to be freed.
2329 If we've still got pointers to it in this file, we're gonna lose hard.
2332 debug_process_finalization (Lisp_Process *p)
2336 Lisp_Object instr, outstr;
2338 get_process_streams (p, &instr, &outstr);
2339 /* if it still has fds, then it hasn't been killed yet. */
2340 assert (NILP(instr));
2341 assert (NILP(outstr));
2342 /* Better not still be in the "with input" table; we know it's got no fds. */
2343 for (i = 0; i < MAXDESC; i++)
2345 Lisp_Object process = filedesc_fds_with_input [i];
2346 assert (!PROCESSP (process) || XPROCESS (process) != p);
2352 Xt_process_to_emacs_event (Lisp_Event *emacs_event)
2356 assert (process_events_occurred > 0);
2358 for (i = 0; i < MAXDESC; i++)
2360 Lisp_Object process = filedesc_with_input[i];
2361 if (PROCESSP (process))
2363 filedesc_with_input[i] = Qnil;
2364 process_events_occurred--;
2365 /* process events have nil as channel */
2366 emacs_event->event_type = process_event;
2367 emacs_event->timestamp = 0; /* #### */
2368 emacs_event->event.process.process = process;
2376 emacs_Xt_select_console (struct console *con)
2378 Lisp_Object console;
2381 if (CONSOLE_X_P (con))
2382 return; /* X consoles are automatically selected for when we
2383 initialize them in Xt */
2384 infd = event_stream_unixoid_select_console (con);
2385 XSETCONSOLE (console, con);
2386 select_filedesc (infd, console);
2390 emacs_Xt_unselect_console (struct console *con)
2392 Lisp_Object console;
2395 if (CONSOLE_X_P (con))
2396 return; /* X consoles are automatically selected for when we
2397 initialize them in Xt */
2398 infd = event_stream_unixoid_unselect_console (con);
2399 XSETCONSOLE (console, con);
2400 unselect_filedesc (infd);
2403 /* read an event from a tty, if one is available. Returns non-zero
2404 if an event was available. Note that when this function is
2405 called, there should always be a tty marked as ready for input.
2406 However, the input condition might actually be EOF, so there
2407 may not really be any input available. (In this case,
2408 read_event_from_tty_or_stream_desc() will arrange for the TTY device
2412 Xt_tty_to_emacs_event (Lisp_Event *emacs_event)
2416 assert (tty_events_occurred > 0);
2417 for (i = 0; i < MAXDESC; i++)
2419 Lisp_Object console = filedesc_with_input[i];
2420 if (CONSOLEP (console))
2422 assert (tty_events_occurred > 0);
2423 tty_events_occurred--;
2424 filedesc_with_input[i] = Qnil;
2425 if (read_event_from_tty_or_stream_desc
2426 (emacs_event, XCONSOLE (console), i))
2435 /************************************************************************/
2436 /* debugging functions to decipher an event */
2437 /************************************************************************/
2440 #include "xintrinsicp.h" /* only describe_event() needs this */
2441 #include <X11/Xproto.h> /* only describe_event() needs this */
2444 describe_event_window (Window window, Display *display)
2448 stderr_out (" window: 0x%lx", (unsigned long) window);
2449 w = XtWindowToWidget (display, window);
2451 stderr_out (" %s", w->core.widget_class->core_class.class_name);
2452 f = x_any_window_to_frame (get_device_from_display (display), window);
2455 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
2456 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
2457 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
2458 strlen (buf), Qterminal, 1);
2464 XEvent_mode_to_string (int mode)
2468 case NotifyNormal: return "Normal";
2469 case NotifyGrab: return "Grab";
2470 case NotifyUngrab: return "Ungrab";
2471 case NotifyWhileGrabbed: return "WhileGrabbed";
2472 default: return "???";
2477 XEvent_detail_to_string (int detail)
2481 case NotifyAncestor: return "Ancestor";
2482 case NotifyInferior: return "Inferior";
2483 case NotifyNonlinear: return "Nonlinear";
2484 case NotifyNonlinearVirtual: return "NonlinearVirtual";
2485 case NotifyPointer: return "Pointer";
2486 case NotifyPointerRoot: return "PointerRoot";
2487 case NotifyDetailNone: return "DetailNone";
2488 default: return "???";
2493 XEvent_visibility_to_string (int state)
2497 case VisibilityFullyObscured: return "FullyObscured";
2498 case VisibilityPartiallyObscured: return "PartiallyObscured";
2499 case VisibilityUnobscured: return "Unobscured";
2500 default: return "???";
2505 describe_event (XEvent *event)
2508 struct device *d = get_device_from_display (event->xany.display);
2510 sprintf (buf, "%s%s", x_event_name (event->type),
2511 event->xany.send_event ? " (send)" : "");
2512 stderr_out ("%-30s", buf);
2513 switch (event->type)
2518 XFocusChangeEvent *ev = &event->xfocus;
2519 describe_event_window (ev->window, ev->display);
2520 stderr_out (" mode: %s\n", XEvent_mode_to_string (ev->mode));
2521 stderr_out (" detail: %s\n", XEvent_detail_to_string(ev->detail));
2527 XKeyEvent *ev = &event->xkey;
2528 unsigned int state = ev->state;
2530 describe_event_window (ev->window, ev->display);
2531 stderr_out (" subwindow: %ld\n", ev->subwindow);
2532 stderr_out (" state: ");
2533 /* Complete list of modifier key masks */
2534 if (state & ShiftMask) stderr_out ("Shift ");
2535 if (state & LockMask) stderr_out ("Lock ");
2536 if (state & ControlMask) stderr_out ("Control ");
2537 if (state & Mod1Mask) stderr_out ("Mod1 ");
2538 if (state & Mod2Mask) stderr_out ("Mod2 ");
2539 if (state & Mod3Mask) stderr_out ("Mod3 ");
2540 if (state & Mod4Mask) stderr_out ("Mod4 ");
2541 if (state & Mod5Mask) stderr_out ("Mod5 ");
2544 stderr_out ("vanilla\n");
2547 if (x_key_is_modifier_p (ev->keycode, d))
2548 stderr_out (" Modifier key");
2549 stderr_out (" keycode: 0x%x\n", ev->keycode);
2554 if (debug_x_events > 1)
2556 XExposeEvent *ev = &event->xexpose;
2557 describe_event_window (ev->window, ev->display);
2558 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2559 ev->x, ev->y, ev->width, ev->height);
2560 stderr_out (" count: %d\n", ev->count);
2566 case GraphicsExpose:
2567 if (debug_x_events > 1)
2569 XGraphicsExposeEvent *ev = &event->xgraphicsexpose;
2570 describe_event_window (ev->drawable, ev->display);
2571 stderr_out (" major: %s\n",
2572 (ev ->major_code == X_CopyArea ? "CopyArea" :
2573 (ev->major_code == X_CopyPlane ? "CopyPlane" : "?")));
2574 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2575 ev->x, ev->y, ev->width, ev->height);
2576 stderr_out (" count: %d\n", ev->count);
2584 if (debug_x_events > 1)
2586 XCrossingEvent *ev = &event->xcrossing;
2587 describe_event_window (ev->window, ev->display);
2589 stderr_out(" subwindow: 0x%x\n", ev->subwindow);
2590 stderr_out(" pos: %d %d\n", ev->x, ev->y);
2591 stderr_out(" root pos: %d %d\n", ev->x_root, ev->y_root);
2593 stderr_out(" mode: %s\n", XEvent_mode_to_string(ev->mode));
2594 stderr_out(" detail: %s\n", XEvent_detail_to_string(ev->detail));
2595 stderr_out(" focus: %d\n", ev->focus);
2597 stderr_out(" state: 0x%x\n", ev->state);
2604 case ConfigureNotify:
2605 if (debug_x_events > 1)
2607 XConfigureEvent *ev = &event->xconfigure;
2608 describe_event_window (ev->window, ev->display);
2609 stderr_out(" above: 0x%lx\n", ev->above);
2610 stderr_out(" size: %d %d %d %d\n", ev->x, ev->y,
2611 ev->width, ev->height);
2612 stderr_out(" redirect: %d\n", ev->override_redirect);
2618 case VisibilityNotify:
2619 if (debug_x_events > 1)
2621 XVisibilityEvent *ev = &event->xvisibility;
2622 describe_event_window (ev->window, ev->display);
2623 stderr_out(" state: %s\n", XEvent_visibility_to_string(ev->state));
2631 XClientMessageEvent *ev = &event->xclient;
2632 char *name = XGetAtomName (ev->display, ev->message_type);
2633 stderr_out ("%s", name);
2634 if (!strcmp (name, "WM_PROTOCOLS")) {
2635 char *protname = XGetAtomName (ev->display, ev->data.l[0]);
2636 stderr_out ("(%s)", protname);
2652 #endif /* include describe_event definition */
2655 /************************************************************************/
2656 /* get the next event from Xt */
2657 /************************************************************************/
2659 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail;
2662 enqueue_Xt_dispatch_event (Lisp_Object event)
2664 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail);
2668 dequeue_Xt_dispatch_event (void)
2670 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail);
2673 /* This business exists because menu events "happen" when
2674 menubar_selection_callback() is called from somewhere deep
2675 within XtAppProcessEvent in emacs_Xt_next_event(). The
2676 callback needs to terminate the modal loop in that function
2677 or else it will continue waiting until another event is
2680 Same business applies to scrollbar events. */
2683 signal_special_Xt_user_event (Lisp_Object channel, Lisp_Object function,
2686 Lisp_Object event = Fmake_event (Qnil, Qnil);
2688 XEVENT (event)->event_type = misc_user_event;
2689 XEVENT (event)->channel = channel;
2690 XEVENT (event)->event.eval.function = function;
2691 XEVENT (event)->event.eval.object = object;
2693 enqueue_Xt_dispatch_event (event);
2697 emacs_Xt_next_event (Lisp_Event *emacs_event)
2699 we_didnt_get_an_event:
2701 while (NILP (dispatch_event_queue) &&
2702 !completed_timeouts &&
2703 !fake_event_occurred &&
2704 !process_events_occurred &&
2705 !tty_events_occurred)
2708 /* Stupid logic in XtAppProcessEvent() dictates that, if process
2709 events and X events are both available, the process event gets
2710 taken first. This will cause an infinite loop if we're being
2711 called from Fdiscard_input().
2713 if (XtAppPending (Xt_app_con) & XtIMXEvent)
2714 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2717 Lisp_Object devcons, concons;
2719 /* We're about to block. Xt has a bug in it (big surprise,
2720 there) in that it blocks using select() and doesn't
2721 flush the Xlib output buffers (XNextEvent() does this
2722 automatically before blocking). So it's necessary
2723 for us to do this ourselves. If we don't do it, then
2724 display output may not be seen until the next time
2725 an X event is received. (This happens esp. with
2726 subprocess output that gets sent to a visible buffer.)
2728 #### The above comment may not have any validity. */
2730 DEVICE_LOOP_NO_BREAK (devcons, concons)
2733 d = XDEVICE (XCAR (devcons));
2735 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2736 /* emacs may be exiting */
2737 XFlush (DEVICE_X_DISPLAY (d));
2739 XtAppProcessEvent (Xt_app_con, XtIMAll);
2743 if (!NILP (dispatch_event_queue))
2745 Lisp_Object event, event2;
2746 XSETEVENT (event2, emacs_event);
2747 event = dequeue_Xt_dispatch_event ();
2748 Fcopy_event (event, event2);
2749 Fdeallocate_event (event);
2751 else if (tty_events_occurred)
2753 if (!Xt_tty_to_emacs_event (emacs_event))
2754 goto we_didnt_get_an_event;
2756 else if (completed_timeouts)
2757 Xt_timeout_to_emacs_event (emacs_event);
2758 else if (fake_event_occurred)
2760 /* A dummy event, so that a cycle of the command loop will occur. */
2761 fake_event_occurred = 0;
2762 /* eval events have nil as channel */
2763 emacs_event->event_type = eval_event;
2764 emacs_event->event.eval.function = Qidentity;
2765 emacs_event->event.eval.object = Qnil;
2767 else /* if (process_events_occurred) */
2768 Xt_process_to_emacs_event (emacs_event);
2770 /* No need to call XFilterEvent; Xt does it for us */
2774 emacs_Xt_event_handler (Widget wid /* unused */,
2775 XtPointer closure /* unused */,
2777 Boolean *continue_to_dispatch /* unused */)
2779 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
2782 if (debug_x_events > 0)
2784 describe_event (event);
2786 #endif /* DEBUG_XEMACS */
2787 if (x_event_to_emacs_event (event, XEVENT (emacs_event)))
2788 enqueue_Xt_dispatch_event (emacs_event);
2790 Fdeallocate_event (emacs_event);
2794 /************************************************************************/
2795 /* input pending / C-g checking */
2796 /************************************************************************/
2799 quit_char_predicate (Display *display, XEvent *event, XPointer data)
2801 struct device *d = get_device_from_display (display);
2802 struct x_device *xd = DEVICE_X_DATA (d);
2804 Bool *critical = (Bool *) data;
2809 if ((event->type != KeyPress) ||
2810 (! x_any_window_to_frame (d, event->xany.window)) ||
2812 & (xd->MetaMask | xd->HyperMask | xd->SuperMask | xd->AltMask)))
2815 /* This duplicates some code that exists elsewhere, but it's relatively
2816 fast and doesn't cons. */
2817 keysym = x_to_emacs_keysym (&event->xkey, 1);
2818 if (NILP (keysym)) return 0;
2819 if (CHAR_OR_CHAR_INTP (keysym))
2820 c = XCHAR_OR_CHAR_INT (keysym);
2821 /* Highly doubtful that these are the quit character, but... */
2822 else if (EQ (keysym, QKbackspace)) c = '\b';
2823 else if (EQ (keysym, QKtab)) c = '\t';
2824 else if (EQ (keysym, QKlinefeed)) c = '\n';
2825 else if (EQ (keysym, QKreturn)) c = '\r';
2826 else if (EQ (keysym, QKescape)) c = 27;
2827 else if (EQ (keysym, QKspace)) c = ' ';
2828 else if (EQ (keysym, QKdelete)) c = 127;
2831 if (event->xkey.state & xd->MetaMask) c |= 0x80;
2832 if ((event->xkey.state & ControlMask) && !(c >= 'A' && c <= 'Z'))
2833 c &= 0x1F; /* unshifted control characters */
2834 quit_char = CONSOLE_QUIT_CHAR (XCONSOLE (DEVICE_CONSOLE (d)));
2837 /* If we've got Control-Shift-G instead of Control-G, that means
2838 we have a critical_quit. Caps_Lock is its own modifier, so it
2839 won't cause ^G to act differently than before. */
2840 if (event->xkey.state & ControlMask) c &= 0x1F;
2843 if (critical) *critical = True;
2849 /* This scans the X input queue for a KeyPress event that matches the
2850 quit character, and sets Vquit_flag. This is called from the
2851 QUIT macro to determine whether we should quit.
2853 In a SIGIO world, this won't be called unless a SIGIO has happened
2854 since the last time we checked.
2856 In a non-SIGIO world, this is called from emacs_Xt_event_pending_p
2857 (which is called from input_pending_p).
2860 x_check_for_quit_char (Display *display)
2864 Bool critical_quit = False;
2865 XEventsQueued (display, QueuedAfterReading);
2866 queued = XCheckIfEvent (display, &event,
2867 quit_char_predicate,
2868 (char *) &critical_quit);
2871 Vquit_flag = (critical_quit ? Qcritical : Qt);
2872 /* don't put the event back onto the queue. Those functions that
2873 wanted to read a ^G directly have arranged to do this. */
2878 check_for_tty_quit_char (struct device *d)
2880 SELECT_TYPE temp_mask;
2881 int infd = DEVICE_INFD (d);
2882 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
2883 Emchar quit_char = CONSOLE_QUIT_CHAR (con);
2885 FD_ZERO (&temp_mask);
2886 FD_SET (infd, &temp_mask);
2893 if (!poll_fds_for_input (temp_mask))
2896 event = Fmake_event (Qnil, Qnil);
2897 if (!read_event_from_tty_or_stream_desc (XEVENT (event), con, infd))
2898 /* EOF, or something ... */
2900 /* #### bogus. quit-char should be allowed to be any sort
2902 the_char = event_to_character (XEVENT (event), 1, 0, 0);
2903 if (the_char >= 0 && the_char == quit_char)
2906 /* do not queue the C-g. See above. */
2910 /* queue the read event to be read for real later. */
2911 enqueue_Xt_dispatch_event (event);
2916 emacs_Xt_quit_p (void)
2918 Lisp_Object devcons, concons;
2919 CONSOLE_LOOP (concons)
2921 struct console *con = XCONSOLE (XCAR (concons));
2922 if (!con->input_enabled)
2925 CONSOLE_DEVICE_LOOP (devcons, con)
2928 d = XDEVICE (XCAR (devcons));
2930 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2931 /* emacs may be exiting */
2932 x_check_for_quit_char (DEVICE_X_DISPLAY (d));
2933 else if (DEVICE_TTY_P (d))
2934 check_for_tty_quit_char (d);
2940 drain_X_queue (void)
2942 Lisp_Object devcons, concons;
2943 CONSOLE_LOOP (concons)
2945 struct console *con = XCONSOLE (XCAR (concons));
2946 if (!con->input_enabled)
2949 /* sjt sez: Have you tried the loop over devices with XtAppPending(),
2950 not XEventsQueued()?
2951 Ben Sigelman sez: No.
2952 sjt sez: I'm guessing that the reason that your patch "works" is this:
2956 + d = XDEVICE (XCAR (devcons));
2957 + if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d)) {
2959 Ie, if the device goes down, XEmacs detects that and deletes it.
2960 Then the if() fails (DEVICE_X_DISPLAY(d) is NULL), and we don't go
2961 into the Xlib-of-no-return. If you know different, I'd like to hear
2964 These ideas haven't been tested; the code below works for Ben.
2966 CONSOLE_DEVICE_LOOP (devcons, con)
2970 d = XDEVICE (XCAR (devcons));
2971 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d)) {
2972 display = DEVICE_X_DISPLAY (d);
2973 while (XEventsQueued (display, QueuedAfterReading))
2974 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2978 /* This is the old code, before Ben Sigelman's patch. */
2980 while (XtAppPending (Xt_app_con) & XtIMXEvent)
2981 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2986 emacs_Xt_event_pending_p (int user_p)
2991 /* If `user_p' is false, then this function returns whether there are any
2992 X, timeout, or fd events pending (that is, whether emacs_Xt_next_event()
2993 would return immediately without blocking).
2995 if `user_p' is true, then this function returns whether there are any
2996 *user generated* events available (that is, whether there are keyboard
2997 or mouse-click events ready to be read). This also implies that
2998 emacs_Xt_next_event() would not block.
3000 In a non-SIGIO world, this also checks whether the user has typed ^G,
3001 since this is a convenient place to do so. We don't need to do this
3002 in a SIGIO world, since input causes an interrupt.
3006 /* I don't think there's any point to this and it will nullify
3007 the speed gains achieved by the sigio_happened checking below.
3008 Its only advantage is that it may possibly make C-g response
3009 a bit faster. The C-g will be noticed within 0.25 second, anyway,
3010 even without this. */
3012 /* First check for C-g if necessary */
3017 /* This function used to simply check whether there were any X
3018 events (or if user_p was 1, it iterated over all the pending
3019 X events using XCheckIfEvent(), looking for keystrokes and
3020 button events). That worked in the old cheesoid event loop,
3021 which didn't go through XtAppDispatchEvent(), but it doesn't
3022 work any more -- X events may not result in anything. For
3023 example, a button press in a blank part of the menubar appears
3024 as an X event but will not result in any Emacs events (a
3025 button press that activates the menubar results in an Emacs
3026 event through the stop_next_event mechanism).
3028 The only accurate way of determining whether these X events
3029 translate into Emacs events is to go ahead and dispatch them
3030 until there's something on the dispatch queue. */
3032 /* See if there are any user events already on the queue. */
3033 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
3034 if (!user_p || command_event_p (event))
3037 /* See if there's any TTY input available.
3039 if (poll_fds_for_input (tty_only_mask))
3044 /* If not user_p and there are any timer or file-desc events
3045 pending, we know there will be an event so we're through. */
3046 XtInputMask pending_value;
3048 /* Note that formerly we just checked the value of XtAppPending()
3049 to determine if there was file-desc input. This doesn't
3050 work any more with the signal_event_pipe; XtAppPending()
3051 will says "yes" in this case but there isn't really any
3052 input. Another way of fixing this problem is for the
3053 signal_event_pipe to generate actual input in the form
3054 of an identity eval event or something. (#### maybe this
3055 actually happens?) */
3057 if (poll_fds_for_input (process_only_mask))
3060 pending_value = XtAppPending (Xt_app_con);
3062 if (pending_value & XtIMTimer)
3066 /* XtAppPending() can be super-slow, esp. over a network connection.
3067 Quantify results have indicated that in some cases the
3068 call to detect_input_pending() completely dominates the
3069 running time of redisplay(). Fortunately, in a SIGIO world
3070 we can more quickly determine whether there are any X events:
3071 if an event has happened since the last time we checked, then
3072 a SIGIO will have happened. On a machine with broken SIGIO,
3073 we'll still be in an OK state -- the sigio_happened flag
3074 will get set at least once a second, so we'll be no more than
3075 one second behind reality. (In general it's OK if we
3076 erroneously report no input pending when input is actually
3077 pending() -- preemption is just a bit less efficient, that's
3078 all. It's bad bad bad if you err the other way -- you've
3079 promised that `next-event' won't block but it actually will,
3080 and some action might get delayed until the next time you
3084 /* quit_check_signal_tick_count is volatile so try to avoid race conditions
3085 by using a temporary variable */
3086 tick_count_val = quit_check_signal_tick_count;
3087 if (last_quit_check_signal_tick_count != tick_count_val
3088 #if !defined (SIGIO) || defined (CYGWIN)
3089 || (XtIMXEvent & XtAppPending (Xt_app_con))
3093 last_quit_check_signal_tick_count = tick_count_val;
3095 /* We need to drain the entire queue now -- if we only
3096 drain part of it, we may later on end up with events
3097 actually pending but detect_input_pending() returning
3098 false because there wasn't another SIGIO. */
3101 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
3102 if (!user_p || command_event_p (event))
3110 emacs_Xt_current_event_timestamp (struct console *c)
3113 Lisp_Object devs = CONSOLE_DEVICE_LIST (c);
3119 struct device *d = XDEVICE (XCAR (devs));
3120 return DEVICE_X_LAST_SERVER_TIMESTAMP (d);
3125 /************************************************************************/
3126 /* replacement for standard string-to-pixel converter */
3127 /************************************************************************/
3129 /* This was constructed by ripping off the standard string-to-pixel
3130 converter from Converters.c in the Xt source code and modifying
3135 /* This is exported by the Xt library (at least by mine). If this
3136 isn't the case somewhere, rename this appropriately and remove
3137 the '#if 0'. Note, however, that I got "unknown structure"
3138 errors when I tried this. */
3139 XtConvertArgRec Const colorConvertArgs[] = {
3140 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
3141 sizeof (Screen *) },
3142 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
3148 #define done(type, value) \
3149 if (toVal->addr != NULL) { \
3150 if (toVal->size < sizeof(type)) { \
3151 toVal->size = sizeof(type); \
3154 *(type*)(toVal->addr) = (value); \
3156 static type static_val; \
3157 static_val = (value); \
3158 toVal->addr = (XPointer)&static_val; \
3160 toVal->size = sizeof(type); \
3161 return True /* Caller supplies `;' */
3163 /* JH: We use this because I think there's a possibility this
3164 is called before the device is properly set up, in which case
3165 I don't want to abort. */
3166 extern struct device *get_device_from_display_1 (Display *dpy);
3169 Boolean EmacsXtCvtStringToPixel (
3173 XrmValuePtr fromVal,
3175 XtPointer *closure_ret)
3177 String str = (String)fromVal->addr;
3186 Cardinal num_params = 1;
3187 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
3189 if (*num_args != 2) {
3190 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToPixel",
3192 "String to pixel conversion needs screen and colormap arguments",
3193 (String *)NULL, (Cardinal *)NULL);
3197 screen = *((Screen **) args[0].addr);
3198 colormap = *((Colormap *) args[1].addr);
3200 /* The original uses the private function CompareISOLatin1().
3201 Use XmuCompareISOLatin1() if you want, but I don't think it
3202 makes any difference here. */
3203 if (strcmp(str, XtDefaultBackground) == 0) {
3204 *closure_ret = False;
3205 /* This refers to the display's "*reverseVideo" resource.
3206 These display resources aren't documented anywhere that
3207 I can find, so I'm going to ignore this. */
3208 /* if (pd->rv) done(Pixel, BlackPixelOfScreen(screen)) else */
3209 done(Pixel, WhitePixelOfScreen(screen));
3211 if (strcmp(str, XtDefaultForeground) == 0) {
3212 *closure_ret = False;
3213 /* if (pd->rv) done(Pixel, WhitePixelOfScreen(screen)) else */
3214 done(Pixel, BlackPixelOfScreen(screen));
3217 /* Originally called XAllocNamedColor() here. */
3218 if ((d = get_device_from_display_1(dpy))) {
3219 visual = DEVICE_X_VISUAL(d);
3220 if (colormap != DEVICE_X_COLORMAP(d)) {
3221 XtAppWarningMsg(the_app_con, "weirdColormap", "cvtStringToPixel",
3223 "The colormap passed to cvtStringToPixel doesn't match the one registered to the device.\n",
3225 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3227 status = XParseColor (dpy, colormap, (char*)str, &screenColor);
3229 status = allocate_nearest_color (dpy, colormap, visual, &screenColor);
3233 /* We haven't set up this device totally yet, so just punt */
3234 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3238 /* Server returns a specific error code but Xlib discards it. Ugh */
3239 if (XLookupColor(DisplayOfScreen(screen), colormap, (char*) str,
3240 &exactColor, &screenColor)) {
3241 XtAppWarningMsg(the_app_con, "noColormap", "cvtStringToPixel",
3243 "Cannot allocate colormap entry for \"%s\"",
3244 params, &num_params);
3247 XtAppWarningMsg(the_app_con, "badValue", "cvtStringToPixel",
3249 "Color name \"%s\" is not defined", params, &num_params);
3252 *closure_ret = False;
3255 *closure_ret = (char*)True;
3256 done(Pixel, screenColor.pixel);
3261 static void EmacsFreePixel (
3268 if (*num_args != 2) {
3269 XtAppWarningMsg(app, "wrongParameters","freePixel","XtToolkitError",
3270 "Freeing a pixel requires screen and colormap arguments",
3271 (String *)NULL, (Cardinal *)NULL);
3276 Screen *screen = *((Screen **) args[0].addr);
3277 Colormap colormap = *((Colormap *) args[1].addr);
3278 XFreeColors(DisplayOfScreen(screen), colormap,
3279 (unsigned long*)toVal->addr, 1, (unsigned long)0);
3284 /************************************************************************/
3285 /* handle focus changes for native widgets */
3286 /************************************************************************/
3288 emacs_Xt_event_widget_focus_in (Widget w,
3291 Cardinal *num_params)
3294 x_any_widget_or_parent_to_frame (get_device_from_display (event->xany.display), w);
3296 XtSetKeyboardFocus (FRAME_X_SHELL_WIDGET (f), w);
3300 emacs_Xt_event_widget_focus_out (Widget w,
3303 Cardinal *num_params)
3307 static XtActionsRec widgetActionsList[] =
3309 {"widget-focus-in", emacs_Xt_event_widget_focus_in },
3310 {"widget-focus-out", emacs_Xt_event_widget_focus_out },
3314 emacs_Xt_event_add_widget_actions (XtAppContext ctx)
3316 XtAppAddActions (ctx, widgetActionsList, 2);
3320 /************************************************************************/
3321 /* initialization */
3322 /************************************************************************/
3325 syms_of_event_Xt (void)
3327 defsymbol (&Qkey_mapping, "key-mapping");
3328 defsymbol (&Qsans_modifiers, "sans-modifiers");
3329 defsymbol (&Qself_insert_command, "self-insert-command");
3333 reinit_vars_of_event_Xt (void)
3335 Xt_event_stream = xnew (struct event_stream);
3336 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
3337 Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending;
3338 Xt_event_stream->next_event_cb = emacs_Xt_next_event;
3339 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
3340 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
3341 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout;
3342 Xt_event_stream->select_console_cb = emacs_Xt_select_console;
3343 Xt_event_stream->unselect_console_cb = emacs_Xt_unselect_console;
3344 Xt_event_stream->select_process_cb = emacs_Xt_select_process;
3345 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process;
3346 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
3347 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
3348 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
3349 Xt_event_stream->current_event_timestamp_cb =
3350 emacs_Xt_current_event_timestamp;
3352 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
3354 last_quit_check_signal_tick_count = 0;
3356 /* this function only makes safe calls */
3357 init_what_input_once ();
3361 vars_of_event_Xt (void)
3363 reinit_vars_of_event_Xt ();
3365 dispatch_event_queue = Qnil;
3366 staticpro (&dispatch_event_queue);
3367 dispatch_event_queue_tail = Qnil;
3368 dump_add_root_object (&dispatch_event_queue_tail);
3370 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /*
3371 *Non-nil means to allow synthetic events. Nil means they are ignored.
3372 Beware: allowing emacs to process SendEvents opens a big security hole.
3374 x_allow_sendevents = 0;
3377 DEFVAR_INT ("debug-x-events", &debug_x_events /*
3378 If non-zero, display debug information about X events that XEmacs sees.
3379 Information is displayed on stderr. Currently defined values are:
3381 1 == non-verbose output
3388 /* This mess is a hack that patches the shell widget to treat visual inheritance
3389 the same as colormap and depth inheritance */
3391 static XtInitProc orig_shell_init_proc;
3393 static void ShellVisualPatch(Widget wanted, Widget new,
3394 ArgList args, Cardinal *num_args)
3397 ShellWidget w = (ShellWidget) new;
3399 /* first, call the original setup */
3400 (*orig_shell_init_proc)(wanted, new, args, num_args);
3402 /* if the visual isn't explicitly set, grab it from the nearest shell ancestor */
3403 if (w->shell.visual == CopyFromParent) {
3405 while (p && !XtIsShell(p)) p = XtParent(p);
3406 if (p) w->shell.visual = ((ShellWidget)p)->shell.visual;
3411 init_event_Xt_late (void) /* called when already initialized */
3413 timeout_id_tick = 1;
3414 pending_timeouts = 0;
3415 completed_timeouts = 0;
3417 event_stream = Xt_event_stream;
3419 #if defined(HAVE_XIM) || defined(USE_XFONTSET)
3420 Initialize_Locale();
3421 #endif /* HAVE_XIM || USE_XFONTSET */
3423 XtToolkitInitialize ();
3424 Xt_app_con = XtCreateApplicationContext ();
3425 XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources);
3428 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000);
3429 XSetErrorHandler (x_error_handler);
3430 XSetIOErrorHandler (x_IO_error_handler);
3432 #ifndef WIN32_NATIVE
3433 XtAppAddInput (Xt_app_con, signal_event_pipe[0],
3434 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
3435 Xt_what_callback, 0);
3438 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRPixel,
3439 EmacsXtCvtStringToPixel,
3440 (XtConvertArgList) colorConvertArgs,
3441 2, XtCacheByDisplay, EmacsFreePixel);
3444 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles,
3445 EmacsXtCvtStringToXIMStyles,
3447 XtCacheByDisplay, EmacsFreeXIMStyles);
3448 #endif /* XIM_XLIB */
3449 /* Add extra actions to native widgets to handle focus and friends. */
3450 emacs_Xt_event_add_widget_actions (Xt_app_con);
3452 /* insert the visual inheritance patch/hack described above */
3453 orig_shell_init_proc = shellClassRec.core_class.initialize;
3454 shellClassRec.core_class.initialize = ShellVisualPatch;