1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/message_pump_glib.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,142 @@ 1.4 +// Copyright (c) 2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_MESSAGE_PUMP_GLIB_H_ 1.9 +#define BASE_MESSAGE_PUMP_GLIB_H_ 1.10 + 1.11 +#include "base/message_pump.h" 1.12 +#include "base/observer_list.h" 1.13 +#include "base/scoped_ptr.h" 1.14 +#include "base/time.h" 1.15 + 1.16 +typedef union _GdkEvent GdkEvent; 1.17 +typedef struct _GMainContext GMainContext; 1.18 +typedef struct _GPollFD GPollFD; 1.19 +typedef struct _GSource GSource; 1.20 + 1.21 +namespace base { 1.22 + 1.23 +// This class implements a MessagePump needed for TYPE_UI MessageLoops on 1.24 +// OS_LINUX platforms using GLib. 1.25 +class MessagePumpForUI : public MessagePump { 1.26 + public: 1.27 + // Observer is notified prior to a GdkEvent event being dispatched. As 1.28 + // Observers are notified of every change, they have to be FAST! 1.29 + class Observer { 1.30 + public: 1.31 + virtual ~Observer() {} 1.32 + 1.33 + // This method is called before processing a message. 1.34 + virtual void WillProcessEvent(GdkEvent* event) = 0; 1.35 + 1.36 + // This method is called after processing a message. 1.37 + virtual void DidProcessEvent(GdkEvent* event) = 0; 1.38 + }; 1.39 + 1.40 + // Dispatcher is used during a nested invocation of Run to dispatch events. 1.41 + // If Run is invoked with a non-NULL Dispatcher, MessageLoop does not 1.42 + // dispatch events (or invoke gtk_main_do_event), rather every event is 1.43 + // passed to Dispatcher's Dispatch method for dispatch. It is up to the 1.44 + // Dispatcher to dispatch, or not, the event. 1.45 + // 1.46 + // The nested loop is exited by either posting a quit, or returning false 1.47 + // from Dispatch. 1.48 + class Dispatcher { 1.49 + public: 1.50 + virtual ~Dispatcher() {} 1.51 + // Dispatches the event. If true is returned processing continues as 1.52 + // normal. If false is returned, the nested loop exits immediately. 1.53 + virtual bool Dispatch(GdkEvent* event) = 0; 1.54 + }; 1.55 + 1.56 + MessagePumpForUI(); 1.57 + virtual ~MessagePumpForUI(); 1.58 + 1.59 + // Like MessagePump::Run, but GdkEvent objects are routed through dispatcher. 1.60 + virtual void RunWithDispatcher(Delegate* delegate, Dispatcher* dispatcher); 1.61 + 1.62 + virtual void Run(Delegate* delegate) { RunWithDispatcher(delegate, NULL); } 1.63 + virtual void Quit(); 1.64 + virtual void ScheduleWork(); 1.65 + virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time); 1.66 + 1.67 + // Internal methods used for processing the pump callbacks. They are 1.68 + // public for simplicity but should not be used directly. HandlePrepare 1.69 + // is called during the prepare step of glib, and returns a timeout that 1.70 + // will be passed to the poll. HandleCheck is called after the poll 1.71 + // has completed, and returns whether or not HandleDispatch should be called. 1.72 + // HandleDispatch is called if HandleCheck returned true. 1.73 + int HandlePrepare(); 1.74 + bool HandleCheck(); 1.75 + void HandleDispatch(); 1.76 + 1.77 + // Adds an Observer, which will start receiving notifications immediately. 1.78 + void AddObserver(Observer* observer); 1.79 + 1.80 + // Removes an Observer. It is safe to call this method while an Observer is 1.81 + // receiving a notification callback. 1.82 + void RemoveObserver(Observer* observer); 1.83 + 1.84 + private: 1.85 + // We may make recursive calls to Run, so we save state that needs to be 1.86 + // separate between them in this structure type. 1.87 + struct RunState { 1.88 + Delegate* delegate; 1.89 + Dispatcher* dispatcher; 1.90 + 1.91 + // Used to flag that the current Run() invocation should return ASAP. 1.92 + bool should_quit; 1.93 + 1.94 + // Used to count how many Run() invocations are on the stack. 1.95 + int run_depth; 1.96 + 1.97 + // This keeps the state of whether the pump got signaled that there was new 1.98 + // work to be done. Since we eat the message on the wake up pipe as soon as 1.99 + // we get it, we keep that state here to stay consistent. 1.100 + bool has_work; 1.101 + }; 1.102 + 1.103 + // Invoked from EventDispatcher. Notifies all observers we're about to 1.104 + // process an event. 1.105 + void WillProcessEvent(GdkEvent* event); 1.106 + 1.107 + // Invoked from EventDispatcher. Notifies all observers we processed an 1.108 + // event. 1.109 + void DidProcessEvent(GdkEvent* event); 1.110 + 1.111 + // Callback prior to gdk dispatching an event. 1.112 + static void EventDispatcher(GdkEvent* event, void* data); 1.113 + 1.114 + RunState* state_; 1.115 + 1.116 + // This is a GLib structure that we can add event sources to. We use the 1.117 + // default GLib context, which is the one to which all GTK events are 1.118 + // dispatched. 1.119 + GMainContext* context_; 1.120 + 1.121 + // This is the time when we need to do delayed work. 1.122 + TimeTicks delayed_work_time_; 1.123 + 1.124 + // The work source. It is shared by all calls to Run and destroyed when 1.125 + // the message pump is destroyed. 1.126 + GSource* work_source_; 1.127 + 1.128 + // We use a wakeup pipe to make sure we'll get out of the glib polling phase 1.129 + // when another thread has scheduled us to do some work. There is a glib 1.130 + // mechanism g_main_context_wakeup, but this won't guarantee that our event's 1.131 + // Dispatch() will be called. 1.132 + int wakeup_pipe_read_; 1.133 + int wakeup_pipe_write_; 1.134 + // Use a scoped_ptr to avoid needing the definition of GPollFD in the header. 1.135 + scoped_ptr<GPollFD> wakeup_gpollfd_; 1.136 + 1.137 + // List of observers. 1.138 + ObserverList<Observer> observers_; 1.139 + 1.140 + DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); 1.141 +}; 1.142 + 1.143 +} // namespace base 1.144 + 1.145 +#endif // BASE_MESSAGE_PUMP_GLIB_H_