int keysym2scancode(kbd_layout_t *k, int keysym, bool shift, bool altgr, bool ctrl) { 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. * * 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 (shift) { mods |= SCANCODE_SHIFT; } if (altgr) { mods |= SCANCODE_ALTGR; } if (ctrl) { mods |= SCANCODE_CTRL; } for (i = 0; i < keysym2code->count; i++) { if ((keysym2code->keycodes[i] & mask) == mods) { return keysym2code->keycodes[i]; } } return keysym2code->keycodes[0]; }
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]; }