blob: 06635de73565a4d4d8e35dcd6ee3726f246cbb20 [file] [log] [blame]
[email protected]8fc3a482008-10-03 16:52:591// 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_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]8fc3a482008-10-03 16:52:598
[email protected]8fc3a482008-10-03 16:52:599#include "base/message_pump.h"
[email protected]05062e22009-05-15 22:40:0510#include "base/observer_list.h"
[email protected]831a32d2009-12-04 20:45:5411#include "base/scoped_ptr.h"
[email protected]8fc3a482008-10-03 16:52:5912#include "base/time.h"
13
[email protected]831a32d2009-12-04 20:45:5414typedef union _GdkEvent GdkEvent;
15typedef struct _GMainContext GMainContext;
16typedef struct _GPollFD GPollFD;
17typedef struct _GSource GSource;
18
[email protected]8fc3a482008-10-03 16:52:5919namespace 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:
[email protected]05062e22009-05-15 22:40:0525 // 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;
[email protected]dbaa96b2009-05-19 23:04:4233
34 // This method is called after processing a message.
35 virtual void DidProcessEvent(GdkEvent* event) = 0;
[email protected]05062e22009-05-15 22:40:0536 };
37
[email protected]148d1052009-07-31 22:53:3738 // 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 };
[email protected]8fc3a482008-10-03 16:52:5953
[email protected]148d1052009-07-31 22:53:3754 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
[email protected]71ad9c6f2010-10-22 16:17:4760 // 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
[email protected]148d1052009-07-31 22:53:3765 virtual void Run(Delegate* delegate) { RunWithDispatcher(delegate, NULL); }
[email protected]8fc3a482008-10-03 16:52:5966 virtual void Quit();
67 virtual void ScheduleWork();
[email protected]7e7fab42010-11-06 22:23:2968 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
[email protected]8fc3a482008-10-03 16:52:5969
[email protected]95fac4232008-11-13 00:25:5170 // 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
[email protected]b105b9e2009-06-01 22:01:5373 // 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.
[email protected]95fac4232008-11-13 00:25:5176 int HandlePrepare();
[email protected]b105b9e2009-06-01 22:01:5377 bool HandleCheck();
[email protected]95fac4232008-11-13 00:25:5178 void HandleDispatch();
79
[email protected]148d1052009-07-31 22:53:3780 // Adds an Observer, which will start receiving notifications immediately.
[email protected]05062e22009-05-15 22:40:0581 void AddObserver(Observer* observer);
82
[email protected]148d1052009-07-31 22:53:3783 // Removes an Observer. It is safe to call this method while an Observer is
[email protected]05062e22009-05-15 22:40:0584 // receiving a notification callback.
85 void RemoveObserver(Observer* observer);
86
[email protected]71ad9c6f2010-10-22 16:17:4787 // 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
[email protected]b2f7ac42010-10-26 18:43:1891 protected:
92 // Returns the dispatcher for the current run state (|state_->dispatcher|).
93 Dispatcher* GetDispatcher();
94
[email protected]8fc3a482008-10-03 16:52:5995 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.
[email protected]e7af5962010-08-05 22:36:0498 struct RunState;
[email protected]8fc3a482008-10-03 16:52:5999
[email protected]05062e22009-05-15 22:40:05100 // Invoked from EventDispatcher. Notifies all observers we're about to
101 // process an event.
102 void WillProcessEvent(GdkEvent* event);
103
[email protected]dbaa96b2009-05-19 23:04:42104 // Invoked from EventDispatcher. Notifies all observers we processed an
105 // event.
106 void DidProcessEvent(GdkEvent* event);
107
[email protected]05062e22009-05-15 22:40:05108 // Callback prior to gdk dispatching an event.
[email protected]831a32d2009-12-04 20:45:54109 static void EventDispatcher(GdkEvent* event, void* data);
[email protected]05062e22009-05-15 22:40:05110
[email protected]8fc3a482008-10-03 16:52:59111 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.
[email protected]7e7fab42010-11-06 22:23:29119 TimeTicks delayed_work_time_;
[email protected]8fc3a482008-10-03 16:52:59120
[email protected]8fc3a482008-10-03 16:52:59121 // The work source. It is shared by all calls to Run and destroyed when
122 // the message pump is destroyed.
123 GSource* work_source_;
[email protected]8fc3a482008-10-03 16:52:59124
[email protected]aa0f2662008-11-18 01:30:42125 // 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_;
[email protected]831a32d2009-12-04 20:45:54131 // Use a scoped_ptr to avoid needing the definition of GPollFD in the header.
132 scoped_ptr<GPollFD> wakeup_gpollfd_;
[email protected]aa0f2662008-11-18 01:30:42133
[email protected]05062e22009-05-15 22:40:05134 // List of observers.
135 ObserverList<Observer> observers_;
136
[email protected]8fc3a482008-10-03 16:52:59137 DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI);
138};
139
140} // namespace base
141
142#endif // BASE_MESSAGE_PUMP_GLIB_H_