LCOV - code coverage report
Current view: top level - eq/deflect - eventHandler.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 5 161 3.1 %
Date: 2016-09-29 05:02:09 Functions: 3 9 33.3 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2013, Daniel Nachbaur <daniel.nachbaur@epfl.ch>
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or modify it under
       5             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       6             :  * by the Free Software Foundation.
       7             :  *
       8             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       9             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      10             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      11             :  * details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      15             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      16             :  */
      17             : 
      18             : #include "eventHandler.h"
      19             : #include "proxy.h"
      20             : 
      21             : #include "../messagePump.h"
      22             : #include "../channel.h"
      23             : #include "../config.h"
      24             : #include "../pipe.h"
      25             : #include "../window.h"
      26             : #include "../configEvent.h"
      27             : 
      28             : #include <lunchbox/perThread.h>
      29             : #include <deflect/Stream.h>
      30             : 
      31             : namespace eq
      32             : {
      33             : namespace deflect
      34             : {
      35             : namespace
      36             : {
      37             : typedef std::vector< EventHandler* > EventHandlers;
      38          14 : static lunchbox::PerThread< EventHandlers > _eventHandlers;
      39             : 
      40             : const float wheelFactor = 1.f / 40.f;
      41             : 
      42             : // Values come from QtCore/qnamespace.h, but don't want to depend on Qt just for that
      43           0 : uint32_t _getKey( const int key )
      44             : {
      45           0 :     switch( key )
      46             :     {
      47           0 :     case 0x01000000: return KC_ESCAPE;
      48           0 :     case 0x01000001: return KC_TAB;
      49           0 :     case 0x01000003: return KC_BACKSPACE;
      50           0 :     case 0x01000004: return KC_RETURN;
      51           0 :     case 0x01000010: return KC_HOME;
      52           0 :     case 0x01000011: return KC_END;
      53           0 :     case 0x01000012: return KC_LEFT;
      54           0 :     case 0x01000013: return KC_UP;
      55           0 :     case 0x01000014: return KC_RIGHT;
      56           0 :     case 0x01000015: return KC_DOWN;
      57           0 :     case 0x01000016: return KC_PAGE_UP;
      58           0 :     case 0x01000017: return KC_PAGE_DOWN;
      59           0 :     case 0x01000020: return KC_SHIFT_L;
      60           0 :     case 0x01000021: return KC_CONTROL_L;
      61           0 :     case 0x01000023: return KC_ALT_L;
      62           0 :     case 0x01000030: return KC_F1;
      63           0 :     case 0x01000031: return KC_F2;
      64           0 :     case 0x01000032: return KC_F3;
      65           0 :     case 0x01000033: return KC_F4;
      66           0 :     case 0x01000034: return KC_F5;
      67           0 :     case 0x01000035: return KC_F6;
      68           0 :     case 0x01000036: return KC_F7;
      69           0 :     case 0x01000037: return KC_F8;
      70           0 :     case 0x01000038: return KC_F9;
      71           0 :     case 0x01000039: return KC_F10;
      72           0 :     case 0x0100003a: return KC_F11;
      73           0 :     case 0x0100003b: return KC_F12;
      74           0 :     case 0x0100003c: return KC_F13;
      75           0 :     case 0x0100003d: return KC_F14;
      76           0 :     case 0x0100003e: return KC_F15;
      77           0 :     case 0x0100003f: return KC_F16;
      78           0 :     case 0x01000040: return KC_F17;
      79           0 :     case 0x01000041: return KC_F18;
      80           0 :     case 0x01000042: return KC_F19;
      81           0 :     case 0x01000043: return KC_F20;
      82           0 :     case 0x01000044: return KC_F21;
      83           0 :     case 0x01000045: return KC_F22;
      84           0 :     case 0x01000046: return KC_F23;
      85           0 :     case 0x01000047: return KC_F24;
      86           0 :     case 0x01001103: return KC_ALT_R;
      87           0 :     case 0x01ffffff: return KC_VOID;
      88           0 :     case 0x20:       return key; // space
      89           0 :     default:         return key+32;
      90             :     }
      91             : }
      92             : 
      93           0 : uint32_t _getButtons( const ::deflect::Event& deflectEvent )
      94             : {
      95           0 :     uint32_t buttons = 0;
      96           0 :     if( deflectEvent.mouseLeft )
      97           0 :         buttons |= PTR_BUTTON1;
      98           0 :     if( deflectEvent.mouseMiddle )
      99           0 :         buttons |= PTR_BUTTON2;
     100           0 :     if( deflectEvent.mouseRight )
     101           0 :         buttons |= PTR_BUTTON3;
     102           0 :     return buttons;
     103             : }
     104             : }
     105             : 
     106           0 : EventHandler::EventHandler( Proxy* proxy )
     107           0 :     : _proxy( proxy )
     108             : {
     109           0 :     LBASSERT( proxy );
     110             : 
     111           0 :     if( !_eventHandlers )
     112           0 :         _eventHandlers = new EventHandlers;
     113           0 :     _eventHandlers->push_back( this );
     114             : 
     115           0 :     Pipe* pipe = proxy->getChannel().getPipe();
     116           0 :     MessagePump* messagePump = pipe->isThreaded() ? pipe->getMessagePump() :
     117           0 :                                             pipe->getConfig()->getMessagePump();
     118           0 :     if( messagePump )
     119           0 :         messagePump->register_( proxy );
     120             :     else
     121           0 :         LBINFO << "Using deflect::EventHandler without MessagePump, "
     122           0 :                << "external event dispatch assumed" << std::endl;
     123           0 : }
     124             : 
     125           0 : EventHandler::~EventHandler()
     126             : {
     127           0 :     Pipe* pipe = _proxy->getChannel().getPipe();
     128             :     MessagePump* messagePump =
     129           0 :         dynamic_cast<MessagePump*>( pipe->isThreaded() ?
     130             :                                     pipe->getMessagePump() :
     131           0 :                                     pipe->getConfig()->getMessagePump( ));
     132           0 :     if( messagePump )
     133           0 :         messagePump->deregister( _proxy );
     134             : 
     135           0 :     EventHandlers::iterator i = lunchbox::find( *_eventHandlers, this );
     136           0 :     LBASSERT( i != _eventHandlers->end( ));
     137           0 :     _eventHandlers->erase( i );
     138           0 :     if( _eventHandlers->empty( ))
     139             :     {
     140           0 :         delete _eventHandlers.get();
     141           0 :         _eventHandlers = 0;
     142             :     }
     143           0 : }
     144             : 
     145          19 : void EventHandler::processEvents( const Proxy* proxy )
     146             : {
     147          19 :     if( !_eventHandlers )
     148          38 :         return;
     149             : 
     150           0 :     for( EventHandlers::const_iterator i = _eventHandlers->begin();
     151           0 :          i != _eventHandlers->end(); ++i )
     152             :     {
     153           0 :         (*i)->_processEvents( proxy );
     154             :     }
     155             : }
     156             : 
     157           0 : void EventHandler::_processEvents( const Proxy* proxy )
     158             : {
     159           0 :     LB_TS_THREAD( _thread );
     160           0 :     if( !_proxy || (proxy && _proxy != proxy ))
     161           0 :         return;
     162             : 
     163           0 :     Channel& channel = _proxy->getChannel();
     164           0 :     const PixelViewport& pvp = channel.getPixelViewport();
     165           0 :     Window* window = channel.getWindow();
     166             : 
     167           0 :     while( _proxy->hasNewEvent( ))
     168             :     {
     169           0 :         ::deflect::Event deflectEvent = _proxy->getEvent();
     170             : 
     171           0 :         if( deflectEvent.type == ::deflect::Event::EVT_CLOSE )
     172             :         {
     173           0 :             _proxy->stopRunning();
     174           0 :             ConfigEvent configEvent;
     175           0 :             configEvent.data.type = Event::EXIT;
     176           0 :             window->getConfig()->sendEvent( configEvent );
     177           0 :             break;
     178             :         }
     179             : 
     180           0 :         Event event;
     181           0 :         event.originator = channel.getID();
     182           0 :         event.serial = channel.getSerial();
     183           0 :         event.type = Event::UNKNOWN;
     184             : 
     185           0 :         const float x = deflectEvent.mouseX * pvp.w;
     186           0 :         const float y = deflectEvent.mouseY * pvp.h;
     187             : 
     188           0 :         switch( deflectEvent.type )
     189             :         {
     190             :         case ::deflect::Event::EVT_KEY_PRESS:
     191             :         case ::deflect::Event::EVT_KEY_RELEASE:
     192           0 :             event.type = deflectEvent.type == ::deflect::Event::EVT_KEY_PRESS ?
     193           0 :                                           Event::KEY_PRESS : Event::KEY_RELEASE;
     194           0 :             event.keyPress.key = _getKey(  deflectEvent.key );
     195           0 :             break;
     196             :         case ::deflect::Event::EVT_PRESS:
     197             :         case ::deflect::Event::EVT_RELEASE:
     198           0 :             event.type = deflectEvent.type == ::deflect::Event::EVT_PRESS ?
     199             :                                           Event::CHANNEL_POINTER_BUTTON_PRESS :
     200           0 :                                           Event::CHANNEL_POINTER_BUTTON_RELEASE;
     201           0 :             event.pointerButtonPress.x = x;
     202           0 :             event.pointerButtonPress.y = y;
     203           0 :             event.pointerButtonPress.buttons = _getButtons( deflectEvent );
     204           0 :             event.pointerButtonPress.button = event.pointerButtonPress.buttons;
     205           0 :             _computePointerDelta( event );
     206           0 :             break;
     207             :         case ::deflect::Event::EVT_DOUBLECLICK:
     208           0 :             break;
     209             :         case ::deflect::Event::EVT_MOVE:
     210             :         case ::deflect::Event::EVT_PAN:
     211           0 :             event.type = Event::CHANNEL_POINTER_MOTION;
     212           0 :             event.pointerMotion.x = x;
     213           0 :             event.pointerMotion.y = y;
     214             : 
     215           0 :             if( deflectEvent.type == ::deflect::Event::EVT_PAN )
     216           0 :                 event.pointerButtonPress.buttons = PTR_BUTTON3;
     217             :             else
     218           0 :                 event.pointerButtonPress.buttons = _getButtons( deflectEvent );
     219           0 :             event.pointerMotion.button = event.pointerMotion.buttons;
     220             : 
     221           0 :             event.pointerMotion.dx = deflectEvent.dx * pvp.w;
     222           0 :             event.pointerMotion.dy = deflectEvent.dy * pvp.h;
     223           0 :             break;
     224             :         case ::deflect::Event::EVT_WHEEL:
     225           0 :             event.type = Event::CHANNEL_POINTER_WHEEL;
     226           0 :             event.pointerWheel.x = x;
     227           0 :             event.pointerWheel.y = pvp.h - y;
     228           0 :             event.pointerWheel.buttons = PTR_BUTTON_NONE;
     229           0 :             event.pointerWheel.xAxis = deflectEvent.dx * wheelFactor;
     230           0 :             event.pointerWheel.yAxis = deflectEvent.dy * wheelFactor;
     231           0 :             event.pointerMotion.dx = -deflectEvent.dx;
     232           0 :             event.pointerMotion.dy = -deflectEvent.dy;
     233           0 :             break;
     234             :         case ::deflect::Event::EVT_PINCH:
     235             :         {
     236           0 :             event.type = Event::CHANNEL_POINTER_WHEEL;
     237           0 :             event.pointerWheel.x = x;
     238           0 :             event.pointerWheel.y = pvp.h - y;
     239           0 :             event.pointerWheel.buttons = PTR_BUTTON_NONE;
     240           0 :             const auto dx = deflectEvent.dx * pvp.w;
     241           0 :             const auto dy = deflectEvent.dy * pvp.h;
     242           0 :             const auto sign = dx + dy;
     243           0 :             const auto zoom = std::copysign( std::sqrt( dx*dx + dy*dy ), sign );
     244           0 :             event.pointerWheel.xAxis = 0.f;
     245           0 :             event.pointerWheel.yAxis = zoom * wheelFactor;
     246           0 :             break;
     247             :         }
     248             :         case ::deflect::Event::EVT_NONE:
     249             :         default:
     250           0 :             break;
     251             :         }
     252             : 
     253           0 :         if( event.type != Event::UNKNOWN )
     254             :         {
     255             :             // TODO: compute and use window x,y coordinates
     256           0 :             if( !window->getRenderContext( x, y, event.context ))
     257           0 :                 LBVERB << "No rendering context for pointer event at " << x
     258           0 :                        << ", " << y << std::endl;
     259           0 :             channel.processEvent( event );
     260             :         }
     261           0 :     }
     262             : }
     263             : 
     264             : }
     265          42 : }

Generated by: LCOV version 1.11