message_pump_glib.h revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2008 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/message_pump.h" 10#include "base/observer_list.h" 11#include "base/scoped_ptr.h" 12#include "base/time.h" 13 14typedef union _GdkEvent GdkEvent; 15typedef struct _GMainContext GMainContext; 16typedef struct _GPollFD GPollFD; 17typedef struct _GSource GSource; 18 19namespace base { 20 21// This class implements a MessagePump needed for TYPE_UI MessageLoops on 22// OS_LINUX platforms using GLib. 23class 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: 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: 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 virtual void Run(Delegate* delegate); 66 virtual void Quit(); 67 virtual void ScheduleWork(); 68 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time); 69 70 // Internal methods used for processing the pump callbacks. They are 71 // public for simplicity but should not be used directly. HandlePrepare 72 // is called during the prepare step of glib, and returns a timeout that 73 // will be passed to the poll. HandleCheck is called after the poll 74 // has completed, and returns whether or not HandleDispatch should be called. 75 // HandleDispatch is called if HandleCheck returned true. 76 int HandlePrepare(); 77 bool HandleCheck(); 78 void HandleDispatch(); 79 80 // Adds an Observer, which will start receiving notifications immediately. 81 void AddObserver(Observer* observer); 82 83 // Removes an Observer. It is safe to call this method while an Observer is 84 // receiving a notification callback. 85 void RemoveObserver(Observer* observer); 86 87 // Dispatch an available GdkEvent. Essentially this allows a subclass to do 88 // some task before/after calling the default handler (EventDispatcher). 89 virtual void DispatchEvents(GdkEvent* event); 90 91 protected: 92 // Returns the dispatcher for the current run state (|state_->dispatcher|). 93 Dispatcher* GetDispatcher(); 94 95 private: 96 // We may make recursive calls to Run, so we save state that needs to be 97 // separate between them in this structure type. 98 struct RunState; 99 100 // Invoked from EventDispatcher. Notifies all observers we're about to 101 // process an event. 102 void WillProcessEvent(GdkEvent* event); 103 104 // Invoked from EventDispatcher. Notifies all observers we processed an 105 // event. 106 void DidProcessEvent(GdkEvent* event); 107 108 // Callback prior to gdk dispatching an event. 109 static void EventDispatcher(GdkEvent* event, void* data); 110 111 RunState* state_; 112 113 // This is a GLib structure that we can add event sources to. We use the 114 // default GLib context, which is the one to which all GTK events are 115 // dispatched. 116 GMainContext* context_; 117 118 // This is the time when we need to do delayed work. 119 TimeTicks delayed_work_time_; 120 121 // The work source. It is shared by all calls to Run and destroyed when 122 // the message pump is destroyed. 123 GSource* work_source_; 124 125 // We use a wakeup pipe to make sure we'll get out of the glib polling phase 126 // when another thread has scheduled us to do some work. There is a glib 127 // mechanism g_main_context_wakeup, but this won't guarantee that our event's 128 // Dispatch() will be called. 129 int wakeup_pipe_read_; 130 int wakeup_pipe_write_; 131 // Use a scoped_ptr to avoid needing the definition of GPollFD in the header. 132 scoped_ptr<GPollFD> wakeup_gpollfd_; 133 134 // List of observers. 135 ObserverList<Observer> observers_; 136 137 DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); 138}; 139 140} // namespace base 141 142#endif // BASE_MESSAGE_PUMP_GLIB_H_ 143