15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/event_synthesis_gtk.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/keycodes/keyboard_code_conversion_gtk.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkEvent* SynthesizeKeyEvent(GdkWindow* window, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool press, guint gdk_key, guint state) { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEvent* event = gdk_event_new(press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.type = press ? GDK_KEY_PRESS : GDK_KEY_RELEASE; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.window = window; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref(window); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.send_event = false; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timespec ts; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clock_gettime(CLOCK_MONOTONIC, &ts); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.state = state; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.keyval = gdk_key; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkKeymapKey* keys; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint n_keys; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->key.keyval != 0 && 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.keyval, &keys, &n_keys)) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.hardware_keycode = keys[0].keycode; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->key.group = keys[0].group; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(keys); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SynthesizeKeyPressEvents(GdkWindow* window, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyboardCode key, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool control, bool shift, bool alt, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GdkEvent*>* events) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (control) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SynthesizeKeyEvent(window, true, GDK_Control_L, 0)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back(SynthesizeKeyEvent(window, true, GDK_Shift_L, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control ? GDK_CONTROL_MASK : 0)); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alt) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint state = (control ? GDK_CONTROL_MASK : 0) | 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (shift ? GDK_SHIFT_MASK : 0); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SynthesizeKeyEvent(window, true, GDK_Alt_L, state)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): handle other state flags besides control, shift, alt? 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example caps lock. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint state = (control ? GDK_CONTROL_MASK : 0) | 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (shift ? GDK_SHIFT_MASK : 0) | 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (alt ? GDK_MOD1_MASK : 0); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint gdk_key = GdkKeyCodeForWindowsKeyCode(key, shift); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back(SynthesizeKeyEvent(window, true, gdk_key, state)); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back(SynthesizeKeyEvent(window, false, gdk_key, state)); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alt) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint state = (control ? GDK_CONTROL_MASK : 0) | 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (shift ? GDK_SHIFT_MASK : 0) | GDK_MOD1_MASK; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SynthesizeKeyEvent(window, false, GDK_Alt_L, state)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SynthesizeKeyEvent(window, false, GDK_Shift_L, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (control ? GDK_CONTROL_MASK : 0) | GDK_SHIFT_MASK)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (control) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back( 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SynthesizeKeyEvent(window, false, GDK_Control_L, GDK_CONTROL_MASK)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 91