Event Handling Equalizer logo

Author: eilemann@gmail.com
State:

Equalizer implements a basic event handling mechanism, simplifying the development of small-sized to medium-sized applications. Complex applications are expected to implement their own event handling, and disable the event handling in Equalizer.

Equalizer normally receives and processes the events from the pipe thread the window belongs to. The exception is the AGL window system, which dispatches all events from the main thread.

Event Handling Data Flow
Event Handling Data Flow

When the event handler receives an event from the window system, it finds the associated eq::Window and creates a generic WindowEvent from the system-specific event. The generic event contains the system-specific event, i.e., the X11 Event, and is passed to Window::processEvent. The default implementation of Window::processEvent transform the window event into a ConfigEvent, which is sent to the application thread using Config::sendEvent. Since the config event is potentially transferred to another node, it no longer contains the system-specific event.

At the end of the frame, Config::endFrame calls Config::processEvent on each queued event. The default implementation is empty, the eqPly example implements some basic mouse and keyboard interaction.

The event dispatch is implemented by subclassing eq::net::CommandQueue into a eq::CommandQueue which 'pumps' events on every pop operation. The CommandQueue is used between the receiver and the rendering threads to dispatch the received commands. Consequently, events are only processed in between task commands. The WGL implementation pumps events in each node and pipe thread.

External Message Pump (WGL/AGL)

Equalizer dispatches the window system events automatically between the execution of two task methods. External toolkits, e.g., QT, might implement a message pump themselves. It is therefore desirable to disable the message pump for application and/or pipe threads to avoid side effect of event dispatch at an unexpected time for the external toolkit.

The virtual method useMessagePump is called by Equalizer during application and pipe thread initialization (before configInit!) to determine if the application or pipe thread shall automatically dispatch OS events. For non-threaded pipes, the method is not called. On WGL and GLX, messages are dispatched in the application and each pipe thread. On AGL, events are dispatched only on the application thread, i.e., Pipe::useMessagePump is never called. If useMessagePump returns false, the application has to dispatch events.

Customized Event Handling

The application can provide its own event handler implementation in Pipe::initEventHandler and Window::initEventHandler. Typically these methods are overwritten to disable Equalizer's event handling by providing an empty implementation.

API

  virtual bool Window::processEvent( const WindowEvent& event );
  void Config::sendEvent( ConfigEvent& event );

  const ConfigEvent* Config::nextEvent();
  bool Config::checkEvent() const;
  virtual void Config::handleEvents();
  virtual bool Config::handleEvent( const ConfigEvent* event );

  class WindowEvent;
  struct ConfigEvent;

  virtual bool Client::useMessagePump() { return true; }
  virtual bool Pipe::useMessagePump()   { return true; }

  virtual void Pipe::initEventHandler();
  virtual void Pipe::exitEventHandler();
  virtual void Window::initEventHandler();
  virtual void Window::exitEventHandler();

Open Issues

None