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)
69 /* Hmm, under unix we want X modifiers, under NT we want X modifiers if
70 we are running X and Windows modifiers otherwise.
71 gak. This is a kludge until we support multiple native GUIs!
78 #include "events-mod.h"
80 static void enqueue_Xt_dispatch_event (Lisp_Object event);
81 static void handle_focus_event_1 (struct frame *f, int in_p);
83 static struct event_stream *Xt_event_stream;
85 /* With the new event model, all events go through XtDispatchEvent()
86 and are picked up by an event handler that is added to each frame
87 widget. (This is how it's supposed to be.) In the old method,
88 Emacs sucks out events directly from XtNextEvent() and only
89 dispatches the events that it doesn't need to deal with. This
90 old way has lots of corresponding junk that is no longer
91 necessary: lwlib extensions, synthetic XAnyEvents, unnecessary
94 /* The one and only one application context that Emacs uses. */
95 XtAppContext Xt_app_con;
97 /* Do we accept events sent by other clients? */
98 int x_allow_sendevents;
100 int modifier_keys_are_sticky;
106 static int process_events_occurred;
107 static int tty_events_occurred;
109 /* Mask of bits indicating the descriptors that we wait for input on */
110 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
112 static const String x_fallback_resources[] =
114 /* This file is automatically generated from the app-defaults file
115 in ../etc/Emacs.ad. These resources are consulted only if no
116 app-defaults file is found at all.
118 #include <Emacs.ad.h>
122 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
123 void emacs_Xt_mapping_action (Widget w, XEvent *event);
124 void debug_process_finalization (Lisp_Process *p);
125 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
126 Boolean *continue_to_dispatch);
128 static int last_quit_check_signal_tick_count;
130 Lisp_Object Qkey_mapping;
131 Lisp_Object Qsans_modifiers;
134 /************************************************************************/
135 /* keymap handling */
136 /************************************************************************/
138 /* X bogusly doesn't define the interpretations of any bits besides
139 ModControl, ModShift, and ModLock; so the Interclient Communication
140 Conventions Manual says that we have to bend over backwards to figure
141 out what the other modifier bits mean. According to ICCCM:
143 - Any keycode which is assigned ModControl is a "control" key.
145 - Any modifier bit which is assigned to a keycode which generates Meta_L
146 or Meta_R is the modifier bit meaning "meta". Likewise for Super, Hyper,
149 - Any keypress event which contains ModControl in its state should be
150 interpreted as a "control" character.
152 - Any keypress event which contains a modifier bit in its state which is
153 generated by a keycode whose corresponding keysym is Meta_L or Meta_R
154 should be interpreted as a "meta" character. Likewise for Super, Hyper,
157 - It is illegal for a keysym to be associated with more than one modifier
160 This means that the only thing that emacs can reasonably interpret as a
161 "meta" key is a key whose keysym is Meta_L or Meta_R, and which generates
162 one of the modifier bits Mod1-Mod5.
164 Unfortunately, many keyboards don't have Meta keys in their default
165 configuration. So, if there are no Meta keys, but there are "Alt" keys,
166 emacs will interpret Alt as Meta. If there are both Meta and Alt keys,
167 then the Meta keys mean "Meta", and the Alt keys mean "Alt" (it used to
168 mean "Symbol," but that just confused the hell out of way too many people).
170 This works with the default configurations of the 19 keyboard-types I've
173 Emacs detects keyboard configurations which violate the above rules, and
174 prints an error message on the standard-error-output. (Perhaps it should
175 use a pop-up-window instead.)
178 /* For every key on the keyboard that has a known character correspondence,
179 we define the ascii-character property of the keysym, and make the
180 default binding for the key be self-insert-command.
182 The following magic is basically intimate knowledge of X11/keysymdef.h.
183 The keysym mappings defined by X11 are based on the iso8859 standards,
184 except for Cyrillic and Greek.
186 In a non-Mule world, a user can still have a multi-lingual editor, by doing
187 (set-face-font "...-iso8859-2" (current-buffer))
188 for all their Latin-2 buffers, etc. */
191 x_keysym_to_character (KeySym keysym)
194 Lisp_Object charset = Qzero;
195 #define USE_CHARSET(var,cs) \
196 ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
198 #define USE_CHARSET(var,lb)
202 if ((keysym & 0xff) < 0xa0)
207 case 0: /* ASCII + Latin1 */
208 USE_CHARSET (charset, LATIN_ISO8859_1);
209 code = keysym & 0x7f;
212 USE_CHARSET (charset, LATIN_ISO8859_2);
213 code = keysym & 0x7f;
216 USE_CHARSET (charset, LATIN_ISO8859_3);
217 code = keysym & 0x7f;
220 USE_CHARSET (charset, LATIN_ISO8859_4);
221 code = keysym & 0x7f;
223 case 4: /* Katakana */
224 USE_CHARSET (charset, KATAKANA_JISX0201);
225 if ((keysym & 0xff) > 0xa0)
226 code = keysym & 0x7f;
229 USE_CHARSET (charset, ARABIC_ISO8859_6);
230 code = keysym & 0x7f;
232 case 6: /* Cyrillic */
234 static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
235 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
236 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
237 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
238 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
239 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
240 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
241 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
242 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
243 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
244 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
245 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
246 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
247 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
248 code = cyrillic[(keysym & 0x7f) - 0x20];
253 static unsigned char const greek[] = /* 0x20 - 0x7f */
254 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
255 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
256 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
257 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
259 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
260 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
261 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
263 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
264 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
265 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
266 USE_CHARSET (charset, GREEK_ISO8859_7);
267 code = greek[(keysym & 0x7f) - 0x20];
270 case 8: /* Technical */
272 case 9: /* Special */
274 case 10: /* Publishing */
278 case 12: /* Hebrew */
279 USE_CHARSET (charset, HEBREW_ISO8859_8);
280 code = keysym & 0x7f;
283 /* #### This needs to deal with character composition. */
284 USE_CHARSET (charset, THAI_TIS620);
285 code = keysym & 0x7f;
287 case 14: /* Korean Hangul */
289 case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
291 case 32: /* Currency */
301 return make_char (MAKE_CHAR (charset, code, 0));
303 return make_char (code + 0x80);
307 /* #### The way that keysym correspondence to characters should work:
308 - a Lisp_Event should contain a keysym AND a character slot.
309 - keybindings are tried with the keysym. If no binding can be found,
310 and there is a corresponding character, call self-insert-command.
312 #### Nuke x-iso8859-1.el.
313 #### Nuke the Qascii_character property.
314 #### Nuke Vcharacter_set_property.
317 maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
319 Lisp_Object character = x_keysym_to_character (keysym);
321 if (CHARP (character))
323 extern Lisp_Object Vcurrent_global_map;
324 extern Lisp_Object Qascii_character;
325 Fput (symbol, Qascii_character, character);
326 if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
327 Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
332 x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
334 KeySym upper_lower[2];
337 if (keysym < 0x80) /* Optimize for ASCII keysyms */
341 xmodmap -e 'keysym NN = scaron'
342 and then press (Shift scaron), X11 will return the different
343 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'.
344 So we "register" both `scaron' and `Scaron'. */
345 #ifdef HAVE_XCONVERTCASE
346 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
348 upper_lower[0] = upper_lower[1] = keysym;
351 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
354 keysym = upper_lower[j];
356 name = XKeysymToString (keysym);
359 /* X guarantees NAME to be in the Host Portable Character Encoding */
360 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
361 Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
362 Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
364 if (! EQ (old_value, new_value)
365 && ! (EQ (old_value, Qsans_modifiers) &&
368 maybe_define_x_key_as_self_inserting_character (keysym, sym);
369 Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
370 Fputhash (sym, new_value, hash_table);
377 x_reset_key_mapping (struct device *d)
379 Display *display = DEVICE_X_DISPLAY (d);
380 struct x_device *xd = DEVICE_X_DATA (d);
381 KeySym *keysym, *keysym_end;
382 Lisp_Object hash_table;
383 int key_code_count, keysyms_per_code;
385 if (xd->x_keysym_map)
386 XFree ((char *) xd->x_keysym_map);
387 XDisplayKeycodes (display,
388 &xd->x_keysym_map_min_code,
389 &xd->x_keysym_map_max_code);
390 key_code_count = xd->x_keysym_map_max_code - xd->x_keysym_map_min_code + 1;
392 XGetKeyboardMapping (display, xd->x_keysym_map_min_code, key_code_count,
393 &xd->x_keysym_map_keysyms_per_code);
395 hash_table = xd->x_keysym_map_hash_table;
396 if (HASH_TABLEP (hash_table))
397 Fclrhash (hash_table);
399 xd->x_keysym_map_hash_table = hash_table =
400 make_lisp_hash_table (128, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
402 for (keysym = xd->x_keysym_map,
403 keysyms_per_code = xd->x_keysym_map_keysyms_per_code,
404 keysym_end = keysym + (key_code_count * keysyms_per_code);
406 keysym += keysyms_per_code)
410 if (keysym[0] == NoSymbol)
413 x_has_keysym (keysym[0], hash_table, 0);
415 for (j = 1; j < keysyms_per_code; j++)
417 if (keysym[j] != keysym[0] &&
418 keysym[j] != NoSymbol)
419 x_has_keysym (keysym[j], hash_table, 1);
425 index_to_name (int indice)
429 case ShiftMapIndex: return "ModShift";
430 case LockMapIndex: return "ModLock";
431 case ControlMapIndex: return "ModControl";
432 case Mod1MapIndex: return "Mod1";
433 case Mod2MapIndex: return "Mod2";
434 case Mod3MapIndex: return "Mod3";
435 case Mod4MapIndex: return "Mod4";
436 case Mod5MapIndex: return "Mod5";
437 default: return "???";
441 /* Boy, I really wish C had local functions... */
442 struct c_doesnt_have_closures /* #### not yet used */
444 int warned_about_overlapping_modifiers;
445 int warned_about_predefined_modifiers;
446 int warned_about_duplicate_modifiers;
455 x_reset_modifier_mapping (struct device *d)
457 Display *display = DEVICE_X_DISPLAY (d);
458 struct x_device *xd = DEVICE_X_DATA (d);
459 int modifier_index, modifier_key, column, mkpm;
460 int warned_about_overlapping_modifiers = 0;
461 int warned_about_predefined_modifiers = 0;
462 int warned_about_duplicate_modifiers = 0;
469 xd->lock_interpretation = 0;
471 if (xd->x_modifier_keymap)
472 XFreeModifiermap (xd->x_modifier_keymap);
474 x_reset_key_mapping (d);
476 xd->x_modifier_keymap = XGetModifierMapping (display);
478 /* Boy, I really wish C had local functions...
481 /* The call to warn_when_safe must be on the same line as the string or
482 make-msgfile won't pick it up properly (the newline doesn't confuse
483 it, but the backslash does). */
485 #define modwarn(name,old,other) \
486 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is generated by %s.", \
487 name, code, index_to_name (old), other), \
488 warned_about_overlapping_modifiers = 1
490 #define modbarf(name,other) \
491 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
492 name, code, other), \
493 warned_about_predefined_modifiers = 1
495 #define check_modifier(name,mask) \
496 if ((1<<modifier_index) != mask) \
497 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
498 name, code, index_to_name (modifier_index)), \
499 warned_about_predefined_modifiers = 1
501 #define store_modifier(name,old) \
502 if (old && old != modifier_index) \
503 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates both %s and %s, which is nonsensical.",\
504 name, code, index_to_name (old), \
505 index_to_name (modifier_index)), \
506 warned_about_duplicate_modifiers = 1; \
507 if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift"); \
508 else if (modifier_index == LockMapIndex) modbarf (name,"ModLock"); \
509 else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl"); \
510 else if (sym == XK_Mode_switch) \
511 mode_bit = modifier_index; /* Mode_switch is special, see below... */ \
512 else if (modifier_index == meta_bit && old != meta_bit) \
513 modwarn (name, meta_bit, "Meta"); \
514 else if (modifier_index == super_bit && old != super_bit) \
515 modwarn (name, super_bit, "Super"); \
516 else if (modifier_index == hyper_bit && old != hyper_bit) \
517 modwarn (name, hyper_bit, "Hyper"); \
518 else if (modifier_index == alt_bit && old != alt_bit) \
519 modwarn (name, alt_bit, "Alt"); \
521 old = modifier_index;
523 mkpm = xd->x_modifier_keymap->max_keypermod;
524 for (modifier_index = 0; modifier_index < 8; modifier_index++)
525 for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
527 for (column = 0; column < 4; column += 2) {
528 KeyCode code = xd->x_modifier_keymap->modifiermap[modifier_index * mkpm
530 KeySym sym = (code ? XKeycodeToKeysym (display, code, column) : 0);
531 if (sym == last_sym) continue;
534 case XK_Mode_switch:store_modifier ("Mode_switch", mode_bit); break;
535 case XK_Meta_L: store_modifier ("Meta_L", meta_bit); break;
536 case XK_Meta_R: store_modifier ("Meta_R", meta_bit); break;
537 case XK_Super_L: store_modifier ("Super_L", super_bit); break;
538 case XK_Super_R: store_modifier ("Super_R", super_bit); break;
539 case XK_Hyper_L: store_modifier ("Hyper_L", hyper_bit); break;
540 case XK_Hyper_R: store_modifier ("Hyper_R", hyper_bit); break;
541 case XK_Alt_L: store_modifier ("Alt_L", alt_bit); break;
542 case XK_Alt_R: store_modifier ("Alt_R", alt_bit); break;
543 case XK_Control_L: check_modifier ("Control_L", ControlMask); break;
544 case XK_Control_R: check_modifier ("Control_R", ControlMask); break;
545 case XK_Shift_L: check_modifier ("Shift_L", ShiftMask); break;
546 case XK_Shift_R: check_modifier ("Shift_R", ShiftMask); break;
547 case XK_Shift_Lock: check_modifier ("Shift_Lock", LockMask);
548 xd->lock_interpretation = XK_Shift_Lock; break;
549 case XK_Caps_Lock: check_modifier ("Caps_Lock", LockMask);
550 xd->lock_interpretation = XK_Caps_Lock; break;
552 /* It probably doesn't make any sense for a modifier bit to be
553 assigned to a key that is not one of the above, but OpenWindows
554 assigns modifier bits to a couple of random function keys for
555 no reason that I can discern, so printing a warning here would
560 #undef store_modifier
561 #undef check_modifier
565 /* If there was no Meta key, then try using the Alt key instead.
566 If there is both a Meta key and an Alt key, then the Alt key
567 is not disturbed and remains an Alt key. */
568 if (! meta_bit && alt_bit)
569 meta_bit = alt_bit, alt_bit = 0;
571 /* mode_bit overrides everything, since it's processed down inside of
572 XLookupString() instead of by us. If Meta and Mode_switch both
573 generate the same modifier bit (which is an error), then we don't
574 interpret that bit as Meta, because we can't make XLookupString()
575 not interpret it as Mode_switch; and interpreting it as both would
579 const char *warn = 0;
580 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
581 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
582 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
583 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
587 (Qkey_mapping, Qwarning,
588 "XEmacs: %s is being used for both Mode_switch and %s.",
589 index_to_name (mode_bit), warn),
590 warned_about_overlapping_modifiers = 1;
595 xd->MetaMask = (meta_bit ? (1 << meta_bit) : 0);
596 xd->HyperMask = (hyper_bit ? (1 << hyper_bit) : 0);
597 xd->SuperMask = (super_bit ? (1 << super_bit) : 0);
598 xd->AltMask = (alt_bit ? (1 << alt_bit) : 0);
599 xd->ModeMask = (mode_bit ? (1 << mode_bit) : 0); /* unused */
602 if (warned_about_overlapping_modifiers)
603 warn_when_safe (Qkey_mapping, Qwarning, "\n"
604 " Two distinct modifier keys (such as Meta and Hyper) cannot generate\n"
605 " the same modifier bit, because Emacs won't be able to tell which\n"
606 " modifier was actually held down when some other key is pressed. It\n"
607 " won't be able to tell Meta-x and Hyper-x apart, for example. Change\n"
608 " one of these keys to use some other modifier bit. If you intend for\n"
609 " these keys to have the same behavior, then change them to have the\n"
610 " same keysym as well as the same modifier bit.");
612 if (warned_about_predefined_modifiers)
613 warn_when_safe (Qkey_mapping, Qwarning, "\n"
614 " The semantics of the modifier bits ModShift, ModLock, and ModControl\n"
615 " are predefined. It does not make sense to assign ModControl to any\n"
616 " keysym other than Control_L or Control_R, or to assign any modifier\n"
617 " bits to the \"control\" keysyms other than ModControl. You can't\n"
618 " turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n"
619 " assigning the key a different modifier bit. You must also make that\n"
620 " key generate an appropriate keysym (Control_L, Meta_L, etc).");
622 /* No need to say anything more for warned_about_duplicate_modifiers. */
624 if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers)
625 warn_when_safe (Qkey_mapping, Qwarning, "\n"
626 " The meanings of the modifier bits Mod1 through Mod5 are determined\n"
627 " by the keysyms used to control those bits. Mod1 does NOT always\n"
628 " mean Meta, although some non-ICCCM-compliant programs assume that.");
632 x_init_modifier_mapping (struct device *d)
634 struct x_device *xd = DEVICE_X_DATA (d);
635 xd->x_keysym_map_hash_table = Qnil;
636 xd->x_keysym_map = NULL;
637 xd->x_modifier_keymap = NULL;
638 x_reset_modifier_mapping (d);
642 x_key_is_modifier_p (KeyCode keycode, struct device *d)
644 struct x_device *xd = DEVICE_X_DATA (d);
648 if (keycode < xd->x_keysym_map_min_code ||
649 keycode > xd->x_keysym_map_max_code)
652 syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
653 xd->x_keysym_map_keysyms_per_code];
654 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
655 if (IsModifierKey (syms [i]) ||
656 syms [i] == XK_Mode_switch) /* why doesn't IsModifierKey count this? */
661 /* key-handling code is always ugly. It just ends up working out
664 Here are some pointers:
666 -- DOWN_MASK indicates which modifiers should be treated as "down"
667 when the corresponding upstroke happens. It gets reset for
668 a particular modifier when that modifier goes up, and reset
669 for all modifiers when a non-modifier key is pressed. Example:
671 I press Control-A-Shift and then release Control-A-Shift.
672 I want the Shift key to be sticky but not the Control key.
674 -- LAST_DOWNKEY and RELEASE_TIME are used to keep track of
675 auto-repeat -- see below.
677 -- If a modifier key is sticky, I can unstick it by pressing
678 the modifier key again. */
681 x_handle_sticky_modifiers (XEvent *ev, struct device *d)
687 if (!modifier_keys_are_sticky) /* Optimize for non-sticky modifiers */
690 xd = DEVICE_X_DATA (d);
691 keycode = ev->xkey.keycode;
694 if (keycode < xd->x_keysym_map_min_code ||
695 keycode > xd->x_keysym_map_max_code)
698 if (! ((type == KeyPress || type == KeyRelease) &&
699 x_key_is_modifier_p (keycode, d)))
700 { /* Not a modifier key */
701 Bool key_event_p = (type == KeyPress || type == KeyRelease);
703 if (type == KeyPress && !xd->last_downkey)
704 xd->last_downkey = keycode;
705 else if (type == ButtonPress ||
706 (type == KeyPress && xd->last_downkey &&
707 (keycode != xd->last_downkey ||
708 ev->xkey.time != xd->release_time)))
710 xd->need_to_add_mask = 0;
711 xd->last_downkey = 0;
713 if (type == KeyPress)
714 xd->release_time = 0;
715 if (type == KeyPress || type == ButtonPress)
719 ev->xkey.state |= xd->need_to_add_mask;
721 ev->xbutton.state |= xd->need_to_add_mask;
723 if (type == KeyRelease && keycode == xd->last_downkey)
724 /* If I hold press-and-release the Control key and then press
725 and hold down the right arrow, I want it to auto-repeat
726 Control-Right. On the other hand, if I do the same but
727 manually press the Right arrow a bunch of times, I want
728 to see one Control-Right and then a bunch of Rights.
729 This means that we need to distinguish between an
730 auto-repeated key and a key pressed and released a bunch
733 Naturally, the designers of the X spec didn't see fit
734 to provide an obvious way to distinguish these cases.
735 So we assume that if the release and the next press
736 occur at the same time, the key was actually auto-
737 repeated. Under Open-Windows, at least, this works. */
738 xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time;
740 else /* Modifier key pressed */
743 KeySym *syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
744 xd->x_keysym_map_keysyms_per_code];
746 /* If a non-modifier key was pressed in the middle of a bunch
747 of modifiers, then it unsticks all the modifiers that were
748 previously pressed. We cannot unstick the modifiers until
749 now because we want to check for auto-repeat of the
752 if (xd->last_downkey)
754 xd->last_downkey = 0;
755 xd->need_to_add_mask = 0;
760 if (type == KeyPress) \
762 /* If modifier key is already sticky, \
763 then unstick it. Note that we do \
764 not test down_mask to deal with the \
765 unlikely but possible case that the \
766 modifier key auto-repeats. */ \
767 if (xd->need_to_add_mask & mask) \
769 xd->need_to_add_mask &= ~mask; \
770 xd->down_mask &= ~mask; \
773 xd->down_mask |= mask; \
777 if (xd->down_mask & mask) \
779 xd->down_mask &= ~mask; \
780 xd->need_to_add_mask |= mask; \
785 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
788 case XK_Control_L: case XK_Control_R: FROB (ControlMask); break;
789 case XK_Shift_L: case XK_Shift_R: FROB (ShiftMask); break;
790 case XK_Meta_L: case XK_Meta_R: FROB (xd->MetaMask); break;
791 case XK_Super_L: case XK_Super_R: FROB (xd->SuperMask); break;
792 case XK_Hyper_L: case XK_Hyper_R: FROB (xd->HyperMask); break;
793 case XK_Alt_L: case XK_Alt_R: FROB (xd->AltMask); break;
800 clear_sticky_modifiers (struct device *d)
802 struct x_device *xd = DEVICE_X_DATA (d);
804 xd->need_to_add_mask = 0;
805 xd->last_downkey = 0;
806 xd->release_time = 0;
811 keysym_obeys_caps_lock_p (KeySym sym, struct device *d)
813 struct x_device *xd = DEVICE_X_DATA (d);
814 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic
815 characters, where "alphabetic" means something more than simply A-Z.
816 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC.
817 But if shift-lock is down, then it does. */
818 if (xd->lock_interpretation == XK_Shift_Lock)
822 ((sym >= XK_A) && (sym <= XK_Z)) ||
823 ((sym >= XK_a) && (sym <= XK_z)) ||
824 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) ||
825 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) ||
826 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) ||
827 ((sym >= XK_oslash) && (sym <= XK_thorn));
830 /* called from EmacsFrame.c (actually from Xt itself) when a
831 MappingNotify event is received. In its infinite wisdom, Xt
832 decided that Xt event handlers never get MappingNotify events.
833 O'Reilly Xt Programming Manual 9.1.2 says:
835 MappingNotify is automatically handled by Xt, so it isn't passed
836 to event handlers and you don't need to worry about it.
838 Of course, we DO worry about it, so we need a special translation. */
840 emacs_Xt_mapping_action (Widget w, XEvent* event)
842 struct device *d = get_device_from_display (event->xany.display);
844 if (DEVICE_X_BEING_DELETED (d))
847 /* nyet. Now this is handled by Xt. */
848 XRefreshKeyboardMapping (&event->xmapping);
850 /* xmodmap generates about a billion MappingKeyboard events, followed
851 by a single MappingModifier event, so it might be worthwhile to
852 take extra MappingKeyboard events out of the queue before requesting
853 the current keymap from the server. */
854 switch (event->xmapping.request)
856 case MappingKeyboard: x_reset_key_mapping (d); break;
857 case MappingModifier: x_reset_modifier_mapping (d); break;
858 case MappingPointer: /* Do something here? */ break;
864 /************************************************************************/
865 /* X to Emacs event conversion */
866 /************************************************************************/
869 x_keysym_to_emacs_keysym (KeySym keysym, int simple_p)
872 if (keysym >= XK_exclam && keysym <= XK_asciitilde)
873 /* We must assume that the X keysym numbers for the ASCII graphic
874 characters are the same as their ASCII codes. */
875 return make_char (keysym);
879 /* These would be handled correctly by the default case, but by
880 special-casing them here we don't garbage a string or call
882 case XK_BackSpace: return QKbackspace;
883 case XK_Tab: return QKtab;
884 case XK_Linefeed: return QKlinefeed;
885 case XK_Return: return QKreturn;
886 case XK_Escape: return QKescape;
887 case XK_space: return QKspace;
888 case XK_Delete: return QKdelete;
891 if (simple_p) return Qnil;
892 /* !!#### not Mule-ized */
893 name = XKeysymToString (keysym);
894 if (!name || !name[0])
895 /* This happens if there is a mismatch between the Xlib of
896 XEmacs and the Xlib of the X server...
898 Let's hard-code in some knowledge of common keysyms introduced
899 in recent X11 releases. Snarfed from X11/keysymdef.h
901 Probably we should add some stuff here for X11R6. */
904 case 0xFF95: return KEYSYM ("kp-home");
905 case 0xFF96: return KEYSYM ("kp-left");
906 case 0xFF97: return KEYSYM ("kp-up");
907 case 0xFF98: return KEYSYM ("kp-right");
908 case 0xFF99: return KEYSYM ("kp-down");
909 case 0xFF9A: return KEYSYM ("kp-prior");
910 case 0xFF9B: return KEYSYM ("kp-next");
911 case 0xFF9C: return KEYSYM ("kp-end");
912 case 0xFF9D: return KEYSYM ("kp-begin");
913 case 0xFF9E: return KEYSYM ("kp-insert");
914 case 0xFF9F: return KEYSYM ("kp-delete");
916 case 0x1005FF10: return KEYSYM ("SunF36"); /* labeled F11 */
917 case 0x1005FF11: return KEYSYM ("SunF37"); /* labeled F12 */
921 sprintf (buf, "unknown-keysym-0x%X", (int) keysym);
925 /* If it's got a one-character name, that's good enough. */
927 return make_char (name[0]);
929 /* If it's in the "Keyboard" character set, downcase it.
930 The case of those keysyms is too totally random for us to
931 force anyone to remember them.
932 The case of the other character sets is significant, however.
934 if ((((unsigned int) keysym) & (~0x1FF)) == ((unsigned int) 0xFE00))
938 for (s1 = name, s2 = buf; *s1; s1++, s2++) {
942 *s2 = tolower (* (unsigned char *) s1);
948 return KEYSYM (name);
953 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
954 /* simple_p means don't try too hard (ASCII only) */
961 char *bufptr = buffer;
962 int bufsiz = sizeof (buffer);
965 XIC xic = FRAME_X_XIC (x_any_window_to_frame
966 (get_device_from_display (event->display),
968 #endif /* XIM_XLIB */
969 #endif /* HAVE_XIM */
971 /* We use XLookupString if we're not using XIM, or are using
972 XIM_XLIB but input context creation failed. */
973 #if ! (defined (HAVE_XIM) && defined (XIM_MOTIF))
974 #if defined (HAVE_XIM) && defined (XIM_XLIB)
976 #endif /* XIM_XLIB */
978 /* Apparently it's necessary to specify a dummy here (rather
979 than passing in 0) to avoid crashes on German IRIX */
981 XLookupString (event, dummy, 200, &keysym, 0);
982 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
983 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
985 #endif /* ! XIM_MOTIF */
988 Lookup_String: /* Come-From XBufferOverflow */
990 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
991 event, bufptr, bufsiz, &keysym, &status);
994 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
995 #endif /* HAVE_XIM */
998 if (x_debug_events > 0)
1000 stderr_out (" status=");
1001 #define print_status_when(S) if (status == S) stderr_out (#S)
1002 print_status_when (XLookupKeySym);
1003 print_status_when (XLookupBoth);
1004 print_status_when (XLookupChars);
1005 print_status_when (XLookupNone);
1006 print_status_when (XBufferOverflow);
1008 if (status == XLookupKeySym || status == XLookupBoth)
1009 stderr_out (" keysym=%s", XKeysymToString (keysym));
1010 if (status == XLookupChars || status == XLookupBoth)
1015 stderr_out (" chars=\"");
1016 for (j=0; j<len; j++)
1017 stderr_out ("%c", bufptr[j]);
1020 else if (bufptr[0] <= 32 || bufptr[0] >= 127)
1021 stderr_out (" char=0x%x", bufptr[0]);
1023 stderr_out (" char=%c", bufptr[0]);
1027 #endif /* DEBUG_XEMACS */
1033 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
1034 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
1038 /* Generate multiple emacs events */
1039 struct device *d = get_device_from_display (event->display);
1041 Lisp_Object instream, fb_instream;
1043 struct gcpro gcpro1, gcpro2;
1045 fb_instream = make_fixed_buffer_input_stream (bufptr, len);
1047 /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */
1049 make_decoding_input_stream (XLSTREAM (fb_instream),
1050 Fget_coding_system (Qundecided));
1052 istr = XLSTREAM (instream);
1054 GCPRO2 (instream, fb_instream);
1055 while ((ch = Lstream_get_emchar (istr)) != EOF)
1057 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1058 Lisp_Event *ev = XEVENT (emacs_event);
1059 ev->channel = DEVICE_CONSOLE (d);
1060 ev->event_type = key_press_event;
1061 ev->timestamp = event->time;
1062 ev->event.key.modifiers = 0;
1063 ev->event.key.keysym = make_char (ch);
1064 enqueue_Xt_dispatch_event (emacs_event);
1066 Lstream_close (istr);
1068 Lstream_delete (istr);
1069 Lstream_delete (XLSTREAM (fb_instream));
1072 case XLookupNone: return Qnil;
1073 case XBufferOverflow:
1074 bufptr = (char *) alloca (len+1);
1078 return Qnil; /* not reached */
1079 #endif /* HAVE_XIM */
1083 set_last_server_timestamp (struct device *d, XEvent *x_event)
1086 switch (x_event->type)
1089 case KeyRelease: t = x_event->xkey.time; break;
1091 case ButtonRelease: t = x_event->xbutton.time; break;
1093 case LeaveNotify: t = x_event->xcrossing.time; break;
1094 case MotionNotify: t = x_event->xmotion.time; break;
1095 case PropertyNotify: t = x_event->xproperty.time; break;
1096 case SelectionClear: t = x_event->xselectionclear.time; break;
1097 case SelectionRequest: t = x_event->xselectionrequest.time; break;
1098 case SelectionNotify: t = x_event->xselection.time; break;
1101 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t;
1105 x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
1107 Display *display = x_event->xany.display;
1108 struct device *d = get_device_from_display (display);
1109 struct x_device *xd = DEVICE_X_DATA (d);
1111 if (DEVICE_X_BEING_DELETED (d))
1112 /* #### Uh, is this 0 correct? */
1115 set_last_server_timestamp (d, x_event);
1117 switch (x_event->type)
1120 x_handle_sticky_modifiers (x_event, d);
1127 unsigned int modifiers = 0;
1128 int shift_p, lock_p;
1129 Bool key_event_p = (x_event->type == KeyPress);
1130 unsigned int *state =
1131 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state;
1133 /* If this is a synthetic KeyPress or Button event, and the user
1134 has expressed a disinterest in this security hole, then drop
1137 ? x_event->xkey.send_event
1138 : x_event->xbutton.send_event)
1139 #ifdef EXTERNAL_WIDGET
1140 /* ben: events get sent to an ExternalShell using XSendEvent.
1141 This is not a perfect solution. */
1142 && !FRAME_X_EXTERNAL_WINDOW_P
1143 (x_any_window_to_frame (d, x_event->xany.window))
1145 && !x_allow_sendevents)
1148 DEVICE_X_MOUSE_TIMESTAMP (d) =
1149 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) =
1150 key_event_p ? x_event->xkey.time : x_event->xbutton.time;
1152 x_handle_sticky_modifiers (x_event, d);
1154 if (*state & ControlMask) modifiers |= MOD_CONTROL;
1155 if (*state & xd->MetaMask) modifiers |= MOD_META;
1156 if (*state & xd->SuperMask) modifiers |= MOD_SUPER;
1157 if (*state & xd->HyperMask) modifiers |= MOD_HYPER;
1158 if (*state & xd->AltMask) modifiers |= MOD_ALT;
1160 /* Ignore the Caps_Lock key if:
1161 - any other modifiers are down, so that Caps_Lock doesn't
1162 turn C-x into C-X, which would suck.
1163 - the event was a mouse event. */
1164 if (modifiers || ! key_event_p)
1165 *state &= (~LockMask);
1167 shift_p = *state & ShiftMask;
1168 lock_p = *state & LockMask;
1170 if (shift_p || lock_p)
1171 modifiers |= MOD_SHIFT;
1176 XKeyEvent *ev = &x_event->xkey;
1177 /* This used to compute the frame from the given X window and
1178 store it here, but we really don't care about the frame. */
1179 emacs_event->channel = DEVICE_CONSOLE (d);
1180 keysym = x_to_emacs_keysym (&x_event->xkey, 0);
1182 /* If the emacs keysym is nil, then that means that the X
1183 keysym was either a Modifier or NoSymbol, which
1184 probably means that we're in the midst of reading a
1185 Multi_key sequence, or a "dead" key prefix, or XIM
1186 input. Ignore it. */
1190 /* More Caps_Lock garbage: Caps_Lock should *only* add the
1191 shift modifier to two-case keys (that is, A-Z and
1192 related characters). So at this point (after looking up
1193 the keysym) if the keysym isn't a dual-case alphabetic,
1194 and if the caps lock key was down but the shift key
1195 wasn't, then turn off the shift modifier. Gag barf */
1196 /* #### type lossage: assuming equivalence of emacs and
1198 /* !!#### maybe fix for Mule */
1199 if (lock_p && !shift_p &&
1200 ! (CHAR_OR_CHAR_INTP (keysym)
1201 && keysym_obeys_caps_lock_p
1202 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
1203 modifiers &= (~MOD_SHIFT);
1205 /* If this key contains two distinct keysyms, that is,
1206 "shift" generates a different keysym than the
1207 non-shifted key, then don't apply the shift modifier
1208 bit: it's implicit. Otherwise, if there would be no
1209 other way to tell the difference between the shifted
1210 and unshifted version of this key, apply the shift bit.
1211 Non-graphics, like Backspace and F1 get the shift bit
1212 in the modifiers slot. Neither the characters "a",
1213 "A", "2", nor "@" normally have the shift bit set.
1214 However, "F1" normally does. */
1215 if (modifiers & MOD_SHIFT)
1217 int Mode_switch_p = *state & xd->ModeMask;
1218 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
1219 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1);
1220 if (top && bot && top != bot)
1221 modifiers &= ~MOD_SHIFT;
1223 emacs_event->event_type = key_press_event;
1224 emacs_event->timestamp = ev->time;
1225 emacs_event->event.key.modifiers = modifiers;
1226 emacs_event->event.key.keysym = keysym;
1228 else /* Mouse press/release event */
1230 XButtonEvent *ev = &x_event->xbutton;
1231 struct frame *frame = x_window_to_frame (d, ev->window);
1234 return 0; /* not for us */
1235 XSETFRAME (emacs_event->channel, frame);
1237 emacs_event->event_type = (x_event->type == ButtonPress) ?
1238 button_press_event : button_release_event;
1240 emacs_event->event.button.modifiers = modifiers;
1241 emacs_event->timestamp = ev->time;
1242 emacs_event->event.button.button = ev->button;
1243 emacs_event->event.button.x = ev->x;
1244 emacs_event->event.button.y = ev->y;
1245 /* because we don't seem to get a FocusIn event for button clicks
1246 when a widget-glyph is selected we will assume that we want the
1247 focus if a button gets pressed. */
1248 if (x_event->type == ButtonPress)
1249 handle_focus_event_1 (frame, 1);
1256 XMotionEvent *ev = &x_event->xmotion;
1257 struct frame *frame = x_window_to_frame (d, ev->window);
1258 unsigned int modifiers = 0;
1259 XMotionEvent event2;
1262 return 0; /* not for us */
1264 /* We use MotionHintMask, so we will get only one motion event
1265 until the next time we call XQueryPointer or the user
1266 clicks the mouse. So call XQueryPointer now (meaning that
1267 the event will be in sync with the server just before
1268 Fnext_event() returns). If the mouse is still in motion,
1269 then the server will immediately generate exactly one more
1270 motion event, which will be on the queue waiting for us
1271 next time around. */
1273 if (XQueryPointer (event2.display, event2.window,
1274 &event2.root, &event2.subwindow,
1275 &event2.x_root, &event2.y_root,
1276 &event2.x, &event2.y,
1278 ev = &event2; /* only one structure copy */
1280 DEVICE_X_MOUSE_TIMESTAMP (d) = ev->time;
1282 XSETFRAME (emacs_event->channel, frame);
1283 emacs_event->event_type = pointer_motion_event;
1284 emacs_event->timestamp = ev->time;
1285 emacs_event->event.motion.x = ev->x;
1286 emacs_event->event.motion.y = ev->y;
1287 if (ev->state & ShiftMask) modifiers |= MOD_SHIFT;
1288 if (ev->state & ControlMask) modifiers |= MOD_CONTROL;
1289 if (ev->state & xd->MetaMask) modifiers |= MOD_META;
1290 if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER;
1291 if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER;
1292 if (ev->state & xd->AltMask) modifiers |= MOD_ALT;
1293 /* Currently ignores Shift_Lock but probably shouldn't
1294 (but it definitely should ignore Caps_Lock). */
1295 emacs_event->event.motion.modifiers = modifiers;
1301 /* Patch bogus TAKE_FOCUS messages from MWM; CurrentTime is
1302 passed as the timestamp of the TAKE_FOCUS, which the ICCCM
1303 explicitly prohibits. */
1304 XClientMessageEvent *ev = &x_event->xclient;
1305 #ifdef HAVE_OFFIX_DND
1306 if (DndIsDropMessage(x_event))
1308 unsigned int state, modifiers = 0, button=0;
1309 struct frame *frame = x_any_window_to_frame (d, ev->window);
1311 unsigned long size, dtype;
1312 Lisp_Object l_type = Qnil, l_data = Qnil;
1313 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
1314 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1316 GCPRO4 (l_type, l_data, l_dndlist, l_item);
1319 return 0; /* not for us */
1320 XSETFRAME (emacs_event->channel, frame);
1322 emacs_event->event_type = misc_user_event;
1323 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1325 state=DndDragButtons(x_event);
1327 if (state & ShiftMask) modifiers |= MOD_SHIFT;
1328 if (state & ControlMask) modifiers |= MOD_CONTROL;
1329 if (state & xd->MetaMask) modifiers |= MOD_META;
1330 if (state & xd->SuperMask) modifiers |= MOD_SUPER;
1331 if (state & xd->HyperMask) modifiers |= MOD_HYPER;
1332 if (state & xd->AltMask) modifiers |= MOD_ALT;
1334 if (state & Button5Mask) button = Button5;
1335 if (state & Button4Mask) button = Button4;
1336 if (state & Button3Mask) button = Button3;
1337 if (state & Button2Mask) button = Button2;
1338 if (state & Button1Mask) button = Button1;
1340 emacs_event->event.misc.modifiers = modifiers;
1341 emacs_event->event.misc.button = button;
1343 DndDropCoordinates(FRAME_X_TEXT_WIDGET(frame), x_event,
1344 &(emacs_event->event.misc.x),
1345 &(emacs_event->event.misc.y) );
1347 DndGetData(x_event,&data,&size);
1349 dtype=DndDataType(x_event);
1352 case DndFiles: /* null terminated strings, end null */
1359 len = strlen ((char*)data);
1360 hurl = dnd_url_hexify_string ((char *)data, "file:");
1361 l_item = make_string ((Bufbyte *)hurl, strlen (hurl));
1362 l_dndlist = Fcons (l_item, l_dndlist);
1366 l_type = Qdragdrop_URL;
1370 l_type = Qdragdrop_MIME;
1371 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
1372 make_string ((Bufbyte *)"8bit", 4),
1373 make_ext_string ((Extbyte *)data,
1374 strlen((char *)data),
1378 /* we have to parse this in some way to extract
1379 content-type and params (in the tm way) and
1381 OR: if data is string, let tm do the job
1382 if data is list[2], give the first two
1385 l_type = Qdragdrop_MIME;
1386 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1387 strlen((char *)data),
1395 char *hurl = dnd_url_hexify_string ((char *) data, "file:");
1397 l_dndlist = list1 ( make_string ((Bufbyte *)hurl,
1399 l_type = Qdragdrop_URL;
1405 /* as it is a real URL it should already be escaped
1406 and escaping again will break them (cause % is unsave) */
1407 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1408 strlen ((char *)data),
1410 l_type = Qdragdrop_URL;
1412 default: /* Unknown, RawData and any other type */
1413 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ),
1414 make_string ((Bufbyte *)"8bit", 4),
1415 make_ext_string ((Extbyte *)data,
1418 l_type = Qdragdrop_MIME;
1422 emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
1423 emacs_event->event.misc.object = Fcons (l_type, l_dndlist);
1429 #endif /* HAVE_OFFIX_DND */
1430 if (ev->message_type == DEVICE_XATOM_WM_PROTOCOLS (d)
1431 && (Atom) (ev->data.l[0]) == DEVICE_XATOM_WM_TAKE_FOCUS (d)
1432 && (Atom) (ev->data.l[1]) == 0)
1434 ev->data.l[1] = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1439 default: /* it's a magic event */
1441 struct frame *frame;
1443 XEvent *x_event_copy = &emacs_event->event.magic.underlying_x_event;
1445 #define FROB(event_member, window_member) \
1446 x_event_copy->event_member = x_event->event_member; \
1447 w = x_event->event_member.window_member
1449 switch (x_event->type)
1451 case SelectionRequest: FROB(xselectionrequest, owner); break;
1452 case SelectionClear: FROB(xselectionclear, window); break;
1453 case SelectionNotify: FROB(xselection, requestor); break;
1454 case PropertyNotify: FROB(xproperty, window); break;
1455 case ClientMessage: FROB(xclient, window); break;
1456 case ConfigureNotify: FROB(xconfigure, window); break;
1458 case GraphicsExpose: FROB(xexpose, window); break;
1460 case UnmapNotify: FROB(xmap, window); break;
1462 case LeaveNotify: FROB(xcrossing, window); break;
1464 case FocusOut: FROB(xfocus, window); break;
1465 case VisibilityNotify: FROB(xvisibility, window); break;
1467 w = x_event->xany.window;
1468 *x_event_copy = *x_event;
1472 frame = x_any_window_to_frame (d, w);
1477 emacs_event->event_type = magic_event;
1478 XSETFRAME (emacs_event->channel, frame);
1488 /************************************************************************/
1489 /* magic-event handling */
1490 /************************************************************************/
1493 handle_focus_event_1 (struct frame *f, int in_p)
1495 #if XtSpecificationRelease > 5
1496 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
1499 XIM_focus_event (f, in_p);
1500 #endif /* HAVE_XIM */
1502 /* On focus change, clear all memory of sticky modifiers
1503 to avoid non-intuitive behavior. */
1504 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f)));
1506 /* We don't want to handle the focus change now, because we might
1507 be in an accept-process-output, sleep-for, or sit-for. So
1510 Actually, we half handle it: we handle it as far as changing the
1511 box cursor for redisplay, but we don't call any hooks or do any
1512 select-frame stuff until after the sit-for.
1514 Unfortunately native widgets break the model because they grab
1515 the keyboard focus and nothing sets it back again. I cannot find
1516 any reasonable way to do this elsewhere so we assert here that
1517 the keyboard focus is on the emacs text widget. Menus and dialogs
1518 do this in their selection callback, but we don't want that since
1519 a button having focus is legitimate. An edit field having focus
1520 is mandatory. Weirdly you get a FocusOut event when you click in
1521 a widget-glyph but you don't get a correspondng FocusIn when you
1522 click in the frame. Why is this? */
1524 #if XtSpecificationRelease > 5
1525 && FRAME_X_TEXT_WIDGET (f) != focus_widget
1529 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
1530 FRAME_X_TEXT_WIDGET (f));
1532 /* do the generic event-stream stuff. */
1536 struct gcpro gcpro1;
1539 conser = Fcons (frm, Fcons (FRAME_DEVICE (f), in_p ? Qt : Qnil));
1541 emacs_handle_focus_change_preliminary (conser);
1542 enqueue_magic_eval_event (emacs_handle_focus_change_final,
1548 /* This is called from the external-widget code */
1550 void emacs_Xt_handle_focus_event (XEvent *event);
1552 emacs_Xt_handle_focus_event (XEvent *event)
1554 struct device *d = get_device_from_display (event->xany.display);
1557 if (DEVICE_X_BEING_DELETED (d))
1561 * It's curious that we're using x_any_window_to_frame() instead
1562 * of x_window_to_frame(). I don't know what the impact of this is.
1564 f = x_any_window_to_frame (d, event->xfocus.window);
1566 /* focus events are sometimes generated just before
1567 a frame is destroyed. */
1569 handle_focus_event_1 (f, event->type == FocusIn);
1572 /* both MapNotify and VisibilityNotify can cause this
1573 JV is_visible has the same semantics as f->visible*/
1575 change_frame_visibility (struct frame *f, int is_visible)
1579 XSETFRAME (frame, f);
1581 if (!FRAME_VISIBLE_P (f) && is_visible)
1583 FRAME_VISIBLE_P (f) = is_visible;
1584 /* This improves the double flicker when uniconifying a frame
1585 some. A lot of it is not showing a buffer which has changed
1586 while the frame was iconified. To fix it further requires
1587 the good 'ol double redisplay structure. */
1588 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1589 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1591 else if (FRAME_VISIBLE_P (f) && !is_visible)
1593 FRAME_VISIBLE_P (f) = 0;
1594 va_run_hook_with_args (Qunmap_frame_hook, 1, frame);
1596 else if (FRAME_VISIBLE_P (f) * is_visible < 0)
1598 FRAME_VISIBLE_P(f) = - FRAME_VISIBLE_P(f);
1599 if (FRAME_REPAINT_P(f))
1600 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1601 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1606 handle_map_event (struct frame *f, XEvent *event)
1610 XSETFRAME (frame, f);
1611 if (event->type == MapNotify)
1613 XWindowAttributes xwa;
1615 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
1616 send synthetic MapNotify events when a window is first
1617 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
1618 Or something like that. We initially tried a different
1619 solution below, but that ran into a different window-
1622 It seems that the only reliable way is to treat a
1623 MapNotify event as a "hint" that the window might or
1624 might not be visible, and check explicitly. */
1626 XGetWindowAttributes (event->xany.display, event->xmap.window,
1628 if (xwa.map_state != IsViewable)
1630 /* Calling Fframe_iconified_p is the only way we have to
1631 correctly update FRAME_ICONIFIED_P */
1632 Fframe_iconified_p (frame);
1636 FRAME_X_TOTALLY_VISIBLE_P (f) = 1;
1638 /* Bleagh again!!!! We initially tried the following hack
1639 around the MWM problem, but it turns out that TWM
1640 has a race condition when you un-iconify, where it maps
1641 the window and then tells the server that the window
1642 is un-iconified. Usually, XEmacs wakes up between
1643 those two occurrences, and thus thinks that un-iconified
1644 windows are still iconified.
1646 Ah, the joys of X. */
1648 /* By Emacs definition, a frame that is iconified is not
1649 visible. Marking a frame as visible will automatically cause
1650 frame-iconified-p to return nil, regardless of whether the
1651 frame is actually iconified. Therefore, we have to ignore
1652 MapNotify events on iconified frames. (It's not obvious
1653 to me why these are being sent, but it happens at startup
1654 with frames that are initially iconified; perhaps they are
1655 synthetic MapNotify events coming from the window manager.)
1656 Note that `frame-iconified-p' queries the server
1657 to determine whether the frame is currently iconified,
1658 rather than consulting some internal (and likely
1659 inaccurate) state flag. Therefore, ignoring the MapNotify
1661 if (!FRAME_VISIBLE_P (f) && NILP (Fframe_iconified_p (frame)))
1663 change_frame_visibility (f, 1);
1667 FRAME_X_TOTALLY_VISIBLE_P (f) = 0;
1668 change_frame_visibility (f, 0);
1669 /* Calling Fframe_iconified_p is the only way we have to
1670 correctly update FRAME_ICONIFIED_P */
1671 Fframe_iconified_p (frame);
1676 handle_client_message (struct frame *f, XEvent *event)
1678 struct device *d = XDEVICE (FRAME_DEVICE (f));
1681 XSETFRAME (frame, f);
1683 if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1684 (Atom) (event->xclient.data.l[0]) == DEVICE_XATOM_WM_DELETE_WINDOW (d))
1686 /* WM_DELETE_WINDOW is a misc-user event, but other ClientMessages,
1687 such as WM_TAKE_FOCUS, are eval events. That's because delete-window
1688 was probably executed with a mouse click, while the others could
1689 have been sent as a result of mouse motion or some other implicit
1690 action. (Call this a "heuristic"...) The reason for caring about
1691 this is so that clicking on the close-box will make emacs prompt
1692 using a dialog box instead of the minibuffer if there are unsaved
1695 enqueue_misc_user_event (frame, Qeval,
1696 list3 (Qdelete_frame, frame, Qt));
1698 else if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1699 (Atom) event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d))
1701 handle_focus_event_1 (f, 1);
1703 /* If there is a dialog box up, focus on it.
1705 #### Actually, we're raising it too, which is wrong. We should
1706 #### just focus on it, but lwlib doesn't currently give us an
1707 #### easy way to do that. This should be fixed.
1709 unsigned long take_focus_timestamp = event->xclient.data.l[1];
1710 Widget widget = lw_raise_all_pop_up_widgets ();
1713 /* kludge: raise_all returns bottommost widget, but we really
1714 want the topmost. So just raise it for now. */
1715 XMapRaised (XtDisplay (widget), XtWindow (widget));
1716 /* Grab the focus with the timestamp of the TAKE_FOCUS. */
1717 XSetInputFocus (XtDisplay (widget), XtWindow (widget),
1718 RevertToParent, take_focus_timestamp);
1725 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
1727 /* This function can GC */
1728 XEvent *event = &emacs_event->event.magic.underlying_x_event;
1729 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
1731 if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f))))
1734 switch (event->type)
1736 case SelectionRequest:
1737 x_handle_selection_request (&event->xselectionrequest);
1740 case SelectionClear:
1741 x_handle_selection_clear (&event->xselectionclear);
1744 case SelectionNotify:
1745 x_handle_selection_notify (&event->xselection);
1748 case PropertyNotify:
1749 x_handle_property_notify (&event->xproperty);
1753 if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
1754 event->xexpose.width, event->xexpose.height)
1756 !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
1757 event->xexpose.width, event->xexpose.height))
1758 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1759 event->xexpose.width, event->xexpose.height);
1762 case GraphicsExpose: /* This occurs when an XCopyArea's source area was
1763 obscured or not available. */
1764 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1765 event->xexpose.width, event->xexpose.height);
1770 handle_map_event (f, event);
1774 if (event->xcrossing.detail != NotifyInferior)
1778 XSETFRAME (frame, f);
1779 /* FRAME_X_MOUSE_P (f) = 1; */
1780 va_run_hook_with_args (Qmouse_enter_frame_hook, 1, frame);
1785 if (event->xcrossing.detail != NotifyInferior)
1789 XSETFRAME (frame, f);
1790 /* FRAME_X_MOUSE_P (f) = 0; */
1791 va_run_hook_with_args (Qmouse_leave_frame_hook, 1, frame);
1798 #ifdef EXTERNAL_WIDGET
1799 /* External widget lossage: Ben said:
1800 YUCK. The only way to make focus changes work properly is to
1801 completely ignore all FocusIn/FocusOut events and depend only
1802 on notifications from the ExternalClient widget. */
1803 if (FRAME_X_EXTERNAL_WINDOW_P (f))
1806 handle_focus_event_1 (f, event->type == FocusIn);
1810 handle_client_message (f, event);
1813 case VisibilityNotify: /* window visibility has changed */
1814 if (event->xvisibility.window == XtWindow (FRAME_X_SHELL_WIDGET (f)))
1816 FRAME_X_TOTALLY_VISIBLE_P (f) =
1817 (event->xvisibility.state == VisibilityUnobscured);
1818 /* Note that the fvwm pager only sends VisibilityNotify when
1819 changing pages. Is this all we need to do ? JV */
1820 /* Nope. We must at least trigger a redisplay here.
1821 Since this case seems similar to MapNotify, I've
1822 factored out some code to change_frame_visibility().
1823 This triggers the necessary redisplay and runs
1824 (un)map-frame-hook. - dkindred@cs.cmu.edu */
1825 /* Changed it again to support the tristate visibility flag */
1826 change_frame_visibility (f, (event->xvisibility.state
1827 != VisibilityFullyObscured) ? 1 : -1);
1831 case ConfigureNotify:
1833 XIM_SetGeometry (f);
1843 /************************************************************************/
1844 /* timeout events */
1845 /************************************************************************/
1847 static int timeout_id_tick;
1849 /* Xt interval id's might not fit into an int (they're pointers, as it
1850 happens), so we need to provide a conversion list. */
1852 static struct Xt_timeout
1855 XtIntervalId interval_id;
1856 struct Xt_timeout *next;
1857 } *pending_timeouts, *completed_timeouts;
1859 static struct Xt_timeout_blocktype
1861 Blocktype_declare (struct Xt_timeout);
1862 } *the_Xt_timeout_blocktype;
1864 /* called by XtAppNextEvent() */
1866 Xt_timeout_callback (XtPointer closure, XtIntervalId *id)
1868 struct Xt_timeout *timeout = (struct Xt_timeout *) closure;
1869 struct Xt_timeout *t2 = pending_timeouts;
1870 /* Remove this one from the list of pending timeouts */
1872 pending_timeouts = pending_timeouts->next;
1875 while (t2->next && t2->next != timeout) t2 = t2->next;
1877 t2->next = t2->next->next;
1879 /* Add this one to the list of completed timeouts */
1880 timeout->next = completed_timeouts;
1881 completed_timeouts = timeout;
1885 emacs_Xt_add_timeout (EMACS_TIME thyme)
1887 struct Xt_timeout *timeout = Blocktype_alloc (the_Xt_timeout_blocktype);
1888 EMACS_TIME current_time;
1891 timeout->id = timeout_id_tick++;
1892 timeout->next = pending_timeouts;
1893 pending_timeouts = timeout;
1894 EMACS_GET_TIME (current_time);
1895 EMACS_SUB_TIME (thyme, thyme, current_time);
1896 milliseconds = EMACS_SECS (thyme) * 1000 +
1897 EMACS_USECS (thyme) / 1000;
1898 if (milliseconds < 1)
1900 timeout->interval_id = XtAppAddTimeOut (Xt_app_con, milliseconds,
1901 Xt_timeout_callback,
1902 (XtPointer) timeout);
1907 emacs_Xt_remove_timeout (int id)
1909 struct Xt_timeout *timeout, *t2;
1913 /* Find the timeout on the list of pending ones, if it's still there. */
1914 if (pending_timeouts)
1916 if (id == pending_timeouts->id)
1918 timeout = pending_timeouts;
1919 pending_timeouts = pending_timeouts->next;
1923 t2 = pending_timeouts;
1924 while (t2->next && t2->next->id != id) t2 = t2->next;
1925 if ( t2->next) /*found it */
1928 t2->next = t2->next->next;
1931 /* if it was pending, we have removed it from the list */
1933 XtRemoveTimeOut (timeout->interval_id);
1936 /* It could be that the Xt call back was already called but we didn't convert
1937 into an Emacs event yet */
1938 if (!timeout && completed_timeouts)
1940 /* Code duplication! */
1941 if (id == completed_timeouts->id)
1943 timeout = completed_timeouts;
1944 completed_timeouts = completed_timeouts->next;
1948 t2 = completed_timeouts;
1949 while (t2->next && t2->next->id != id) t2 = t2->next;
1950 if ( t2->next) /*found it */
1953 t2->next = t2->next->next;
1958 /* If we found the thing on the lists of timeouts,
1959 and removed it, deallocate
1962 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1966 Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
1968 struct Xt_timeout *timeout = completed_timeouts;
1970 completed_timeouts = completed_timeouts->next;
1971 emacs_event->event_type = timeout_event;
1972 /* timeout events have nil as channel */
1973 emacs_event->timestamp = 0; /* #### wrong!! */
1974 emacs_event->event.timeout.interval_id = timeout->id;
1975 emacs_event->event.timeout.function = Qnil;
1976 emacs_event->event.timeout.object = Qnil;
1977 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1981 /************************************************************************/
1982 /* process and tty events */
1983 /************************************************************************/
1985 struct what_is_ready_closure
1992 static Lisp_Object *filedesc_with_input;
1993 static struct what_is_ready_closure **filedesc_to_what_closure;
1996 init_what_input_once (void)
2000 filedesc_with_input = xnew_array (Lisp_Object, MAXDESC);
2001 filedesc_to_what_closure =
2002 xnew_array (struct what_is_ready_closure *, MAXDESC);
2004 for (i = 0; i < MAXDESC; i++)
2006 filedesc_to_what_closure[i] = 0;
2007 filedesc_with_input[i] = Qnil;
2010 process_events_occurred = 0;
2011 tty_events_occurred = 0;
2015 mark_what_as_being_ready (struct what_is_ready_closure *closure)
2017 if (NILP (filedesc_with_input[closure->fd]))
2019 SELECT_TYPE temp_mask;
2020 FD_ZERO (&temp_mask);
2021 FD_SET (closure->fd, &temp_mask);
2022 /* Check to make sure there's *really* input available.
2023 Sometimes things seem to get confused and this gets called
2024 for the tty fd when there's really only input available
2025 on some process's fd. (It will subsequently get called
2026 for that process's fd, so returning without setting any
2027 flags will take care of it.) To see the problem, uncomment
2028 the stderr_out below, turn NORMAL_QUIT_CHECK_TIMEOUT_MSECS
2029 down to 25, do sh -c 'xemacs -nw -q -f shell 2>/tmp/log'
2030 and press return repeatedly. (Seen under AIX & Linux.)
2031 -dkindred@cs.cmu.edu */
2032 if (!poll_fds_for_input (temp_mask))
2035 stderr_out ("mark_what_as_being_ready: no input available (fd=%d)\n",
2040 filedesc_with_input[closure->fd] = closure->what;
2041 if (PROCESSP (closure->what))
2042 /* Don't increment this if the current process is already marked
2043 * as having input. */
2044 process_events_occurred++;
2046 tty_events_occurred++;
2051 Xt_what_callback (void *closure, int *source, XtInputId *id)
2053 /* If closure is 0, then we got a fake event from a signal handler.
2054 The only purpose of this is to make XtAppProcessEvent() stop
2057 mark_what_as_being_ready ((struct what_is_ready_closure *) closure);
2060 fake_event_occurred++;
2061 drain_signal_event_pipe ();
2066 select_filedesc (int fd, Lisp_Object what)
2068 struct what_is_ready_closure *closure;
2070 /* If somebody is trying to select something that's already selected
2071 for, then something went wrong. The generic routines ought to
2072 detect this and error before here. */
2073 assert (!filedesc_to_what_closure[fd]);
2075 closure = xnew (struct what_is_ready_closure);
2077 closure->what = what;
2079 XtAppAddInput (Xt_app_con, fd,
2080 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
2081 Xt_what_callback, closure);
2082 filedesc_to_what_closure[fd] = closure;
2086 unselect_filedesc (int fd)
2088 struct what_is_ready_closure *closure = filedesc_to_what_closure[fd];
2091 if (!NILP (filedesc_with_input[fd]))
2093 /* We are unselecting this process before we have drained the rest of
2094 the input from it, probably from status_notify() in the command loop.
2095 This can happen like so:
2097 - We are waiting in XtAppNextEvent()
2098 - Process generates output
2099 - Process is marked as being ready
2100 - Process dies, SIGCHLD gets generated before we return (!?)
2101 It could happen I guess.
2102 - sigchld_handler() marks process as dead
2103 - Somehow we end up getting a new KeyPress event on the queue
2104 at the same time (I'm really so sure how that happens but I'm
2105 not sure it can't either so let's assume it can...).
2106 - Key events have priority so we return that instead of the proc.
2107 - Before dispatching the lisp key event we call status_notify()
2108 - Which deselects the process that SIGCHLD marked as dead.
2110 Thus we never remove it from _with_input and turn it into a lisp
2111 event, so we need to do it here. But this does not mean that we're
2112 throwing away the last block of output - status_notify() has already
2113 taken care of running the proc filter or whatever.
2115 filedesc_with_input[fd] = Qnil;
2116 if (PROCESSP (closure->what))
2118 assert (process_events_occurred > 0);
2119 process_events_occurred--;
2123 assert (tty_events_occurred > 0);
2124 tty_events_occurred--;
2127 XtRemoveInput (closure->id);
2129 filedesc_to_what_closure[fd] = 0;
2133 emacs_Xt_select_process (Lisp_Process *p)
2135 Lisp_Object process;
2136 int infd = event_stream_unixoid_select_process (p);
2138 XSETPROCESS (process, p);
2139 select_filedesc (infd, process);
2143 emacs_Xt_unselect_process (Lisp_Process *p)
2145 int infd = event_stream_unixoid_unselect_process (p);
2147 unselect_filedesc (infd);
2151 emacs_Xt_create_stream_pair (void* inhandle, void* outhandle,
2152 Lisp_Object* instream, Lisp_Object* outstream, int flags)
2154 USID u = event_stream_unixoid_create_stream_pair
2155 (inhandle, outhandle, instream, outstream, flags);
2156 if (u != USID_ERROR)
2162 emacs_Xt_delete_stream_pair (Lisp_Object instream, Lisp_Object outstream)
2164 event_stream_unixoid_delete_stream_pair (instream, outstream);
2165 return USID_DONTHASH;
2168 /* This is called from GC when a process object is about to be freed.
2169 If we've still got pointers to it in this file, we're gonna lose hard.
2172 debug_process_finalization (Lisp_Process *p)
2176 Lisp_Object instr, outstr;
2178 get_process_streams (p, &instr, &outstr);
2179 /* if it still has fds, then it hasn't been killed yet. */
2180 assert (NILP(instr));
2181 assert (NILP(outstr));
2182 /* Better not still be in the "with input" table; we know it's got no fds. */
2183 for (i = 0; i < MAXDESC; i++)
2185 Lisp_Object process = filedesc_fds_with_input [i];
2186 assert (!PROCESSP (process) || XPROCESS (process) != p);
2192 Xt_process_to_emacs_event (Lisp_Event *emacs_event)
2196 assert (process_events_occurred > 0);
2198 for (i = 0; i < MAXDESC; i++)
2200 Lisp_Object process = filedesc_with_input[i];
2201 if (PROCESSP (process))
2203 filedesc_with_input[i] = Qnil;
2204 process_events_occurred--;
2205 /* process events have nil as channel */
2206 emacs_event->event_type = process_event;
2207 emacs_event->timestamp = 0; /* #### */
2208 emacs_event->event.process.process = process;
2216 emacs_Xt_select_console (struct console *con)
2218 Lisp_Object console;
2221 if (CONSOLE_X_P (con))
2222 return; /* X consoles are automatically selected for when we
2223 initialize them in Xt */
2224 infd = event_stream_unixoid_select_console (con);
2225 XSETCONSOLE (console, con);
2226 select_filedesc (infd, console);
2230 emacs_Xt_unselect_console (struct console *con)
2232 Lisp_Object console;
2235 if (CONSOLE_X_P (con))
2236 return; /* X consoles are automatically selected for when we
2237 initialize them in Xt */
2238 infd = event_stream_unixoid_unselect_console (con);
2239 XSETCONSOLE (console, con);
2240 unselect_filedesc (infd);
2243 /* read an event from a tty, if one is available. Returns non-zero
2244 if an event was available. Note that when this function is
2245 called, there should always be a tty marked as ready for input.
2246 However, the input condition might actually be EOF, so there
2247 may not really be any input available. (In this case,
2248 read_event_from_tty_or_stream_desc() will arrange for the TTY device
2252 Xt_tty_to_emacs_event (Lisp_Event *emacs_event)
2256 assert (tty_events_occurred > 0);
2257 for (i = 0; i < MAXDESC; i++)
2259 Lisp_Object console = filedesc_with_input[i];
2260 if (CONSOLEP (console))
2262 assert (tty_events_occurred > 0);
2263 tty_events_occurred--;
2264 filedesc_with_input[i] = Qnil;
2265 if (read_event_from_tty_or_stream_desc
2266 (emacs_event, XCONSOLE (console), i))
2275 /************************************************************************/
2276 /* debugging functions to decipher an event */
2277 /************************************************************************/
2280 #include "xintrinsicp.h" /* only describe_event() needs this */
2281 #include <X11/Xproto.h> /* only describe_event() needs this */
2284 describe_event_window (Window window, Display *display)
2288 stderr_out (" window: 0x%lx", (unsigned long) window);
2289 w = XtWindowToWidget (display, window);
2291 stderr_out (" %s", w->core.widget_class->core_class.class_name);
2292 f = x_any_window_to_frame (get_device_from_display (display), window);
2295 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
2296 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
2297 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
2298 strlen (buf), Qterminal);
2304 XEvent_mode_to_string (int mode)
2308 case NotifyNormal: return "Normal";
2309 case NotifyGrab: return "Grab";
2310 case NotifyUngrab: return "Ungrab";
2311 case NotifyWhileGrabbed: return "WhileGrabbed";
2312 default: return "???";
2317 XEvent_detail_to_string (int detail)
2321 case NotifyAncestor: return "Ancestor";
2322 case NotifyInferior: return "Inferior";
2323 case NotifyNonlinear: return "Nonlinear";
2324 case NotifyNonlinearVirtual: return "NonlinearVirtual";
2325 case NotifyPointer: return "Pointer";
2326 case NotifyPointerRoot: return "PointerRoot";
2327 case NotifyDetailNone: return "DetailNone";
2328 default: return "???";
2333 XEvent_visibility_to_string (int state)
2337 case VisibilityFullyObscured: return "FullyObscured";
2338 case VisibilityPartiallyObscured: return "PartiallyObscured";
2339 case VisibilityUnobscured: return "Unobscured";
2340 default: return "???";
2345 describe_event (XEvent *event)
2348 struct device *d = get_device_from_display (event->xany.display);
2350 sprintf (buf, "%s%s", x_event_name (event->type),
2351 event->xany.send_event ? " (send)" : "");
2352 stderr_out ("%-30s", buf);
2353 switch (event->type)
2358 XFocusChangeEvent *ev = &event->xfocus;
2359 describe_event_window (ev->window, ev->display);
2360 stderr_out (" mode: %s\n", XEvent_mode_to_string (ev->mode));
2361 stderr_out (" detail: %s\n", XEvent_detail_to_string(ev->detail));
2367 XKeyEvent *ev = &event->xkey;
2368 unsigned int state = ev->state;
2370 describe_event_window (ev->window, ev->display);
2371 stderr_out (" subwindow: %ld\n", ev->subwindow);
2372 stderr_out (" state: ");
2373 /* Complete list of modifier key masks */
2374 if (state & ShiftMask) stderr_out ("Shift ");
2375 if (state & LockMask) stderr_out ("Lock ");
2376 if (state & ControlMask) stderr_out ("Control ");
2377 if (state & Mod1Mask) stderr_out ("Mod1 ");
2378 if (state & Mod2Mask) stderr_out ("Mod2 ");
2379 if (state & Mod3Mask) stderr_out ("Mod3 ");
2380 if (state & Mod4Mask) stderr_out ("Mod4 ");
2381 if (state & Mod5Mask) stderr_out ("Mod5 ");
2384 stderr_out ("vanilla\n");
2387 if (x_key_is_modifier_p (ev->keycode, d))
2388 stderr_out (" Modifier key");
2389 stderr_out (" keycode: 0x%x\n", ev->keycode);
2394 if (x_debug_events > 1)
2396 XExposeEvent *ev = &event->xexpose;
2397 describe_event_window (ev->window, ev->display);
2398 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2399 ev->x, ev->y, ev->width, ev->height);
2400 stderr_out (" count: %d\n", ev->count);
2406 case GraphicsExpose:
2407 if (x_debug_events > 1)
2409 XGraphicsExposeEvent *ev = &event->xgraphicsexpose;
2410 describe_event_window (ev->drawable, ev->display);
2411 stderr_out (" major: %s\n",
2412 (ev ->major_code == X_CopyArea ? "CopyArea" :
2413 (ev->major_code == X_CopyPlane ? "CopyPlane" : "?")));
2414 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2415 ev->x, ev->y, ev->width, ev->height);
2416 stderr_out (" count: %d\n", ev->count);
2424 if (x_debug_events > 1)
2426 XCrossingEvent *ev = &event->xcrossing;
2427 describe_event_window (ev->window, ev->display);
2429 stderr_out(" subwindow: 0x%x\n", ev->subwindow);
2430 stderr_out(" pos: %d %d\n", ev->x, ev->y);
2431 stderr_out(" root pos: %d %d\n", ev->x_root, ev->y_root);
2433 stderr_out(" mode: %s\n", XEvent_mode_to_string(ev->mode));
2434 stderr_out(" detail: %s\n", XEvent_detail_to_string(ev->detail));
2435 stderr_out(" focus: %d\n", ev->focus);
2437 stderr_out(" state: 0x%x\n", ev->state);
2444 case ConfigureNotify:
2445 if (x_debug_events > 1)
2447 XConfigureEvent *ev = &event->xconfigure;
2448 describe_event_window (ev->window, ev->display);
2449 stderr_out(" above: 0x%lx\n", ev->above);
2450 stderr_out(" size: %d %d %d %d\n", ev->x, ev->y,
2451 ev->width, ev->height);
2452 stderr_out(" redirect: %d\n", ev->override_redirect);
2458 case VisibilityNotify:
2459 if (x_debug_events > 1)
2461 XVisibilityEvent *ev = &event->xvisibility;
2462 describe_event_window (ev->window, ev->display);
2463 stderr_out(" state: %s\n", XEvent_visibility_to_string(ev->state));
2471 XClientMessageEvent *ev = &event->xclient;
2472 char *name = XGetAtomName (ev->display, ev->message_type);
2473 stderr_out ("%s", name);
2474 if (!strcmp (name, "WM_PROTOCOLS")) {
2475 char *protname = XGetAtomName (ev->display, ev->data.l[0]);
2476 stderr_out ("(%s)", protname);
2492 #endif /* include describe_event definition */
2495 /************************************************************************/
2496 /* get the next event from Xt */
2497 /************************************************************************/
2499 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail;
2502 enqueue_Xt_dispatch_event (Lisp_Object event)
2504 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail);
2508 dequeue_Xt_dispatch_event (void)
2510 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail);
2513 /* This business exists because menu events "happen" when
2514 menubar_selection_callback() is called from somewhere deep
2515 within XtAppProcessEvent in emacs_Xt_next_event(). The
2516 callback needs to terminate the modal loop in that function
2517 or else it will continue waiting until another event is
2520 Same business applies to scrollbar events. */
2523 signal_special_Xt_user_event (Lisp_Object channel, Lisp_Object function,
2526 Lisp_Object event = Fmake_event (Qnil, Qnil);
2528 XEVENT (event)->event_type = misc_user_event;
2529 XEVENT (event)->channel = channel;
2530 XEVENT (event)->event.eval.function = function;
2531 XEVENT (event)->event.eval.object = object;
2533 enqueue_Xt_dispatch_event (event);
2537 emacs_Xt_next_event (Lisp_Event *emacs_event)
2539 we_didnt_get_an_event:
2541 while (NILP (dispatch_event_queue) &&
2542 !completed_timeouts &&
2543 !fake_event_occurred &&
2544 !process_events_occurred &&
2545 !tty_events_occurred)
2548 /* Stupid logic in XtAppProcessEvent() dictates that, if process
2549 events and X events are both available, the process event gets
2550 taken first. This will cause an infinite loop if we're being
2551 called from Fdiscard_input().
2553 if (XtAppPending (Xt_app_con) & XtIMXEvent)
2554 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2557 Lisp_Object devcons, concons;
2559 /* We're about to block. Xt has a bug in it (big surprise,
2560 there) in that it blocks using select() and doesn't
2561 flush the Xlib output buffers (XNextEvent() does this
2562 automatically before blocking). So it's necessary
2563 for us to do this ourselves. If we don't do it, then
2564 display output may not be seen until the next time
2565 an X event is received. (This happens esp. with
2566 subprocess output that gets sent to a visible buffer.)
2568 #### The above comment may not have any validity. */
2570 DEVICE_LOOP_NO_BREAK (devcons, concons)
2573 d = XDEVICE (XCAR (devcons));
2575 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2576 /* emacs may be exiting */
2577 XFlush (DEVICE_X_DISPLAY (d));
2579 XtAppProcessEvent (Xt_app_con, XtIMAll);
2583 if (!NILP (dispatch_event_queue))
2585 Lisp_Object event, event2;
2586 XSETEVENT (event2, emacs_event);
2587 event = dequeue_Xt_dispatch_event ();
2588 Fcopy_event (event, event2);
2589 Fdeallocate_event (event);
2591 else if (tty_events_occurred)
2593 if (!Xt_tty_to_emacs_event (emacs_event))
2594 goto we_didnt_get_an_event;
2596 else if (completed_timeouts)
2597 Xt_timeout_to_emacs_event (emacs_event);
2598 else if (fake_event_occurred)
2600 /* A dummy event, so that a cycle of the command loop will occur. */
2601 fake_event_occurred = 0;
2602 /* eval events have nil as channel */
2603 emacs_event->event_type = eval_event;
2604 emacs_event->event.eval.function = Qidentity;
2605 emacs_event->event.eval.object = Qnil;
2607 else /* if (process_events_occurred) */
2608 Xt_process_to_emacs_event (emacs_event);
2610 /* No need to call XFilterEvent; Xt does it for us */
2614 emacs_Xt_event_handler (Widget wid /* unused */,
2615 XtPointer closure /* unused */,
2617 Boolean *continue_to_dispatch /* unused */)
2619 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
2622 if (x_debug_events > 0)
2624 describe_event (event);
2626 #endif /* DEBUG_XEMACS */
2627 if (x_event_to_emacs_event (event, XEVENT (emacs_event)))
2628 enqueue_Xt_dispatch_event (emacs_event);
2630 Fdeallocate_event (emacs_event);
2634 /************************************************************************/
2635 /* input pending / C-g checking */
2636 /************************************************************************/
2639 quit_char_predicate (Display *display, XEvent *event, XPointer data)
2641 struct device *d = get_device_from_display (display);
2642 struct x_device *xd = DEVICE_X_DATA (d);
2644 Bool *critical = (Bool *) data;
2649 if ((event->type != KeyPress) ||
2650 (! x_any_window_to_frame (d, event->xany.window)) ||
2652 & (xd->MetaMask | xd->HyperMask | xd->SuperMask | xd->AltMask)))
2655 /* This duplicates some code that exists elsewhere, but it's relatively
2656 fast and doesn't cons. */
2657 keysym = x_to_emacs_keysym (&event->xkey, 1);
2658 if (NILP (keysym)) return 0;
2659 if (CHAR_OR_CHAR_INTP (keysym))
2660 c = XCHAR_OR_CHAR_INT (keysym);
2661 /* Highly doubtful that these are the quit character, but... */
2662 else if (EQ (keysym, QKbackspace)) c = '\b';
2663 else if (EQ (keysym, QKtab)) c = '\t';
2664 else if (EQ (keysym, QKlinefeed)) c = '\n';
2665 else if (EQ (keysym, QKreturn)) c = '\r';
2666 else if (EQ (keysym, QKescape)) c = 27;
2667 else if (EQ (keysym, QKspace)) c = ' ';
2668 else if (EQ (keysym, QKdelete)) c = 127;
2671 if (event->xkey.state & xd->MetaMask) c |= 0x80;
2672 if ((event->xkey.state & ControlMask) && !(c >= 'A' && c <= 'Z'))
2673 c &= 0x1F; /* unshifted control characters */
2674 quit_char = CONSOLE_QUIT_CHAR (XCONSOLE (DEVICE_CONSOLE (d)));
2677 /* If we've got Control-Shift-G instead of Control-G, that means
2678 we have a critical_quit. Caps_Lock is its own modifier, so it
2679 won't cause ^G to act differently than before. */
2680 if (event->xkey.state & ControlMask) c &= 0x1F;
2683 if (critical) *critical = True;
2689 /* This scans the X input queue for a KeyPress event that matches the
2690 quit character, and sets Vquit_flag. This is called from the
2691 QUIT macro to determine whether we should quit.
2693 In a SIGIO world, this won't be called unless a SIGIO has happened
2694 since the last time we checked.
2696 In a non-SIGIO world, this is called from emacs_Xt_event_pending_p
2697 (which is called from input_pending_p).
2700 x_check_for_quit_char (Display *display)
2704 Bool critical_quit = False;
2705 XEventsQueued (display, QueuedAfterReading);
2706 queued = XCheckIfEvent (display, &event,
2707 quit_char_predicate,
2708 (char *) &critical_quit);
2711 Vquit_flag = (critical_quit ? Qcritical : Qt);
2712 /* don't put the event back onto the queue. Those functions that
2713 wanted to read a ^G directly have arranged to do this. */
2718 check_for_tty_quit_char (struct device *d)
2720 SELECT_TYPE temp_mask;
2721 int infd = DEVICE_INFD (d);
2722 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
2723 Emchar quit_char = CONSOLE_QUIT_CHAR (con);
2725 FD_ZERO (&temp_mask);
2726 FD_SET (infd, &temp_mask);
2733 if (!poll_fds_for_input (temp_mask))
2736 event = Fmake_event (Qnil, Qnil);
2737 if (!read_event_from_tty_or_stream_desc (XEVENT (event), con, infd))
2738 /* EOF, or something ... */
2740 /* #### bogus. quit-char should be allowed to be any sort
2742 the_char = event_to_character (XEVENT (event), 1, 0, 0);
2743 if (the_char >= 0 && the_char == quit_char)
2746 /* do not queue the C-g. See above. */
2750 /* queue the read event to be read for real later. */
2751 enqueue_Xt_dispatch_event (event);
2756 emacs_Xt_quit_p (void)
2758 Lisp_Object devcons, concons;
2759 CONSOLE_LOOP (concons)
2761 struct console *con = XCONSOLE (XCAR (concons));
2762 if (!con->input_enabled)
2765 CONSOLE_DEVICE_LOOP (devcons, con)
2768 d = XDEVICE (XCAR (devcons));
2770 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2771 /* emacs may be exiting */
2772 x_check_for_quit_char (DEVICE_X_DISPLAY (d));
2773 else if (DEVICE_TTY_P (d))
2774 check_for_tty_quit_char (d);
2780 drain_X_queue (void)
2782 while (XtAppPending (Xt_app_con) & XtIMXEvent)
2783 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2787 emacs_Xt_event_pending_p (int user_p)
2792 /* If `user_p' is false, then this function returns whether there are any
2793 X, timeout, or fd events pending (that is, whether emacs_Xt_next_event()
2794 would return immediately without blocking).
2796 if `user_p' is true, then this function returns whether there are any
2797 *user generated* events available (that is, whether there are keyboard
2798 or mouse-click events ready to be read). This also implies that
2799 emacs_Xt_next_event() would not block.
2801 In a non-SIGIO world, this also checks whether the user has typed ^G,
2802 since this is a convenient place to do so. We don't need to do this
2803 in a SIGIO world, since input causes an interrupt.
2807 /* I don't think there's any point to this and it will nullify
2808 the speed gains achieved by the sigio_happened checking below.
2809 Its only advantage is that it may possibly make C-g response
2810 a bit faster. The C-g will be noticed within 0.25 second, anyway,
2811 even without this. */
2813 /* First check for C-g if necessary */
2818 /* This function used to simply check whether there were any X
2819 events (or if user_p was 1, it iterated over all the pending
2820 X events using XCheckIfEvent(), looking for keystrokes and
2821 button events). That worked in the old cheesoid event loop,
2822 which didn't go through XtAppDispatchEvent(), but it doesn't
2823 work any more -- X events may not result in anything. For
2824 example, a button press in a blank part of the menubar appears
2825 as an X event but will not result in any Emacs events (a
2826 button press that activates the menubar results in an Emacs
2827 event through the stop_next_event mechanism).
2829 The only accurate way of determining whether these X events
2830 translate into Emacs events is to go ahead and dispatch them
2831 until there's something on the dispatch queue. */
2833 /* See if there are any user events already on the queue. */
2834 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
2835 if (!user_p || command_event_p (event))
2838 /* See if there's any TTY input available.
2840 if (poll_fds_for_input (tty_only_mask))
2845 /* If not user_p and there are any timer or file-desc events
2846 pending, we know there will be an event so we're through. */
2847 XtInputMask pending_value;
2849 /* Note that formerly we just checked the value of XtAppPending()
2850 to determine if there was file-desc input. This doesn't
2851 work any more with the signal_event_pipe; XtAppPending()
2852 will says "yes" in this case but there isn't really any
2853 input. Another way of fixing this problem is for the
2854 signal_event_pipe to generate actual input in the form
2855 of an identity eval event or something. (#### maybe this
2856 actually happens?) */
2858 if (poll_fds_for_input (process_only_mask))
2861 pending_value = XtAppPending (Xt_app_con);
2863 if (pending_value & XtIMTimer)
2867 /* XtAppPending() can be super-slow, esp. over a network connection.
2868 Quantify results have indicated that in some cases the
2869 call to detect_input_pending() completely dominates the
2870 running time of redisplay(). Fortunately, in a SIGIO world
2871 we can more quickly determine whether there are any X events:
2872 if an event has happened since the last time we checked, then
2873 a SIGIO will have happened. On a machine with broken SIGIO,
2874 we'll still be in an OK state -- the sigio_happened flag
2875 will get set at least once a second, so we'll be no more than
2876 one second behind reality. (In general it's OK if we
2877 erroneously report no input pending when input is actually
2878 pending() -- preemption is just a bit less efficient, that's
2879 all. It's bad bad bad if you err the other way -- you've
2880 promised that `next-event' won't block but it actually will,
2881 and some action might get delayed until the next time you
2885 /* quit_check_signal_tick_count is volatile so try to avoid race conditions
2886 by using a temporary variable */
2887 tick_count_val = quit_check_signal_tick_count;
2888 if (last_quit_check_signal_tick_count != tick_count_val)
2890 last_quit_check_signal_tick_count = tick_count_val;
2892 /* We need to drain the entire queue now -- if we only
2893 drain part of it, we may later on end up with events
2894 actually pending but detect_input_pending() returning
2895 false because there wasn't another SIGIO. */
2898 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
2899 if (!user_p || command_event_p (event))
2907 /************************************************************************/
2908 /* replacement for standard string-to-pixel converter */
2909 /************************************************************************/
2911 /* This was constructed by ripping off the standard string-to-pixel
2912 converter from Converters.c in the Xt source code and modifying
2917 /* This is exported by the Xt library (at least by mine). If this
2918 isn't the case somewhere, rename this appropriately and remove
2919 the '#if 0'. Note, however, that I got "unknown structure"
2920 errors when I tried this. */
2921 XtConvertArgRec Const colorConvertArgs[] = {
2922 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
2923 sizeof (Screen *) },
2924 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
2930 #define done(type, value) \
2931 if (toVal->addr != NULL) { \
2932 if (toVal->size < sizeof(type)) { \
2933 toVal->size = sizeof(type); \
2936 *(type*)(toVal->addr) = (value); \
2938 static type static_val; \
2939 static_val = (value); \
2940 toVal->addr = (XPointer)&static_val; \
2942 toVal->size = sizeof(type); \
2943 return True /* Caller supplies `;' */
2945 /* JH: We use this because I think there's a possibility this
2946 is called before the device is properly set up, in which case
2947 I don't want to abort. */
2948 extern struct device *get_device_from_display_1 (Display *dpy);
2951 Boolean EmacsXtCvtStringToPixel (
2955 XrmValuePtr fromVal,
2957 XtPointer *closure_ret)
2959 String str = (String)fromVal->addr;
2968 Cardinal num_params = 1;
2969 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
2971 if (*num_args != 2) {
2972 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToPixel",
2974 "String to pixel conversion needs screen and colormap arguments",
2975 (String *)NULL, (Cardinal *)NULL);
2979 screen = *((Screen **) args[0].addr);
2980 colormap = *((Colormap *) args[1].addr);
2982 /* The original uses the private function CompareISOLatin1().
2983 Use XmuCompareISOLatin1() if you want, but I don't think it
2984 makes any difference here. */
2985 if (strcmp(str, XtDefaultBackground) == 0) {
2986 *closure_ret = False;
2987 /* This refers to the display's "*reverseVideo" resource.
2988 These display resources aren't documented anywhere that
2989 I can find, so I'm going to ignore this. */
2990 /* if (pd->rv) done(Pixel, BlackPixelOfScreen(screen)) else */
2991 done(Pixel, WhitePixelOfScreen(screen));
2993 if (strcmp(str, XtDefaultForeground) == 0) {
2994 *closure_ret = False;
2995 /* if (pd->rv) done(Pixel, WhitePixelOfScreen(screen)) else */
2996 done(Pixel, BlackPixelOfScreen(screen));
2999 /* Originally called XAllocNamedColor() here. */
3000 if ((d = get_device_from_display_1(dpy))) {
3001 visual = DEVICE_X_VISUAL(d);
3002 if (colormap != DEVICE_X_COLORMAP(d)) {
3003 XtAppWarningMsg(the_app_con, "wierdColormap", "cvtStringToPixel",
3005 "The colormap passed to cvtStringToPixel doesn't match the one registerd to the device.\n",
3007 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3009 status = XParseColor (dpy, colormap, (char*)str, &screenColor);
3011 status = allocate_nearest_color (dpy, colormap, visual, &screenColor);
3015 /* We haven't set up this device totally yet, so just punt */
3016 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3020 /* Server returns a specific error code but Xlib discards it. Ugh */
3021 if (XLookupColor(DisplayOfScreen(screen), colormap, (char*) str,
3022 &exactColor, &screenColor)) {
3023 XtAppWarningMsg(the_app_con, "noColormap", "cvtStringToPixel",
3025 "Cannot allocate colormap entry for \"%s\"",
3026 params, &num_params);
3029 XtAppWarningMsg(the_app_con, "badValue", "cvtStringToPixel",
3031 "Color name \"%s\" is not defined", params, &num_params);
3034 *closure_ret = False;
3037 *closure_ret = (char*)True;
3038 done(Pixel, screenColor.pixel);
3043 static void EmacsFreePixel (
3050 if (*num_args != 2) {
3051 XtAppWarningMsg(app, "wrongParameters","freePixel","XtToolkitError",
3052 "Freeing a pixel requires screen and colormap arguments",
3053 (String *)NULL, (Cardinal *)NULL);
3058 Screen *screen = *((Screen **) args[0].addr);
3059 Colormap colormap = *((Colormap *) args[1].addr);
3060 XFreeColors(DisplayOfScreen(screen), colormap,
3061 (unsigned long*)toVal->addr, 1, (unsigned long)0);
3066 /************************************************************************/
3067 /* initialization */
3068 /************************************************************************/
3071 syms_of_event_Xt (void)
3073 defsymbol (&Qkey_mapping, "key-mapping");
3074 defsymbol (&Qsans_modifiers, "sans-modifiers");
3075 defsymbol (&Qself_insert_command, "self-insert-command");
3079 reinit_vars_of_event_Xt (void)
3081 Xt_event_stream = xnew (struct event_stream);
3082 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
3083 Xt_event_stream->next_event_cb = emacs_Xt_next_event;
3084 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
3085 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
3086 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout;
3087 Xt_event_stream->select_console_cb = emacs_Xt_select_console;
3088 Xt_event_stream->unselect_console_cb = emacs_Xt_unselect_console;
3089 Xt_event_stream->select_process_cb = emacs_Xt_select_process;
3090 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process;
3091 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
3092 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
3093 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
3095 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
3097 last_quit_check_signal_tick_count = 0;
3099 /* this function only makes safe calls */
3100 init_what_input_once ();
3104 vars_of_event_Xt (void)
3106 reinit_vars_of_event_Xt ();
3108 dispatch_event_queue = Qnil;
3109 staticpro (&dispatch_event_queue);
3110 dispatch_event_queue_tail = Qnil;
3111 pdump_wire (&dispatch_event_queue_tail);
3113 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
3114 *Non-nil makes modifier keys sticky.
3115 This means that you can release the modifier key before pressing down
3116 the key that you wish to be modified. Although this is non-standard
3117 behavior, it is recommended because it reduces the strain on your hand,
3118 thus reducing the incidence of the dreaded Emacs-pinky syndrome.
3120 modifier_keys_are_sticky = 0;
3122 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /*
3123 *Non-nil means to allow synthetic events. Nil means they are ignored.
3124 Beware: allowing emacs to process SendEvents opens a big security hole.
3126 x_allow_sendevents = 0;
3129 DEFVAR_INT ("x-debug-events", &x_debug_events /*
3130 If non-zero, display debug information about X events that XEmacs sees.
3131 Information is displayed on stderr. Currently defined values are:
3133 1 == non-verbose output
3140 /* This mess is a hack that patches the shell widget to treat visual inheritance
3141 the same as colormap and depth inheritance */
3143 static XtInitProc orig_shell_init_proc;
3145 static void ShellVisualPatch(Widget wanted, Widget new,
3146 ArgList args, Cardinal *num_args)
3149 ShellWidget w = (ShellWidget) new;
3151 /* first, call the original setup */
3152 (*orig_shell_init_proc)(wanted, new, args, num_args);
3154 /* if the visual isn't explicitly set, grab it from the nearest shell ancestor */
3155 if (w->shell.visual == CopyFromParent) {
3157 while (p && !XtIsShell(p)) p = XtParent(p);
3158 if (p) w->shell.visual = ((ShellWidget)p)->shell.visual;
3163 init_event_Xt_late (void) /* called when already initialized */
3165 timeout_id_tick = 1;
3166 pending_timeouts = 0;
3167 completed_timeouts = 0;
3169 event_stream = Xt_event_stream;
3171 #if defined(HAVE_XIM) || defined(USE_XFONTSET)
3172 Initialize_Locale();
3173 #endif /* HAVE_XIM || USE_XFONTSET */
3175 XtToolkitInitialize ();
3176 Xt_app_con = XtCreateApplicationContext ();
3177 XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources);
3180 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000);
3181 XSetErrorHandler (x_error_handler);
3182 XSetIOErrorHandler (x_IO_error_handler);
3185 XtAppAddInput (Xt_app_con, signal_event_pipe[0],
3186 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
3187 Xt_what_callback, 0);
3190 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRPixel,
3191 EmacsXtCvtStringToPixel,
3192 (XtConvertArgList) colorConvertArgs,
3193 2, XtCacheByDisplay, EmacsFreePixel);
3196 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles,
3197 EmacsXtCvtStringToXIMStyles,
3199 XtCacheByDisplay, EmacsFreeXIMStyles);
3200 #endif /* XIM_XLIB */
3202 /* insert the visual inheritance patch/hack described above */
3203 orig_shell_init_proc = shellClassRec.core_class.initialize;
3204 shellClassRec.core_class.initialize = ShellVisualPatch;