• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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