1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/base/gtk/event_synthesis_gtk.h" 6 7 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" 8 9 namespace ui { 10 11 GdkEvent* SynthesizeKeyEvent(GdkWindow* window, 12 bool press, guint gdk_key, guint state) { 13 GdkEvent* event = gdk_event_new(press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); 14 15 event->key.type = press ? GDK_KEY_PRESS : GDK_KEY_RELEASE; 16 event->key.window = window; 17 if (window) 18 g_object_ref(window); 19 event->key.send_event = false; 20 21 struct timespec ts; 22 clock_gettime(CLOCK_MONOTONIC, &ts); 23 event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; 24 25 event->key.state = state; 26 event->key.keyval = gdk_key; 27 28 GdkKeymapKey* keys; 29 gint n_keys; 30 if (event->key.keyval != 0 && 31 gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), 32 event->key.keyval, &keys, &n_keys)) { 33 event->key.hardware_keycode = keys[0].keycode; 34 event->key.group = keys[0].group; 35 g_free(keys); 36 } 37 38 return event; 39 } 40 41 void SynthesizeKeyPressEvents(GdkWindow* window, 42 KeyboardCode key, 43 bool control, bool shift, bool alt, 44 std::vector<GdkEvent*>* events) { 45 if (control) 46 events->push_back( 47 SynthesizeKeyEvent(window, true, GDK_Control_L, 0)); 48 49 if (shift) { 50 events->push_back(SynthesizeKeyEvent(window, true, GDK_Shift_L, 51 control ? GDK_CONTROL_MASK : 0)); 52 } 53 54 if (alt) { 55 guint state = (control ? GDK_CONTROL_MASK : 0) | 56 (shift ? GDK_SHIFT_MASK : 0); 57 events->push_back( 58 SynthesizeKeyEvent(window, true, GDK_Alt_L, state)); 59 } 60 61 // TODO(estade): handle other state flags besides control, shift, alt? 62 // For example caps lock. 63 guint state = (control ? GDK_CONTROL_MASK : 0) | 64 (shift ? GDK_SHIFT_MASK : 0) | 65 (alt ? GDK_MOD1_MASK : 0); 66 67 guint gdk_key = GdkKeyCodeForWindowsKeyCode(key, shift); 68 events->push_back(SynthesizeKeyEvent(window, true, gdk_key, state)); 69 events->push_back(SynthesizeKeyEvent(window, false, gdk_key, state)); 70 71 if (alt) { 72 guint state = (control ? GDK_CONTROL_MASK : 0) | 73 (shift ? GDK_SHIFT_MASK : 0) | GDK_MOD1_MASK; 74 events->push_back( 75 SynthesizeKeyEvent(window, false, GDK_Alt_L, state)); 76 } 77 78 if (shift) { 79 events->push_back( 80 SynthesizeKeyEvent(window, false, GDK_Shift_L, 81 (control ? GDK_CONTROL_MASK : 0) | GDK_SHIFT_MASK)); 82 } 83 84 if (control) { 85 events->push_back( 86 SynthesizeKeyEvent(window, false, GDK_Control_L, GDK_CONTROL_MASK)); 87 } 88 } 89 90 } // namespace ui 91