Mercurial > hg > xemacs-beta
diff src/event-Xt.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 41dbb7a9d5f2 |
line wrap: on
line diff
--- a/src/event-Xt.c Mon Aug 13 11:19:22 2007 +0200 +++ b/src/event-Xt.c Mon Aug 13 11:20:41 2007 +0200 @@ -65,9 +65,19 @@ #include "offix.h" #endif +#ifdef WINDOWSNT +/* Hmm, under unix we want X modifiers, under NT we want X modifiers if + we are running X and Windows modifiers otherwise. + gak. This is a kludge until we support multiple native GUIs! +*/ +#undef MOD_ALT +#undef MOD_CONTROL +#undef MOD_SHIFT +#endif + #include "events-mod.h" -static void handle_focus_event_1 (struct frame *f, int in_p); +static void enqueue_Xt_dispatch_event (Lisp_Object event); static struct event_stream *Xt_event_stream; @@ -86,6 +96,8 @@ /* Do we accept events sent by other clients? */ int x_allow_sendevents; +int modifier_keys_are_sticky; + #ifdef DEBUG_XEMACS int x_debug_events; #endif @@ -96,7 +108,7 @@ /* Mask of bits indicating the descriptors that we wait for input on */ extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask; -static const String x_fallback_resources[] = +static CONST String x_fallback_resources[] = { /* This file is automatically generated from the app-defaults file in ../etc/Emacs.ad. These resources are consulted only if no @@ -108,7 +120,7 @@ static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p); void emacs_Xt_mapping_action (Widget w, XEvent *event); -void debug_process_finalization (Lisp_Process *p); +void debug_process_finalization (struct Lisp_Process *p); void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch); @@ -162,204 +174,6 @@ use a pop-up-window instead.) */ -/* For every key on the keyboard that has a known character correspondence, - we define the ascii-character property of the keysym, and make the - default binding for the key be self-insert-command. - - The following magic is basically intimate knowledge of X11/keysymdef.h. - The keysym mappings defined by X11 are based on the iso8859 standards, - except for Cyrillic and Greek. - - In a non-Mule world, a user can still have a multi-lingual editor, by doing - (set-face-font "...-iso8859-2" (current-buffer)) - for all their Latin-2 buffers, etc. */ - -static Lisp_Object -x_keysym_to_character (KeySym keysym) -{ -#ifdef MULE - Lisp_Object charset = Qzero; -#define USE_CHARSET(var,cs) \ - ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs)) -#else -#define USE_CHARSET(var,lb) -#endif /* MULE */ - int code = 0; - - if ((keysym & 0xff) < 0xa0) - return Qnil; - - switch (keysym >> 8) - { - case 0: /* ASCII + Latin1 */ - USE_CHARSET (charset, LATIN_ISO8859_1); - code = keysym & 0x7f; - break; - case 1: /* Latin2 */ - USE_CHARSET (charset, LATIN_ISO8859_2); - code = keysym & 0x7f; - break; - case 2: /* Latin3 */ - USE_CHARSET (charset, LATIN_ISO8859_3); - code = keysym & 0x7f; - break; - case 3: /* Latin4 */ - USE_CHARSET (charset, LATIN_ISO8859_4); - code = keysym & 0x7f; - break; - case 4: /* Katakana */ - USE_CHARSET (charset, KATAKANA_JISX0201); - if ((keysym & 0xff) > 0xa0) - code = keysym & 0x7f; - break; - case 5: /* Arabic */ - USE_CHARSET (charset, ARABIC_ISO8859_6); - code = keysym & 0x7f; - break; - case 6: /* Cyrillic */ - { - static unsigned char const cyrillic[] = /* 0x20 - 0x7f */ - {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f, - 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f, - 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53, - 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, - 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52, - 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a, - 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33, - 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32, - 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a}; - USE_CHARSET (charset, CYRILLIC_ISO8859_5); - code = cyrillic[(keysym & 0x7f) - 0x20]; - break; - } - case 7: /* Greek */ - { - static unsigned char const greek[] = /* 0x20 - 0x7f */ - {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c, - 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f, - 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c, - 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - USE_CHARSET (charset, GREEK_ISO8859_7); - code = greek[(keysym & 0x7f) - 0x20]; - break; - } - case 8: /* Technical */ - break; - case 9: /* Special */ - break; - case 10: /* Publishing */ - break; - case 11: /* APL */ - break; - case 12: /* Hebrew */ - USE_CHARSET (charset, HEBREW_ISO8859_8); - code = keysym & 0x7f; - break; - case 13: /* Thai */ - /* #### This needs to deal with character composition. */ - USE_CHARSET (charset, THAI_TIS620); - code = keysym & 0x7f; - break; - case 14: /* Korean Hangul */ - break; - case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */ - break; - case 32: /* Currency */ - break; - default: - break; - } - - if (code == 0) - return Qnil; - -#ifdef MULE - return make_char (MAKE_CHAR (charset, code, 0)); -#else - return make_char (code + 0x80); -#endif -} - -/* #### The way that keysym correspondence to characters should work: - - a Lisp_Event should contain a keysym AND a character slot. - - keybindings are tried with the keysym. If no binding can be found, - and there is a corresponding character, call self-insert-command. - - #### Nuke x-iso8859-1.el. - #### Nuke the Qascii_character property. - #### Nuke Vcharacter_set_property. -*/ -static void -maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol) -{ - Lisp_Object character = x_keysym_to_character (keysym); - - if (CHARP (character)) - { - extern Lisp_Object Vcurrent_global_map; - extern Lisp_Object Qascii_character; - Fput (symbol, Qascii_character, character); - if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil))) - Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command); - } -} - -static void -x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers) -{ - KeySym upper_lower[2]; - int j; - - if (keysym < 0x80) /* Optimize for ASCII keysyms */ - return; - - /* If you execute: - xmodmap -e 'keysym NN = scaron' - and then press (Shift scaron), X11 will return the different - keysym `Scaron', but `xmodmap -pke' might not even mention `Scaron'. - So we "register" both `scaron' and `Scaron'. */ -#ifdef HAVE_XCONVERTCASE - XConvertCase (keysym, &upper_lower[0], &upper_lower[1]); -#else - upper_lower[0] = upper_lower[1] = keysym; -#endif - - for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++) - { - char *name; - keysym = upper_lower[j]; - - name = XKeysymToString (keysym); - if (name) - { - /* X guarantees NAME to be in the Host Portable Character Encoding */ - Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0); - Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers; - Lisp_Object old_value = Fgethash (sym, hash_table, Qnil); - - if (! EQ (old_value, new_value) - && ! (EQ (old_value, Qsans_modifiers) && - EQ (new_value, Qt))) - { - maybe_define_x_key_as_self_inserting_character (keysym, sym); - Fputhash (build_ext_string (name, Qbinary), new_value, hash_table); - Fputhash (sym, new_value, hash_table); - } - } - } -} - static void x_reset_key_mapping (struct device *d) { @@ -397,18 +211,34 @@ if (keysym[0] == NoSymbol) continue; - x_has_keysym (keysym[0], hash_table, 0); + { + char *name = XKeysymToString (keysym[0]); + Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[0], 0); + if (name) + { + Fputhash (build_string (name), Qsans_modifiers, hash_table); + Fputhash (sym, Qsans_modifiers, hash_table); + } + } for (j = 1; j < keysyms_per_code; j++) { if (keysym[j] != keysym[0] && keysym[j] != NoSymbol) - x_has_keysym (keysym[j], hash_table, 1); + { + char *name = XKeysymToString (keysym[j]); + Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[j], 0); + if (name && NILP (Fgethash (sym, hash_table, Qnil))) + { + Fputhash (build_string (name), Qt, hash_table); + Fputhash (sym, Qt, hash_table); + } + } } } } -static const char * +static CONST char * index_to_name (int indice) { switch (indice) @@ -563,7 +393,7 @@ be totally wrong. */ if (mode_bit) { - const char *warn = 0; + CONST char *warn = 0; if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; else if (mode_bit == super_bit) warn = "Super", super_bit = 0; @@ -977,8 +807,7 @@ len = XmImMbLookupString (XtWindowToWidget (event->display, event->window), event, bufptr, bufsiz, &keysym, &status); #else /* XIM_XLIB */ - if (xic) - len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status); + len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status); #endif /* HAVE_XIM */ #ifdef DEBUG_XEMACS @@ -1029,9 +858,10 @@ Lstream *istr; struct gcpro gcpro1, gcpro2; - fb_instream = make_fixed_buffer_input_stream (bufptr, len); - - /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */ + fb_instream = + make_fixed_buffer_input_stream ((unsigned char *) bufptr, len); + + /* ### Use Fget_coding_system (Vcomposed_input_coding_system) */ instream = make_decoding_input_stream (XLSTREAM (fb_instream), Fget_coding_system (Qundecided)); @@ -1042,7 +872,7 @@ while ((ch = Lstream_get_emchar (istr)) != EOF) { Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - Lisp_Event *ev = XEVENT (emacs_event); + struct Lisp_Event *ev = XEVENT (emacs_event); ev->channel = DEVICE_CONSOLE (d); ev->event_type = key_press_event; ev->timestamp = event->time; @@ -1089,7 +919,7 @@ } static int -x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event) +x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event) { Display *display = x_event->xany.display; struct device *d = get_device_from_display (display); @@ -1111,7 +941,7 @@ case ButtonPress: case ButtonRelease: { - int modifiers = 0; + unsigned int modifiers = 0; int shift_p, lock_p; Bool key_event_p = (x_event->type == KeyPress); unsigned int *state = @@ -1138,11 +968,11 @@ x_handle_sticky_modifiers (x_event, d); - if (*state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; - if (*state & xd->MetaMask) modifiers |= XEMACS_MOD_META; - if (*state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; - if (*state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; - if (*state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; + if (*state & ControlMask) modifiers |= MOD_CONTROL; + if (*state & xd->MetaMask) modifiers |= MOD_META; + if (*state & xd->SuperMask) modifiers |= MOD_SUPER; + if (*state & xd->HyperMask) modifiers |= MOD_HYPER; + if (*state & xd->AltMask) modifiers |= MOD_ALT; /* Ignore the Caps_Lock key if: - any other modifiers are down, so that Caps_Lock doesn't @@ -1155,7 +985,7 @@ lock_p = *state & LockMask; if (shift_p || lock_p) - modifiers |= XEMACS_MOD_SHIFT; + modifiers |= MOD_SHIFT; if (key_event_p) { @@ -1187,7 +1017,7 @@ ! (CHAR_OR_CHAR_INTP (keysym) && keysym_obeys_caps_lock_p ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) - modifiers &= (~XEMACS_MOD_SHIFT); + modifiers &= (~MOD_SHIFT); /* If this key contains two distinct keysyms, that is, "shift" generates a different keysym than the @@ -1199,13 +1029,13 @@ in the modifiers slot. Neither the characters "a", "A", "2", nor "@" normally have the shift bit set. However, "F1" normally does. */ - if (modifiers & XEMACS_MOD_SHIFT) + if (modifiers & MOD_SHIFT) { int Mode_switch_p = *state & xd->ModeMask; KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); if (top && bot && top != bot) - modifiers &= ~XEMACS_MOD_SHIFT; + modifiers &= ~MOD_SHIFT; } emacs_event->event_type = key_press_event; emacs_event->timestamp = ev->time; @@ -1216,7 +1046,6 @@ { XButtonEvent *ev = &x_event->xbutton; struct frame *frame = x_window_to_frame (d, ev->window); - if (! frame) return 0; /* not for us */ XSETFRAME (emacs_event->channel, frame); @@ -1229,11 +1058,7 @@ emacs_event->event.button.button = ev->button; emacs_event->event.button.x = ev->x; emacs_event->event.button.y = ev->y; - /* because we don't seem to get a FocusIn event for button clicks - when a widget-glyph is selected we will assume that we want the - focus if a button gets pressed. */ - if (x_event->type == ButtonPress) - handle_focus_event_1 (frame, 1); + } } break; @@ -1242,7 +1067,7 @@ { XMotionEvent *ev = &x_event->xmotion; struct frame *frame = x_window_to_frame (d, ev->window); - int modifiers = 0; + unsigned int modifiers = 0; XMotionEvent event2; if (! frame) @@ -1271,12 +1096,12 @@ emacs_event->timestamp = ev->time; emacs_event->event.motion.x = ev->x; emacs_event->event.motion.y = ev->y; - if (ev->state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; - if (ev->state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; - if (ev->state & xd->MetaMask) modifiers |= XEMACS_MOD_META; - if (ev->state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; - if (ev->state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; - if (ev->state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; + if (ev->state & ShiftMask) modifiers |= MOD_SHIFT; + if (ev->state & ControlMask) modifiers |= MOD_CONTROL; + if (ev->state & xd->MetaMask) modifiers |= MOD_META; + if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER; + if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER; + if (ev->state & xd->AltMask) modifiers |= MOD_ALT; /* Currently ignores Shift_Lock but probably shouldn't (but it definitely should ignore Caps_Lock). */ emacs_event->event.motion.modifiers = modifiers; @@ -1292,9 +1117,7 @@ #ifdef HAVE_OFFIX_DND if (DndIsDropMessage(x_event)) { - unsigned int state; - int modifiers = 0; - unsigned int button=0; + unsigned int state, modifiers = 0, button=0; struct frame *frame = x_any_window_to_frame (d, ev->window); Extbyte *data; unsigned long size, dtype; @@ -1313,12 +1136,12 @@ state=DndDragButtons(x_event); - if (state & ShiftMask) modifiers |= XEMACS_MOD_SHIFT; - if (state & ControlMask) modifiers |= XEMACS_MOD_CONTROL; - if (state & xd->MetaMask) modifiers |= XEMACS_MOD_META; - if (state & xd->SuperMask) modifiers |= XEMACS_MOD_SUPER; - if (state & xd->HyperMask) modifiers |= XEMACS_MOD_HYPER; - if (state & xd->AltMask) modifiers |= XEMACS_MOD_ALT; + if (state & ShiftMask) modifiers |= MOD_SHIFT; + if (state & ControlMask) modifiers |= MOD_CONTROL; + if (state & xd->MetaMask) modifiers |= MOD_META; + if (state & xd->SuperMask) modifiers |= MOD_SUPER; + if (state & xd->HyperMask) modifiers |= MOD_HYPER; + if (state & xd->AltMask) modifiers |= MOD_ALT; if (state & Button5Mask) button = Button5; if (state & Button4Mask) button = Button4; @@ -1361,7 +1184,7 @@ make_string ((Bufbyte *)"8bit", 4), make_ext_string ((Extbyte *)data, strlen((char *)data), - Qctext) ) ); + FORMAT_CTEXT) ) ); break; case DndMIME: /* we have to parse this in some way to extract @@ -1374,7 +1197,7 @@ l_type = Qdragdrop_MIME; l_dndlist = list1 ( make_ext_string ((Extbyte *)data, strlen((char *)data), - Qbinary) ); + FORMAT_BINARY) ); break; case DndFile: case DndDir: @@ -1395,7 +1218,7 @@ and escaping again will break them (cause % is unsave) */ l_dndlist = list1 ( make_ext_string ((Extbyte *)data, strlen ((char *)data), - Qfile_name) ); + FORMAT_FILENAME) ); l_type = Qdragdrop_URL; break; default: /* Unknown, RawData and any other type */ @@ -1403,7 +1226,7 @@ make_string ((Bufbyte *)"8bit", 4), make_ext_string ((Extbyte *)data, size, - Qbinary) ) ); + FORMAT_BINARY) ) ); l_type = Qdragdrop_MIME; break; } @@ -1452,7 +1275,6 @@ case FocusIn: case FocusOut: FROB(xfocus, window); break; case VisibilityNotify: FROB(xvisibility, window); break; - case CreateNotify: FROB(xcreatewindow, window); break; default: w = x_event->xany.window; *x_event_copy = *x_event; @@ -1482,12 +1304,10 @@ static void handle_focus_event_1 (struct frame *f, int in_p) { -#if XtSpecificationRelease > 5 - Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f)); -#endif #ifdef HAVE_XIM XIM_focus_event (f, in_p); #endif /* HAVE_XIM */ + /* On focus change, clear all memory of sticky modifiers to avoid non-intuitive behavior. */ clear_sticky_modifiers (XDEVICE (FRAME_DEVICE (f))); @@ -1499,26 +1319,7 @@ Actually, we half handle it: we handle it as far as changing the box cursor for redisplay, but we don't call any hooks or do any select-frame stuff until after the sit-for. - - Unfortunately native widgets break the model because they grab - the keyboard focus and nothing sets it back again. I cannot find - any reasonable way to do this elsewhere so we assert here that - the keyboard focus is on the emacs text widget. Menus and dialogs - do this in their selection callback, but we don't want that since - a button having focus is legitimate. An edit field having focus - is mandatory. Weirdly you get a FocusOut event when you click in - a widget-glyph but you don't get a correspondng FocusIn when you - click in the frame. Why is this? */ - if (in_p -#if XtSpecificationRelease > 5 - && FRAME_X_TEXT_WIDGET (f) != focus_widget -#endif - ) - { - lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f), - FRAME_X_TEXT_WIDGET (f)); - } - /* do the generic event-stream stuff. */ + */ { Lisp_Object frm; Lisp_Object conser; @@ -1603,7 +1404,7 @@ /* Bleagh!!!!!! Apparently some window managers (e.g. MWM) send synthetic MapNotify events when a window is first - created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE. + created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE. Or something like that. We initially tried a different solution below, but that ran into a different window- manager bug. @@ -1711,26 +1512,7 @@ } static void -emacs_Xt_force_event_pending (struct frame* f) -{ - XEvent event; - - Display* dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f))); - event.xclient.type = ClientMessage; - event.xclient.display = dpy; - event.xclient.message_type = XInternAtom (dpy, "BumpQueue", False); - event.xclient.format = 32; - event.xclient.window = 0; - - /* Send the drop message */ - XSendEvent(dpy, XtWindow (FRAME_X_SHELL_WIDGET (f)), - True, NoEventMask, &event); - /* Force event pending to check the X queue. */ - quit_check_signal_tick_count++; -} - -static void -emacs_Xt_handle_magic_event (Lisp_Event *emacs_event) +emacs_Xt_handle_magic_event (struct Lisp_Event *emacs_event) { /* This function can GC */ XEvent *event = &emacs_event->event.magic.underlying_x_event; @@ -1758,13 +1540,8 @@ break; case Expose: - if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height) - && - !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height)) - x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); + x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); break; case GraphicsExpose: /* This occurs when an XCopyArea's source area was @@ -1802,7 +1579,6 @@ case FocusIn: case FocusOut: - #ifdef EXTERNAL_WIDGET /* External widget lossage: Ben said: YUCK. The only way to make focus changes work properly is to @@ -1842,9 +1618,6 @@ #endif break; - case CreateNotify: - break; - default: break; } @@ -1860,14 +1633,14 @@ /* Xt interval id's might not fit into an int (they're pointers, as it happens), so we need to provide a conversion list. */ -static struct Xt_timeout +struct Xt_timeout { int id; XtIntervalId interval_id; struct Xt_timeout *next; } *pending_timeouts, *completed_timeouts; -static struct Xt_timeout_blocktype +struct Xt_timeout_blocktype { Blocktype_declare (struct Xt_timeout); } *the_Xt_timeout_blocktype; @@ -1974,7 +1747,7 @@ } static void -Xt_timeout_to_emacs_event (Lisp_Event *emacs_event) +Xt_timeout_to_emacs_event (struct Lisp_Event *emacs_event) { struct Xt_timeout *timeout = completed_timeouts; assert (timeout); @@ -2141,7 +1914,7 @@ } static void -emacs_Xt_select_process (Lisp_Process *p) +emacs_Xt_select_process (struct Lisp_Process *p) { Lisp_Object process; int infd = event_stream_unixoid_select_process (p); @@ -2151,7 +1924,7 @@ } static void -emacs_Xt_unselect_process (Lisp_Process *p) +emacs_Xt_unselect_process (struct Lisp_Process *p) { int infd = event_stream_unixoid_unselect_process (p); @@ -2180,7 +1953,7 @@ If we've still got pointers to it in this file, we're gonna lose hard. */ void -debug_process_finalization (Lisp_Process *p) +debug_process_finalization (struct Lisp_Process *p) { #if 0 /* #### */ int i; @@ -2200,27 +1973,25 @@ } static void -Xt_process_to_emacs_event (Lisp_Event *emacs_event) +Xt_process_to_emacs_event (struct Lisp_Event *emacs_event) { int i; + Lisp_Object process; assert (process_events_occurred > 0); - for (i = 0; i < MAXDESC; i++) { - Lisp_Object process = filedesc_with_input[i]; + process = filedesc_with_input[i]; if (PROCESSP (process)) - { - filedesc_with_input[i] = Qnil; - process_events_occurred--; - /* process events have nil as channel */ - emacs_event->event_type = process_event; - emacs_event->timestamp = 0; /* #### */ - emacs_event->event.process.process = process; - return; - } + break; } - abort (); + assert (i < MAXDESC); + filedesc_with_input[i] = Qnil; + process_events_occurred--; + /* process events have nil as channel */ + emacs_event->event_type = process_event; + emacs_event->timestamp = 0; /* #### */ + emacs_event->event.process.process = process; } static void @@ -2228,6 +1999,9 @@ { Lisp_Object console; int infd; +#ifdef HAVE_GPM + int mousefd; +#endif if (CONSOLE_X_P (con)) return; /* X consoles are automatically selected for when we @@ -2235,6 +2009,22 @@ infd = event_stream_unixoid_select_console (con); XSETCONSOLE (console, con); select_filedesc (infd, console); +#ifdef HAVE_GPM + /* On a stream device (ie: noninteractive), bad things can happen. */ + if (EQ (CONSOLE_TYPE (con), Qtty)) { + mousefd = CONSOLE_TTY_MOUSE_FD (con); + /* We check filedesc_to_what_closure[fd] here because if you run + ** XEmacs from a TTY, it will fire up GPM, select the mouse fd, then + ** if you run gnuattach to connect to another TTY, it will fire up + ** GPM again, and try to reselect the mouse fd. GPM uses the same + ** fd for every connection apparently, and select_filedesc will + ** fail its assertion if we try to select it twice. + */ + if ((mousefd >= 0) && !filedesc_to_what_closure[mousefd]) { + select_filedesc (mousefd, console); + } + } +#endif } static void @@ -2242,6 +2032,9 @@ { Lisp_Object console; int infd; +#ifdef HAVE_GPM + int mousefd; +#endif if (CONSOLE_X_P (con)) return; /* X consoles are automatically selected for when we @@ -2249,6 +2042,15 @@ infd = event_stream_unixoid_unselect_console (con); XSETCONSOLE (console, con); unselect_filedesc (infd); +#ifdef HAVE_GPM + /* On a stream device (ie: noninteractive), bad things can happen. */ + if (EQ (CONSOLE_TYPE (con), Qtty)) { + mousefd = CONSOLE_TTY_MOUSE_FD (con); + if (mousefd >= 0) { + unselect_filedesc (mousefd); + } + } +#endif } /* read an event from a tty, if one is available. Returns non-zero @@ -2260,7 +2062,7 @@ to be deleted.) */ static int -Xt_tty_to_emacs_event (Lisp_Event *emacs_event) +Xt_tty_to_emacs_event (struct Lisp_Event *emacs_event) { int i; @@ -2306,12 +2108,12 @@ char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4); sprintf (buf, " \"%s\"", XSTRING_DATA (f->name)); write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0, - strlen (buf), Qterminal, 1); + strlen (buf), FORMAT_TERMINAL); } stderr_out ("\n"); } -static const char * +static CONST char * XEvent_mode_to_string (int mode) { switch (mode) @@ -2324,7 +2126,7 @@ } } -static const char * +static CONST char * XEvent_detail_to_string (int detail) { switch (detail) @@ -2340,7 +2142,7 @@ } } -static const char * +static CONST char * XEvent_visibility_to_string (int state) { switch (state) @@ -2509,7 +2311,7 @@ static Lisp_Object dispatch_event_queue, dispatch_event_queue_tail; -void +static void enqueue_Xt_dispatch_event (Lisp_Object event) { enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); @@ -2545,7 +2347,7 @@ } static void -emacs_Xt_next_event (Lisp_Event *emacs_event) +emacs_Xt_next_event (struct Lisp_Event *emacs_event) { we_didnt_get_an_event: @@ -2930,10 +2732,10 @@ the '#if 0'. Note, however, that I got "unknown structure" errors when I tried this. */ XtConvertArgRec Const colorConvertArgs[] = { - { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), - sizeof (Screen *) }, - { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), - sizeof (Colormap) } + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *)}, + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), + sizeof(Colormap)} }; #endif @@ -3075,42 +2877,6 @@ /************************************************************************/ -/* handle focus changes for native widgets */ -/************************************************************************/ -static void -emacs_Xt_event_widget_focus_in (Widget w, - XEvent *event, - String *params, - Cardinal *num_params) -{ - struct frame* f = - x_any_widget_or_parent_to_frame (get_device_from_display (event->xany.display), w); - - XtSetKeyboardFocus (FRAME_X_SHELL_WIDGET (f), w); -} - -static void -emacs_Xt_event_widget_focus_out (Widget w, - XEvent *event, - String *params, - Cardinal *num_params) -{ -} - -static XtActionsRec widgetActionsList[] = -{ - {"widget-focus-in", emacs_Xt_event_widget_focus_in }, - {"widget-focus-out", emacs_Xt_event_widget_focus_out }, -}; - -static void -emacs_Xt_event_add_widget_actions (XtAppContext ctx) -{ - XtAppAddActions (ctx, widgetActionsList, 2); -} - - -/************************************************************************/ /* initialization */ /************************************************************************/ @@ -3119,15 +2885,20 @@ { defsymbol (&Qkey_mapping, "key-mapping"); defsymbol (&Qsans_modifiers, "sans-modifiers"); - defsymbol (&Qself_insert_command, "self-insert-command"); } void -reinit_vars_of_event_Xt (void) +vars_of_event_Xt (void) { + dispatch_event_queue = Qnil; + staticpro (&dispatch_event_queue); + dispatch_event_queue_tail = Qnil; + + /* this function only makes safe calls */ + init_what_input_once (); + Xt_event_stream = xnew (struct event_stream); Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p; - Xt_event_stream->force_event_pending = emacs_Xt_force_event_pending; Xt_event_stream->next_event_cb = emacs_Xt_next_event; Xt_event_stream->handle_magic_event_cb = emacs_Xt_handle_magic_event; Xt_event_stream->add_timeout_cb = emacs_Xt_add_timeout; @@ -3140,23 +2911,14 @@ Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair; Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair; - the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype); - - last_quit_check_signal_tick_count = 0; - - /* this function only makes safe calls */ - init_what_input_once (); -} - -void -vars_of_event_Xt (void) -{ - reinit_vars_of_event_Xt (); - - dispatch_event_queue = Qnil; - staticpro (&dispatch_event_queue); - dispatch_event_queue_tail = Qnil; - pdump_wire (&dispatch_event_queue_tail); + DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /* +*Non-nil makes modifier keys sticky. +This means that you can release the modifier key before pressing down +the key that you wish to be modified. Although this is non-standard +behavior, it is recommended because it reduces the strain on your hand, +thus reducing the incidence of the dreaded Emacs-pinky syndrome. +*/ ); + modifier_keys_are_sticky = 0; DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents /* *Non-nil means to allow synthetic events. Nil means they are ignored. @@ -3174,6 +2936,10 @@ */ ); x_debug_events = 0; #endif + + the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype); + + last_quit_check_signal_tick_count = 0; } /* This mess is a hack that patches the shell widget to treat visual inheritance @@ -3220,7 +2986,7 @@ XSetErrorHandler (x_error_handler); XSetIOErrorHandler (x_IO_error_handler); -#ifndef WIN32_NATIVE +#ifndef WINDOWSNT XtAppAddInput (Xt_app_con, signal_event_pipe[0], (XtPointer) (XtInputReadMask /* | XtInputExceptMask */), Xt_what_callback, 0); @@ -3237,8 +3003,6 @@ NULL, 0, XtCacheByDisplay, EmacsFreeXIMStyles); #endif /* XIM_XLIB */ - /* Add extra actions to native widgets to handle focus and friends. */ - emacs_Xt_event_add_widget_actions (Xt_app_con); /* insert the visual inheritance patch/hack described above */ orig_shell_init_proc = shellClassRec.core_class.initialize;