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.
5 #ifndef BASE_MESSAGE_PUMP_GLIB_H_
6 #define BASE_MESSAGE_PUMP_GLIB_H_
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_pump.h"
11 #include "base/observer_list.h"
12 #include "base/time.h"
14 typedef union _GdkEvent GdkEvent
;
15 typedef struct _GMainContext GMainContext
;
16 typedef struct _GPollFD GPollFD
;
17 typedef struct _GSource GSource
;
21 // This class implements a MessagePump needed for TYPE_UI MessageLoops on
22 // OS_LINUX platforms using GLib.
23 class MessagePumpForUI
: public MessagePump
{
25 // Observer is notified prior to a GdkEvent event being dispatched. As
26 // Observers are notified of every change, they have to be FAST!
29 virtual ~Observer() {}
31 // This method is called before processing a message.
32 virtual void WillProcessEvent(GdkEvent
* event
) = 0;
34 // This method is called after processing a message.
35 virtual void DidProcessEvent(GdkEvent
* event
) = 0;
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.
44 // The nested loop is exited by either posting a quit, or returning false
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;
55 virtual ~MessagePumpForUI();
57 // Like MessagePump::Run, but GdkEvent objects are routed through dispatcher.
58 virtual void RunWithDispatcher(Delegate
* delegate
, Dispatcher
* dispatcher
);
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
);
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.
73 void HandleDispatch();
75 // Adds an Observer, which will start receiving notifications immediately.
76 void AddObserver(Observer
* observer
);
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
);
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
);
86 // Overridden from MessagePump:
87 virtual void Run(Delegate
* delegate
);
89 virtual void ScheduleWork();
90 virtual void ScheduleDelayedWork(const TimeTicks
& delayed_work_time
);
93 // Returns the dispatcher for the current run state (|state_->dispatcher|).
94 Dispatcher
* GetDispatcher();
97 // We may make recursive calls to Run, so we save state that needs to be
98 // separate between them in this structure type.
101 // Invoked from EventDispatcher. Notifies all observers we're about to
103 void WillProcessEvent(GdkEvent
* event
);
105 // Invoked from EventDispatcher. Notifies all observers we processed an
107 void DidProcessEvent(GdkEvent
* event
);
109 // Callback prior to gdk dispatching an event.
110 static void EventDispatcher(GdkEvent
* event
, void* data
);
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
117 GMainContext
* context_
;
119 // This is the time when we need to do delayed work.
120 TimeTicks delayed_work_time_
;
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_
;
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_
;
135 // List of observers.
136 ObserverList
<Observer
> observers_
;
138 DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI
);
143 #endif // BASE_MESSAGE_PUMP_GLIB_H_