• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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