LCOV - code coverage report
Current view: top level - eq/deflect - eventHandler.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 5 154 3.2 %
Date: 2017-12-16 05:07:20 Functions: 3 9 33.3 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2013-2017, 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 "../channel.h"
      22             : #include "../config.h"
      23             : #include "../messagePump.h"
      24             : #include "../pipe.h"
      25             : #include "../window.h"
      26             : 
      27             : #include <deflect/Stream.h>
      28             : #include <eq/fabric/keyEvent.h>
      29             : #include <eq/fabric/sizeEvent.h>
      30             : #include <lunchbox/algorithm.h>
      31             : #include <lunchbox/perThread.h>
      32             : 
      33             : namespace eq
      34             : {
      35             : namespace deflect
      36             : {
      37             : namespace
      38             : {
      39             : typedef std::vector<EventHandler*> EventHandlers;
      40          10 : static lunchbox::PerThread<EventHandlers> _eventHandlers;
      41             : 
      42             : const float wheelFactor = 1.f / 40.f;
      43             : 
      44             : // Values come from QtCore/qnamespace.h, but don't want to depend on Qt just for
      45             : // that
      46           0 : uint32_t _getKey(const int key)
      47             : {
      48           0 :     switch (key)
      49             :     {
      50             :     case 0x01000000:
      51           0 :         return KC_ESCAPE;
      52             :     case 0x01000001:
      53           0 :         return KC_TAB;
      54             :     case 0x01000003:
      55           0 :         return KC_BACKSPACE;
      56             :     case 0x01000004:
      57           0 :         return KC_RETURN;
      58             :     case 0x01000010:
      59           0 :         return KC_HOME;
      60             :     case 0x01000011:
      61           0 :         return KC_END;
      62             :     case 0x01000012:
      63           0 :         return KC_LEFT;
      64             :     case 0x01000013:
      65           0 :         return KC_UP;
      66             :     case 0x01000014:
      67           0 :         return KC_RIGHT;
      68             :     case 0x01000015:
      69           0 :         return KC_DOWN;
      70             :     case 0x01000016:
      71           0 :         return KC_PAGE_UP;
      72             :     case 0x01000017:
      73           0 :         return KC_PAGE_DOWN;
      74             :     case 0x01000020:
      75           0 :         return KC_SHIFT_L;
      76             :     case 0x01000021:
      77           0 :         return KC_CONTROL_L;
      78             :     case 0x01000023:
      79           0 :         return KC_ALT_L;
      80             :     case 0x01000030:
      81           0 :         return KC_F1;
      82             :     case 0x01000031:
      83           0 :         return KC_F2;
      84             :     case 0x01000032:
      85           0 :         return KC_F3;
      86             :     case 0x01000033:
      87           0 :         return KC_F4;
      88             :     case 0x01000034:
      89           0 :         return KC_F5;
      90             :     case 0x01000035:
      91           0 :         return KC_F6;
      92             :     case 0x01000036:
      93           0 :         return KC_F7;
      94             :     case 0x01000037:
      95           0 :         return KC_F8;
      96             :     case 0x01000038:
      97           0 :         return KC_F9;
      98             :     case 0x01000039:
      99           0 :         return KC_F10;
     100             :     case 0x0100003a:
     101           0 :         return KC_F11;
     102             :     case 0x0100003b:
     103           0 :         return KC_F12;
     104             :     case 0x0100003c:
     105           0 :         return KC_F13;
     106             :     case 0x0100003d:
     107           0 :         return KC_F14;
     108             :     case 0x0100003e:
     109           0 :         return KC_F15;
     110             :     case 0x0100003f:
     111           0 :         return KC_F16;
     112             :     case 0x01000040:
     113           0 :         return KC_F17;
     114             :     case 0x01000041:
     115           0 :         return KC_F18;
     116             :     case 0x01000042:
     117           0 :         return KC_F19;
     118             :     case 0x01000043:
     119           0 :         return KC_F20;
     120             :     case 0x01000044:
     121           0 :         return KC_F21;
     122             :     case 0x01000045:
     123           0 :         return KC_F22;
     124             :     case 0x01000046:
     125           0 :         return KC_F23;
     126             :     case 0x01000047:
     127           0 :         return KC_F24;
     128             :     case 0x01001103:
     129           0 :         return KC_ALT_R;
     130             :     case 0x01ffffff:
     131           0 :         return KC_VOID;
     132             :     case 0x20:
     133           0 :         return key; // space
     134             :     default:
     135           0 :         return key + 32;
     136             :     }
     137             : }
     138             : 
     139           0 : uint32_t _getButtons(const ::deflect::Event& deflectEvent)
     140             : {
     141           0 :     uint32_t buttons = 0;
     142           0 :     if (deflectEvent.mouseLeft)
     143           0 :         buttons |= PTR_BUTTON1;
     144           0 :     if (deflectEvent.mouseMiddle)
     145           0 :         buttons |= PTR_BUTTON2;
     146           0 :     if (deflectEvent.mouseRight)
     147           0 :         buttons |= PTR_BUTTON3;
     148           0 :     return buttons;
     149             : }
     150             : }
     151             : 
     152           0 : EventHandler::EventHandler(Proxy* proxy)
     153           0 :     : _proxy(proxy)
     154             : {
     155           0 :     LBASSERT(proxy);
     156             : 
     157           0 :     if (!_eventHandlers)
     158           0 :         _eventHandlers = new EventHandlers;
     159           0 :     _eventHandlers->push_back(this);
     160             : 
     161           0 :     Pipe* pipe = proxy->getChannel().getPipe();
     162           0 :     MessagePump* messagePump = pipe->isThreaded()
     163           0 :                                    ? pipe->getMessagePump()
     164           0 :                                    : pipe->getConfig()->getMessagePump();
     165           0 :     if (messagePump)
     166           0 :         messagePump->register_(proxy);
     167             :     else
     168           0 :         LBINFO << "Using deflect::EventHandler without MessagePump, "
     169           0 :                << "external event dispatch assumed" << std::endl;
     170           0 : }
     171             : 
     172           0 : EventHandler::~EventHandler()
     173             : {
     174           0 :     Pipe* pipe = _proxy->getChannel().getPipe();
     175             :     MessagePump* messagePump = dynamic_cast<MessagePump*>(
     176           0 :         pipe->isThreaded() ? pipe->getMessagePump()
     177           0 :                            : pipe->getConfig()->getMessagePump());
     178           0 :     if (messagePump)
     179           0 :         messagePump->deregister(_proxy);
     180             : 
     181           0 :     EventHandlers::iterator i = lunchbox::find(*_eventHandlers, this);
     182           0 :     LBASSERT(i != _eventHandlers->end());
     183           0 :     _eventHandlers->erase(i);
     184           0 :     if (_eventHandlers->empty())
     185             :     {
     186           0 :         delete _eventHandlers.get();
     187           0 :         _eventHandlers = 0;
     188             :     }
     189           0 : }
     190             : 
     191        7014 : void EventHandler::processEvents(const Proxy* proxy)
     192             : {
     193        7014 :     if (!_eventHandlers)
     194        7014 :         return;
     195             : 
     196           0 :     for (EventHandler* handler : *_eventHandlers)
     197           0 :         handler->_processEvents(proxy);
     198             : }
     199             : 
     200           0 : void EventHandler::_processEvents(const Proxy* proxy)
     201             : {
     202           0 :     LB_TS_THREAD(_thread);
     203           0 :     if (!_proxy || (proxy && _proxy != proxy))
     204           0 :         return;
     205             : 
     206           0 :     Channel& channel = _proxy->getChannel();
     207           0 :     const PixelViewport& pvp = channel.getPixelViewport();
     208           0 :     Window* window = channel.getWindow();
     209             : 
     210           0 :     while (_proxy->hasNewEvent())
     211             :     {
     212           0 :         const ::deflect::Event deflectEvent = _proxy->getEvent();
     213           0 :         const float x = deflectEvent.mouseX * pvp.w;
     214           0 :         const float y = deflectEvent.mouseY * pvp.h;
     215             : 
     216           0 :         switch (deflectEvent.type)
     217             :         {
     218             :         case ::deflect::Event::EVT_CLOSE:
     219           0 :             _proxy->stopRunning();
     220           0 :             window->processEvent(EVENT_EXIT);
     221           0 :             return;
     222             : 
     223             :         case ::deflect::Event::EVT_KEY_PRESS:
     224             :         case ::deflect::Event::EVT_KEY_RELEASE:
     225             :         {
     226           0 :             KeyEvent event;
     227             :             const EventType type =
     228           0 :                 deflectEvent.type == ::deflect::Event::EVT_KEY_PRESS
     229           0 :                     ? EVENT_KEY_PRESS
     230           0 :                     : EVENT_KEY_RELEASE;
     231           0 :             event.key = _getKey(deflectEvent.key);
     232           0 :             channel.processEvent(type, event);
     233           0 :             break;
     234             :         }
     235             :         case ::deflect::Event::EVT_PRESS:
     236             :         case ::deflect::Event::EVT_RELEASE:
     237             :         {
     238           0 :             PointerEvent event;
     239             :             const EventType type =
     240           0 :                 deflectEvent.type == ::deflect::Event::EVT_PRESS
     241           0 :                     ? EVENT_CHANNEL_POINTER_BUTTON_PRESS
     242           0 :                     : EVENT_CHANNEL_POINTER_BUTTON_RELEASE;
     243           0 :             event.x = x;
     244           0 :             event.y = y;
     245           0 :             event.buttons = _getButtons(deflectEvent);
     246           0 :             event.button = event.buttons;
     247           0 :             _computePointerDelta(type, event);
     248             : 
     249           0 :             channel.processEvent(type, event);
     250           0 :             break;
     251             :         }
     252             :         case ::deflect::Event::EVT_MOVE:
     253             :         case ::deflect::Event::EVT_PAN:
     254             :         {
     255           0 :             PointerEvent event;
     256           0 :             event.x = x;
     257           0 :             event.y = y;
     258           0 :             event.dx = deflectEvent.dx * pvp.w;
     259           0 :             event.dy = deflectEvent.dy * pvp.h;
     260             : 
     261           0 :             if (deflectEvent.type == ::deflect::Event::EVT_PAN)
     262           0 :                 event.buttons = PTR_BUTTON3;
     263             :             else
     264           0 :                 event.buttons = _getButtons(deflectEvent);
     265           0 :             event.button = event.buttons;
     266             : 
     267           0 :             channel.processEvent(EVENT_CHANNEL_POINTER_MOTION, event);
     268           0 :             break;
     269             :         }
     270             :         case ::deflect::Event::EVT_WHEEL:
     271             :         {
     272           0 :             PointerEvent event;
     273           0 :             event.x = x;
     274           0 :             event.y = pvp.h - y;
     275           0 :             event.xAxis = deflectEvent.dx * wheelFactor;
     276           0 :             event.yAxis = deflectEvent.dy * wheelFactor;
     277           0 :             event.dx = -deflectEvent.dx;
     278           0 :             event.dy = -deflectEvent.dy;
     279             : 
     280           0 :             channel.processEvent(EVENT_CHANNEL_POINTER_WHEEL, event);
     281           0 :             break;
     282             :         }
     283             :         case ::deflect::Event::EVT_PINCH:
     284             :         {
     285           0 :             PointerEvent event;
     286           0 :             event.x = x;
     287           0 :             event.y = pvp.h - y;
     288           0 :             const auto dx = deflectEvent.dx * pvp.w;
     289           0 :             const auto dy = deflectEvent.dy * pvp.h;
     290           0 :             const auto sign = dx + dy;
     291           0 :             const auto zoom = std::copysign(std::sqrt(dx * dx + dy * dy), sign);
     292           0 :             event.xAxis = 0.f;
     293           0 :             event.yAxis = zoom * wheelFactor;
     294             : 
     295           0 :             channel.processEvent(EVENT_CHANNEL_POINTER_WHEEL, event);
     296           0 :             break;
     297             :         }
     298             : 
     299             :         case ::deflect::Event::EVT_DOUBLECLICK:
     300             :         case ::deflect::Event::EVT_NONE:
     301             :         default:
     302           0 :             break;
     303             :         }
     304             :     }
     305             : }
     306             : }
     307          30 : }

Generated by: LCOV version 1.11