static guint get_numeric_keyval (GthBrowser *browser, GdkEventKey *event) { guint keyval; gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (browser))), event->hardware_keycode, event->state & ~GDK_SHIFT_MASK, event->group, &keyval, NULL, NULL, NULL); /* This fixes the keyboard shortcuts for French keyboards (and * maybe others as well) where the number keys are shifted. */ if ((keyval < GDK_KEY_1) || (keyval > GDK_KEY_3)) gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (browser))), event->hardware_keycode, event->state | GDK_SHIFT_MASK, event->group, &keyval, NULL, NULL, NULL); return keyval; }
gboolean on_mainwin_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { // local hotkeys GdkModifierType consumed; guint accel_key; gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), event->hardware_keycode, event->state, 0, &accel_key, NULL, NULL, &consumed); if (accel_key == GDK_ISO_Left_Tab) accel_key = GDK_Tab; int mods = event->state & gtk_accelerator_get_default_mod_mask (); mods &= ~(consumed&~GDK_SHIFT_MASK); int lower = gdk_keyval_to_lower (accel_key); if (lower != accel_key) { accel_key = lower; } trace ("pressed: keycode: %x, mods: %x, hw: %x, translated: %x\n", event->keyval, mods, event->hardware_keycode, accel_key); DB_plugin_t *hkplug = deadbeef->plug_get_for_id ("hotkeys"); if (hkplug) { int ctx; DB_plugin_action_t *act = ((DB_hotkeys_plugin_t *)hkplug)->get_action_for_keycombo (accel_key, mods, 0, &ctx); if (act && act->callback2) { trace ("executing action %s in ctx %d\n", act->name, ctx); act->callback2 (act, ctx); return TRUE; } else if (act && act->callback) { gtkui_exec_action_14 (act, -1); } } trace ("action not found\n"); return FALSE; }
void cell_renderer_key_set_scancode (CellRendererKey *key, gint scancode) { gboolean changed; g_return_if_fail (IS_CELL_RENDERER_KEY(key)); g_object_freeze_notify(G_OBJECT(key)); changed = FALSE; if (scancode != key->scancode) { key->scancode = scancode; g_object_notify(G_OBJECT(key), "scancode"); changed = TRUE; } g_object_thaw_notify(G_OBJECT(key)); if (changed) { const gchar *text; /* sync string to the key values */ if (scancode <= 0) { text = "None"; } else { guint keyval = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(), scancode, 0, 0, &keyval, NULL, NULL, NULL); text = gdk_keyval_name(keyval); } g_object_set(key, "text", text, NULL); } }
/** * Extract the keyval of the key event if no modifier keys were pressed - * in other words get the keyval of the key by itself. The other way around * would be to use the hardware keysyms directly rather than the keyvals, * but the mapping looks to be messier. */ uint16_t gtk_get_unmodified_keyval( GdkEventKey *event ) { GdkKeymap *keymap = gdk_keymap_get_default(); guint keyval; gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval, NULL, NULL, NULL ); return keyval; }
static gboolean snooper_accel_group_find_func(GtkAccelKey *key, GClosure *closure, gpointer data) { guint keyval; GdkModifierType consumed; gdk_keymap_translate_keyboard_state (NULL, KEVENT(data)->hardware_keycode, KEVENT(data)->state, KEVENT(data)->group, &keyval, NULL, NULL, &consumed); #ifdef DEBUG_ALL DEBUG_MSG("snooper: _accel_group_find_func: compared (%d,%d) with (%d,%d)\n", key->accel_key, key->accel_mods, keyval, KEVENT(data)->state & ~consumed ); #endif /* DEBUG_ALL */ return ( (key->accel_key == keyval) && (key->accel_mods == ( KEVENT(data)->state & ~consumed) ) ); }
static bool clean_mask(guint hardware_keycode, GdkModifierType state, gint group, guint* clean, guint* keyval) { GdkModifierType consumed = 0; if ((gdk_keymap_translate_keyboard_state( gdk_keymap_get_default(), hardware_keycode, state, group, keyval, NULL, NULL, &consumed) ) == FALSE) { return false; } if (clean != NULL) { *clean = state & ~consumed & ALL_ACCELS_MASK; } /* numpad numbers */ switch (*keyval) { case GDK_KEY_KP_0: *keyval = GDK_KEY_0; break; case GDK_KEY_KP_1: *keyval = GDK_KEY_1; break; case GDK_KEY_KP_2: *keyval = GDK_KEY_2; break; case GDK_KEY_KP_3: *keyval = GDK_KEY_3; break; case GDK_KEY_KP_4: *keyval = GDK_KEY_4; break; case GDK_KEY_KP_5: *keyval = GDK_KEY_5; break; case GDK_KEY_KP_6: *keyval = GDK_KEY_6; break; case GDK_KEY_KP_7: *keyval = GDK_KEY_7; break; case GDK_KEY_KP_8: *keyval = GDK_KEY_8; break; case GDK_KEY_KP_9: *keyval = GDK_KEY_9; break; } return true; }
/* Send keyboard accelerators to the parent window, if necessary. * This code is heavily based on gtk_menu_key_press () */ static gboolean hildon_app_menu_key_press (GtkWidget *widget, GdkEventKey *event) { GtkWindow *parent_window; HildonAppMenuPrivate *priv; g_return_val_if_fail (HILDON_IS_APP_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->key_press_event (widget, event)) return TRUE; priv = HILDON_APP_MENU_GET_PRIVATE (widget); parent_window = priv->parent_window; if (parent_window) { guint accel_key, accel_mods; GdkModifierType consumed_modifiers; GdkDisplay *display; GSList *accel_groups; GSList *list; display = gtk_widget_get_display (widget); /* Figure out what modifiers went into determining the key symbol */ gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display), event->hardware_keycode, event->state, event->group, NULL, NULL, NULL, &consumed_modifiers); accel_key = gdk_keyval_to_lower (event->keyval); accel_mods = event->state & gtk_accelerator_get_default_mod_mask () & ~consumed_modifiers; /* If lowercasing affects the keysym, then we need to include SHIFT in the modifiers, * We re-upper case when we match against the keyval, but display and save in caseless form. */ if (accel_key != event->keyval) accel_mods |= GDK_SHIFT_MASK; accel_groups = gtk_accel_groups_from_object (G_OBJECT (parent_window)); for (list = accel_groups; list; list = list->next) { GtkAccelGroup *accel_group = list->data; if (gtk_accel_group_query (accel_group, accel_key, accel_mods, NULL)) { gtk_window_activate_key (parent_window, event); priv->hide_idle_id = gdk_threads_add_idle (hildon_app_menu_hide_idle, widget); break; } } } return TRUE; }
gint KeymapWrapper::GetKeyLevel(GdkEventKey *aGdkKeyEvent) { gint level; if (!gdk_keymap_translate_keyboard_state(mGdkKeymap, aGdkKeyEvent->hardware_keycode, GdkModifierType(aGdkKeyEvent->state), aGdkKeyEvent->group, NULL, NULL, &level, NULL)) { return -1; } return level; }
gboolean match_xi2_key (Key *key, XIDeviceEvent *event) { guint keyval; GdkModifierType consumed; gint group; guint keycode, state; if (key == NULL) return FALSE; setup_modifiers (); state = device_xi2_translate_state (&event->mods, &event->group); if (have_xkb (event->display)) group = XkbGroupForCoreState (state); else group = (state & GDK_KEY_Mode_switch) ? 1 : 0; keycode = event->detail; /* Check if we find a keysym that matches our current state */ if (gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), keycode, state, group, &keyval, NULL, NULL, &consumed)) { guint lower, upper; guint mask; /* The Key structure contains virtual modifiers, whereas * the XEvent will be using the real modifier, so translate those */ mask = key->state; gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mask); gdk_keyval_convert_case (keyval, &lower, &upper); /* If we are checking against the lower version of the * keysym, we might need the Shift state for matching, * so remove it from the consumed modifiers */ if (lower == key->keysym) consumed &= ~GDK_SHIFT_MASK; return ((lower == key->keysym || upper == key->keysym) && (state & ~consumed & gsd_used_mods) == mask); } /* The key we passed doesn't have a keysym, so try with just the keycode */ return (key != NULL && key->state == (state & gsd_used_mods) && key_uses_keycode (key, keycode)); }
static void translate_key_event (GdkDisplay *display, GdkX11DeviceManagerCore *device_manager, GdkEvent *event, XEvent *xevent) { GdkKeymap *keymap = gdk_keymap_get_for_display (display); GdkModifierType consumed, state; event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; event->key.time = xevent->xkey.time; gdk_event_set_device (event, device_manager->core_keyboard); event->key.state = (GdkModifierType) xevent->xkey.state; event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state); event->key.hardware_keycode = xevent->xkey.keycode; event->key.keyval = GDK_KEY_VoidSymbol; gdk_keymap_translate_keyboard_state (keymap, event->key.hardware_keycode, event->key.state, event->key.group, &event->key.keyval, NULL, NULL, &consumed); state = event->key.state & ~consumed; _gdk_x11_keymap_add_virt_mods (keymap, &state); event->key.state |= state; event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); _gdk_x11_event_translate_keyboard_string (&event->key); #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_EVENTS) { g_message ("%s:\t\twindow: %ld key: %12s %d", event->type == GDK_KEY_PRESS ? "key press " : "key release", xevent->xkey.window, event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)", event->key.keyval); if (event->key.length > 0) g_message ("\t\tlength: %4d string: \"%s\"", event->key.length, event->key.string); } #endif /* G_ENABLE_DEBUG */ return; }
/* static */ guint KeymapWrapper::GetGDKKeyvalWithoutModifier(const GdkEventKey *aGdkKeyEvent) { KeymapWrapper* keymapWrapper = GetInstance(); guint state = (aGdkKeyEvent->state & keymapWrapper->GetModifierMask(NUM_LOCK)); guint keyval; if (!gdk_keymap_translate_keyboard_state(keymapWrapper->mGdkKeymap, aGdkKeyEvent->hardware_keycode, GdkModifierType(state), aGdkKeyEvent->group, &keyval, NULL, NULL, NULL)) { return 0; } return keyval; }
/* Owen magic */ static GdkFilterReturn filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { XEvent *xev = (XEvent *) xevent; guint keyval; gint group; GdkScreen *screen = (GdkScreen *)data; if (xev->type == KeyPress || xev->type == KeyRelease) { /* get the keysym */ group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT; gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), xev->xkey.keycode, xev->xkey.state, group, &keyval, NULL, NULL, NULL); if (keyval == GDK_Control_L || keyval == GDK_Control_R) { if (xev->type == KeyPress) { XAllowEvents (xev->xkey.display, SyncKeyboard, xev->xkey.time); } else { XAllowEvents (xev->xkey.display, AsyncKeyboard, xev->xkey.time); gsd_locate_pointer (screen); } } else { XAllowEvents (xev->xkey.display, ReplayKeyboard, xev->xkey.time); XUngrabKeyboard (gdk_x11_get_default_xdisplay (), xev->xkey.time); } }
static GdkEventKey * key_event_to_gdk (ClutterKeyEvent *event_clutter) { GdkDisplay *display = gdk_display_get_default (); GdkKeymap *keymap = gdk_keymap_get_for_display (display); GdkEventKey *event_gdk; event_gdk = (GdkEventKey *)gdk_event_new ((event_clutter->type == CLUTTER_KEY_PRESS) ? GDK_KEY_PRESS : GDK_KEY_RELEASE); event_gdk->window = window_for_actor ((ClutterActor *)event_clutter->stage); event_gdk->send_event = FALSE; event_gdk->time = event_clutter->time; /* This depends on ClutterModifierType and GdkModifierType being * identical, which they are currently. (They both match the X * modifier state in the low 16-bits and have the same extensions.) */ event_gdk->state = event_clutter->modifier_state; event_gdk->keyval = event_clutter->keyval; event_gdk->hardware_keycode = event_clutter->hardware_keycode; /* For non-proper non-XKB support, we'd need a huge cut-and-paste * from gdkkeys-x11.c; this is a macro that just shifts a few bits * out of state, so won't make the situation worse if the server * doesn't support XKB; we'll just end up with group == 0 */ event_gdk->group = XkbGroupForCoreState (event_gdk->state); gdk_keymap_translate_keyboard_state (keymap, event_gdk->hardware_keycode, event_gdk->state, event_gdk->group, &event_gdk->keyval, NULL, NULL, NULL); if (event_clutter->unicode_value) { /* This is not particularly close to what GDK does - event_gdk->string * is supposed to be in the locale encoding, and have control keys * as control characters, etc. See gdkevents-x11.c:translate_key_event(). * Hopefully no input method is using event.string. */ char buf[6]; event_gdk->length = g_unichar_to_utf8 (event_clutter->unicode_value, buf); event_gdk->string = g_strndup (buf, event_gdk->length); } event_gdk->is_modifier = key_is_modifier (event_gdk->keyval); return event_gdk; }
static VALUE rg_translate_keyboard_state(VALUE self, VALUE hardware_keycode, VALUE state, VALUE group) { guint keyval; gint effective_group, level; GdkModifierType consumed_modifiers; gboolean ret; ret = gdk_keymap_translate_keyboard_state(_SELF(self), NUM2UINT(hardware_keycode), RVAL2GFLAGS(state, GDK_TYPE_MODIFIER_TYPE), NUM2INT(group), &keyval, &effective_group, &level, &consumed_modifiers); return ret ? rb_ary_new3(4, UINT2NUM(keyval), INT2NUM(effective_group), INT2NUM(level), GFLAGS2RVAL(consumed_modifiers, GDK_TYPE_MODIFIER_TYPE)) : Qnil; }
PRUint32 KeymapWrapper::GetCharCodeFor(const GdkEventKey *aGdkKeyEvent, guint aModifierState, gint aGroup) { guint keyval; if (!gdk_keymap_translate_keyboard_state(mGdkKeymap, aGdkKeyEvent->hardware_keycode, GdkModifierType(aModifierState), aGroup, &keyval, NULL, NULL, NULL)) { return 0; } GdkEventKey tmpEvent = *aGdkKeyEvent; tmpEvent.state = aModifierState; tmpEvent.keyval = keyval; tmpEvent.group = aGroup; return GetCharCodeFor(&tmpEvent); }
gboolean match_key (Key *key, XEvent *event) { guint keyval; GdkModifierType consumed; gint group; if (key == NULL) return FALSE; setup_modifiers (); #ifdef HAVE_X11_EXTENSIONS_XKB_H if (have_xkb (event->xkey.display)) group = XkbGroupForCoreState (event->xkey.state); else #endif group = (event->xkey.state & GDK_KEY_Mode_switch) ? 1 : 0; /* Check if we find a keysym that matches our current state */ if (gdk_keymap_translate_keyboard_state (NULL, event->xkey.keycode, event->xkey.state, group, &keyval, NULL, NULL, &consumed)) { guint lower, upper; gdk_keyval_convert_case (keyval, &lower, &upper); /* If we are checking against the lower version of the * keysym, we might need the Shift state for matching, * so remove it from the consumed modifiers */ if (lower == key->keysym) consumed &= ~GDK_SHIFT_MASK; return ((lower == key->keysym || upper == key->keysym) && (event->xkey.state & ~consumed & msd_used_mods) == key->state); } /* The key we passed doesn't have a keysym, so try with just the keycode */ return (key != NULL && key->state == (event->xkey.state & msd_used_mods) && key_uses_keycode (key, event->xkey.keycode)); }
static gchar * snooper_parse_key(GdkEventKey *kevent) { gchar *tmpstr = NULL; const gchar *ctrl, *shift, *mod1; guint keyval; GdkModifierType consumed; gint modified; gdk_keymap_translate_keyboard_state (NULL, kevent->hardware_keycode, kevent->state, kevent->group, &keyval, NULL, NULL, &consumed); modified = kevent->state & ~consumed; ctrl = modified & GDK_CONTROL_MASK ? "c": ""; shift = modified & GDK_SHIFT_MASK ? "s": ""; mod1 = modified& GDK_MOD1_MASK ? "m": ""; modified &= (GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK); if (modified) { tmpstr = g_strdup_printf("<%s%s%s>%c", ctrl, shift, mod1, gdk_keyval_to_unicode(keyval)); }else{ tmpstr = g_strdup_printf("%c", gdk_keyval_to_unicode(keyval)); } DEBUG_MSG("snooper: key parsed = '%s'\n", tmpstr); return tmpstr; }
static NimfEvent * translate_xkey_event (XEvent *xevent) { g_debug (G_STRLOC ": %s", G_STRFUNC); GdkKeymap *keymap = gdk_keymap_get_default (); GdkModifierType consumed, state; NimfEvent *nimf_event = nimf_event_new (NIMF_EVENT_NOTHING); if (xevent->type == KeyPress) nimf_event->key.type = NIMF_EVENT_KEY_PRESS; else nimf_event->key.type = NIMF_EVENT_KEY_RELEASE; nimf_event->key.state = (NimfModifierType) xevent->xkey.state; #if GTK_CHECK_VERSION (3, 6, 0) gint group = gdk_x11_keymap_get_group_for_state (keymap, xevent->xkey.state); #else gint group = XkbGroupForCoreState (xevent->xkey.state); #endif nimf_event->key.hardware_keycode = xevent->xkey.keycode; nimf_event->key.keyval = NIMF_KEY_VoidSymbol; gdk_keymap_translate_keyboard_state (keymap, nimf_event->key.hardware_keycode, nimf_event->key.state, group, &nimf_event->key.keyval, NULL, NULL, &consumed); state = nimf_event->key.state & ~consumed; gdk_keymap_add_virtual_modifiers (keymap, &state); nimf_event->key.state |= (NimfModifierType) state; return nimf_event; }
gboolean cb_inputbar_keypress(GtkWidget *widget, GdkEventKey *event, Browser *b) { unsigned int keyval; GdkModifierType consumed_modifiers; int i; gboolean processed = FALSE; gdk_keymap_translate_keyboard_state( ripcurl->Global.keymap, event->hardware_keycode, event->state, event->group, /* in */ &keyval, NULL, NULL, &consumed_modifiers); /* out */ for (i = 0; i < LENGTH(inputbar_shortcuts); i++) { if (keyval == inputbar_shortcuts[i].keyval && (event->state & ~consumed_modifiers & ALL_MASK) == inputbar_shortcuts[i].mask && inputbar_shortcuts[i].func) { inputbar_shortcuts[i].func(b, &(inputbar_shortcuts[i].arg)); processed = TRUE; } } return processed; }
void translate_key_event (GdkDisplay *display, GdkEvent *event, XEvent *xevent) { GdkKeymap *keymap = gdk_keymap_get_for_display (display); event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; event->key.time = xevent->xkey.time; event->key.state = (GdkModifierType) xevent->xkey.state; #ifdef HAVE_XKB event->key.group = XkbGroupForCoreState (xevent->xkey.state); #else event->key.group = 0; #endif event->key.hardware_keycode = xevent->xkey.keycode; event->key.keyval = GDK_VoidSymbol; gdk_keymap_translate_keyboard_state (keymap, event->key.hardware_keycode, event->key.state, event->key.group, &event->key.keyval, NULL, NULL, NULL); event->key.is_modifier = 0; /* Fill in event->string crudely, since various programs * depend on it. */ event->key.string = NULL; event->key.length = 0; return; }
gboolean hotkey_pressed(GtkWidget *dialog, GdkEventKey *ev, PrefsData *data) { gchar *key_text; guint keyval; GdkModifierType state,consumed; state = ev->state; gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(), ev->hardware_keycode, state, ev->group, &keyval, NULL,NULL,&consumed); state &= ~consumed; state &= gtk_accelerator_get_default_mod_mask(); key_text = gtk_accelerator_name (keyval, state); gtk_label_set_text(GTK_LABEL(data->hotkey_key_label),key_text); g_free(key_text); return FALSE; }
/** * _gtk_key_hash_lookup: * @key_hash: a #GtkKeyHash * @hardware_keycode: hardware keycode field from a #GdkEventKey * @state: state field from a #GdkEventKey * @mask: mask of modifiers to consider when matching against the * modifiers in entries. * @group: group field from a #GdkEventKey * * Looks up the best matching entry or entries in the hash table for * a given event. The results are sorted so that entries with less * modifiers come before entries with more modifiers. * * The matches returned by this function can be exact (i.e. keycode, level * and group all match) or fuzzy (i.e. keycode and level match, but group * does not). As long there are any exact matches, only exact matches * are returned. If there are no exact matches, fuzzy matches will be * returned, as long as they are not shadowing a possible exact match. * This means that fuzzy matches won't be considered if their keyval is * present in the current group. * * Return value: A #GSList of matching entries. **/ GSList * _gtk_key_hash_lookup (GtkKeyHash *key_hash, guint16 hardware_keycode, GdkModifierType state, GdkModifierType mask, gint group) { GHashTable *keycode_hash = key_hash_get_keycode_hash (key_hash); GSList *keys = g_hash_table_lookup (keycode_hash, GUINT_TO_POINTER ((guint)hardware_keycode)); GSList *results = NULL; GSList *l; gboolean have_exact = FALSE; guint keyval; gint effective_group; gint level; GdkModifierType modifiers; GdkModifierType consumed_modifiers; const GdkModifierType xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK; const GdkModifierType vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK; /* We don't want Caps_Lock to affect keybinding lookups. */ state &= ~GDK_LOCK_MASK; gdk_keymap_map_virtual_modifiers (key_hash->keymap, &mask); gdk_keymap_translate_keyboard_state (key_hash->keymap, hardware_keycode, state, group, &keyval, &effective_group, &level, &consumed_modifiers); GTK_NOTE (KEYBINDINGS, g_message ("Looking up keycode = %u, modifiers = 0x%04x,\n" " keyval = %u, group = %d, level = %d, consumed_modifiers = 0x%04x", hardware_keycode, state, keyval, effective_group, level, consumed_modifiers)); if (keys) { GSList *tmp_list = keys; while (tmp_list) { GtkKeyHashEntry *entry = tmp_list->data; /* If the virtual Super, Hyper or Meta modifiers are present, * they will also be mapped to some of the Mod2 - Mod5 modifiers, * so we compare them twice, ignoring either set. * We accept combinations involving virtual modifiers only if they * are mapped to separate modifiers; i.e. if Super and Hyper are * both mapped to Mod4, then pressing a key that is mapped to Mod4 * will not match a Super+Hyper entry. */ modifiers = entry->modifiers; if (gdk_keymap_map_virtual_modifiers (key_hash->keymap, &modifiers) && ((modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || (modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods))) { gint i; if (keyval == entry->keyval) /* Exact match */ { GTK_NOTE (KEYBINDINGS, g_message (" found exact match, keyval = %u, modifiers = 0x%04x", entry->keyval, entry->modifiers)); if (!have_exact) { g_slist_free (results); results = NULL; } have_exact = TRUE; results = g_slist_prepend (results, entry); } if (!have_exact) { for (i = 0; i < entry->n_keys; i++) { if (entry->keys[i].keycode == hardware_keycode && entry->keys[i].level == level) /* Match for all but group */ { GTK_NOTE (KEYBINDINGS, g_message (" found group = %d, level = %d", entry->keys[i].group, entry->keys[i].level)); results = g_slist_prepend (results, entry); break; } } } } tmp_list = tmp_list->next; } } if (!have_exact && results) { /* If there are fuzzy matches, check that the current group doesn't also * define these keyvals; if yes, discard results because a widget up in * the stack may have an exact match and we don't want to 'steal' it. */ guint oldkeyval = 0; GtkKeyHashEntry *keyhashentry; results = sort_lookup_results_by_keyval (results); for (l = results; l; l = l->next) { keyhashentry = l->data; if (l == results || oldkeyval != keyhashentry->keyval) { oldkeyval = keyhashentry->keyval; if (keyval_in_group (key_hash->keymap, oldkeyval, group)) { g_slist_free (results); return NULL; } } } } results = sort_lookup_results (results); for (l = results; l; l = l->next) l->data = ((GtkKeyHashEntry *)l->data)->value; return results; }
/* Owen magic */ static GdkFilterReturn filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { XEvent *xev = (XEvent *) xevent; guint keyval; gint group; GdkScreen *screen = (GdkScreen *)data; if (xev->type == ButtonPress) { XAllowEvents (xev->xbutton.display, ReplayPointer, xev->xbutton.time); XUngrabButton (xev->xbutton.display, AnyButton, AnyModifier, xev->xbutton.window); XUngrabKeyboard (xev->xbutton.display, xev->xbutton.time); } if (xev->type == KeyPress || xev->type == KeyRelease) { /* get the keysym */ group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT; gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), xev->xkey.keycode, xev->xkey.state, group, &keyval, NULL, NULL, NULL); if (keyval == GDK_KEY_Control_L || keyval == GDK_KEY_Control_R) { if (xev->type == KeyPress) { XAllowEvents (xev->xkey.display, SyncKeyboard, xev->xkey.time); XGrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window, False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); } else { XUngrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window); XAllowEvents (xev->xkey.display, AsyncKeyboard, xev->xkey.time); csd_locate_pointer (screen); } } else { XAllowEvents (xev->xkey.display, ReplayKeyboard, xev->xkey.time); XUngrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window); XUngrabKeyboard (xev->xkey.display, xev->xkey.time); } }
static gboolean grab_key_callback(GtkWidget* widget, GdkEventKey* event, void* data) { GdkModifierType accel_mods = 0; guint accel_keyval; EggCellRendererKeys *keys; char *path; gboolean edited; gboolean cleared; GdkModifierType consumed_modifiers; guint upper; GdkModifierType ignored_modifiers; keys = EGG_CELL_RENDERER_KEYS(data); if (is_modifier(event->hardware_keycode)) { return TRUE; } edited = FALSE; cleared = FALSE; consumed_modifiers = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(), event->hardware_keycode, event->state, event->group, NULL, NULL, NULL, &consumed_modifiers); upper = event->keyval; accel_keyval = gdk_keyval_to_lower(upper); if (accel_keyval == GDK_ISO_Left_Tab) { accel_keyval = GDK_Tab; } /* Put shift back if it changed the case of the key, not otherwise. */ if (upper != accel_keyval && (consumed_modifiers & GDK_SHIFT_MASK)) { consumed_modifiers &= ~(GDK_SHIFT_MASK); } egg_keymap_resolve_virtual_modifiers(gdk_keymap_get_default(), EGG_VIRTUAL_NUM_LOCK_MASK | EGG_VIRTUAL_SCROLL_LOCK_MASK | EGG_VIRTUAL_LOCK_MASK, &ignored_modifiers); /* http://bugzilla.gnome.org/show_bug.cgi?id=139605 * mouse keys should effect keybindings */ ignored_modifiers |= GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK; /* filter consumed/ignored modifiers */ if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK) { accel_mods = event->state & GDK_MODIFIER_MASK & ~(consumed_modifiers | ignored_modifiers); } else if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_X) { accel_mods = event->state & GDK_MODIFIER_MASK & ~(ignored_modifiers); } else { g_assert_not_reached(); } if (accel_mods == 0 && accel_keyval == GDK_Escape) { goto out; /* cancel */ } /* clear the accelerator on Backspace */ if (accel_mods == 0 && accel_keyval == GDK_BackSpace) { cleared = TRUE; goto out; } if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK) { if (!gtk_accelerator_valid (accel_keyval, accel_mods)) { accel_keyval = 0; accel_mods = 0; } } edited = TRUE; out: gdk_keyboard_ungrab(event->time); gdk_pointer_ungrab(event->time); path = g_strdup(g_object_get_data(G_OBJECT(keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH)); gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(keys->edit_widget)); gtk_cell_editable_remove_widget(GTK_CELL_EDITABLE(keys->edit_widget)); keys->edit_widget = NULL; keys->grab_widget = NULL; if (edited) { g_signal_emit_by_name(G_OBJECT(keys), "accel_edited", path, accel_keyval, accel_mods, event->hardware_keycode); } else if (cleared) { g_signal_emit_by_name(G_OBJECT(keys), "accel_cleared", path); } g_free (path); return TRUE; }
/* * Translate a Java KeyEvent object into a GdkEventKey event, then * pass it to the GTK main loop for processing. */ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent (JNIEnv *env, jobject obj, jint id, jlong when, jint mods, jint keyCode, jint keyLocation) { void *ptr; GdkEvent *event = NULL; GdkKeymapKey *keymap_keys = NULL; gint n_keys = 0; guint lookup_keyval = 0; gdk_threads_enter (); ptr = gtkpeer_get_widget (env, obj); if (id == AWT_KEY_PRESSED) event = gdk_event_new (GDK_KEY_PRESS); else if (id == AWT_KEY_RELEASED) event = gdk_event_new (GDK_KEY_RELEASE); else { gdk_threads_leave (); /* Don't send AWT KEY_TYPED events to GTK. */ return; } if (GTK_IS_BUTTON (ptr)) event->key.window = GTK_BUTTON (get_widget(GTK_WIDGET (ptr)))->event_window; else if (GTK_IS_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))) event->key.window = GTK_WIDGET (GTK_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))->container.child)->window; else event->key.window = get_widget(GTK_WIDGET (ptr))->window; event->key.send_event = 0; event->key.time = (guint32) when; if (mods & AWT_SHIFT_DOWN_MASK) event->key.state |= GDK_SHIFT_MASK; if (mods & AWT_CTRL_DOWN_MASK) event->key.state |= GDK_CONTROL_MASK; if (mods & AWT_ALT_DOWN_MASK) event->key.state |= GDK_MOD1_MASK; /* This hack is needed because the AWT has no notion of num lock. It infers numlock state from the only Java virtual keys that are affected by it. */ if (keyCode == VK_NUMPAD9 || keyCode == VK_NUMPAD8 || keyCode == VK_NUMPAD7 || keyCode == VK_NUMPAD6 || keyCode == VK_NUMPAD5 || keyCode == VK_NUMPAD4 || keyCode == VK_NUMPAD3 || keyCode == VK_NUMPAD2 || keyCode == VK_NUMPAD1 || keyCode == VK_NUMPAD0 || keyCode == VK_DECIMAL) event->key.state |= GDK_MOD2_MASK; /* These values don't need to be filled in since GTK doesn't use them. */ event->key.length = 0; event->key.string = NULL; lookup_keyval = cp_gtk_awt_keycode_to_keysym (keyCode, keyLocation); if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), lookup_keyval, &keymap_keys, &n_keys)) { /* No matching keymap entry was found. */ g_printerr ("No matching keymap entries were found\n"); gdk_threads_leave (); return; } /* Note: if n_keys > 1 then there are multiple hardware keycodes that translate to lookup_keyval. We arbitrarily choose the first hardware keycode from the list returned by gdk_keymap_get_entries_for_keyval. */ event->key.hardware_keycode = keymap_keys[0].keycode; event->key.group = keymap_keys[0].group; g_free (keymap_keys); if (!gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), event->key.hardware_keycode, event->key.state, event->key.group, &event->key.keyval, NULL, NULL, NULL)) { /* No matching keyval was found. */ g_printerr ("No matching keyval was found\n"); gdk_threads_leave (); return; } /* keyevent = (GdkEventKey *) event; */ /* g_printerr ("generated event: sent: %d time: %d state: %d keyval: %d length: %d string: %s hardware_keycode: %d group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */ /* We already received the original key event on the window itself, so we don't want to resend it. */ if (!GTK_IS_WINDOW (ptr)) { if (GTK_IS_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))) gtk_widget_event (GTK_WIDGET (GTK_SCROLLED_WINDOW (get_widget(GTK_WIDGET (ptr)))->container.child), event); else gtk_widget_event (get_widget(GTK_WIDGET (ptr)), event); } gdk_threads_leave (); }
static gboolean grab_key_callback (GtkWidget *widget, GdkEventKey *event, GtkCellRendererAccel *accel) { GdkModifierType accel_mods = 0; guint accel_key; gchar *path; gboolean edited; gboolean cleared; GdkModifierType consumed_modifiers; GdkDisplay *display; display = gtk_widget_get_display (widget); if (event->is_modifier) return TRUE; edited = FALSE; cleared = FALSE; gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display), event->hardware_keycode, event->state, event->group, NULL, NULL, NULL, &consumed_modifiers); accel_key = gdk_keyval_to_lower (event->keyval); if (accel_key == GDK_ISO_Left_Tab) accel_key = GDK_Tab; accel_mods = event->state & gtk_accelerator_get_default_mod_mask (); /* Filter consumed modifiers */ if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK) accel_mods &= ~consumed_modifiers; /* Put shift back if it changed the case of the key, not otherwise. */ if (accel_key != event->keyval) accel_mods |= GDK_SHIFT_MASK; if (accel_mods == 0) { switch (event->keyval) { case GDK_Escape: goto out; /* cancel */ case GDK_BackSpace: /* clear the accelerator on Backspace */ cleared = TRUE; goto out; default: break; } } if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK) { if (!gtk_accelerator_valid (accel_key, accel_mods)) { gtk_widget_error_bell (widget); return TRUE; } } edited = TRUE; out: gdk_display_keyboard_ungrab (display, event->time); gdk_display_pointer_ungrab (display, event->time); path = g_strdup (g_object_get_data (G_OBJECT (accel->edit_widget), "gtk-cell-renderer-text")); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (accel->edit_widget)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (accel->edit_widget)); accel->edit_widget = NULL; accel->grab_widget = NULL; if (edited) g_signal_emit (accel, signals[ACCEL_EDITED], 0, path, accel_key, accel_mods, event->hardware_keycode); else if (cleared) g_signal_emit (accel, signals[ACCEL_CLEARED], 0, path); g_free (path); return TRUE; }
/** * _gtk_key_hash_lookup: * @key_hash: a #GtkKeyHash * @hardware_keycode: hardware keycode field from a #GdkEventKey * @state: state field from a #GdkEventKey * @mask: mask of modifiers to consider when matching against the * modifiers in entries. * @group: group field from a #GdkEventKey * * Looks up the best matching entry or entries in the hash table for * a given event. The results are sorted so that entries with less * modifiers come before entries with more modifiers. * * Return value: A #GSList of all matching entries. If there were exact * matches, they are returned, otherwise all fuzzy matches are * returned. (A fuzzy match is a match in keycode and level, but not * in group.) **/ GSList * _gtk_key_hash_lookup (GtkKeyHash *key_hash, guint16 hardware_keycode, GdkModifierType state, GdkModifierType mask, gint group) { GHashTable *keycode_hash = key_hash_get_keycode_hash (key_hash); GSList *keys = g_hash_table_lookup (keycode_hash, GUINT_TO_POINTER ((guint)hardware_keycode)); GSList *results = NULL; GSList *l; gboolean have_exact = FALSE; guint keyval; gint effective_group; gint level; GdkModifierType consumed_modifiers; /* We don't want Caps_Lock to affect keybinding lookups. */ state &= ~GDK_LOCK_MASK; gdk_keymap_translate_keyboard_state (key_hash->keymap, hardware_keycode, state, group, &keyval, &effective_group, &level, &consumed_modifiers); GTK_NOTE (KEYBINDINGS, g_message ("Looking up keycode = %u, modifiers = 0x%04x,\n" " keyval = %u, group = %d, level = %d, consumed_modifiers = 0x%04x", hardware_keycode, state, keyval, effective_group, level, consumed_modifiers)); if (keys) { GSList *tmp_list = keys; while (tmp_list) { GtkKeyHashEntry *entry = tmp_list->data; GdkModifierType xmods, vmods; /* If the virtual super, hyper or meta modifiers are present, * they will also be mapped to some of the mod2 - mod5 modifiers, * so we compare them twice, ignoring either set. */ xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK; vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK; if ((entry->modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || (entry->modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)) { gint i; if (keyval == entry->keyval) /* Exact match */ { GTK_NOTE (KEYBINDINGS, g_message (" found exact match, keyval = %u, modifiers = 0x%04x", entry->keyval, entry->modifiers)); if (!have_exact) { g_slist_free (results); results = NULL; } have_exact = TRUE; results = g_slist_prepend (results, entry); } if (!have_exact) { for (i = 0; i < entry->n_keys; i++) { if (entry->keys[i].keycode == hardware_keycode && entry->keys[i].level == level) /* Match for all but group */ { GTK_NOTE (KEYBINDINGS, g_message (" found group = %d, level = %d", entry->keys[i].group, entry->keys[i].level)); results = g_slist_prepend (results, entry); break; } } } } tmp_list = tmp_list->next; } } results = sort_lookup_results (results); for (l = results; l; l = l->next) l->data = ((GtkKeyHashEntry *)l->data)->value; return results; }
static gboolean ccm_config_entry_shortcut_key_release_event (GtkWidget * widget, GdkEventKey * event) { CCMConfigEntryShortcut *self = CCM_CONFIG_ENTRY_SHORTCUT (widget); gboolean ret = FALSE; if (self->priv->edited && event->type == GDK_KEY_RELEASE) { gchar *value = g_strdup (""); gchar *tmp; if (event->keyval == GDK_BackSpace) value = g_strdup (_("Disabled")); else if (event->keyval == GDK_Escape) value = g_strdup (self->priv->old_value); else { guint keyval = 0; GdkModifierType mods = 0; GdkModifierType consumed_modifiers; EggVirtualModifierType modifier; consumed_modifiers = 0; keyval = gdk_keyval_to_lower (event->keyval); if (keyval == GDK_ISO_Left_Tab) keyval = GDK_Tab; gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), event->hardware_keycode, event->state, event->group, &keyval, NULL, NULL, &consumed_modifiers); if (event->keyval != keyval && (consumed_modifiers & GDK_SHIFT_MASK)) consumed_modifiers &= ~(GDK_SHIFT_MASK); mods = event->state & GDK_MODIFIER_MASK & ~(consumed_modifiers); egg_keymap_virtualize_modifiers (gdk_keymap_get_default (), mods, &modifier); switch (keyval) { case GDK_Shift_L: case GDK_Shift_R: modifier |= EGG_VIRTUAL_SHIFT_MASK; keyval = 0; break; case GDK_Control_L: case GDK_Control_R: modifier |= EGG_VIRTUAL_CONTROL_MASK; keyval = 0; break; case GDK_Alt_L: case GDK_Alt_R: modifier |= EGG_VIRTUAL_ALT_MASK; keyval = 0; break; case GDK_Super_L: case GDK_Super_R: modifier |= EGG_VIRTUAL_SUPER_MASK; keyval = 0; break; default: break; } if (event->is_modifier) keyval = 0; modifier &= ~(EGG_VIRTUAL_META_MASK); modifier &= ~(EGG_VIRTUAL_HYPER_MASK); value = egg_virtual_accelerator_name (keyval, 0, modifier); if (self->priv->mouse) { if (event->state & GDK_BUTTON1_MASK) { tmp = g_strconcat (value, "Button1", NULL); g_free (value); value = tmp; } if (event->state & GDK_BUTTON2_MASK) { tmp = g_strconcat (value, "Button2", NULL); g_free (value); value = tmp; } if (event->state & GDK_BUTTON3_MASK) { tmp = g_strconcat (value, "Button3", NULL); g_free (value); value = tmp; } if (self->priv->button & GDK_BUTTON4_MASK) { tmp = g_strconcat (value, "Button4", NULL); g_free (value); value = tmp; } if (self->priv->button & GDK_BUTTON5_MASK) { tmp = g_strconcat (value, "Button5", NULL); g_free (value); value = tmp; } } } self->priv->edited = FALSE; gdk_keyboard_ungrab (GDK_CURRENT_TIME); gdk_pointer_ungrab (GDK_CURRENT_TIME); gtk_entry_set_text (GTK_ENTRY (self), value); if (self->priv->config) ccm_config_set_string (self->priv->config, value, NULL); g_free (value); } if (GTK_WIDGET_CLASS (ccm_config_entry_shortcut_parent_class)->key_release_event) ret = GTK_WIDGET_CLASS (ccm_config_entry_shortcut_parent_class)->key_release_event (widget, event); return ret; }
gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data ) { gboolean wasConsumed = FALSE; /* default to report event not consumed */ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION(data); guint key = 0; gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ), event->hardware_keycode, (GdkModifierType)event->state, 0, &key, 0, 0, 0 ); switch ( key ) { case GDK_Escape: { action->private_data->transferFocus = TRUE; gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal ); ege_adjustment_action_defocus( action ); wasConsumed = TRUE; } break; case GDK_Return: case GDK_KP_Enter: { action->private_data->transferFocus = TRUE; ege_adjustment_action_defocus( action ); wasConsumed = TRUE; } break; case GDK_Tab: { action->private_data->transferFocus = FALSE; wasConsumed = process_tab( widget, 1 ); } break; case GDK_ISO_Left_Tab: { action->private_data->transferFocus = FALSE; wasConsumed = process_tab( widget, -1 ); } break; case GDK_Up: case GDK_KP_Up: { action->private_data->transferFocus = FALSE; gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) ); gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val + action->private_data->step ); wasConsumed = TRUE; } break; case GDK_Down: case GDK_KP_Down: { action->private_data->transferFocus = FALSE; gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) ); gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val - action->private_data->step ); wasConsumed = TRUE; } break; case GDK_Page_Up: case GDK_KP_Page_Up: { action->private_data->transferFocus = FALSE; gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) ); gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val + action->private_data->page ); wasConsumed = TRUE; } break; case GDK_Page_Down: case GDK_KP_Page_Down: { action->private_data->transferFocus = FALSE; gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) ); gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val - action->private_data->page ); wasConsumed = TRUE; } break; case GDK_z: case GDK_Z: { action->private_data->transferFocus = FALSE; gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal ); wasConsumed = TRUE; } break; } return wasConsumed; }
static GdkFilterReturn filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { XEvent *xevent = (XEvent *) gdk_xevent; GdkKeymap *keymap = gdk_keymap_get_default(); guint keyval; GdkModifierType consumed, modifiers; guint mod_mask = gtk_accelerator_get_default_mod_mask(); GSList *iter; (void) event; (void) data; switch (xevent->type) { case KeyPress: modifiers = xevent->xkey.state; TRACE (g_print ("Got KeyPress keycode: %d, modifiers: 0x%x\n", xevent->xkey.keycode, xevent->xkey.state)); gdk_keymap_translate_keyboard_state( keymap, xevent->xkey.keycode, modifiers, /* See top comment why we don't use this here: XkbGroupForCoreState (xevent->xkey.state) */ WE_ONLY_USE_ONE_GROUP, &keyval, NULL, NULL, &consumed); /* Map non-virtual to virtual modifiers */ modifiers &= ~consumed; gdk_keymap_add_virtual_modifiers(keymap, &modifiers); modifiers &= mod_mask; TRACE (g_print ("Translated keyval: %d, vmodifiers: 0x%x, name: %s\n", keyval, modifiers, gtk_accelerator_name(keyval, modifiers))); /* * Set the last event time for use when showing * windows to avoid anti-focus-stealing code. */ processing_event = TRUE; last_event_time = xevent->xkey.time; iter = bindings; while (iter != NULL) { /* NOTE: ``iter`` might be removed from the list * in the callback. */ struct Binding *binding = iter->data; iter = iter->next; if (keyvalues_equal(binding->keyval, keyval) && modifiers_equal(binding->modifiers, modifiers)) { TRACE (g_print ("Calling handler for '%s'...\n", binding->keystring)); (binding->handler) (binding->keystring, binding->user_data); } } processing_event = FALSE; break; case KeyRelease: TRACE (g_print ("Got KeyRelease! \n")); break; } return GDK_FILTER_CONTINUE; }