int qemu_input_key_value_to_qcode(const KeyValue *value) { if (value->type == KEY_VALUE_KIND_QCODE) { return value->u.qcode; } else { assert(value->type == KEY_VALUE_KIND_NUMBER); return qemu_input_key_number_to_qcode(value->u.number); } }
int keysym2scancode(kbd_layout_t *k, int keysym, QKbdState *kbd, bool down) { static const uint32_t mask = SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL; uint32_t mods, i; struct keysym2code *keysym2code; #ifdef XK_ISO_Left_Tab if (keysym == XK_ISO_Left_Tab) { keysym = XK_Tab; } #endif keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym)); if (!keysym2code) { trace_keymap_unmapped(keysym); warn_report("no scancode found for keysym %d", keysym); return 0; } if (keysym2code->count == 1) { return keysym2code->keycodes[0]; } /* We have multiple keysym -> keycode mappings. */ if (down) { /* * On keydown: Check whenever we find one mapping where the * modifier state of the mapping matches the current user * interface modifier state. If so, prefer that one. */ mods = 0; if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) { mods |= SCANCODE_SHIFT; } if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) { mods |= SCANCODE_ALTGR; } if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) { mods |= SCANCODE_CTRL; } for (i = 0; i < keysym2code->count; i++) { if ((keysym2code->keycodes[i] & mask) == mods) { return keysym2code->keycodes[i]; } } } else { /* * On keyup: Try find a key which is actually down. */ for (i = 0; i < keysym2code->count; i++) { QKeyCode qcode = qemu_input_key_number_to_qcode (keysym2code->keycodes[i]); if (kbd && qkbd_state_key_get(kbd, qcode)) { return keysym2code->keycodes[i]; } } } return keysym2code->keycodes[0]; }