Esempio n. 1
0
guint
gdk_keymap_lookup_key (GdkKeymap          *keymap,
                       const GdkKeymapKey *key)
{
  guint sym;

  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0);
  g_return_val_if_fail (key != NULL, 0);
  g_return_val_if_fail (key->group < 4, 0);
  
  /* Accept only the default keymap */
  if (keymap != NULL && keymap != gdk_keymap_get_default ())
    return 0;

  update_keymap ();
  
  if (key->keycode >= 256 ||
      key->group < 0 || key->group >= 2 ||
      key->level < 0 || key->level >= 2)
    return 0;
  
  sym = keysym_tab[key->keycode*4 + key->group*2 + key->level];
  
  if (sym == GDK_VoidSymbol)
    return 0;
  else
    return sym;
}
Esempio n. 2
0
static void init_keyboard(Keyboard *keyboard) {
    int ret = xkb_x11_setup_xkb_extension(keyboard->conn,
        XKB_X11_MIN_MAJOR_XKB_VERSION,
        XKB_X11_MIN_MINOR_XKB_VERSION,
        XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
        NULL, NULL, &keyboard->first_xkb_event, NULL);
    if (!ret) {
        fprintf(stderr, "Failed to setup XKB extension.\n");
        exit(EXIT_FAILURE);
    }
    keyboard->ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
    if (!keyboard->ctx) {
        fprintf(stderr, "Failed to create XKB context.\n");
        exit(EXIT_FAILURE);
    }
    keyboard->device_id = xkb_x11_get_core_keyboard_device_id(keyboard->conn);
    if (keyboard->device_id == -1) {
        fprintf(stderr, "Failed to create keyboard device.\n");
        exit(EXIT_FAILURE);
    }
    static const xcb_xkb_map_part_t required_map_parts = (
        XCB_XKB_MAP_PART_KEY_TYPES |
        XCB_XKB_MAP_PART_KEY_SYMS |
        XCB_XKB_MAP_PART_MODIFIER_MAP |
        XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
        XCB_XKB_MAP_PART_KEY_ACTIONS |
        XCB_XKB_MAP_PART_VIRTUAL_MODS |
        XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
    static const xcb_xkb_event_type_t required_events = (
        XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
        XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
        XCB_XKB_EVENT_TYPE_STATE_NOTIFY);
    xcb_xkb_select_events(
        keyboard->conn,
        keyboard->device_id,
        required_events,
        0,
        required_events,
        required_map_parts,
        required_map_parts,
        NULL);
    keyboard->compose_table = xkb_compose_table_new_from_locale(keyboard->ctx, get_locale(), XKB_COMPOSE_COMPILE_NO_FLAGS);
    if (!keyboard->compose_table) {
        fprintf(stderr, "Failed create compose table.\n");
        exit(EXIT_FAILURE);
    }
    keyboard->compose_state = xkb_compose_state_new(keyboard->compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
    if (!keyboard->compose_state) {
        fprintf(stderr, "Failed create compose state.\n");
        exit(EXIT_FAILURE);
    }
    update_keymap(keyboard);
}
Esempio n. 3
0
static void process_keyboard_event(Keyboard *keyboard, xcb_generic_event_t *event) {
    union xkb_event {
        struct {
            uint8_t response_type;
            uint8_t xkbType;
            uint16_t sequence;
            xcb_timestamp_t time;
            uint8_t deviceID;
        } any;
        xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
        xcb_xkb_map_notify_event_t map_notify;
        xcb_xkb_state_notify_event_t state_notify;
    } *e = (union xkb_event *)event;
    if (e->any.deviceID != keyboard->device_id) {
        return;
    }
    switch (e->any.xkbType) {
        case XCB_XKB_NEW_KEYBOARD_NOTIFY:
            if (e->new_keyboard_notify.changed & XCB_XKB_NKN_DETAIL_KEYCODES) {
                update_keymap(keyboard);
            }
            break;
        case XCB_XKB_MAP_NOTIFY:
            update_keymap(keyboard);
            break;
        case XCB_XKB_STATE_NOTIFY:
            xkb_state_update_mask(keyboard->state,
                e->state_notify.baseMods,
                e->state_notify.latchedMods,
                e->state_notify.lockedMods,
                e->state_notify.baseGroup,
                e->state_notify.latchedGroup,
                e->state_notify.lockedGroup);
            break;
        default:
            break;
    }
}
Esempio n. 4
0
PangoDirection
gdk_keymap_get_direction (GdkKeymap *keymap)
{
  update_keymap ();

  switch (PRIMARYLANGID (LOWORD ((DWORD) (gintptr) _gdk_input_locale)))
    {
    case LANG_HEBREW:
    case LANG_ARABIC:
#ifdef LANG_URDU
    case LANG_URDU:
#endif
    case LANG_FARSI:
      /* Others? */
      return PANGO_DIRECTION_RTL;

    default:
      return PANGO_DIRECTION_LTR;
    }
}
Esempio n. 5
0
gboolean
gdk_keymap_translate_keyboard_state (GdkKeymap       *keymap,
                                     guint            hardware_keycode,
                                     GdkModifierType  state,
                                     gint             group,
                                     guint           *keyval,
                                     gint            *effective_group,
                                     gint            *level,
                                     GdkModifierType *consumed_modifiers)
{
  guint tmp_keyval;
  guint *keyvals;
  gint shift_level;
  gboolean ignore_shift = FALSE;
  gboolean ignore_group = FALSE;
      
  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
  g_return_val_if_fail (group < 4, FALSE);
  
#if 0
  GDK_NOTE (EVENTS, g_print ("gdk_keymap_translate_keyboard_state: keycode=%#x state=%#x group=%d\n",
			     hardware_keycode, state, group));
#endif
  if (keyval)
    *keyval = 0;
  if (effective_group)
    *effective_group = 0;
  if (level)
    *level = 0;
  if (consumed_modifiers)
    *consumed_modifiers = 0;

  /* Accept only the default keymap */
  if (keymap != NULL && keymap != gdk_keymap_get_default ())
    return FALSE;

  if (hardware_keycode >= 256)
    return FALSE;

  if (group < 0 || group >= 2)
    return FALSE;

  update_keymap ();

  keyvals = keysym_tab + hardware_keycode*4;

  if ((state & GDK_LOCK_MASK) &&
      (state & GDK_SHIFT_MASK) &&
      ((gdk_shift_modifiers & GDK_LOCK_MASK) ||
       (keyvals[group*2 + 1] == gdk_keyval_to_upper (keyvals[group*2 + 0]))))
    /* Shift always disables ShiftLock. Shift disables CapsLock for
     * keys with lowercase/uppercase letter pairs.
     */
    shift_level = 0;
  else if (state & gdk_shift_modifiers)
    shift_level = 1;
  else
    shift_level = 0;

  /* Drop group and shift if there are no keysymbols on
   * the key for those.
   */
  if (shift_level == 1 &&
      keyvals[group*2 + 1] == GDK_VoidSymbol &&
      keyvals[group*2] != GDK_VoidSymbol)
    {
      shift_level = 0;
      ignore_shift = TRUE;
    }

  if (group == 1 &&
      keyvals[2 + shift_level] == GDK_VoidSymbol &&
      keyvals[0 + shift_level] != GDK_VoidSymbol)
    {
      group = 0;
      ignore_group = TRUE;
    }

  if (keyvals[group *2 + shift_level] == GDK_VoidSymbol &&
      keyvals[0 + 0] != GDK_VoidSymbol)
    {
      shift_level = 0;
      group = 0;
      ignore_group = TRUE;
      ignore_shift = TRUE;
    }

  /* See whether the group and shift level actually mattered
   * to know what to put in consumed_modifiers
   */
  if (keyvals[group*2 + 1] == GDK_VoidSymbol ||
      keyvals[group*2 + 0] == keyvals[group*2 + 1])
    ignore_shift = TRUE;

  if (keyvals[2 + shift_level] == GDK_VoidSymbol ||
      keyvals[0 + shift_level] == keyvals[2 + shift_level])
    ignore_group = TRUE;

  tmp_keyval = keyvals[group*2 + shift_level];

  /* If a true CapsLock is toggled, and Shift is not down,
   * and the shifted keysym is the uppercase of the unshifted,
   * use it.
   */
  if (!(gdk_shift_modifiers & GDK_LOCK_MASK) &&
      !(state & GDK_SHIFT_MASK) &&
      (state & GDK_LOCK_MASK))
    {
      guint upper = gdk_keyval_to_upper (tmp_keyval);
      if (upper == keyvals[group*2 + 1])
	tmp_keyval = upper;
    }

  if (keyval)
    *keyval = tmp_keyval;

  if (effective_group)
    *effective_group = group;

  if (level)
    *level = shift_level;

  if (consumed_modifiers)
    {
      *consumed_modifiers =
	(ignore_group ? 0 : GDK_MOD2_MASK) |
	(ignore_shift ? 0 : (GDK_SHIFT_MASK|GDK_LOCK_MASK));
    }
				
#if 0
  GDK_NOTE (EVENTS, g_print ("... group=%d level=%d cmods=%#x keyval=%s\n",
			     group, shift_level, tmp_modifiers, gdk_keyval_name (tmp_keyval)));
#endif

  return tmp_keyval != GDK_VoidSymbol;
}
Esempio n. 6
0
gboolean
gdk_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
                                    guint          hardware_keycode,
                                    GdkKeymapKey **keys,
                                    guint        **keyvals,
                                    gint          *n_entries)
{
  GArray *key_array;
  GArray *keyval_array;

  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
  g_return_val_if_fail (n_entries != NULL, FALSE);

  if (hardware_keycode <= 0 ||
      hardware_keycode >= 256)
    {
      if (keys)
        *keys = NULL;
      if (keyvals)
        *keyvals = NULL;

      *n_entries = 0;
      return FALSE;
    }
  
  if (keys)
    key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
  else
    key_array = NULL;
  
  if (keyvals)
    keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
  else
    keyval_array = NULL;
  
  /* Accept only the default keymap */
  if (keymap == NULL || keymap == gdk_keymap_get_default ())
    {
      gint i;

      update_keymap ();

      for (i = 0; i < 4; i++)
	{
	  if (key_array)
            {
              GdkKeymapKey key;
	      
              key.keycode = hardware_keycode;
              
              key.group = i / 2;
              key.level = i % 2;
              
              g_array_append_val (key_array, key);
            }

          if (keyval_array)
            g_array_append_val (keyval_array, keysym_tab[hardware_keycode*4+i]);
	}
    }

  if ((key_array && key_array->len > 0) ||
      (keyval_array && keyval_array->len > 0))
    {
      if (keys)
        *keys = (GdkKeymapKey*) key_array->data;

      if (keyvals)
        *keyvals = (guint*) keyval_array->data;

      if (key_array)
        *n_entries = key_array->len;
      else
        *n_entries = keyval_array->len;
    }
  else
    {
      if (keys)
        *keys = NULL;

      if (keyvals)
        *keyvals = NULL;
      
      *n_entries = 0;
    }

  if (key_array)
    g_array_free (key_array, key_array->len > 0 ? FALSE : TRUE);
  if (keyval_array)
    g_array_free (keyval_array, keyval_array->len > 0 ? FALSE : TRUE);

  return *n_entries > 0;
}
Esempio n. 7
0
gboolean
gdk_keymap_get_entries_for_keyval (GdkKeymap     *keymap,
                                   guint          keyval,
                                   GdkKeymapKey **keys,
                                   gint          *n_keys)
{
  GArray *retval;

  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
  g_return_val_if_fail (keys != NULL, FALSE);
  g_return_val_if_fail (n_keys != NULL, FALSE);
  g_return_val_if_fail (keyval != 0, FALSE);
  
  retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));

  /* Accept only the default keymap */
  if (keymap == NULL || keymap == gdk_keymap_get_default ())
    {
      gint vk;
      
      update_keymap ();

      for (vk = 0; vk < 256; vk++)
	{
	  gint i;

	  for (i = 0; i < 4; i++)
	    {
	      if (keysym_tab[vk*4+i] == keyval)
		{
		  GdkKeymapKey key;
		  
		  key.keycode = vk;
		  
		  /* 2 levels (normal, shift), two groups (normal, AltGr) */
		  key.group = i / 2;
		  key.level = i % 2;
		  
		  g_array_append_val (retval, key);
		}
	    }
	}
    }

#ifdef G_ENABLE_DEBUG
  if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
    {
      gint i;

      g_print ("gdk_keymap_get_entries_for_keyval: %#.04x (%s):",
	       keyval, gdk_keyval_name (keyval));
      for (i = 0; i < retval->len; i++)
	{
	  GdkKeymapKey *entry = (GdkKeymapKey *) retval->data + i;
	  g_print ("  %#.02x %d %d", entry->keycode, entry->group, entry->level);
	}
      g_print ("\n");
    }
#endif

  if (retval->len > 0)
    {
      *keys = (GdkKeymapKey*) retval->data;
      *n_keys = retval->len;
    }
  else
    {
      *keys = NULL;
      *n_keys = 0;
    }
      
  g_array_free (retval, retval->len > 0 ? FALSE : TRUE);

  return *n_keys > 0;
}