1 // Copyright (c) 2012 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 "base/message_loop/message_pump_gtk.h" 6 7 #include <gtk/gtk.h> 8 #include <gdk/gdkx.h> 9 10 #include "base/debug/trace_event.h" 11 #include "base/profiler/scoped_profile.h" 12 13 namespace base { 14 15 namespace { 16 17 const char* EventToTypeString(const GdkEvent* event) { 18 switch (event->type) { 19 case GDK_NOTHING: return "GDK_NOTHING"; 20 case GDK_DELETE: return "GDK_DELETE"; 21 case GDK_DESTROY: return "GDK_DESTROY"; 22 case GDK_EXPOSE: return "GDK_EXPOSE"; 23 case GDK_MOTION_NOTIFY: return "GDK_MOTION_NOTIFY"; 24 case GDK_BUTTON_PRESS: return "GDK_BUTTON_PRESS"; 25 case GDK_2BUTTON_PRESS: return "GDK_2BUTTON_PRESS"; 26 case GDK_3BUTTON_PRESS: return "GDK_3BUTTON_PRESS"; 27 case GDK_BUTTON_RELEASE: return "GDK_BUTTON_RELEASE"; 28 case GDK_KEY_PRESS: return "GDK_KEY_PRESS"; 29 case GDK_KEY_RELEASE: return "GDK_KEY_RELEASE"; 30 case GDK_ENTER_NOTIFY: return "GDK_ENTER_NOTIFY"; 31 case GDK_LEAVE_NOTIFY: return "GDK_LEAVE_NOTIFY"; 32 case GDK_FOCUS_CHANGE: return "GDK_FOCUS_CHANGE"; 33 case GDK_CONFIGURE: return "GDK_CONFIGURE"; 34 case GDK_MAP: return "GDK_MAP"; 35 case GDK_UNMAP: return "GDK_UNMAP"; 36 case GDK_PROPERTY_NOTIFY: return "GDK_PROPERTY_NOTIFY"; 37 case GDK_SELECTION_CLEAR: return "GDK_SELECTION_CLEAR"; 38 case GDK_SELECTION_REQUEST: return "GDK_SELECTION_REQUEST"; 39 case GDK_SELECTION_NOTIFY: return "GDK_SELECTION_NOTIFY"; 40 case GDK_PROXIMITY_IN: return "GDK_PROXIMITY_IN"; 41 case GDK_PROXIMITY_OUT: return "GDK_PROXIMITY_OUT"; 42 case GDK_DRAG_ENTER: return "GDK_DRAG_ENTER"; 43 case GDK_DRAG_LEAVE: return "GDK_DRAG_LEAVE"; 44 case GDK_DRAG_MOTION: return "GDK_DRAG_MOTION"; 45 case GDK_DRAG_STATUS: return "GDK_DRAG_STATUS"; 46 case GDK_DROP_START: return "GDK_DROP_START"; 47 case GDK_DROP_FINISHED: return "GDK_DROP_FINISHED"; 48 case GDK_CLIENT_EVENT: return "GDK_CLIENT_EVENT"; 49 case GDK_VISIBILITY_NOTIFY: return "GDK_VISIBILITY_NOTIFY"; 50 case GDK_NO_EXPOSE: return "GDK_NO_EXPOSE"; 51 case GDK_SCROLL: return "GDK_SCROLL"; 52 case GDK_WINDOW_STATE: return "GDK_WINDOW_STATE"; 53 case GDK_SETTING: return "GDK_SETTING"; 54 case GDK_OWNER_CHANGE: return "GDK_OWNER_CHANGE"; 55 case GDK_GRAB_BROKEN: return "GDK_GRAB_BROKEN"; 56 case GDK_DAMAGE: return "GDK_DAMAGE"; 57 default: 58 return "Unknown Gdk Event"; 59 } 60 } 61 62 } // namespace 63 64 MessagePumpGtk::MessagePumpGtk() : MessagePumpGlib() { 65 gdk_event_handler_set(&EventDispatcher, this, NULL); 66 } 67 68 MessagePumpGtk::~MessagePumpGtk() { 69 gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), 70 this, NULL); 71 } 72 73 void MessagePumpGtk::DispatchEvents(GdkEvent* event) { 74 UNSHIPPED_TRACE_EVENT1("task", "MessagePumpGtk::DispatchEvents", 75 "type", EventToTypeString(event)); 76 77 WillProcessEvent(event); 78 gtk_main_do_event(event); 79 DidProcessEvent(event); 80 } 81 82 // static 83 Display* MessagePumpGtk::GetDefaultXDisplay() { 84 static GdkDisplay* display = gdk_display_get_default(); 85 if (!display) { 86 // GTK / GDK has not been initialized, which is a decision we wish to 87 // support, for example for the GPU process. 88 static Display* xdisplay = XOpenDisplay(NULL); 89 return xdisplay; 90 } 91 return GDK_DISPLAY_XDISPLAY(display); 92 } 93 94 void MessagePumpGtk::AddObserver(MessagePumpGdkObserver* observer) { 95 observers_.AddObserver(observer); 96 } 97 98 void MessagePumpGtk::RemoveObserver(MessagePumpGdkObserver* observer) { 99 observers_.RemoveObserver(observer); 100 } 101 102 void MessagePumpGtk::WillProcessEvent(GdkEvent* event) { 103 FOR_EACH_OBSERVER(MessagePumpGdkObserver, 104 observers_, 105 WillProcessEvent(event)); 106 } 107 108 void MessagePumpGtk::DidProcessEvent(GdkEvent* event) { 109 FOR_EACH_OBSERVER(MessagePumpGdkObserver, 110 observers_, 111 DidProcessEvent(event)); 112 } 113 114 // static 115 void MessagePumpGtk::EventDispatcher(GdkEvent* event, gpointer data) { 116 MessagePumpGtk* message_pump = reinterpret_cast<MessagePumpGtk*>(data); 117 message_pump->DispatchEvents(event); 118 } 119 120 } // namespace base 121