// 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 "app/event_synthesis_gtk.h" #include "app/keyboard_code_conversion_gtk.h" namespace app { 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, app::KeyboardCode key, bool control, bool shift, bool alt, std::vector* 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 = 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 app