Index: base/event_synthesis_gtk.cc |
diff --git a/base/event_synthesis_gtk.cc b/base/event_synthesis_gtk.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..20559099e2ab4e82d36d74f694b6447e01f9dc1b |
--- /dev/null |
+++ b/base/event_synthesis_gtk.cc |
@@ -0,0 +1,90 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/event_synthesis_gtk.h" |
+ |
+#include "base/keyboard_code_conversion_gtk.h" |
+ |
+namespace base { |
+ |
+GdkEvent* SynthesizeKeyEvent(GdkWindow* window, |
+ bool press, guint gdk_key, guint state) { |
+ GdkEvent* event = gdk_event_new(press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); |
+ |
+ event->key.type = press ? GDK_KEY_PRESS : GDK_KEY_RELEASE; |
+ event->key.window = window; |
+ if (window) |
+ g_object_ref(window); |
+ event->key.send_event = false; |
+ |
+ struct timespec ts; |
+ clock_gettime(CLOCK_MONOTONIC, &ts); |
+ event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; |
+ |
+ event->key.state = state; |
+ event->key.keyval = gdk_key; |
+ |
+ GdkKeymapKey* keys; |
+ gint n_keys; |
+ if (event->key.keyval != 0 && |
+ gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), |
+ event->key.keyval, &keys, &n_keys)) { |
+ event->key.hardware_keycode = keys[0].keycode; |
+ event->key.group = keys[0].group; |
+ g_free(keys); |
+ } |
+ |
+ return event; |
+} |
+ |
+void SynthesizeKeyPressEvents(GdkWindow* window, |
+ base::KeyboardCode key, |
+ bool control, bool shift, bool alt, |
+ std::vector<GdkEvent*>* events) { |
+ if (control) |
+ events->push_back( |
+ SynthesizeKeyEvent(window, true, GDK_Control_L, 0)); |
+ |
+ if (shift) { |
+ events->push_back(SynthesizeKeyEvent(window, true, GDK_Shift_L, |
+ control ? GDK_CONTROL_MASK : 0)); |
+ } |
+ |
+ if (alt) { |
+ guint state = (control ? GDK_CONTROL_MASK : 0) | |
+ (shift ? GDK_SHIFT_MASK : 0); |
+ events->push_back( |
+ SynthesizeKeyEvent(window, true, GDK_Alt_L, state)); |
+ } |
+ |
+ // TODO(estade): handle other state flags besides control, shift, alt? |
+ // For example caps lock. |
+ guint state = (control ? GDK_CONTROL_MASK : 0) | |
+ (shift ? GDK_SHIFT_MASK : 0) | |
+ (alt ? GDK_MOD1_MASK : 0); |
+ |
+ guint gdk_key = base::GdkKeyCodeForWindowsKeyCode(key, shift); |
+ events->push_back(SynthesizeKeyEvent(window, true, gdk_key, state)); |
+ events->push_back(SynthesizeKeyEvent(window, false, gdk_key, state)); |
+ |
+ if (alt) { |
+ guint state = (control ? GDK_CONTROL_MASK : 0) | |
+ (shift ? GDK_SHIFT_MASK : 0) | GDK_MOD1_MASK; |
+ events->push_back( |
+ SynthesizeKeyEvent(window, false, GDK_Alt_L, state)); |
+ } |
+ |
+ if (shift) { |
+ events->push_back( |
+ SynthesizeKeyEvent(window, false, GDK_Shift_L, |
+ (control ? GDK_CONTROL_MASK : 0) | GDK_SHIFT_MASK)); |
+ } |
+ |
+ if (control) { |
+ events->push_back( |
+ SynthesizeKeyEvent(window, false, GDK_Control_L, GDK_CONTROL_MASK)); |
+ } |
+} |
+ |
+} // namespace base |