# HG changeset patch # User Jim Blandy # Date 717854271 0 # Node ID 74ae34a80f94d5c4163b56b3d224d3aee750a0a7 # Parent 0a0646ae381f6ccdb6a556c301666146d440d70a * xterm.c (x_meta_mod_mask): New variable, indicating which X modifier bits denote meta keys. (x_find_modifier_meanings): New function, to set x_meta_mod_mask. (x_convert_modifiers): Use that. (x_term_init): Call x_find_modifier_meanings. * xterm.c (XTread_socket): Pass PropertyNotify events from the root window to x_invalidate_cut_buffer_cache. (x_term_init): Call x_watch_cut_buffer_cache here. diff -r 0a0646ae381f -r 74ae34a80f94 src/xterm.c --- a/src/xterm.c Wed Sep 30 11:35:45 1992 +0000 +++ b/src/xterm.c Wed Sep 30 11:57:51 1992 +0000 @@ -1428,6 +1428,75 @@ /* Any buttons grabbed. */ unsigned int x_mouse_grabbed; +/* Which modifier keys are on which modifier bits? + + With each keystroke, X returns eight bits indicating which modifier + keys were held down when the key was pressed. The low three bits + indicate the state of the shift, shift lock, caps lock, and control + keys; their interpretation is fixed. However, the interpretation + of the other five modifier bits depends on what keys are attached + to them. If the Meta_L and Meta_R keysyms are on mod5, then mod5 + is the meta bit. + + x_meta_mod_mask is a mask containing the bits used for the meta key. + It may have more than one bit set, if more than one modifier bit + has meta keys on it. Basically, if EVENT is a KeyPress event, + the meta key is pressed if (EVENT.state & x_meta_mod_mask) != 0. */ +static int x_meta_mod_mask; + +/* Initialize mode_switch_bit and modifier_meaning. */ +static void +x_find_modifier_meanings () +{ + KeyCode min_code, max_code; + KeySym *syms; + int syms_per_code; + XModifierKeymap *mods; + + x_meta_mod_mask = 0; + + XDisplayKeycodes (x_current_display, &min_code, &max_code); + syms = XGetKeyboardMapping (x_current_display, + min_code, max_code - min_code + 1, + &syms_per_code); + mods = XGetModifierMapping (x_current_display); + + /* If CapsLock is on the lock modifier, then only letters should be + affected; since XLookupString takes care of this for us, the lock + modifier shouldn't set shift_modifier. However, if ShiftLock is + on the lock modifier, then lock should mean shift. */ + { + int row, col; /* The row and column in the modifier table. */ + + for (row = 3; row < 8; row++) + for (col = 0; col < mods->max_keypermod; col++) + { + KeyCode code = + mods->modifiermap[(row * mods->max_keypermod) + col]; + + /* Are any of this keycode's keysyms a meta key? */ + { + int code_col; + + for (code_col = 0; code_col < syms_per_code; code_col++) + { + int sym = syms[(code * syms_per_code) + code_col]; + + if (sym == XK_Meta_L || sym == XK_Meta_R) + { + x_meta_mod_mask |= (1 << row); + break; + } + } + } + } + } + + XFree ((char *) syms); + XFreeModifierMap (mods); +} + + /* Convert a set of X modifier bits to the proper form for a struct input_event modifiers value. */ @@ -1437,7 +1506,7 @@ { return ( ((state & (ShiftMask | LockMask)) ? shift_modifier : 0) | ((state & ControlMask) ? ctrl_modifier : 0) - | ((state & Mod1Mask) ? meta_modifier : 0)); + | ((state & x_meta_mod_mask) ? meta_modifier : 0)); } extern struct frame *x_window_to_scrollbar (); @@ -1802,9 +1871,20 @@ break; case PropertyNotify: - /* If we were to do this synchronously, there'd be no worry - about re-selecting. */ - x_send_incremental (event); + + /* If we're being told about a root window property, then it's + a cut buffer change. */ + if (event.xproperty.window == ROOT_WINDOW) + x_invalidate_cut_buffer_cache (&event.xproperty); + + /* Otherwise, we're probably handling an incremental + selection transmission. */ + else + { + /* If we were to do this synchronously, there'd be no worry + about re-selecting. */ + x_send_incremental (event); + } break; case Expose: @@ -3665,7 +3745,14 @@ + 2); sprintf (x_id_name, "%s@%s", XSTRING (invocation_name)->data, hostname); } + + /* Figure out which modifier bits mean what. */ + x_find_modifier_meanings (); + /* Watch for PropertyNotify events on the root window; we use them + to figure out when to invalidate our cache of the cut buffers. */ + x_watch_cut_buffer_cache (); + dup2 (ConnectionNumber (x_current_display), 0); #ifndef SYSV_STREAMS