From: Yuuki Harano Date: Tue, 9 Jul 2019 17:32:35 +0000 (+0900) Subject: Implement Meta key detection X-Git-Tag: emacs-29.0.90~3838 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=519a4ac39f7cd9e2339b203463704db48752bc5b;p=emacs.git Implement Meta key detection * ../src/pgtkterm.c (x_find_modifier_meanings, ) (key_press_event, construct_mouse_click, scroll_event) (pgtk_term_init): * src/pgtkterm.h (struct pgtk_display_info): * ../src/gtkutil.c (xg_tool_bar_callback): meta キーの検出を実装。 X11 で alt キーを meta キーとして使えなくなっていたのを修正。 --- diff --git a/src/gtkutil.c b/src/gtkutil.c index 9655c8dfc12..2da6beb2ca5 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -4693,7 +4693,7 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data) #ifndef HAVE_PGTK event.modifiers = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), mod); #else - event.modifiers = pgtk_gtk_to_emacs_modifiers (mod); + event.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), mod); #endif kbd_buffer_store_event (&event); diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 2e98dedbc75..5890326430f 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -4895,64 +4895,100 @@ static void size_allocate(GtkWidget *widget, GtkAllocation *alloc, gpointer *use } } -int -pgtk_gtk_to_emacs_modifiers (int state) +static void +x_find_modifier_meanings (struct pgtk_display_info *dpyinfo) +{ + GdkDisplay *gdpy = dpyinfo->gdpy; + GdkKeymap *keymap = gdk_keymap_get_for_display (gdpy); + GdkModifierType state = GDK_META_MASK; + gboolean r = gdk_keymap_map_virtual_modifiers (keymap, &state); + if (r) { + /* Meta key exists. */ + if (state == GDK_META_MASK) { + dpyinfo->meta_mod_mask = GDK_MOD1_MASK; /* maybe this is meta. */ + dpyinfo->alt_mod_mask = 0; + } else { + dpyinfo->meta_mod_mask = state & ~GDK_META_MASK; + if (dpyinfo->meta_mod_mask == GDK_MOD1_MASK) + dpyinfo->alt_mod_mask = 0; + else + dpyinfo->alt_mod_mask = GDK_MOD1_MASK; + } + } else { + dpyinfo->meta_mod_mask = GDK_MOD1_MASK; + dpyinfo->alt_mod_mask = 0; + } +} + +static void get_modifier_values( + int *mod_ctrl, + int *mod_meta, + int *mod_alt, + int *mod_hyper, + int *mod_super) { - int mod_ctrl = ctrl_modifier; - int mod_meta = meta_modifier; - int mod_alt = alt_modifier; - int mod_hyper = hyper_modifier; - int mod_super = super_modifier; Lisp_Object tem; + *mod_ctrl = ctrl_modifier; + *mod_meta = meta_modifier; + *mod_alt = alt_modifier; + *mod_hyper = hyper_modifier; + *mod_super = super_modifier; + tem = Fget (Vx_ctrl_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_ctrl = XFIXNUM (tem) & INT_MAX; + if (INTEGERP (tem)) *mod_ctrl = XFIXNUM (tem) & INT_MAX; tem = Fget (Vx_alt_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_alt = XFIXNUM (tem) & INT_MAX; + if (INTEGERP (tem)) *mod_alt = XFIXNUM (tem) & INT_MAX; tem = Fget (Vx_meta_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_meta = XFIXNUM (tem) & INT_MAX; + if (INTEGERP (tem)) *mod_meta = XFIXNUM (tem) & INT_MAX; tem = Fget (Vx_hyper_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_hyper = XFIXNUM (tem) & INT_MAX; + if (INTEGERP (tem)) *mod_hyper = XFIXNUM (tem) & INT_MAX; tem = Fget (Vx_super_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_super = XFIXNUM (tem) & INT_MAX; - - return ( ((state & GDK_SHIFT_MASK) ? shift_modifier : 0) - | ((state & GDK_CONTROL_MASK) ? mod_ctrl : 0) - | ((state & GDK_META_MASK) ? mod_meta : 0) - | ((state & GDK_MOD1_MASK) ? mod_alt : 0) - | ((state & GDK_SUPER_MASK) ? mod_super : 0) - | ((state & GDK_HYPER_MASK) ? mod_hyper : 0)); + if (INTEGERP (tem)) *mod_super = XFIXNUM (tem) & INT_MAX; } -static int -pgtk_emacs_to_gtk_modifiers (EMACS_INT state) +int +pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo, int state) { - EMACS_INT mod_ctrl = ctrl_modifier; - EMACS_INT mod_meta = meta_modifier; - EMACS_INT mod_alt = alt_modifier; - EMACS_INT mod_hyper = hyper_modifier; - EMACS_INT mod_super = super_modifier; + int mod_ctrl; + int mod_meta; + int mod_alt; + int mod_hyper; + int mod_super; + int mod; - Lisp_Object tem; + get_modifier_values(&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper, &mod_super); - tem = Fget (Vx_ctrl_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_ctrl = XFIXNUM (tem); - tem = Fget (Vx_alt_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_alt = XFIXNUM (tem); - tem = Fget (Vx_meta_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_meta = XFIXNUM (tem); - tem = Fget (Vx_hyper_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_hyper = XFIXNUM (tem); - tem = Fget (Vx_super_keysym, Qmodifier_value); - if (INTEGERP (tem)) mod_super = XFIXNUM (tem); + mod = 0; + if (state & GDK_SHIFT_MASK) mod |= shift_modifier; + if (state & GDK_CONTROL_MASK) mod |= mod_ctrl; + if (state & dpyinfo->meta_mod_mask) mod |= mod_meta; + if (state & dpyinfo->alt_mod_mask) mod |= mod_alt; + if (state & GDK_SUPER_MASK) mod |= mod_super; + if (state & GDK_HYPER_MASK) mod |= mod_hyper; + return mod; +} + +static int +pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state) +{ + int mod_ctrl; + int mod_meta; + int mod_alt; + int mod_hyper; + int mod_super; + int mask; + get_modifier_values(&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper, &mod_super); - return ( ((state & mod_alt) ? GDK_MOD1_MASK : 0) - | ((state & mod_super) ? GDK_SUPER_MASK : 0) - | ((state & mod_hyper) ? GDK_HYPER_MASK : 0) - | ((state & shift_modifier) ? GDK_SHIFT_MASK : 0) - | ((state & mod_ctrl) ? GDK_CONTROL_MASK : 0) - | ((state & mod_meta) ? GDK_META_MASK : 0)); + mask = 0; + if (state & mod_alt) mask |= dpyinfo->alt_mod_mask; + if (state & mod_super) mask |= GDK_SUPER_MASK; + if (state & mod_hyper) mask |= GDK_HYPER_MASK; + if (state & shift_modifier) mask |= GDK_SHIFT_MASK; + if (state & mod_ctrl) mask |= GDK_CONTROL_MASK; + if (state & mod_meta) mask |= dpyinfo->meta_mod_mask; + return mask; } #define IsCursorKey(keysym) (0xff50 <= (keysym) && (keysym) < 0xff60) @@ -5008,7 +5044,7 @@ static gboolean key_press_event(GtkWidget *widget, GdkEvent *event, gpointer *us Lisp_Object c; guint state = event->key.state; - state |= pgtk_emacs_to_gtk_modifiers (extra_keyboard_modifiers); + state |= pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f), extra_keyboard_modifiers); modifiers = state; /* This will have to go some day... */ @@ -5031,7 +5067,7 @@ static gboolean key_press_event(GtkWidget *widget, GdkEvent *event, gpointer *us /* Common for all keysym input events. */ XSETFRAME (inev.ie.frame_or_window, f); - inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (modifiers); + inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers); inev.ie.timestamp = event->key.time; /* First deal with keysyms which have defined @@ -5680,7 +5716,7 @@ construct_mouse_click (struct input_event *result, result->kind = MOUSE_CLICK_EVENT; result->code = event->button - 1; result->timestamp = event->time; - result->modifiers = (pgtk_gtk_to_emacs_modifiers (event->state) + result->modifiers = (pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->state) | (event->type == GDK_BUTTON_RELEASE ? up_modifier : down_modifier)); @@ -5817,7 +5853,7 @@ scroll_event(GtkWidget *widget, GdkEvent *event, gpointer *user_data) inev.ie.kind = WHEEL_EVENT; inev.ie.timestamp = event->scroll.time; - inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (event->scroll.state); + inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state); XSETINT (inev.ie.x, event->scroll.x); XSETINT (inev.ie.y, event->scroll.y); XSETFRAME (inev.ie.frame_or_window, f); @@ -6158,10 +6194,8 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) *nametail++ = '@'; lispstpcpy (nametail, system_name); -#if 0 /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); -#endif /* Get the scroll bar cursor. */ /* We must create a GTK cursor, it is required for GTK widgets. */ diff --git a/src/pgtkterm.h b/src/pgtkterm.h index 3222bb25975..c85a9ea097e 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -222,6 +222,9 @@ struct pgtk_display_info /* The frame where the mouse was last time we reported a mouse position. */ struct frame *last_mouse_glyph_frame; + + /* Modifier masks in gdk */ + int meta_mod_mask, alt_mod_mask; }; /* This is a chain of structures for all the PGTK displays currently in use. */ @@ -529,7 +532,7 @@ extern int pgtk_lisp_to_color (Lisp_Object color, Emacs_Color *col); /* Implemented in pgtkterm.c */ extern void pgtk_clear_area (struct frame *f, int x, int y, int width, int height); -extern int pgtk_gtk_to_emacs_modifiers (int state); +extern int pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo, int state); extern void pgtk_clear_under_internal_border (struct frame *f); extern void pgtk_set_event_handler(struct frame *f);