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 :
8 : #include "base/message_pump.h"
9 : #include "base/observer_list.h"
10 : #include "base/scoped_ptr.h"
11 : #include "base/time.h"
12 :
13 : typedef union _GdkEvent GdkEvent;
14 : typedef struct _GMainContext GMainContext;
15 : typedef struct _GPollFD GPollFD;
16 : typedef struct _GSource GSource;
17 :
18 : namespace base {
19 :
20 : // This class implements a MessagePump needed for TYPE_UI MessageLoops on
21 : // OS_LINUX platforms using GLib.
22 : class MessagePumpForUI : public MessagePump {
23 : public:
24 : // Observer is notified prior to a GdkEvent event being dispatched. As
25 : // Observers are notified of every change, they have to be FAST!
26 : class Observer {
27 : public:
28 : virtual ~Observer() {}
29 :
30 : // This method is called before processing a message.
31 : virtual void WillProcessEvent(GdkEvent* event) = 0;
32 :
33 : // This method is called after processing a message.
34 : virtual void DidProcessEvent(GdkEvent* event) = 0;
35 : };
36 :
37 : // Dispatcher is used during a nested invocation of Run to dispatch events.
38 : // If Run is invoked with a non-NULL Dispatcher, MessageLoop does not
39 : // dispatch events (or invoke gtk_main_do_event), rather every event is
40 : // passed to Dispatcher's Dispatch method for dispatch. It is up to the
41 : // Dispatcher to dispatch, or not, the event.
42 : //
43 : // The nested loop is exited by either posting a quit, or returning false
44 : // from Dispatch.
45 : class Dispatcher {
46 : public:
47 : virtual ~Dispatcher() {}
48 : // Dispatches the event. If true is returned processing continues as
49 : // normal. If false is returned, the nested loop exits immediately.
50 : virtual bool Dispatch(GdkEvent* event) = 0;
51 : };
52 :
53 : MessagePumpForUI();
54 : virtual ~MessagePumpForUI();
55 :
56 : // Like MessagePump::Run, but GdkEvent objects are routed through dispatcher.
57 : virtual void RunWithDispatcher(Delegate* delegate, Dispatcher* dispatcher);
58 :
59 0 : virtual void Run(Delegate* delegate) { RunWithDispatcher(delegate, NULL); }
60 : virtual void Quit();
61 : virtual void ScheduleWork();
62 : virtual void ScheduleDelayedWork(const Time& delayed_work_time);
63 :
64 : // Internal methods used for processing the pump callbacks. They are
65 : // public for simplicity but should not be used directly. HandlePrepare
66 : // is called during the prepare step of glib, and returns a timeout that
67 : // will be passed to the poll. HandleCheck is called after the poll
68 : // has completed, and returns whether or not HandleDispatch should be called.
69 : // HandleDispatch is called if HandleCheck returned true.
70 : int HandlePrepare();
71 : bool HandleCheck();
72 : void HandleDispatch();
73 :
74 : // Adds an Observer, which will start receiving notifications immediately.
75 : void AddObserver(Observer* observer);
76 :
77 : // Removes an Observer. It is safe to call this method while an Observer is
78 : // receiving a notification callback.
79 : void RemoveObserver(Observer* observer);
80 :
81 : private:
82 : // We may make recursive calls to Run, so we save state that needs to be
83 : // separate between them in this structure type.
84 : struct RunState {
85 : Delegate* delegate;
86 : Dispatcher* dispatcher;
87 :
88 : // Used to flag that the current Run() invocation should return ASAP.
89 : bool should_quit;
90 :
91 : // Used to count how many Run() invocations are on the stack.
92 : int run_depth;
93 :
94 : // This keeps the state of whether the pump got signaled that there was new
95 : // work to be done. Since we eat the message on the wake up pipe as soon as
96 : // we get it, we keep that state here to stay consistent.
97 : bool has_work;
98 : };
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 : Time 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_
|