1// Copyright 2014 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 "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" 6 7#include <gdk/gdk.h> 8#include <gdk/gdkx.h> 9#include <gtk/gtk.h> 10#include <X11/X.h> 11 12#include "base/memory/singleton.h" 13#include "ui/gfx/x/x11_types.h" 14 15namespace libgtk2ui { 16 17// static 18Gtk2EventLoop* Gtk2EventLoop::GetInstance() { 19 return Singleton<Gtk2EventLoop>::get(); 20} 21 22Gtk2EventLoop::Gtk2EventLoop() { 23 gdk_event_handler_set(GdkEventTrampoline, this, NULL); 24} 25 26Gtk2EventLoop::~Gtk2EventLoop() { 27 gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), 28 NULL, NULL); 29} 30 31// static 32void Gtk2EventLoop::GdkEventTrampoline(GdkEvent* event, gpointer data) { 33 Gtk2EventLoop* loop = reinterpret_cast<Gtk2EventLoop*>(data); 34 loop->DispatchGdkEvent(event); 35} 36 37void Gtk2EventLoop::DispatchGdkEvent(GdkEvent* gdk_event) { 38 switch (gdk_event->type) { 39 case GDK_KEY_PRESS: 40 case GDK_KEY_RELEASE: 41 ProcessGdkEventKey(gdk_event->key); 42 break; 43 default: 44 break; // Do nothing. 45 } 46 47 gtk_main_do_event(gdk_event); 48} 49 50void Gtk2EventLoop::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) { 51 // This function translates GdkEventKeys into XKeyEvents and puts them to 52 // the X event queue. 53 // 54 // base::MessagePumpX11 is using the X11 event queue and all key events should 55 // be processed there. However, there are cases(*1) that GdkEventKeys are 56 // created instead of XKeyEvents. In these cases, we have to translate 57 // GdkEventKeys to XKeyEvents and puts them to the X event queue so our main 58 // event loop can handle those key events. 59 // 60 // (*1) At least ibus-gtk in async mode creates a copy of user's key event and 61 // pushes it back to the GDK event queue. In this case, there is no 62 // corresponding key event in the X event queue. So we have to handle this 63 // case. ibus-gtk is used through gtk-immodule to support IMEs. 64 65 XEvent x_event = {0}; 66 x_event.xkey.type = 67 gdk_event_key.type == GDK_KEY_PRESS ? KeyPress : KeyRelease; 68 x_event.xkey.send_event = gdk_event_key.send_event; 69 x_event.xkey.display = gfx::GetXDisplay(); 70 x_event.xkey.window = GDK_WINDOW_XID(gdk_event_key.window); 71 x_event.xkey.root = DefaultRootWindow(x_event.xkey.display); 72 x_event.xkey.time = gdk_event_key.time; 73 x_event.xkey.state = gdk_event_key.state; 74 x_event.xkey.keycode = gdk_event_key.hardware_keycode; 75 x_event.xkey.same_screen = true; 76 77 XPutBackEvent(x_event.xkey.display, &x_event); 78} 79 80} // namespace libgtk2ui 81