1 /* The event_stream interface for X11 with Xt, and/or tty frames.
2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1996 Ben Wing.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: Not in FSF. */
28 #include "console-x.h"
29 #include "../lwlib/lwlib.h"
30 #include "EmacsFrame.h"
32 #include "blocktype.h"
35 #include "console-tty.h"
38 #include "objects-x.h"
40 #include "redisplay.h"
44 #include "sysproc.h" /* for MAXDESC */
46 #include "xintrinsicp.h" /* CoreP.h needs this */
47 #include <X11/CoreP.h> /* Numerous places access the fields of
48 a core widget directly. We could
49 use XtGetValues(), but ... */
50 #include <X11/ShellP.h>
57 #include "file-coding.h"
64 #if defined (HAVE_OFFIX_DND)
68 #include "events-mod.h"
70 static void enqueue_Xt_dispatch_event (Lisp_Object event);
71 static void handle_focus_event_1 (struct frame *f, int in_p);
73 static struct event_stream *Xt_event_stream;
75 /* With the new event model, all events go through XtDispatchEvent()
76 and are picked up by an event handler that is added to each frame
77 widget. (This is how it's supposed to be.) In the old method,
78 Emacs sucks out events directly from XtNextEvent() and only
79 dispatches the events that it doesn't need to deal with. This
80 old way has lots of corresponding junk that is no longer
81 necessary: lwlib extensions, synthetic XAnyEvents, unnecessary
84 /* The one and only one application context that Emacs uses. */
85 XtAppContext Xt_app_con;
87 /* Do we accept events sent by other clients? */
88 int x_allow_sendevents;
90 int modifier_keys_are_sticky;
96 static int process_events_occurred;
97 static int tty_events_occurred;
99 /* Mask of bits indicating the descriptors that we wait for input on */
100 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
102 static const String x_fallback_resources[] =
104 /* This file is automatically generated from the app-defaults file
105 in ../etc/Emacs.ad. These resources are consulted only if no
106 app-defaults file is found at all.
108 #include <Emacs.ad.h>
112 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
113 void emacs_Xt_mapping_action (Widget w, XEvent *event);
114 void debug_process_finalization (Lisp_Process *p);
115 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
116 Boolean *continue_to_dispatch);
118 static int last_quit_check_signal_tick_count;
120 Lisp_Object Qkey_mapping;
121 Lisp_Object Qsans_modifiers;
124 /************************************************************************/
125 /* keymap handling */
126 /************************************************************************/
128 /* X bogusly doesn't define the interpretations of any bits besides
129 ModControl, ModShift, and ModLock; so the Interclient Communication
130 Conventions Manual says that we have to bend over backwards to figure
131 out what the other modifier bits mean. According to ICCCM:
133 - Any keycode which is assigned ModControl is a "control" key.
135 - Any modifier bit which is assigned to a keycode which generates Meta_L
136 or Meta_R is the modifier bit meaning "meta". Likewise for Super, Hyper,
139 - Any keypress event which contains ModControl in its state should be
140 interpreted as a "control" character.
142 - Any keypress event which contains a modifier bit in its state which is
143 generated by a keycode whose corresponding keysym is Meta_L or Meta_R
144 should be interpreted as a "meta" character. Likewise for Super, Hyper,
147 - It is illegal for a keysym to be associated with more than one modifier
150 This means that the only thing that emacs can reasonably interpret as a
151 "meta" key is a key whose keysym is Meta_L or Meta_R, and which generates
152 one of the modifier bits Mod1-Mod5.
154 Unfortunately, many keyboards don't have Meta keys in their default
155 configuration. So, if there are no Meta keys, but there are "Alt" keys,
156 emacs will interpret Alt as Meta. If there are both Meta and Alt keys,
157 then the Meta keys mean "Meta", and the Alt keys mean "Alt" (it used to
158 mean "Symbol," but that just confused the hell out of way too many people).
160 This works with the default configurations of the 19 keyboard-types I've
163 Emacs detects keyboard configurations which violate the above rules, and
164 prints an error message on the standard-error-output. (Perhaps it should
165 use a pop-up-window instead.)
168 /* For every key on the keyboard that has a known character correspondence,
169 we define the ascii-character property of the keysym, and make the
170 default binding for the key be self-insert-command.
172 The following magic is basically intimate knowledge of X11/keysymdef.h.
173 The keysym mappings defined by X11 are based on the iso8859 standards,
174 except for Cyrillic and Greek.
176 In a non-Mule world, a user can still have a multi-lingual editor, by doing
177 (set-face-font "...-iso8859-2" (current-buffer))
178 for all their Latin-2 buffers, etc. */
181 x_keysym_to_character (KeySym keysym)
184 Lisp_Object charset = Qzero;
185 #define USE_CHARSET(var,cs) \
186 ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
188 #define USE_CHARSET(var,lb)
192 if ((keysym & 0xff) < 0xa0)
197 case 0: /* ASCII + Latin1 */
198 USE_CHARSET (charset, LATIN_ISO8859_1);
199 code = keysym & 0x7f;
202 USE_CHARSET (charset, LATIN_ISO8859_2);
203 code = keysym & 0x7f;
206 USE_CHARSET (charset, LATIN_ISO8859_3);
207 code = keysym & 0x7f;
210 USE_CHARSET (charset, LATIN_ISO8859_4);
211 code = keysym & 0x7f;
213 case 4: /* Katakana */
214 USE_CHARSET (charset, KATAKANA_JISX0201);
215 if ((keysym & 0xff) > 0xa0)
216 code = keysym & 0x7f;
219 USE_CHARSET (charset, ARABIC_ISO8859_6);
220 code = keysym & 0x7f;
222 case 6: /* Cyrillic */
224 static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
225 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
226 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
227 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
228 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
229 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
230 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
231 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
232 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
233 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
234 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
235 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
236 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
237 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
238 code = cyrillic[(keysym & 0x7f) - 0x20];
243 static unsigned char const greek[] = /* 0x20 - 0x7f */
244 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
245 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
246 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
247 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
249 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
250 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
251 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
253 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
254 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
255 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
256 USE_CHARSET (charset, GREEK_ISO8859_7);
257 code = greek[(keysym & 0x7f) - 0x20];
260 case 8: /* Technical */
262 case 9: /* Special */
264 case 10: /* Publishing */
268 case 12: /* Hebrew */
269 USE_CHARSET (charset, HEBREW_ISO8859_8);
270 code = keysym & 0x7f;
273 /* #### This needs to deal with character composition. */
274 USE_CHARSET (charset, THAI_TIS620);
275 code = keysym & 0x7f;
277 case 14: /* Korean Hangul */
279 case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
281 case 32: /* Currency */
291 return make_char (MAKE_CHAR (charset, code, 0));
293 return make_char (code + 0x80);
297 /* #### The way that keysym correspondence to characters should work:
298 - a Lisp_Event should contain a keysym AND a character slot.
299 - keybindings are tried with the keysym. If no binding can be found,
300 and there is a corresponding character, call self-insert-command.
302 #### Nuke x-iso8859-1.el.
303 #### Nuke the Qascii_character property.
304 #### Nuke Vcharacter_set_property.
307 maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
309 Lisp_Object character = x_keysym_to_character (keysym);
311 if (CHARP (character))
313 extern Lisp_Object Vcurrent_global_map;
314 extern Lisp_Object Qascii_character;
315 Fput (symbol, Qascii_character, character);
316 if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
317 Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
322 x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
324 KeySym upper_lower[2];
327 if (keysym < 0x80) /* Optimize for ASCII keysyms */
331 xmodmap -e 'keysym NN = scaron'
332 and then press (Shift scaron), X11 will return the different
333 keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'.
334 So we "register" both `scaron' and `Scaron'. */
335 #ifdef HAVE_XCONVERTCASE
336 XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
338 upper_lower[0] = upper_lower[1] = keysym;
341 for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
344 keysym = upper_lower[j];
346 name = XKeysymToString (keysym);
349 /* X guarantees NAME to be in the Host Portable Character Encoding */
350 Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
351 Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
352 Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
354 if (! EQ (old_value, new_value)
355 && ! (EQ (old_value, Qsans_modifiers) &&
358 maybe_define_x_key_as_self_inserting_character (keysym, sym);
359 Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
360 Fputhash (sym, new_value, hash_table);
367 x_reset_key_mapping (struct device *d)
369 Display *display = DEVICE_X_DISPLAY (d);
370 struct x_device *xd = DEVICE_X_DATA (d);
371 KeySym *keysym, *keysym_end;
372 Lisp_Object hash_table;
373 int key_code_count, keysyms_per_code;
375 if (xd->x_keysym_map)
376 XFree ((char *) xd->x_keysym_map);
377 XDisplayKeycodes (display,
378 &xd->x_keysym_map_min_code,
379 &xd->x_keysym_map_max_code);
380 key_code_count = xd->x_keysym_map_max_code - xd->x_keysym_map_min_code + 1;
382 XGetKeyboardMapping (display, xd->x_keysym_map_min_code, key_code_count,
383 &xd->x_keysym_map_keysyms_per_code);
385 hash_table = xd->x_keysym_map_hash_table;
386 if (HASH_TABLEP (hash_table))
387 Fclrhash (hash_table);
389 xd->x_keysym_map_hash_table = hash_table =
390 make_lisp_hash_table (128, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
392 for (keysym = xd->x_keysym_map,
393 keysyms_per_code = xd->x_keysym_map_keysyms_per_code,
394 keysym_end = keysym + (key_code_count * keysyms_per_code);
396 keysym += keysyms_per_code)
400 if (keysym[0] == NoSymbol)
403 x_has_keysym (keysym[0], hash_table, 0);
405 for (j = 1; j < keysyms_per_code; j++)
407 if (keysym[j] != keysym[0] &&
408 keysym[j] != NoSymbol)
409 x_has_keysym (keysym[j], hash_table, 1);
415 index_to_name (int indice)
419 case ShiftMapIndex: return "ModShift";
420 case LockMapIndex: return "ModLock";
421 case ControlMapIndex: return "ModControl";
422 case Mod1MapIndex: return "Mod1";
423 case Mod2MapIndex: return "Mod2";
424 case Mod3MapIndex: return "Mod3";
425 case Mod4MapIndex: return "Mod4";
426 case Mod5MapIndex: return "Mod5";
427 default: return "???";
431 /* Boy, I really wish C had local functions... */
432 struct c_doesnt_have_closures /* #### not yet used */
434 int warned_about_overlapping_modifiers;
435 int warned_about_predefined_modifiers;
436 int warned_about_duplicate_modifiers;
445 x_reset_modifier_mapping (struct device *d)
447 Display *display = DEVICE_X_DISPLAY (d);
448 struct x_device *xd = DEVICE_X_DATA (d);
449 int modifier_index, modifier_key, column, mkpm;
450 int warned_about_overlapping_modifiers = 0;
451 int warned_about_predefined_modifiers = 0;
452 int warned_about_duplicate_modifiers = 0;
459 xd->lock_interpretation = 0;
461 if (xd->x_modifier_keymap)
462 XFreeModifiermap (xd->x_modifier_keymap);
464 x_reset_key_mapping (d);
466 xd->x_modifier_keymap = XGetModifierMapping (display);
468 /* Boy, I really wish C had local functions...
471 /* The call to warn_when_safe must be on the same line as the string or
472 make-msgfile won't pick it up properly (the newline doesn't confuse
473 it, but the backslash does). */
475 #define modwarn(name,old,other) \
476 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is generated by %s.", \
477 name, code, index_to_name (old), other), \
478 warned_about_overlapping_modifiers = 1
480 #define modbarf(name,other) \
481 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
482 name, code, other), \
483 warned_about_predefined_modifiers = 1
485 #define check_modifier(name,mask) \
486 if ((1<<modifier_index) != mask) \
487 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates %s, which is nonsensical.", \
488 name, code, index_to_name (modifier_index)), \
489 warned_about_predefined_modifiers = 1
491 #define store_modifier(name,old) \
492 if (old && old != modifier_index) \
493 warn_when_safe (Qkey_mapping, Qwarning, "XEmacs: %s (0x%x) generates both %s and %s, which is nonsensical.",\
494 name, code, index_to_name (old), \
495 index_to_name (modifier_index)), \
496 warned_about_duplicate_modifiers = 1; \
497 if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift"); \
498 else if (modifier_index == LockMapIndex) modbarf (name,"ModLock"); \
499 else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl"); \
500 else if (sym == XK_Mode_switch) \
501 mode_bit = modifier_index; /* Mode_switch is special, see below... */ \
502 else if (modifier_index == meta_bit && old != meta_bit) \
503 modwarn (name, meta_bit, "Meta"); \
504 else if (modifier_index == super_bit && old != super_bit) \
505 modwarn (name, super_bit, "Super"); \
506 else if (modifier_index == hyper_bit && old != hyper_bit) \
507 modwarn (name, hyper_bit, "Hyper"); \
508 else if (modifier_index == alt_bit && old != alt_bit) \
509 modwarn (name, alt_bit, "Alt"); \
511 old = modifier_index;
513 mkpm = xd->x_modifier_keymap->max_keypermod;
514 for (modifier_index = 0; modifier_index < 8; modifier_index++)
515 for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
517 for (column = 0; column < 4; column += 2) {
518 KeyCode code = xd->x_modifier_keymap->modifiermap[modifier_index * mkpm
520 KeySym sym = (code ? XKeycodeToKeysym (display, code, column) : 0);
521 if (sym == last_sym) continue;
524 case XK_Mode_switch:store_modifier ("Mode_switch", mode_bit); break;
525 case XK_Meta_L: store_modifier ("Meta_L", meta_bit); break;
526 case XK_Meta_R: store_modifier ("Meta_R", meta_bit); break;
527 case XK_Super_L: store_modifier ("Super_L", super_bit); break;
528 case XK_Super_R: store_modifier ("Super_R", super_bit); break;
529 case XK_Hyper_L: store_modifier ("Hyper_L", hyper_bit); break;
530 case XK_Hyper_R: store_modifier ("Hyper_R", hyper_bit); break;
531 case XK_Alt_L: store_modifier ("Alt_L", alt_bit); break;
532 case XK_Alt_R: store_modifier ("Alt_R", alt_bit); break;
533 case XK_Control_L: check_modifier ("Control_L", ControlMask); break;
534 case XK_Control_R: check_modifier ("Control_R", ControlMask); break;
535 case XK_Shift_L: check_modifier ("Shift_L", ShiftMask); break;
536 case XK_Shift_R: check_modifier ("Shift_R", ShiftMask); break;
537 case XK_Shift_Lock: check_modifier ("Shift_Lock", LockMask);
538 xd->lock_interpretation = XK_Shift_Lock; break;
539 case XK_Caps_Lock: check_modifier ("Caps_Lock", LockMask);
540 xd->lock_interpretation = XK_Caps_Lock; break;
542 /* It probably doesn't make any sense for a modifier bit to be
543 assigned to a key that is not one of the above, but OpenWindows
544 assigns modifier bits to a couple of random function keys for
545 no reason that I can discern, so printing a warning here would
550 #undef store_modifier
551 #undef check_modifier
555 /* If there was no Meta key, then try using the Alt key instead.
556 If there is both a Meta key and an Alt key, then the Alt key
557 is not disturbed and remains an Alt key. */
558 if (! meta_bit && alt_bit)
559 meta_bit = alt_bit, alt_bit = 0;
561 /* mode_bit overrides everything, since it's processed down inside of
562 XLookupString() instead of by us. If Meta and Mode_switch both
563 generate the same modifier bit (which is an error), then we don't
564 interpret that bit as Meta, because we can't make XLookupString()
565 not interpret it as Mode_switch; and interpreting it as both would
569 const char *warn = 0;
570 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0;
571 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
572 else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
573 else if (mode_bit == alt_bit) warn = "Alt", alt_bit = 0;
577 (Qkey_mapping, Qwarning,
578 "XEmacs: %s is being used for both Mode_switch and %s.",
579 index_to_name (mode_bit), warn),
580 warned_about_overlapping_modifiers = 1;
585 xd->MetaMask = (meta_bit ? (1 << meta_bit) : 0);
586 xd->HyperMask = (hyper_bit ? (1 << hyper_bit) : 0);
587 xd->SuperMask = (super_bit ? (1 << super_bit) : 0);
588 xd->AltMask = (alt_bit ? (1 << alt_bit) : 0);
589 xd->ModeMask = (mode_bit ? (1 << mode_bit) : 0); /* unused */
592 if (warned_about_overlapping_modifiers)
593 warn_when_safe (Qkey_mapping, Qwarning, "\n"
594 " Two distinct modifier keys (such as Meta and Hyper) cannot generate\n"
595 " the same modifier bit, because Emacs won't be able to tell which\n"
596 " modifier was actually held down when some other key is pressed. It\n"
597 " won't be able to tell Meta-x and Hyper-x apart, for example. Change\n"
598 " one of these keys to use some other modifier bit. If you intend for\n"
599 " these keys to have the same behavior, then change them to have the\n"
600 " same keysym as well as the same modifier bit.");
602 if (warned_about_predefined_modifiers)
603 warn_when_safe (Qkey_mapping, Qwarning, "\n"
604 " The semantics of the modifier bits ModShift, ModLock, and ModControl\n"
605 " are predefined. It does not make sense to assign ModControl to any\n"
606 " keysym other than Control_L or Control_R, or to assign any modifier\n"
607 " bits to the \"control\" keysyms other than ModControl. You can't\n"
608 " turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n"
609 " assigning the key a different modifier bit. You must also make that\n"
610 " key generate an appropriate keysym (Control_L, Meta_L, etc).");
612 /* No need to say anything more for warned_about_duplicate_modifiers. */
614 if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers)
615 warn_when_safe (Qkey_mapping, Qwarning, "\n"
616 " The meanings of the modifier bits Mod1 through Mod5 are determined\n"
617 " by the keysyms used to control those bits. Mod1 does NOT always\n"
618 " mean Meta, although some non-ICCCM-compliant programs assume that.");
622 x_init_modifier_mapping (struct device *d)
624 struct x_device *xd = DEVICE_X_DATA (d);
625 xd->x_keysym_map_hash_table = Qnil;
626 xd->x_keysym_map = NULL;
627 xd->x_modifier_keymap = NULL;
628 x_reset_modifier_mapping (d);
632 x_key_is_modifier_p (KeyCode keycode, struct device *d)
634 struct x_device *xd = DEVICE_X_DATA (d);
638 if (keycode < xd->x_keysym_map_min_code ||
639 keycode > xd->x_keysym_map_max_code)
642 syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
643 xd->x_keysym_map_keysyms_per_code];
644 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
645 if (IsModifierKey (syms [i]) ||
646 syms [i] == XK_Mode_switch) /* why doesn't IsModifierKey count this? */
651 /* key-handling code is always ugly. It just ends up working out
654 Here are some pointers:
656 -- DOWN_MASK indicates which modifiers should be treated as "down"
657 when the corresponding upstroke happens. It gets reset for
658 a particular modifier when that modifier goes up, and reset
659 for all modifiers when a non-modifier key is pressed. Example:
661 I press Control-A-Shift and then release Control-A-Shift.
662 I want the Shift key to be sticky but not the Control key.
664 -- LAST_DOWNKEY and RELEASE_TIME are used to keep track of
665 auto-repeat -- see below.
667 -- If a modifier key is sticky, I can unstick it by pressing
668 the modifier key again. */
671 x_handle_sticky_modifiers (XEvent *ev, struct device *d)
677 if (!modifier_keys_are_sticky) /* Optimize for non-sticky modifiers */
680 xd = DEVICE_X_DATA (d);
681 keycode = ev->xkey.keycode;
684 if (keycode < xd->x_keysym_map_min_code ||
685 keycode > xd->x_keysym_map_max_code)
688 if (! ((type == KeyPress || type == KeyRelease) &&
689 x_key_is_modifier_p (keycode, d)))
690 { /* Not a modifier key */
691 Bool key_event_p = (type == KeyPress || type == KeyRelease);
693 if (type == KeyPress && !xd->last_downkey)
694 xd->last_downkey = keycode;
695 else if (type == ButtonPress ||
696 (type == KeyPress && xd->last_downkey &&
697 (keycode != xd->last_downkey ||
698 ev->xkey.time != xd->release_time)))
700 xd->need_to_add_mask = 0;
701 xd->last_downkey = 0;
703 if (type == KeyPress)
704 xd->release_time = 0;
705 if (type == KeyPress || type == ButtonPress)
709 ev->xkey.state |= xd->need_to_add_mask;
711 ev->xbutton.state |= xd->need_to_add_mask;
713 if (type == KeyRelease && keycode == xd->last_downkey)
714 /* If I hold press-and-release the Control key and then press
715 and hold down the right arrow, I want it to auto-repeat
716 Control-Right. On the other hand, if I do the same but
717 manually press the Right arrow a bunch of times, I want
718 to see one Control-Right and then a bunch of Rights.
719 This means that we need to distinguish between an
720 auto-repeated key and a key pressed and released a bunch
723 Naturally, the designers of the X spec didn't see fit
724 to provide an obvious way to distinguish these cases.
725 So we assume that if the release and the next press
726 occur at the same time, the key was actually auto-
727 repeated. Under Open-Windows, at least, this works. */
728 xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time;
730 else /* Modifier key pressed */
733 KeySym *syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) *
734 xd->x_keysym_map_keysyms_per_code];
736 /* If a non-modifier key was pressed in the middle of a bunch
737 of modifiers, then it unsticks all the modifiers that were
738 previously pressed. We cannot unstick the modifiers until
739 now because we want to check for auto-repeat of the
742 if (xd->last_downkey)
744 xd->last_downkey = 0;
745 xd->need_to_add_mask = 0;
750 if (type == KeyPress) \
752 /* If modifier key is already sticky, \
753 then unstick it. Note that we do \
754 not test down_mask to deal with the \
755 unlikely but possible case that the \
756 modifier key auto-repeats. */ \
757 if (xd->need_to_add_mask & mask) \
759 xd->need_to_add_mask &= ~mask; \
760 xd->down_mask &= ~mask; \
763 xd->down_mask |= mask; \
767 if (xd->down_mask & mask) \
769 xd->down_mask &= ~mask; \
770 xd->need_to_add_mask |= mask; \
775 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++)
778 case XK_Control_L: case XK_Control_R: FROB (ControlMask); break;
779 case XK_Shift_L: case XK_Shift_R: FROB (ShiftMask); break;
780 case XK_Meta_L: case XK_Meta_R: FROB (xd->MetaMask); break;
781 case XK_Super_L: case XK_Super_R: FROB (xd->SuperMask); break;
782 case XK_Hyper_L: case XK_Hyper_R: FROB (xd->HyperMask); break;
783 case XK_Alt_L: case XK_Alt_R: FROB (xd->AltMask); break;
790 clear_sticky_modifiers (struct device *d)
792 struct x_device *xd = DEVICE_X_DATA (d);
794 xd->need_to_add_mask = 0;
795 xd->last_downkey = 0;
796 xd->release_time = 0;
801 keysym_obeys_caps_lock_p (KeySym sym, struct device *d)
803 struct x_device *xd = DEVICE_X_DATA (d);
804 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic
805 characters, where "alphabetic" means something more than simply A-Z.
806 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC.
807 But if shift-lock is down, then it does. */
808 if (xd->lock_interpretation == XK_Shift_Lock)
812 ((sym >= XK_A) && (sym <= XK_Z)) ||
813 ((sym >= XK_a) && (sym <= XK_z)) ||
814 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) ||
815 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) ||
816 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) ||
817 ((sym >= XK_oslash) && (sym <= XK_thorn));
820 /* called from EmacsFrame.c (actually from Xt itself) when a
821 MappingNotify event is received. In its infinite wisdom, Xt
822 decided that Xt event handlers never get MappingNotify events.
823 O'Reilly Xt Programming Manual 9.1.2 says:
825 MappingNotify is automatically handled by Xt, so it isn't passed
826 to event handlers and you don't need to worry about it.
828 Of course, we DO worry about it, so we need a special translation. */
830 emacs_Xt_mapping_action (Widget w, XEvent* event)
832 struct device *d = get_device_from_display (event->xany.display);
834 if (DEVICE_X_BEING_DELETED (d))
837 /* nyet. Now this is handled by Xt. */
838 XRefreshKeyboardMapping (&event->xmapping);
840 /* xmodmap generates about a billion MappingKeyboard events, followed
841 by a single MappingModifier event, so it might be worthwhile to
842 take extra MappingKeyboard events out of the queue before requesting
843 the current keymap from the server. */
844 switch (event->xmapping.request)
846 case MappingKeyboard: x_reset_key_mapping (d); break;
847 case MappingModifier: x_reset_modifier_mapping (d); break;
848 case MappingPointer: /* Do something here? */ break;
854 /************************************************************************/
855 /* X to Emacs event conversion */
856 /************************************************************************/
859 x_keysym_to_emacs_keysym (KeySym keysym, int simple_p)
862 if (keysym >= XK_exclam && keysym <= XK_asciitilde)
863 /* We must assume that the X keysym numbers for the ASCII graphic
864 characters are the same as their ASCII codes. */
865 return make_char (keysym);
869 /* These would be handled correctly by the default case, but by
870 special-casing them here we don't garbage a string or call
872 case XK_BackSpace: return QKbackspace;
873 case XK_Tab: return QKtab;
874 case XK_Linefeed: return QKlinefeed;
875 case XK_Return: return QKreturn;
876 case XK_Escape: return QKescape;
877 case XK_space: return QKspace;
878 case XK_Delete: return QKdelete;
881 if (simple_p) return Qnil;
882 /* !!#### not Mule-ized */
883 name = XKeysymToString (keysym);
884 if (!name || !name[0])
885 /* This happens if there is a mismatch between the Xlib of
886 XEmacs and the Xlib of the X server...
888 Let's hard-code in some knowledge of common keysyms introduced
889 in recent X11 releases. Snarfed from X11/keysymdef.h
891 Probably we should add some stuff here for X11R6. */
894 case 0xFF95: return KEYSYM ("kp-home");
895 case 0xFF96: return KEYSYM ("kp-left");
896 case 0xFF97: return KEYSYM ("kp-up");
897 case 0xFF98: return KEYSYM ("kp-right");
898 case 0xFF99: return KEYSYM ("kp-down");
899 case 0xFF9A: return KEYSYM ("kp-prior");
900 case 0xFF9B: return KEYSYM ("kp-next");
901 case 0xFF9C: return KEYSYM ("kp-end");
902 case 0xFF9D: return KEYSYM ("kp-begin");
903 case 0xFF9E: return KEYSYM ("kp-insert");
904 case 0xFF9F: return KEYSYM ("kp-delete");
906 case 0x1005FF10: return KEYSYM ("SunF36"); /* labeled F11 */
907 case 0x1005FF11: return KEYSYM ("SunF37"); /* labeled F12 */
911 sprintf (buf, "unknown-keysym-0x%X", (int) keysym);
915 /* If it's got a one-character name, that's good enough. */
917 return make_char (name[0]);
919 /* If it's in the "Keyboard" character set, downcase it.
920 The case of those keysyms is too totally random for us to
921 force anyone to remember them.
922 The case of the other character sets is significant, however.
924 if ((((unsigned int) keysym) & (~0x1FF)) == ((unsigned int) 0xFE00))
928 for (s1 = name, s2 = buf; *s1; s1++, s2++) {
932 *s2 = tolower (* (unsigned char *) s1);
938 return KEYSYM (name);
943 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
944 /* simple_p means don't try too hard (ASCII only) */
951 char *bufptr = buffer;
952 int bufsiz = sizeof (buffer);
955 XIC xic = FRAME_X_XIC (x_any_window_to_frame
956 (get_device_from_display (event->display),
958 #endif /* XIM_XLIB */
959 #endif /* HAVE_XIM */
961 /* We use XLookupString if we're not using XIM, or are using
962 XIM_XLIB but input context creation failed. */
963 #if ! (defined (HAVE_XIM) && defined (XIM_MOTIF))
964 #if defined (HAVE_XIM) && defined (XIM_XLIB)
966 #endif /* XIM_XLIB */
968 /* Apparently it's necessary to specify a dummy here (rather
969 than passing in 0) to avoid crashes on German IRIX */
971 XLookupString (event, dummy, 200, &keysym, 0);
972 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
973 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
975 #endif /* ! XIM_MOTIF */
978 Lookup_String: /* Come-From XBufferOverflow */
980 len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
981 event, bufptr, bufsiz, &keysym, &status);
984 len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
985 #endif /* HAVE_XIM */
988 if (x_debug_events > 0)
990 stderr_out (" status=");
991 #define print_status_when(S) if (status == S) stderr_out (#S)
992 print_status_when (XLookupKeySym);
993 print_status_when (XLookupBoth);
994 print_status_when (XLookupChars);
995 print_status_when (XLookupNone);
996 print_status_when (XBufferOverflow);
998 if (status == XLookupKeySym || status == XLookupBoth)
999 stderr_out (" keysym=%s", XKeysymToString (keysym));
1000 if (status == XLookupChars || status == XLookupBoth)
1005 stderr_out (" chars=\"");
1006 for (j=0; j<len; j++)
1007 stderr_out ("%c", bufptr[j]);
1010 else if (bufptr[0] <= 32 || bufptr[0] >= 127)
1011 stderr_out (" char=0x%x", bufptr[0]);
1013 stderr_out (" char=%c", bufptr[0]);
1017 #endif /* DEBUG_XEMACS */
1023 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
1024 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
1028 /* Generate multiple emacs events */
1029 struct device *d = get_device_from_display (event->display);
1031 Lisp_Object instream, fb_instream;
1033 struct gcpro gcpro1, gcpro2;
1035 fb_instream = make_fixed_buffer_input_stream (bufptr, len);
1037 /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */
1039 make_decoding_input_stream (XLSTREAM (fb_instream),
1040 Fget_coding_system (Qundecided));
1042 istr = XLSTREAM (instream);
1044 GCPRO2 (instream, fb_instream);
1045 while ((ch = Lstream_get_emchar (istr)) != EOF)
1047 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
1048 Lisp_Event *ev = XEVENT (emacs_event);
1049 ev->channel = DEVICE_CONSOLE (d);
1050 ev->event_type = key_press_event;
1051 ev->timestamp = event->time;
1052 ev->event.key.modifiers = 0;
1053 ev->event.key.keysym = make_char (ch);
1054 enqueue_Xt_dispatch_event (emacs_event);
1056 Lstream_close (istr);
1058 Lstream_delete (istr);
1059 Lstream_delete (XLSTREAM (fb_instream));
1062 case XLookupNone: return Qnil;
1063 case XBufferOverflow:
1064 bufptr = (char *) alloca (len+1);
1068 return Qnil; /* not reached */
1069 #endif /* HAVE_XIM */
1073 set_last_server_timestamp (struct device *d, XEvent *x_event)
1076 switch (x_event->type)
1079 case KeyRelease: t = x_event->xkey.time; break;
1081 case ButtonRelease: t = x_event->xbutton.time; break;
1083 case LeaveNotify: t = x_event->xcrossing.time; break;
1084 case MotionNotify: t = x_event->xmotion.time; break;
1085 case PropertyNotify: t = x_event->xproperty.time; break;
1086 case SelectionClear: t = x_event->xselectionclear.time; break;
1087 case SelectionRequest: t = x_event->xselectionrequest.time; break;
1088 case SelectionNotify: t = x_event->xselection.time; break;
1091 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t;
1095 x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
1097 Display *display = x_event->xany.display;
1098 struct device *d = get_device_from_display (display);
1099 struct x_device *xd = DEVICE_X_DATA (d);
1101 if (DEVICE_X_BEING_DELETED (d))
1102 /* #### Uh, is this 0 correct? */
1105 set_last_server_timestamp (d, x_event);
1107 switch (x_event->type)
1110 x_handle_sticky_modifiers (x_event, d);
1118 int shift_p, lock_p;
1119 Bool key_event_p = (x_event->type == KeyPress);
1120 unsigned int *state =
1121 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state;
1123 /* If this is a synthetic KeyPress or Button event, and the user
1124 has expressed a disinterest in this security hole, then drop
1127 ? x_event->xkey.send_event
1128 : x_event->xbutton.send_event)
1129 #ifdef EXTERNAL_WIDGET
1130 /* ben: events get sent to an ExternalShell using XSendEvent.
1131 This is not a perfect solution. */
1132 && !FRAME_X_EXTERNAL_WINDOW_P
1133 (x_any_window_to_frame (d, x_event->xany.window))
1135 && !x_allow_sendevents)
1138 DEVICE_X_MOUSE_TIMESTAMP (d) =
1139 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) =
1140 key_event_p ? x_event->xkey.time : x_event->xbutton.time;
1142 x_handle_sticky_modifiers (x_event, d);
1144 if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1145 if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1146 if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1147 if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1148 if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1150 /* Ignore the Caps_Lock key if:
1151 - any other modifiers are down, so that Caps_Lock doesn't
1152 turn C-x into C-X, which would suck.
1153 - the event was a mouse event. */
1154 if (modifiers || ! key_event_p)
1155 *state &= (~LockMask);
1157 shift_p = *state & ShiftMask;
1158 lock_p = *state & LockMask;
1160 if (shift_p || lock_p)
1161 modifiers |= XEMACS_MOD_SHIFT;
1166 XKeyEvent *ev = &x_event->xkey;
1167 /* This used to compute the frame from the given X window and
1168 store it here, but we really don't care about the frame. */
1169 emacs_event->channel = DEVICE_CONSOLE (d);
1170 keysym = x_to_emacs_keysym (&x_event->xkey, 0);
1172 /* If the emacs keysym is nil, then that means that the X
1173 keysym was either a Modifier or NoSymbol, which
1174 probably means that we're in the midst of reading a
1175 Multi_key sequence, or a "dead" key prefix, or XIM
1176 input. Ignore it. */
1180 /* More Caps_Lock garbage: Caps_Lock should *only* add the
1181 shift modifier to two-case keys (that is, A-Z and
1182 related characters). So at this point (after looking up
1183 the keysym) if the keysym isn't a dual-case alphabetic,
1184 and if the caps lock key was down but the shift key
1185 wasn't, then turn off the shift modifier. Gag barf */
1186 /* #### type lossage: assuming equivalence of emacs and
1188 /* !!#### maybe fix for Mule */
1189 if (lock_p && !shift_p &&
1190 ! (CHAR_OR_CHAR_INTP (keysym)
1191 && keysym_obeys_caps_lock_p
1192 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
1193 modifiers &= (~XEMACS_MOD_SHIFT);
1195 /* If this key contains two distinct keysyms, that is,
1196 "shift" generates a different keysym than the
1197 non-shifted key, then don't apply the shift modifier
1198 bit: it's implicit. Otherwise, if there would be no
1199 other way to tell the difference between the shifted
1200 and unshifted version of this key, apply the shift bit.
1201 Non-graphics, like Backspace and F1 get the shift bit
1202 in the modifiers slot. Neither the characters "a",
1203 "A", "2", nor "@" normally have the shift bit set.
1204 However, "F1" normally does. */
1205 if (modifiers & XEMACS_MOD_SHIFT)
1207 int Mode_switch_p = *state & xd->ModeMask;
1208 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
1209 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1);
1210 if (top && bot && top != bot)
1211 modifiers &= ~XEMACS_MOD_SHIFT;
1213 emacs_event->event_type = key_press_event;
1214 emacs_event->timestamp = ev->time;
1215 emacs_event->event.key.modifiers = modifiers;
1216 emacs_event->event.key.keysym = keysym;
1218 else /* Mouse press/release event */
1220 XButtonEvent *ev = &x_event->xbutton;
1221 struct frame *frame = x_window_to_frame (d, ev->window);
1224 return 0; /* not for us */
1225 XSETFRAME (emacs_event->channel, frame);
1227 emacs_event->event_type = (x_event->type == ButtonPress) ?
1228 button_press_event : button_release_event;
1230 emacs_event->event.button.modifiers = modifiers;
1231 emacs_event->timestamp = ev->time;
1232 emacs_event->event.button.button = ev->button;
1233 emacs_event->event.button.x = ev->x;
1234 emacs_event->event.button.y = ev->y;
1235 /* because we don't seem to get a FocusIn event for button clicks
1236 when a widget-glyph is selected we will assume that we want the
1237 focus if a button gets pressed. */
1238 if (x_event->type == ButtonPress)
1239 handle_focus_event_1 (frame, 1);
1246 XMotionEvent *ev = &x_event->xmotion;
1247 struct frame *frame = x_window_to_frame (d, ev->window);
1249 XMotionEvent event2;
1252 return 0; /* not for us */
1254 /* We use MotionHintMask, so we will get only one motion event
1255 until the next time we call XQueryPointer or the user
1256 clicks the mouse. So call XQueryPointer now (meaning that
1257 the event will be in sync with the server just before
1258 Fnext_event() returns). If the mouse is still in motion,
1259 then the server will immediately generate exactly one more
1260 motion event, which will be on the queue waiting for us
1261 next time around. */
1263 if (XQueryPointer (event2.display, event2.window,
1264 &event2.root, &event2.subwindow,
1265 &event2.x_root, &event2.y_root,
1266 &event2.x, &event2.y,
1268 ev = &event2; /* only one structure copy */
1270 DEVICE_X_MOUSE_TIMESTAMP (d) = ev->time;
1272 XSETFRAME (emacs_event->channel, frame);
1273 emacs_event->event_type = pointer_motion_event;
1274 emacs_event->timestamp = ev->time;
1275 emacs_event->event.motion.x = ev->x;
1276 emacs_event->event.motion.y = ev->y;
1277 if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
1278 if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1279 if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1280 if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1281 if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1282 if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1283 /* Currently ignores Shift_Lock but probably shouldn't
1284 (but it definitely should ignore Caps_Lock). */
1285 emacs_event->event.motion.modifiers = modifiers;
1291 /* Patch bogus TAKE_FOCUS messages from MWM; CurrentTime is
1292 passed as the timestamp of the TAKE_FOCUS, which the ICCCM
1293 explicitly prohibits. */
1294 XClientMessageEvent *ev = &x_event->xclient;
1295 #ifdef HAVE_OFFIX_DND
1296 if (DndIsDropMessage(x_event))
1300 unsigned int button=0;
1301 struct frame *frame = x_any_window_to_frame (d, ev->window);
1303 unsigned long size, dtype;
1304 Lisp_Object l_type = Qnil, l_data = Qnil;
1305 Lisp_Object l_dndlist = Qnil, l_item = Qnil;
1306 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1308 GCPRO4 (l_type, l_data, l_dndlist, l_item);
1311 return 0; /* not for us */
1312 XSETFRAME (emacs_event->channel, frame);
1314 emacs_event->event_type = misc_user_event;
1315 emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1317 state=DndDragButtons(x_event);
1319 if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT;
1320 if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL;
1321 if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META;
1322 if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER;
1323 if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER;
1324 if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT;
1326 if (state & Button5Mask) button = Button5;
1327 if (state & Button4Mask) button = Button4;
1328 if (state & Button3Mask) button = Button3;
1329 if (state & Button2Mask) button = Button2;
1330 if (state & Button1Mask) button = Button1;
1332 emacs_event->event.misc.modifiers = modifiers;
1333 emacs_event->event.misc.button = button;
1335 DndDropCoordinates(FRAME_X_TEXT_WIDGET(frame), x_event,
1336 &(emacs_event->event.misc.x),
1337 &(emacs_event->event.misc.y) );
1339 DndGetData(x_event,&data,&size);
1341 dtype=DndDataType(x_event);
1344 case DndFiles: /* null terminated strings, end null */
1351 len = strlen ((char*)data);
1352 hurl = dnd_url_hexify_string ((char *)data, "file:");
1353 l_item = make_string ((Bufbyte *)hurl, strlen (hurl));
1354 l_dndlist = Fcons (l_item, l_dndlist);
1358 l_type = Qdragdrop_URL;
1362 l_type = Qdragdrop_MIME;
1363 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
1364 make_string ((Bufbyte *)"8bit", 4),
1365 make_ext_string ((Extbyte *)data,
1366 strlen((char *)data),
1370 /* we have to parse this in some way to extract
1371 content-type and params (in the tm way) and
1373 OR: if data is string, let tm do the job
1374 if data is list[2], give the first two
1377 l_type = Qdragdrop_MIME;
1378 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1379 strlen((char *)data),
1387 char *hurl = dnd_url_hexify_string ((char *) data, "file:");
1389 l_dndlist = list1 ( make_string ((Bufbyte *)hurl,
1391 l_type = Qdragdrop_URL;
1397 /* as it is a real URL it should already be escaped
1398 and escaping again will break them (cause % is unsave) */
1399 l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
1400 strlen ((char *)data),
1402 l_type = Qdragdrop_URL;
1404 default: /* Unknown, RawData and any other type */
1405 l_dndlist = list1 ( list3 ( list1 ( make_string ((Bufbyte *)"application/octet-stream", 24) ),
1406 make_string ((Bufbyte *)"8bit", 4),
1407 make_ext_string ((Extbyte *)data,
1410 l_type = Qdragdrop_MIME;
1414 emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
1415 emacs_event->event.misc.object = Fcons (l_type, l_dndlist);
1421 #endif /* HAVE_OFFIX_DND */
1422 if (ev->message_type == DEVICE_XATOM_WM_PROTOCOLS (d)
1423 && (Atom) (ev->data.l[0]) == DEVICE_XATOM_WM_TAKE_FOCUS (d)
1424 && (Atom) (ev->data.l[1]) == 0)
1426 ev->data.l[1] = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
1431 default: /* it's a magic event */
1433 struct frame *frame;
1435 XEvent *x_event_copy = &emacs_event->event.magic.underlying_x_event;
1437 #define FROB(event_member, window_member) \
1438 x_event_copy->event_member = x_event->event_member; \
1439 w = x_event->event_member.window_member
1441 switch (x_event->type)
1443 case SelectionRequest: FROB(xselectionrequest, owner); break;
1444 case SelectionClear: FROB(xselectionclear, window); break;
1445 case SelectionNotify: FROB(xselection, requestor); break;
1446 case PropertyNotify: FROB(xproperty, window); break;
1447 case ClientMessage: FROB(xclient, window); break;
1448 case ConfigureNotify: FROB(xconfigure, window); break;
1450 case GraphicsExpose: FROB(xexpose, window); break;
1452 case UnmapNotify: FROB(xmap, window); break;
1454 case LeaveNotify: FROB(xcrossing, window); break;
1456 case FocusOut: FROB(xfocus, window); break;
1457 case VisibilityNotify: FROB(xvisibility, window); break;
1458 case CreateNotify: FROB(xcreatewindow, window); break;
1460 w = x_event->xany.window;
1461 *x_event_copy = *x_event;
1465 frame = x_any_window_to_frame (d, w);
1470 emacs_event->event_type = magic_event;
1471 XSETFRAME (emacs_event->channel, frame);
1481 /************************************************************************/
1482 /* magic-event handling */
1483 /************************************************************************/
1486 handle_focus_event_1 (struct frame *f, int in_p)
1488 #if XtSpecificationRelease > 5
1489 Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
1492 XIM_focus_event (f, in_p);
1493 #endif /* HAVE_XIM */
1495 /* On focus change, clear all memory of sticky modifiers
1496 to avoid non-intuitive behavior. */
1497 clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f)));
1499 /* We don't want to handle the focus change now, because we might
1500 be in an accept-process-output, sleep-for, or sit-for. So
1503 Actually, we half handle it: we handle it as far as changing the
1504 box cursor for redisplay, but we don't call any hooks or do any
1505 select-frame stuff until after the sit-for.
1507 Unfortunately native widgets break the model because they grab
1508 the keyboard focus and nothing sets it back again. I cannot find
1509 any reasonable way to do this elsewhere so we assert here that
1510 the keyboard focus is on the emacs text widget. Menus and dialogs
1511 do this in their selection callback, but we don't want that since
1512 a button having focus is legitimate. An edit field having focus
1513 is mandatory. Weirdly you get a FocusOut event when you click in
1514 a widget-glyph but you don't get a correspondng FocusIn when you
1515 click in the frame. Why is this? */
1517 #if XtSpecificationRelease > 5
1518 && FRAME_X_TEXT_WIDGET (f) != focus_widget
1522 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
1523 FRAME_X_TEXT_WIDGET (f));
1525 /* do the generic event-stream stuff. */
1529 struct gcpro gcpro1;
1532 conser = Fcons (frm, Fcons (FRAME_DEVICE (f), in_p ? Qt : Qnil));
1534 emacs_handle_focus_change_preliminary (conser);
1535 enqueue_magic_eval_event (emacs_handle_focus_change_final,
1541 /* This is called from the external-widget code */
1543 void emacs_Xt_handle_focus_event (XEvent *event);
1545 emacs_Xt_handle_focus_event (XEvent *event)
1547 struct device *d = get_device_from_display (event->xany.display);
1550 if (DEVICE_X_BEING_DELETED (d))
1554 * It's curious that we're using x_any_window_to_frame() instead
1555 * of x_window_to_frame(). I don't know what the impact of this is.
1557 f = x_any_window_to_frame (d, event->xfocus.window);
1559 /* focus events are sometimes generated just before
1560 a frame is destroyed. */
1562 handle_focus_event_1 (f, event->type == FocusIn);
1565 /* both MapNotify and VisibilityNotify can cause this
1566 JV is_visible has the same semantics as f->visible*/
1568 change_frame_visibility (struct frame *f, int is_visible)
1572 XSETFRAME (frame, f);
1574 if (!FRAME_VISIBLE_P (f) && is_visible)
1576 FRAME_VISIBLE_P (f) = is_visible;
1577 /* This improves the double flicker when uniconifying a frame
1578 some. A lot of it is not showing a buffer which has changed
1579 while the frame was iconified. To fix it further requires
1580 the good 'ol double redisplay structure. */
1581 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1582 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1584 else if (FRAME_VISIBLE_P (f) && !is_visible)
1586 FRAME_VISIBLE_P (f) = 0;
1587 va_run_hook_with_args (Qunmap_frame_hook, 1, frame);
1589 else if (FRAME_VISIBLE_P (f) * is_visible < 0)
1591 FRAME_VISIBLE_P(f) = - FRAME_VISIBLE_P(f);
1592 if (FRAME_REPAINT_P(f))
1593 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1594 va_run_hook_with_args (Qmap_frame_hook, 1, frame);
1599 handle_map_event (struct frame *f, XEvent *event)
1603 XSETFRAME (frame, f);
1604 if (event->type == MapNotify)
1606 XWindowAttributes xwa;
1608 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM)
1609 send synthetic MapNotify events when a window is first
1610 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
1611 Or something like that. We initially tried a different
1612 solution below, but that ran into a different window-
1615 It seems that the only reliable way is to treat a
1616 MapNotify event as a "hint" that the window might or
1617 might not be visible, and check explicitly. */
1619 XGetWindowAttributes (event->xany.display, event->xmap.window,
1621 if (xwa.map_state != IsViewable)
1623 /* Calling Fframe_iconified_p is the only way we have to
1624 correctly update FRAME_ICONIFIED_P */
1625 Fframe_iconified_p (frame);
1629 FRAME_X_TOTALLY_VISIBLE_P (f) = 1;
1631 /* Bleagh again!!!! We initially tried the following hack
1632 around the MWM problem, but it turns out that TWM
1633 has a race condition when you un-iconify, where it maps
1634 the window and then tells the server that the window
1635 is un-iconified. Usually, XEmacs wakes up between
1636 those two occurrences, and thus thinks that un-iconified
1637 windows are still iconified.
1639 Ah, the joys of X. */
1641 /* By Emacs definition, a frame that is iconified is not
1642 visible. Marking a frame as visible will automatically cause
1643 frame-iconified-p to return nil, regardless of whether the
1644 frame is actually iconified. Therefore, we have to ignore
1645 MapNotify events on iconified frames. (It's not obvious
1646 to me why these are being sent, but it happens at startup
1647 with frames that are initially iconified; perhaps they are
1648 synthetic MapNotify events coming from the window manager.)
1649 Note that `frame-iconified-p' queries the server
1650 to determine whether the frame is currently iconified,
1651 rather than consulting some internal (and likely
1652 inaccurate) state flag. Therefore, ignoring the MapNotify
1654 if (!FRAME_VISIBLE_P (f) && NILP (Fframe_iconified_p (frame)))
1656 change_frame_visibility (f, 1);
1660 FRAME_X_TOTALLY_VISIBLE_P (f) = 0;
1661 change_frame_visibility (f, 0);
1662 /* Calling Fframe_iconified_p is the only way we have to
1663 correctly update FRAME_ICONIFIED_P */
1664 Fframe_iconified_p (frame);
1669 handle_client_message (struct frame *f, XEvent *event)
1671 struct device *d = XDEVICE (FRAME_DEVICE (f));
1674 XSETFRAME (frame, f);
1676 if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1677 (Atom) (event->xclient.data.l[0]) == DEVICE_XATOM_WM_DELETE_WINDOW (d))
1679 /* WM_DELETE_WINDOW is a misc-user event, but other ClientMessages,
1680 such as WM_TAKE_FOCUS, are eval events. That's because delete-window
1681 was probably executed with a mouse click, while the others could
1682 have been sent as a result of mouse motion or some other implicit
1683 action. (Call this a "heuristic"...) The reason for caring about
1684 this is so that clicking on the close-box will make emacs prompt
1685 using a dialog box instead of the minibuffer if there are unsaved
1688 enqueue_misc_user_event (frame, Qeval,
1689 list3 (Qdelete_frame, frame, Qt));
1691 else if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) &&
1692 (Atom) event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d))
1694 handle_focus_event_1 (f, 1);
1696 /* If there is a dialog box up, focus on it.
1698 #### Actually, we're raising it too, which is wrong. We should
1699 #### just focus on it, but lwlib doesn't currently give us an
1700 #### easy way to do that. This should be fixed.
1702 unsigned long take_focus_timestamp = event->xclient.data.l[1];
1703 Widget widget = lw_raise_all_pop_up_widgets ();
1706 /* kludge: raise_all returns bottommost widget, but we really
1707 want the topmost. So just raise it for now. */
1708 XMapRaised (XtDisplay (widget), XtWindow (widget));
1709 /* Grab the focus with the timestamp of the TAKE_FOCUS. */
1710 XSetInputFocus (XtDisplay (widget), XtWindow (widget),
1711 RevertToParent, take_focus_timestamp);
1718 emacs_Xt_force_event_pending (struct frame* f)
1722 Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f)));
1723 event.xclient.type = ClientMessage;
1724 event.xclient.display = dpy;
1725 event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False);
1726 event.xclient.format = 32;
1727 event.xclient.window = 0;
1729 /* Send the drop message */
1730 XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)),
1731 True, NoEventMask, &event);
1732 /* Force event pending to check the X queue. */
1733 quit_check_signal_tick_count++;
1737 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
1739 /* This function can GC */
1740 XEvent *event = &emacs_event->event.magic.underlying_x_event;
1741 struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
1743 if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f))))
1746 switch (event->type)
1748 case SelectionRequest:
1749 x_handle_selection_request (&event->xselectionrequest);
1752 case SelectionClear:
1753 x_handle_selection_clear (&event->xselectionclear);
1756 case SelectionNotify:
1757 x_handle_selection_notify (&event->xselection);
1760 case PropertyNotify:
1761 x_handle_property_notify (&event->xproperty);
1765 if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
1766 event->xexpose.width, event->xexpose.height)
1768 !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
1769 event->xexpose.width, event->xexpose.height))
1770 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1771 event->xexpose.width, event->xexpose.height);
1774 case GraphicsExpose: /* This occurs when an XCopyArea's source area was
1775 obscured or not available. */
1776 x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
1777 event->xexpose.width, event->xexpose.height);
1782 handle_map_event (f, event);
1786 if (event->xcrossing.detail != NotifyInferior)
1790 XSETFRAME (frame, f);
1791 /* FRAME_X_MOUSE_P (f) = 1; */
1792 va_run_hook_with_args (Qmouse_enter_frame_hook, 1, frame);
1797 if (event->xcrossing.detail != NotifyInferior)
1801 XSETFRAME (frame, f);
1802 /* FRAME_X_MOUSE_P (f) = 0; */
1803 va_run_hook_with_args (Qmouse_leave_frame_hook, 1, frame);
1810 #ifdef EXTERNAL_WIDGET
1811 /* External widget lossage: Ben said:
1812 YUCK. The only way to make focus changes work properly is to
1813 completely ignore all FocusIn/FocusOut events and depend only
1814 on notifications from the ExternalClient widget. */
1815 if (FRAME_X_EXTERNAL_WINDOW_P (f))
1818 handle_focus_event_1 (f, event->type == FocusIn);
1822 handle_client_message (f, event);
1825 case VisibilityNotify: /* window visibility has changed */
1826 if (event->xvisibility.window == XtWindow (FRAME_X_SHELL_WIDGET (f)))
1828 FRAME_X_TOTALLY_VISIBLE_P (f) =
1829 (event->xvisibility.state == VisibilityUnobscured);
1830 /* Note that the fvwm pager only sends VisibilityNotify when
1831 changing pages. Is this all we need to do ? JV */
1832 /* Nope. We must at least trigger a redisplay here.
1833 Since this case seems similar to MapNotify, I've
1834 factored out some code to change_frame_visibility().
1835 This triggers the necessary redisplay and runs
1836 (un)map-frame-hook. - dkindred@cs.cmu.edu */
1837 /* Changed it again to support the tristate visibility flag */
1838 change_frame_visibility (f, (event->xvisibility.state
1839 != VisibilityFullyObscured) ? 1 : -1);
1843 case ConfigureNotify:
1845 XIM_SetGeometry (f);
1850 printf ("window created\n");
1858 /************************************************************************/
1859 /* timeout events */
1860 /************************************************************************/
1862 static int timeout_id_tick;
1864 /* Xt interval id's might not fit into an int (they're pointers, as it
1865 happens), so we need to provide a conversion list. */
1867 static struct Xt_timeout
1870 XtIntervalId interval_id;
1871 struct Xt_timeout *next;
1872 } *pending_timeouts, *completed_timeouts;
1874 static struct Xt_timeout_blocktype
1876 Blocktype_declare (struct Xt_timeout);
1877 } *the_Xt_timeout_blocktype;
1879 /* called by XtAppNextEvent() */
1881 Xt_timeout_callback (XtPointer closure, XtIntervalId *id)
1883 struct Xt_timeout *timeout = (struct Xt_timeout *) closure;
1884 struct Xt_timeout *t2 = pending_timeouts;
1885 /* Remove this one from the list of pending timeouts */
1887 pending_timeouts = pending_timeouts->next;
1890 while (t2->next && t2->next != timeout) t2 = t2->next;
1892 t2->next = t2->next->next;
1894 /* Add this one to the list of completed timeouts */
1895 timeout->next = completed_timeouts;
1896 completed_timeouts = timeout;
1900 emacs_Xt_add_timeout (EMACS_TIME thyme)
1902 struct Xt_timeout *timeout = Blocktype_alloc (the_Xt_timeout_blocktype);
1903 EMACS_TIME current_time;
1906 timeout->id = timeout_id_tick++;
1907 timeout->next = pending_timeouts;
1908 pending_timeouts = timeout;
1909 EMACS_GET_TIME (current_time);
1910 EMACS_SUB_TIME (thyme, thyme, current_time);
1911 milliseconds = EMACS_SECS (thyme) * 1000 +
1912 EMACS_USECS (thyme) / 1000;
1913 if (milliseconds < 1)
1915 timeout->interval_id = XtAppAddTimeOut (Xt_app_con, milliseconds,
1916 Xt_timeout_callback,
1917 (XtPointer) timeout);
1922 emacs_Xt_remove_timeout (int id)
1924 struct Xt_timeout *timeout, *t2;
1928 /* Find the timeout on the list of pending ones, if it's still there. */
1929 if (pending_timeouts)
1931 if (id == pending_timeouts->id)
1933 timeout = pending_timeouts;
1934 pending_timeouts = pending_timeouts->next;
1938 t2 = pending_timeouts;
1939 while (t2->next && t2->next->id != id) t2 = t2->next;
1940 if ( t2->next) /*found it */
1943 t2->next = t2->next->next;
1946 /* if it was pending, we have removed it from the list */
1948 XtRemoveTimeOut (timeout->interval_id);
1951 /* It could be that the Xt call back was already called but we didn't convert
1952 into an Emacs event yet */
1953 if (!timeout && completed_timeouts)
1955 /* Code duplication! */
1956 if (id == completed_timeouts->id)
1958 timeout = completed_timeouts;
1959 completed_timeouts = completed_timeouts->next;
1963 t2 = completed_timeouts;
1964 while (t2->next && t2->next->id != id) t2 = t2->next;
1965 if ( t2->next) /*found it */
1968 t2->next = t2->next->next;
1973 /* If we found the thing on the lists of timeouts,
1974 and removed it, deallocate
1977 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1981 Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
1983 struct Xt_timeout *timeout = completed_timeouts;
1985 completed_timeouts = completed_timeouts->next;
1986 emacs_event->event_type = timeout_event;
1987 /* timeout events have nil as channel */
1988 emacs_event->timestamp = 0; /* #### wrong!! */
1989 emacs_event->event.timeout.interval_id = timeout->id;
1990 emacs_event->event.timeout.function = Qnil;
1991 emacs_event->event.timeout.object = Qnil;
1992 Blocktype_free (the_Xt_timeout_blocktype, timeout);
1996 /************************************************************************/
1997 /* process and tty events */
1998 /************************************************************************/
2000 struct what_is_ready_closure
2007 static Lisp_Object *filedesc_with_input;
2008 static struct what_is_ready_closure **filedesc_to_what_closure;
2011 init_what_input_once (void)
2015 filedesc_with_input = xnew_array (Lisp_Object, MAXDESC);
2016 filedesc_to_what_closure =
2017 xnew_array (struct what_is_ready_closure *, MAXDESC);
2019 for (i = 0; i < MAXDESC; i++)
2021 filedesc_to_what_closure[i] = 0;
2022 filedesc_with_input[i] = Qnil;
2025 process_events_occurred = 0;
2026 tty_events_occurred = 0;
2030 mark_what_as_being_ready (struct what_is_ready_closure *closure)
2032 if (NILP (filedesc_with_input[closure->fd]))
2034 SELECT_TYPE temp_mask;
2035 FD_ZERO (&temp_mask);
2036 FD_SET (closure->fd, &temp_mask);
2037 /* Check to make sure there's *really* input available.
2038 Sometimes things seem to get confused and this gets called
2039 for the tty fd when there's really only input available
2040 on some process's fd. (It will subsequently get called
2041 for that process's fd, so returning without setting any
2042 flags will take care of it.) To see the problem, uncomment
2043 the stderr_out below, turn NORMAL_QUIT_CHECK_TIMEOUT_MSECS
2044 down to 25, do sh -c 'xemacs -nw -q -f shell 2>/tmp/log'
2045 and press return repeatedly. (Seen under AIX & Linux.)
2046 -dkindred@cs.cmu.edu */
2047 if (!poll_fds_for_input (temp_mask))
2050 stderr_out ("mark_what_as_being_ready: no input available (fd=%d)\n",
2055 filedesc_with_input[closure->fd] = closure->what;
2056 if (PROCESSP (closure->what))
2057 /* Don't increment this if the current process is already marked
2058 * as having input. */
2059 process_events_occurred++;
2061 tty_events_occurred++;
2066 Xt_what_callback (void *closure, int *source, XtInputId *id)
2068 /* If closure is 0, then we got a fake event from a signal handler.
2069 The only purpose of this is to make XtAppProcessEvent() stop
2072 mark_what_as_being_ready ((struct what_is_ready_closure *) closure);
2075 fake_event_occurred++;
2076 drain_signal_event_pipe ();
2081 select_filedesc (int fd, Lisp_Object what)
2083 struct what_is_ready_closure *closure;
2085 /* If somebody is trying to select something that's already selected
2086 for, then something went wrong. The generic routines ought to
2087 detect this and error before here. */
2088 assert (!filedesc_to_what_closure[fd]);
2090 closure = xnew (struct what_is_ready_closure);
2092 closure->what = what;
2094 XtAppAddInput (Xt_app_con, fd,
2095 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
2096 Xt_what_callback, closure);
2097 filedesc_to_what_closure[fd] = closure;
2101 unselect_filedesc (int fd)
2103 struct what_is_ready_closure *closure = filedesc_to_what_closure[fd];
2106 if (!NILP (filedesc_with_input[fd]))
2108 /* We are unselecting this process before we have drained the rest of
2109 the input from it, probably from status_notify() in the command loop.
2110 This can happen like so:
2112 - We are waiting in XtAppNextEvent()
2113 - Process generates output
2114 - Process is marked as being ready
2115 - Process dies, SIGCHLD gets generated before we return (!?)
2116 It could happen I guess.
2117 - sigchld_handler() marks process as dead
2118 - Somehow we end up getting a new KeyPress event on the queue
2119 at the same time (I'm really so sure how that happens but I'm
2120 not sure it can't either so let's assume it can...).
2121 - Key events have priority so we return that instead of the proc.
2122 - Before dispatching the lisp key event we call status_notify()
2123 - Which deselects the process that SIGCHLD marked as dead.
2125 Thus we never remove it from _with_input and turn it into a lisp
2126 event, so we need to do it here. But this does not mean that we're
2127 throwing away the last block of output - status_notify() has already
2128 taken care of running the proc filter or whatever.
2130 filedesc_with_input[fd] = Qnil;
2131 if (PROCESSP (closure->what))
2133 assert (process_events_occurred > 0);
2134 process_events_occurred--;
2138 assert (tty_events_occurred > 0);
2139 tty_events_occurred--;
2142 XtRemoveInput (closure->id);
2144 filedesc_to_what_closure[fd] = 0;
2148 emacs_Xt_select_process (Lisp_Process *p)
2150 Lisp_Object process;
2151 int infd = event_stream_unixoid_select_process (p);
2153 XSETPROCESS (process, p);
2154 select_filedesc (infd, process);
2158 emacs_Xt_unselect_process (Lisp_Process *p)
2160 int infd = event_stream_unixoid_unselect_process (p);
2162 unselect_filedesc (infd);
2166 emacs_Xt_create_stream_pair (void* inhandle, void* outhandle,
2167 Lisp_Object* instream, Lisp_Object* outstream, int flags)
2169 USID u = event_stream_unixoid_create_stream_pair
2170 (inhandle, outhandle, instream, outstream, flags);
2171 if (u != USID_ERROR)
2177 emacs_Xt_delete_stream_pair (Lisp_Object instream, Lisp_Object outstream)
2179 event_stream_unixoid_delete_stream_pair (instream, outstream);
2180 return USID_DONTHASH;
2183 /* This is called from GC when a process object is about to be freed.
2184 If we've still got pointers to it in this file, we're gonna lose hard.
2187 debug_process_finalization (Lisp_Process *p)
2191 Lisp_Object instr, outstr;
2193 get_process_streams (p, &instr, &outstr);
2194 /* if it still has fds, then it hasn't been killed yet. */
2195 assert (NILP(instr));
2196 assert (NILP(outstr));
2197 /* Better not still be in the "with input" table; we know it's got no fds. */
2198 for (i = 0; i < MAXDESC; i++)
2200 Lisp_Object process = filedesc_fds_with_input [i];
2201 assert (!PROCESSP (process) || XPROCESS (process) != p);
2207 Xt_process_to_emacs_event (Lisp_Event *emacs_event)
2211 assert (process_events_occurred > 0);
2213 for (i = 0; i < MAXDESC; i++)
2215 Lisp_Object process = filedesc_with_input[i];
2216 if (PROCESSP (process))
2218 filedesc_with_input[i] = Qnil;
2219 process_events_occurred--;
2220 /* process events have nil as channel */
2221 emacs_event->event_type = process_event;
2222 emacs_event->timestamp = 0; /* #### */
2223 emacs_event->event.process.process = process;
2231 emacs_Xt_select_console (struct console *con)
2233 Lisp_Object console;
2236 if (CONSOLE_X_P (con))
2237 return; /* X consoles are automatically selected for when we
2238 initialize them in Xt */
2239 infd = event_stream_unixoid_select_console (con);
2240 XSETCONSOLE (console, con);
2241 select_filedesc (infd, console);
2245 emacs_Xt_unselect_console (struct console *con)
2247 Lisp_Object console;
2250 if (CONSOLE_X_P (con))
2251 return; /* X consoles are automatically selected for when we
2252 initialize them in Xt */
2253 infd = event_stream_unixoid_unselect_console (con);
2254 XSETCONSOLE (console, con);
2255 unselect_filedesc (infd);
2258 /* read an event from a tty, if one is available. Returns non-zero
2259 if an event was available. Note that when this function is
2260 called, there should always be a tty marked as ready for input.
2261 However, the input condition might actually be EOF, so there
2262 may not really be any input available. (In this case,
2263 read_event_from_tty_or_stream_desc() will arrange for the TTY device
2267 Xt_tty_to_emacs_event (Lisp_Event *emacs_event)
2271 assert (tty_events_occurred > 0);
2272 for (i = 0; i < MAXDESC; i++)
2274 Lisp_Object console = filedesc_with_input[i];
2275 if (CONSOLEP (console))
2277 assert (tty_events_occurred > 0);
2278 tty_events_occurred--;
2279 filedesc_with_input[i] = Qnil;
2280 if (read_event_from_tty_or_stream_desc
2281 (emacs_event, XCONSOLE (console), i))
2290 /************************************************************************/
2291 /* debugging functions to decipher an event */
2292 /************************************************************************/
2295 #include "xintrinsicp.h" /* only describe_event() needs this */
2296 #include <X11/Xproto.h> /* only describe_event() needs this */
2299 describe_event_window (Window window, Display *display)
2303 stderr_out (" window: 0x%lx", (unsigned long) window);
2304 w = XtWindowToWidget (display, window);
2306 stderr_out (" %s", w->core.widget_class->core_class.class_name);
2307 f = x_any_window_to_frame (get_device_from_display (display), window);
2310 char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
2311 sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
2312 write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
2313 strlen (buf), Qterminal, 1);
2319 XEvent_mode_to_string (int mode)
2323 case NotifyNormal: return "Normal";
2324 case NotifyGrab: return "Grab";
2325 case NotifyUngrab: return "Ungrab";
2326 case NotifyWhileGrabbed: return "WhileGrabbed";
2327 default: return "???";
2332 XEvent_detail_to_string (int detail)
2336 case NotifyAncestor: return "Ancestor";
2337 case NotifyInferior: return "Inferior";
2338 case NotifyNonlinear: return "Nonlinear";
2339 case NotifyNonlinearVirtual: return "NonlinearVirtual";
2340 case NotifyPointer: return "Pointer";
2341 case NotifyPointerRoot: return "PointerRoot";
2342 case NotifyDetailNone: return "DetailNone";
2343 default: return "???";
2348 XEvent_visibility_to_string (int state)
2352 case VisibilityFullyObscured: return "FullyObscured";
2353 case VisibilityPartiallyObscured: return "PartiallyObscured";
2354 case VisibilityUnobscured: return "Unobscured";
2355 default: return "???";
2360 describe_event (XEvent *event)
2363 struct device *d = get_device_from_display (event->xany.display);
2365 sprintf (buf, "%s%s", x_event_name (event->type),
2366 event->xany.send_event ? " (send)" : "");
2367 stderr_out ("%-30s", buf);
2368 switch (event->type)
2373 XFocusChangeEvent *ev = &event->xfocus;
2374 describe_event_window (ev->window, ev->display);
2375 stderr_out (" mode: %s\n", XEvent_mode_to_string (ev->mode));
2376 stderr_out (" detail: %s\n", XEvent_detail_to_string(ev->detail));
2382 XKeyEvent *ev = &event->xkey;
2383 unsigned int state = ev->state;
2385 describe_event_window (ev->window, ev->display);
2386 stderr_out (" subwindow: %ld\n", ev->subwindow);
2387 stderr_out (" state: ");
2388 /* Complete list of modifier key masks */
2389 if (state & ShiftMask) stderr_out ("Shift ");
2390 if (state & LockMask) stderr_out ("Lock ");
2391 if (state & ControlMask) stderr_out ("Control ");
2392 if (state & Mod1Mask) stderr_out ("Mod1 ");
2393 if (state & Mod2Mask) stderr_out ("Mod2 ");
2394 if (state & Mod3Mask) stderr_out ("Mod3 ");
2395 if (state & Mod4Mask) stderr_out ("Mod4 ");
2396 if (state & Mod5Mask) stderr_out ("Mod5 ");
2399 stderr_out ("vanilla\n");
2402 if (x_key_is_modifier_p (ev->keycode, d))
2403 stderr_out (" Modifier key");
2404 stderr_out (" keycode: 0x%x\n", ev->keycode);
2409 if (x_debug_events > 1)
2411 XExposeEvent *ev = &event->xexpose;
2412 describe_event_window (ev->window, ev->display);
2413 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2414 ev->x, ev->y, ev->width, ev->height);
2415 stderr_out (" count: %d\n", ev->count);
2421 case GraphicsExpose:
2422 if (x_debug_events > 1)
2424 XGraphicsExposeEvent *ev = &event->xgraphicsexpose;
2425 describe_event_window (ev->drawable, ev->display);
2426 stderr_out (" major: %s\n",
2427 (ev ->major_code == X_CopyArea ? "CopyArea" :
2428 (ev->major_code == X_CopyPlane ? "CopyPlane" : "?")));
2429 stderr_out (" region: x=%d y=%d width=%d height=%d\n",
2430 ev->x, ev->y, ev->width, ev->height);
2431 stderr_out (" count: %d\n", ev->count);
2439 if (x_debug_events > 1)
2441 XCrossingEvent *ev = &event->xcrossing;
2442 describe_event_window (ev->window, ev->display);
2444 stderr_out(" subwindow: 0x%x\n", ev->subwindow);
2445 stderr_out(" pos: %d %d\n", ev->x, ev->y);
2446 stderr_out(" root pos: %d %d\n", ev->x_root, ev->y_root);
2448 stderr_out(" mode: %s\n", XEvent_mode_to_string(ev->mode));
2449 stderr_out(" detail: %s\n", XEvent_detail_to_string(ev->detail));
2450 stderr_out(" focus: %d\n", ev->focus);
2452 stderr_out(" state: 0x%x\n", ev->state);
2459 case ConfigureNotify:
2460 if (x_debug_events > 1)
2462 XConfigureEvent *ev = &event->xconfigure;
2463 describe_event_window (ev->window, ev->display);
2464 stderr_out(" above: 0x%lx\n", ev->above);
2465 stderr_out(" size: %d %d %d %d\n", ev->x, ev->y,
2466 ev->width, ev->height);
2467 stderr_out(" redirect: %d\n", ev->override_redirect);
2473 case VisibilityNotify:
2474 if (x_debug_events > 1)
2476 XVisibilityEvent *ev = &event->xvisibility;
2477 describe_event_window (ev->window, ev->display);
2478 stderr_out(" state: %s\n", XEvent_visibility_to_string(ev->state));
2486 XClientMessageEvent *ev = &event->xclient;
2487 char *name = XGetAtomName (ev->display, ev->message_type);
2488 stderr_out ("%s", name);
2489 if (!strcmp (name, "WM_PROTOCOLS")) {
2490 char *protname = XGetAtomName (ev->display, ev->data.l[0]);
2491 stderr_out ("(%s)", protname);
2507 #endif /* include describe_event definition */
2510 /************************************************************************/
2511 /* get the next event from Xt */
2512 /************************************************************************/
2514 static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail;
2517 enqueue_Xt_dispatch_event (Lisp_Object event)
2519 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail);
2523 dequeue_Xt_dispatch_event (void)
2525 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail);
2528 /* This business exists because menu events "happen" when
2529 menubar_selection_callback() is called from somewhere deep
2530 within XtAppProcessEvent in emacs_Xt_next_event(). The
2531 callback needs to terminate the modal loop in that function
2532 or else it will continue waiting until another event is
2535 Same business applies to scrollbar events. */
2538 signal_special_Xt_user_event (Lisp_Object channel, Lisp_Object function,
2541 Lisp_Object event = Fmake_event (Qnil, Qnil);
2543 XEVENT (event)->event_type = misc_user_event;
2544 XEVENT (event)->channel = channel;
2545 XEVENT (event)->event.eval.function = function;
2546 XEVENT (event)->event.eval.object = object;
2548 enqueue_Xt_dispatch_event (event);
2552 emacs_Xt_next_event (Lisp_Event *emacs_event)
2554 we_didnt_get_an_event:
2556 while (NILP (dispatch_event_queue) &&
2557 !completed_timeouts &&
2558 !fake_event_occurred &&
2559 !process_events_occurred &&
2560 !tty_events_occurred)
2563 /* Stupid logic in XtAppProcessEvent() dictates that, if process
2564 events and X events are both available, the process event gets
2565 taken first. This will cause an infinite loop if we're being
2566 called from Fdiscard_input().
2568 if (XtAppPending (Xt_app_con) & XtIMXEvent)
2569 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2572 Lisp_Object devcons, concons;
2574 /* We're about to block. Xt has a bug in it (big surprise,
2575 there) in that it blocks using select() and doesn't
2576 flush the Xlib output buffers (XNextEvent() does this
2577 automatically before blocking). So it's necessary
2578 for us to do this ourselves. If we don't do it, then
2579 display output may not be seen until the next time
2580 an X event is received. (This happens esp. with
2581 subprocess output that gets sent to a visible buffer.)
2583 #### The above comment may not have any validity. */
2585 DEVICE_LOOP_NO_BREAK (devcons, concons)
2588 d = XDEVICE (XCAR (devcons));
2590 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2591 /* emacs may be exiting */
2592 XFlush (DEVICE_X_DISPLAY (d));
2594 XtAppProcessEvent (Xt_app_con, XtIMAll);
2598 if (!NILP (dispatch_event_queue))
2600 Lisp_Object event, event2;
2601 XSETEVENT (event2, emacs_event);
2602 event = dequeue_Xt_dispatch_event ();
2603 Fcopy_event (event, event2);
2604 Fdeallocate_event (event);
2606 else if (tty_events_occurred)
2608 if (!Xt_tty_to_emacs_event (emacs_event))
2609 goto we_didnt_get_an_event;
2611 else if (completed_timeouts)
2612 Xt_timeout_to_emacs_event (emacs_event);
2613 else if (fake_event_occurred)
2615 /* A dummy event, so that a cycle of the command loop will occur. */
2616 fake_event_occurred = 0;
2617 /* eval events have nil as channel */
2618 emacs_event->event_type = eval_event;
2619 emacs_event->event.eval.function = Qidentity;
2620 emacs_event->event.eval.object = Qnil;
2622 else /* if (process_events_occurred) */
2623 Xt_process_to_emacs_event (emacs_event);
2625 /* No need to call XFilterEvent; Xt does it for us */
2629 emacs_Xt_event_handler (Widget wid /* unused */,
2630 XtPointer closure /* unused */,
2632 Boolean *continue_to_dispatch /* unused */)
2634 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
2637 if (x_debug_events > 0)
2639 describe_event (event);
2641 #endif /* DEBUG_XEMACS */
2642 if (x_event_to_emacs_event (event, XEVENT (emacs_event)))
2643 enqueue_Xt_dispatch_event (emacs_event);
2645 Fdeallocate_event (emacs_event);
2649 /************************************************************************/
2650 /* input pending / C-g checking */
2651 /************************************************************************/
2654 quit_char_predicate (Display *display, XEvent *event, XPointer data)
2656 struct device *d = get_device_from_display (display);
2657 struct x_device *xd = DEVICE_X_DATA (d);
2659 Bool *critical = (Bool *) data;
2664 if ((event->type != KeyPress) ||
2665 (! x_any_window_to_frame (d, event->xany.window)) ||
2667 & (xd->MetaMask | xd->HyperMask | xd->SuperMask | xd->AltMask)))
2670 /* This duplicates some code that exists elsewhere, but it's relatively
2671 fast and doesn't cons. */
2672 keysym = x_to_emacs_keysym (&event->xkey, 1);
2673 if (NILP (keysym)) return 0;
2674 if (CHAR_OR_CHAR_INTP (keysym))
2675 c = XCHAR_OR_CHAR_INT (keysym);
2676 /* Highly doubtful that these are the quit character, but... */
2677 else if (EQ (keysym, QKbackspace)) c = '\b';
2678 else if (EQ (keysym, QKtab)) c = '\t';
2679 else if (EQ (keysym, QKlinefeed)) c = '\n';
2680 else if (EQ (keysym, QKreturn)) c = '\r';
2681 else if (EQ (keysym, QKescape)) c = 27;
2682 else if (EQ (keysym, QKspace)) c = ' ';
2683 else if (EQ (keysym, QKdelete)) c = 127;
2686 if (event->xkey.state & xd->MetaMask) c |= 0x80;
2687 if ((event->xkey.state & ControlMask) && !(c >= 'A' && c <= 'Z'))
2688 c &= 0x1F; /* unshifted control characters */
2689 quit_char = CONSOLE_QUIT_CHAR (XCONSOLE (DEVICE_CONSOLE (d)));
2692 /* If we've got Control-Shift-G instead of Control-G, that means
2693 we have a critical_quit. Caps_Lock is its own modifier, so it
2694 won't cause ^G to act differently than before. */
2695 if (event->xkey.state & ControlMask) c &= 0x1F;
2698 if (critical) *critical = True;
2704 /* This scans the X input queue for a KeyPress event that matches the
2705 quit character, and sets Vquit_flag. This is called from the
2706 QUIT macro to determine whether we should quit.
2708 In a SIGIO world, this won't be called unless a SIGIO has happened
2709 since the last time we checked.
2711 In a non-SIGIO world, this is called from emacs_Xt_event_pending_p
2712 (which is called from input_pending_p).
2715 x_check_for_quit_char (Display *display)
2719 Bool critical_quit = False;
2720 XEventsQueued (display, QueuedAfterReading);
2721 queued = XCheckIfEvent (display, &event,
2722 quit_char_predicate,
2723 (char *) &critical_quit);
2726 Vquit_flag = (critical_quit ? Qcritical : Qt);
2727 /* don't put the event back onto the queue. Those functions that
2728 wanted to read a ^G directly have arranged to do this. */
2733 check_for_tty_quit_char (struct device *d)
2735 SELECT_TYPE temp_mask;
2736 int infd = DEVICE_INFD (d);
2737 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
2738 Emchar quit_char = CONSOLE_QUIT_CHAR (con);
2740 FD_ZERO (&temp_mask);
2741 FD_SET (infd, &temp_mask);
2748 if (!poll_fds_for_input (temp_mask))
2751 event = Fmake_event (Qnil, Qnil);
2752 if (!read_event_from_tty_or_stream_desc (XEVENT (event), con, infd))
2753 /* EOF, or something ... */
2755 /* #### bogus. quit-char should be allowed to be any sort
2757 the_char = event_to_character (XEVENT (event), 1, 0, 0);
2758 if (the_char >= 0 && the_char == quit_char)
2761 /* do not queue the C-g. See above. */
2765 /* queue the read event to be read for real later. */
2766 enqueue_Xt_dispatch_event (event);
2771 emacs_Xt_quit_p (void)
2773 Lisp_Object devcons, concons;
2774 CONSOLE_LOOP (concons)
2776 struct console *con = XCONSOLE (XCAR (concons));
2777 if (!con->input_enabled)
2780 CONSOLE_DEVICE_LOOP (devcons, con)
2783 d = XDEVICE (XCAR (devcons));
2785 if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d))
2786 /* emacs may be exiting */
2787 x_check_for_quit_char (DEVICE_X_DISPLAY (d));
2788 else if (DEVICE_TTY_P (d))
2789 check_for_tty_quit_char (d);
2795 drain_X_queue (void)
2797 while (XtAppPending (Xt_app_con) & XtIMXEvent)
2798 XtAppProcessEvent (Xt_app_con, XtIMXEvent);
2802 emacs_Xt_event_pending_p (int user_p)
2807 /* If `user_p' is false, then this function returns whether there are any
2808 X, timeout, or fd events pending (that is, whether emacs_Xt_next_event()
2809 would return immediately without blocking).
2811 if `user_p' is true, then this function returns whether there are any
2812 *user generated* events available (that is, whether there are keyboard
2813 or mouse-click events ready to be read). This also implies that
2814 emacs_Xt_next_event() would not block.
2816 In a non-SIGIO world, this also checks whether the user has typed ^G,
2817 since this is a convenient place to do so. We don't need to do this
2818 in a SIGIO world, since input causes an interrupt.
2822 /* I don't think there's any point to this and it will nullify
2823 the speed gains achieved by the sigio_happened checking below.
2824 Its only advantage is that it may possibly make C-g response
2825 a bit faster. The C-g will be noticed within 0.25 second, anyway,
2826 even without this. */
2828 /* First check for C-g if necessary */
2833 /* This function used to simply check whether there were any X
2834 events (or if user_p was 1, it iterated over all the pending
2835 X events using XCheckIfEvent(), looking for keystrokes and
2836 button events). That worked in the old cheesoid event loop,
2837 which didn't go through XtAppDispatchEvent(), but it doesn't
2838 work any more -- X events may not result in anything. For
2839 example, a button press in a blank part of the menubar appears
2840 as an X event but will not result in any Emacs events (a
2841 button press that activates the menubar results in an Emacs
2842 event through the stop_next_event mechanism).
2844 The only accurate way of determining whether these X events
2845 translate into Emacs events is to go ahead and dispatch them
2846 until there's something on the dispatch queue. */
2848 /* See if there are any user events already on the queue. */
2849 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
2850 if (!user_p || command_event_p (event))
2853 /* See if there's any TTY input available.
2855 if (poll_fds_for_input (tty_only_mask))
2860 /* If not user_p and there are any timer or file-desc events
2861 pending, we know there will be an event so we're through. */
2862 XtInputMask pending_value;
2864 /* Note that formerly we just checked the value of XtAppPending()
2865 to determine if there was file-desc input. This doesn't
2866 work any more with the signal_event_pipe; XtAppPending()
2867 will says "yes" in this case but there isn't really any
2868 input. Another way of fixing this problem is for the
2869 signal_event_pipe to generate actual input in the form
2870 of an identity eval event or something. (#### maybe this
2871 actually happens?) */
2873 if (poll_fds_for_input (process_only_mask))
2876 pending_value = XtAppPending (Xt_app_con);
2878 if (pending_value & XtIMTimer)
2882 /* XtAppPending() can be super-slow, esp. over a network connection.
2883 Quantify results have indicated that in some cases the
2884 call to detect_input_pending() completely dominates the
2885 running time of redisplay(). Fortunately, in a SIGIO world
2886 we can more quickly determine whether there are any X events:
2887 if an event has happened since the last time we checked, then
2888 a SIGIO will have happened. On a machine with broken SIGIO,
2889 we'll still be in an OK state -- the sigio_happened flag
2890 will get set at least once a second, so we'll be no more than
2891 one second behind reality. (In general it's OK if we
2892 erroneously report no input pending when input is actually
2893 pending() -- preemption is just a bit less efficient, that's
2894 all. It's bad bad bad if you err the other way -- you've
2895 promised that `next-event' won't block but it actually will,
2896 and some action might get delayed until the next time you
2900 /* quit_check_signal_tick_count is volatile so try to avoid race conditions
2901 by using a temporary variable */
2902 tick_count_val = quit_check_signal_tick_count;
2903 if (last_quit_check_signal_tick_count != tick_count_val)
2905 last_quit_check_signal_tick_count = tick_count_val;
2907 /* We need to drain the entire queue now -- if we only
2908 drain part of it, we may later on end up with events
2909 actually pending but detect_input_pending() returning
2910 false because there wasn't another SIGIO. */
2913 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
2914 if (!user_p || command_event_p (event))
2922 /************************************************************************/
2923 /* replacement for standard string-to-pixel converter */
2924 /************************************************************************/
2926 /* This was constructed by ripping off the standard string-to-pixel
2927 converter from Converters.c in the Xt source code and modifying
2932 /* This is exported by the Xt library (at least by mine). If this
2933 isn't the case somewhere, rename this appropriately and remove
2934 the '#if 0'. Note, however, that I got "unknown structure"
2935 errors when I tried this. */
2936 XtConvertArgRec Const colorConvertArgs[] = {
2937 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
2938 sizeof (Screen *) },
2939 { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
2945 #define done(type, value) \
2946 if (toVal->addr != NULL) { \
2947 if (toVal->size < sizeof(type)) { \
2948 toVal->size = sizeof(type); \
2951 *(type*)(toVal->addr) = (value); \
2953 static type static_val; \
2954 static_val = (value); \
2955 toVal->addr = (XPointer)&static_val; \
2957 toVal->size = sizeof(type); \
2958 return True /* Caller supplies `;' */
2960 /* JH: We use this because I think there's a possibility this
2961 is called before the device is properly set up, in which case
2962 I don't want to abort. */
2963 extern struct device *get_device_from_display_1 (Display *dpy);
2966 Boolean EmacsXtCvtStringToPixel (
2970 XrmValuePtr fromVal,
2972 XtPointer *closure_ret)
2974 String str = (String)fromVal->addr;
2983 Cardinal num_params = 1;
2984 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
2986 if (*num_args != 2) {
2987 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToPixel",
2989 "String to pixel conversion needs screen and colormap arguments",
2990 (String *)NULL, (Cardinal *)NULL);
2994 screen = *((Screen **) args[0].addr);
2995 colormap = *((Colormap *) args[1].addr);
2997 /* The original uses the private function CompareISOLatin1().
2998 Use XmuCompareISOLatin1() if you want, but I don't think it
2999 makes any difference here. */
3000 if (strcmp(str, XtDefaultBackground) == 0) {
3001 *closure_ret = False;
3002 /* This refers to the display's "*reverseVideo" resource.
3003 These display resources aren't documented anywhere that
3004 I can find, so I'm going to ignore this. */
3005 /* if (pd->rv) done(Pixel, BlackPixelOfScreen(screen)) else */
3006 done(Pixel, WhitePixelOfScreen(screen));
3008 if (strcmp(str, XtDefaultForeground) == 0) {
3009 *closure_ret = False;
3010 /* if (pd->rv) done(Pixel, WhitePixelOfScreen(screen)) else */
3011 done(Pixel, BlackPixelOfScreen(screen));
3014 /* Originally called XAllocNamedColor() here. */
3015 if ((d = get_device_from_display_1(dpy))) {
3016 visual = DEVICE_X_VISUAL(d);
3017 if (colormap != DEVICE_X_COLORMAP(d)) {
3018 XtAppWarningMsg(the_app_con, "wierdColormap", "cvtStringToPixel",
3020 "The colormap passed to cvtStringToPixel doesn't match the one registerd to the device.\n",
3022 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3024 status = XParseColor (dpy, colormap, (char*)str, &screenColor);
3026 status = allocate_nearest_color (dpy, colormap, visual, &screenColor);
3030 /* We haven't set up this device totally yet, so just punt */
3031 status = XAllocNamedColor(dpy, colormap, (char*)str, &screenColor, &exactColor);
3035 /* Server returns a specific error code but Xlib discards it. Ugh */
3036 if (XLookupColor(DisplayOfScreen(screen), colormap, (char*) str,
3037 &exactColor, &screenColor)) {
3038 XtAppWarningMsg(the_app_con, "noColormap", "cvtStringToPixel",
3040 "Cannot allocate colormap entry for \"%s\"",
3041 params, &num_params);
3044 XtAppWarningMsg(the_app_con, "badValue", "cvtStringToPixel",
3046 "Color name \"%s\" is not defined", params, &num_params);
3049 *closure_ret = False;
3052 *closure_ret = (char*)True;
3053 done(Pixel, screenColor.pixel);
3058 static void EmacsFreePixel (
3065 if (*num_args != 2) {
3066 XtAppWarningMsg(app, "wrongParameters","freePixel","XtToolkitError",
3067 "Freeing a pixel requires screen and colormap arguments",
3068 (String *)NULL, (Cardinal *)NULL);
3073 Screen *screen = *((Screen **) args[0].addr);
3074 Colormap colormap = *((Colormap *) args[1].addr);
3075 XFreeColors(DisplayOfScreen(screen), colormap,
3076 (unsigned long*)toVal->addr, 1, (unsigned long)0);
3081 /************************************************************************/
3082 /* initialization */
3083 /************************************************************************/
3086 syms_of_event_Xt (void)
3088 defsymbol (&Qkey_mapping, "key-mapping");
3089 defsymbol (&Qsans_modifiers, "sans-modifiers");
3090 defsymbol (&Qself_insert_command, "self-insert-command");
3094 reinit_vars_of_event_Xt (void)
3096 Xt_event_stream = xnew (struct event_stream);
3097 Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
3098 Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending;
3099 Xt_event_stream->next_event_cb = emacs_Xt_next_event;
3100 Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event;
3101 Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout;
3102 Xt_event_stream->remove_timeout_cb = emacs_Xt_remove_timeout;
3103 Xt_event_stream->select_console_cb = emacs_Xt_select_console;
3104 Xt_event_stream->unselect_console_cb = emacs_Xt_unselect_console;
3105 Xt_event_stream->select_process_cb = emacs_Xt_select_process;
3106 Xt_event_stream->unselect_process_cb = emacs_Xt_unselect_process;
3107 Xt_event_stream->quit_p_cb = emacs_Xt_quit_p;
3108 Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
3109 Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
3111 the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
3113 last_quit_check_signal_tick_count = 0;
3115 /* this function only makes safe calls */
3116 init_what_input_once ();
3120 vars_of_event_Xt (void)
3122 reinit_vars_of_event_Xt ();
3124 dispatch_event_queue = Qnil;
3125 staticpro (&dispatch_event_queue);
3126 dispatch_event_queue_tail = Qnil;
3127 pdump_wire (&dispatch_event_queue_tail);
3129 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
3130 *Non-nil makes modifier keys sticky.
3131 This means that you can release the modifier key before pressing down
3132 the key that you wish to be modified. Although this is non-standard
3133 behavior, it is recommended because it reduces the strain on your hand,
3134 thus reducing the incidence of the dreaded Emacs-pinky syndrome.
3136 modifier_keys_are_sticky = 0;
3138 DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /*
3139 *Non-nil means to allow synthetic events. Nil means they are ignored.
3140 Beware: allowing emacs to process SendEvents opens a big security hole.
3142 x_allow_sendevents = 0;
3145 DEFVAR_INT ("x-debug-events", &x_debug_events /*
3146 If non-zero, display debug information about X events that XEmacs sees.
3147 Information is displayed on stderr. Currently defined values are:
3149 1 == non-verbose output
3156 /* This mess is a hack that patches the shell widget to treat visual inheritance
3157 the same as colormap and depth inheritance */
3159 static XtInitProc orig_shell_init_proc;
3161 static void ShellVisualPatch(Widget wanted, Widget new,
3162 ArgList args, Cardinal *num_args)
3165 ShellWidget w = (ShellWidget) new;
3167 /* first, call the original setup */
3168 (*orig_shell_init_proc)(wanted, new, args, num_args);
3170 /* if the visual isn't explicitly set, grab it from the nearest shell ancestor */
3171 if (w->shell.visual == CopyFromParent) {
3173 while (p && !XtIsShell(p)) p = XtParent(p);
3174 if (p) w->shell.visual = ((ShellWidget)p)->shell.visual;
3179 init_event_Xt_late (void) /* called when already initialized */
3181 timeout_id_tick = 1;
3182 pending_timeouts = 0;
3183 completed_timeouts = 0;
3185 event_stream = Xt_event_stream;
3187 #if defined(HAVE_XIM) || defined(USE_XFONTSET)
3188 Initialize_Locale();
3189 #endif /* HAVE_XIM || USE_XFONTSET */
3191 XtToolkitInitialize ();
3192 Xt_app_con = XtCreateApplicationContext ();
3193 XtAppSetFallbackResources (Xt_app_con, (String *) x_fallback_resources);
3196 x_selection_timeout = (XtAppGetSelectionTimeout (Xt_app_con) / 1000);
3197 XSetErrorHandler (x_error_handler);
3198 XSetIOErrorHandler (x_IO_error_handler);
3201 XtAppAddInput (Xt_app_con, signal_event_pipe[0],
3202 (XtPointer) (XtInputReadMask /* | XtInputExceptMask */),
3203 Xt_what_callback, 0);
3206 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRPixel,
3207 EmacsXtCvtStringToPixel,
3208 (XtConvertArgList) colorConvertArgs,
3209 2, XtCacheByDisplay, EmacsFreePixel);
3212 XtAppSetTypeConverter (Xt_app_con, XtRString, XtRXimStyles,
3213 EmacsXtCvtStringToXIMStyles,
3215 XtCacheByDisplay, EmacsFreeXIMStyles);
3216 #endif /* XIM_XLIB */
3218 /* insert the visual inheritance patch/hack described above */
3219 orig_shell_init_proc = shellClassRec.core_class.initialize;
3220 shellClassRec.core_class.initialize = ShellVisualPatch;