Home | History | Annotate | Download | only in base
      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:
     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:
     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