1 // Copyright (c) 2011 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 #ifndef BASE_MESSAGE_PUMP_GLIB_H_ 6 #define BASE_MESSAGE_PUMP_GLIB_H_ 7 #pragma once 8 9 #include "base/memory/scoped_ptr.h" 10 #include "base/message_pump.h" 11 #include "base/observer_list.h" 12 #include "base/time.h" 13 14 typedef union _GdkEvent GdkEvent; 15 typedef struct _GMainContext GMainContext; 16 typedef struct _GPollFD GPollFD; 17 typedef struct _GSource GSource; 18 19 namespace base { 20 21 // This class implements a MessagePump needed for TYPE_UI MessageLoops on 22 // OS_LINUX platforms using GLib. 23 class MessagePumpForUI : public MessagePump { 24 public: 25 // Observer is notified prior to a GdkEvent event being dispatched. As 26 // Observers are notified of every change, they have to be FAST! 27 class Observer { 28 public: ~Observer()29 virtual ~Observer() {} 30 31 // This method is called before processing a message. 32 virtual void WillProcessEvent(GdkEvent* event) = 0; 33 34 // This method is called after processing a message. 35 virtual void DidProcessEvent(GdkEvent* event) = 0; 36 }; 37 38 // Dispatcher is used during a nested invocation of Run to dispatch events. 39 // If Run is invoked with a non-NULL Dispatcher, MessageLoop does not 40 // dispatch events (or invoke gtk_main_do_event), rather every event is 41 // passed to Dispatcher's Dispatch method for dispatch. It is up to the 42 // Dispatcher to dispatch, or not, the event. 43 // 44 // The nested loop is exited by either posting a quit, or returning false 45 // from Dispatch. 46 class Dispatcher { 47 public: ~Dispatcher()48 virtual ~Dispatcher() {} 49 // Dispatches the event. If true is returned processing continues as 50 // normal. If false is returned, the nested loop exits immediately. 51 virtual bool Dispatch(GdkEvent* event) = 0; 52 }; 53 54 MessagePumpForUI(); 55 virtual ~MessagePumpForUI(); 56 57 // Like MessagePump::Run, but GdkEvent objects are routed through dispatcher. 58 virtual void RunWithDispatcher(Delegate* delegate, Dispatcher* dispatcher); 59 60 // Run a single iteration of the mainloop. A return value of true indicates 61 // that an event was handled. |block| indicates if it should wait if no event 62 // is ready for processing. 63 virtual bool RunOnce(GMainContext* context, bool block); 64 65 // Internal methods used for processing the pump callbacks. They are 66 // public for simplicity but should not be used directly. HandlePrepare 67 // is called during the prepare step of glib, and returns a timeout that 68 // will be passed to the poll. HandleCheck is called after the poll 69 // has completed, and returns whether or not HandleDispatch should be called. 70 // HandleDispatch is called if HandleCheck returned true. 71 int HandlePrepare(); 72 bool HandleCheck(); 73 void HandleDispatch(); 74 75 // Adds an Observer, which will start receiving notifications immediately. 76 void AddObserver(Observer* observer); 77 78 // Removes an Observer. It is safe to call this method while an Observer is 79 // receiving a notification callback. 80 void RemoveObserver(Observer* observer); 81 82 // Dispatch an available GdkEvent. Essentially this allows a subclass to do 83 // some task before/after calling the default handler (EventDispatcher). 84 virtual void DispatchEvents(GdkEvent* event); 85 86 // Overridden from MessagePump: 87 virtual void Run(Delegate* delegate); 88 virtual void Quit(); 89 virtual void ScheduleWork(); 90 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time); 91 92 protected: 93 // Returns the dispatcher for the current run state (|state_->dispatcher|). 94 Dispatcher* GetDispatcher(); 95 96 private: 97 // We may make recursive calls to Run, so we save state that needs to be 98 // separate between them in this structure type. 99 struct RunState; 100 101 // Invoked from EventDispatcher. Notifies all observers we're about to 102 // process an event. 103 void WillProcessEvent(GdkEvent* event); 104 105 // Invoked from EventDispatcher. Notifies all observers we processed an 106 // event. 107 void DidProcessEvent(GdkEvent* event); 108 109 // Callback prior to gdk dispatching an event. 110 static void EventDispatcher(GdkEvent* event, void* data); 111 112 RunState* state_; 113 114 // This is a GLib structure that we can add event sources to. We use the 115 // default GLib context, which is the one to which all GTK events are 116 // dispatched. 117 GMainContext* context_; 118 119 // This is the time when we need to do delayed work. 120 TimeTicks delayed_work_time_; 121 122 // The work source. It is shared by all calls to Run and destroyed when 123 // the message pump is destroyed. 124 GSource* work_source_; 125 126 // We use a wakeup pipe to make sure we'll get out of the glib polling phase 127 // when another thread has scheduled us to do some work. There is a glib 128 // mechanism g_main_context_wakeup, but this won't guarantee that our event's 129 // Dispatch() will be called. 130 int wakeup_pipe_read_; 131 int wakeup_pipe_write_; 132 // Use a scoped_ptr to avoid needing the definition of GPollFD in the header. 133 scoped_ptr<GPollFD> wakeup_gpollfd_; 134 135 // List of observers. 136 ObserverList<Observer> observers_; 137 138 DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); 139 }; 140 141 } // namespace base 142 143 #endif // BASE_MESSAGE_PUMP_GLIB_H_ 144