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/events/keycodes/keyboard_code_conversion_gtk.h"
8
9 namespace ui {
10
SynthesizeKeyEvent(GdkWindow * window,bool press,guint gdk_key,guint state)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
SynthesizeKeyPressEvents(GdkWindow * window,KeyboardCode key,bool control,bool shift,bool alt,std::vector<GdkEvent * > * events)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