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 : // Values come from QtCore/qnamespace.h, but don't want to depend on Qt just for that
41 0 : uint32_t _getKey( const int key )
42 : {
43 0 : switch( key )
44 : {
45 0 : case 0x01000000: return KC_ESCAPE;
46 0 : case 0x01000001: return KC_TAB;
47 0 : case 0x01000003: return KC_BACKSPACE;
48 0 : case 0x01000004: return KC_RETURN;
49 0 : case 0x01000010: return KC_HOME;
50 0 : case 0x01000011: return KC_END;
51 0 : case 0x01000012: return KC_LEFT;
52 0 : case 0x01000013: return KC_UP;
53 0 : case 0x01000014: return KC_RIGHT;
54 0 : case 0x01000015: return KC_DOWN;
55 0 : case 0x01000016: return KC_PAGE_UP;
56 0 : case 0x01000017: return KC_PAGE_DOWN;
57 0 : case 0x01000020: return KC_SHIFT_L;
58 0 : case 0x01000021: return KC_CONTROL_L;
59 0 : case 0x01000023: return KC_ALT_L;
60 0 : case 0x01000030: return KC_F1;
61 0 : case 0x01000031: return KC_F2;
62 0 : case 0x01000032: return KC_F3;
63 0 : case 0x01000033: return KC_F4;
64 0 : case 0x01000034: return KC_F5;
65 0 : case 0x01000035: return KC_F6;
66 0 : case 0x01000036: return KC_F7;
67 0 : case 0x01000037: return KC_F8;
68 0 : case 0x01000038: return KC_F9;
69 0 : case 0x01000039: return KC_F10;
70 0 : case 0x0100003a: return KC_F11;
71 0 : case 0x0100003b: return KC_F12;
72 0 : case 0x0100003c: return KC_F13;
73 0 : case 0x0100003d: return KC_F14;
74 0 : case 0x0100003e: return KC_F15;
75 0 : case 0x0100003f: return KC_F16;
76 0 : case 0x01000040: return KC_F17;
77 0 : case 0x01000041: return KC_F18;
78 0 : case 0x01000042: return KC_F19;
79 0 : case 0x01000043: return KC_F20;
80 0 : case 0x01000044: return KC_F21;
81 0 : case 0x01000045: return KC_F22;
82 0 : case 0x01000046: return KC_F23;
83 0 : case 0x01000047: return KC_F24;
84 0 : case 0x01001103: return KC_ALT_R;
85 0 : case 0x01ffffff: return KC_VOID;
86 0 : case 0x20: return key; // space
87 0 : default: return key+32;
88 : }
89 : }
90 : }
91 :
92 0 : EventHandler::EventHandler( Proxy* proxy )
93 0 : : _proxy( proxy )
94 : {
95 0 : LBASSERT( proxy );
96 :
97 0 : if( !_eventHandlers )
98 0 : _eventHandlers = new EventHandlers;
99 0 : _eventHandlers->push_back( this );
100 :
101 0 : Pipe* pipe = proxy->getChannel().getPipe();
102 0 : MessagePump* messagePump = pipe->isThreaded() ? pipe->getMessagePump() :
103 0 : pipe->getConfig()->getMessagePump();
104 0 : if( messagePump )
105 0 : messagePump->register_( proxy );
106 : else
107 0 : LBINFO << "Using deflect::EventHandler without MessagePump, "
108 0 : << "external event dispatch assumed" << std::endl;
109 0 : }
110 :
111 0 : EventHandler::~EventHandler()
112 : {
113 0 : Pipe* pipe = _proxy->getChannel().getPipe();
114 : MessagePump* messagePump =
115 0 : dynamic_cast<MessagePump*>( pipe->isThreaded() ?
116 : pipe->getMessagePump() :
117 0 : pipe->getConfig()->getMessagePump( ));
118 0 : if( messagePump )
119 0 : messagePump->deregister( _proxy );
120 :
121 0 : EventHandlers::iterator i = lunchbox::find( *_eventHandlers, this );
122 0 : LBASSERT( i != _eventHandlers->end( ));
123 0 : _eventHandlers->erase( i );
124 0 : if( _eventHandlers->empty( ))
125 : {
126 0 : delete _eventHandlers.get();
127 0 : _eventHandlers = 0;
128 : }
129 0 : }
130 :
131 21 : void EventHandler::processEvents( const Proxy* proxy )
132 : {
133 21 : if( !_eventHandlers )
134 42 : return;
135 :
136 0 : for( EventHandlers::const_iterator i = _eventHandlers->begin();
137 0 : i != _eventHandlers->end(); ++i )
138 : {
139 0 : (*i)->_processEvents( proxy );
140 : }
141 : }
142 :
143 0 : void EventHandler::_processEvents( const Proxy* proxy )
144 : {
145 0 : LB_TS_THREAD( _thread );
146 0 : if( !_proxy || (proxy && _proxy != proxy ))
147 0 : return;
148 :
149 0 : Channel& channel = _proxy->getChannel();
150 0 : const PixelViewport& pvp = channel.getPixelViewport();
151 0 : Window* window = channel.getWindow();
152 :
153 0 : while( _proxy->hasNewEvent( ))
154 : {
155 0 : ::deflect::Event deflectEvent = _proxy->getEvent();
156 :
157 0 : if( deflectEvent.type == ::deflect::Event::EVT_CLOSE )
158 : {
159 0 : _proxy->stopRunning();
160 0 : ConfigEvent configEvent;
161 0 : configEvent.data.type = Event::EXIT;
162 0 : window->getConfig()->sendEvent( configEvent );
163 0 : break;
164 : }
165 :
166 0 : Event event;
167 0 : event.originator = channel.getID();
168 0 : event.serial = channel.getSerial();
169 0 : event.type = Event::UNKNOWN;
170 :
171 0 : const float x = deflectEvent.mouseX * pvp.w;
172 0 : const float y = deflectEvent.mouseY * pvp.h;
173 :
174 0 : if( _proxy-> getNavigationMode() == Proxy::MODE_PAN )
175 0 : std::swap( deflectEvent.mouseLeft, deflectEvent.mouseRight );
176 :
177 0 : switch( deflectEvent.type )
178 : {
179 : case ::deflect::Event::EVT_KEY_PRESS:
180 : case ::deflect::Event::EVT_KEY_RELEASE:
181 0 : event.type = deflectEvent.type == ::deflect::Event::EVT_KEY_PRESS ?
182 0 : Event::KEY_PRESS : Event::KEY_RELEASE;
183 0 : event.keyPress.key = _getKey( deflectEvent.key );
184 0 : break;
185 : case ::deflect::Event::EVT_PRESS:
186 : case ::deflect::Event::EVT_RELEASE:
187 0 : event.type = deflectEvent.type == ::deflect::Event::EVT_PRESS ?
188 : Event::CHANNEL_POINTER_BUTTON_PRESS :
189 0 : Event::CHANNEL_POINTER_BUTTON_RELEASE;
190 0 : event.pointerButtonPress.x = x;
191 0 : event.pointerButtonPress.y = y;
192 :
193 0 : if( deflectEvent.mouseLeft )
194 0 : event.pointerButtonPress.buttons |= PTR_BUTTON1;
195 0 : if( deflectEvent.mouseMiddle )
196 0 : event.pointerButtonPress.buttons |= PTR_BUTTON2;
197 0 : if( deflectEvent.mouseRight )
198 0 : event.pointerButtonPress.buttons |= PTR_BUTTON3;
199 0 : event.pointerButtonPress.button = event.pointerButtonPress.buttons;
200 0 : _computePointerDelta( event );
201 0 : break;
202 : case ::deflect::Event::EVT_DOUBLECLICK:
203 0 : break;
204 : case ::deflect::Event::EVT_MOVE:
205 0 : event.type = Event::CHANNEL_POINTER_MOTION;
206 0 : event.pointerMotion.x = x;
207 0 : event.pointerMotion.y = y;
208 :
209 0 : if( deflectEvent.mouseLeft )
210 0 : event.pointerButtonPress.buttons |= PTR_BUTTON1;
211 0 : if( deflectEvent.mouseMiddle )
212 0 : event.pointerButtonPress.buttons |= PTR_BUTTON2;
213 0 : if( deflectEvent.mouseRight )
214 0 : event.pointerButtonPress.buttons |= PTR_BUTTON3;
215 :
216 0 : event.pointerMotion.button = event.pointerMotion.buttons;
217 0 : event.pointerMotion.dx = deflectEvent.dx * pvp.w;
218 0 : event.pointerMotion.dy = deflectEvent.dy * pvp.h;
219 0 : break;
220 : case ::deflect::Event::EVT_WHEEL:
221 0 : event.type = Event::CHANNEL_POINTER_WHEEL;
222 0 : event.pointerWheel.x = x;
223 0 : event.pointerWheel.y = pvp.h - y;
224 0 : event.pointerWheel.buttons = PTR_BUTTON_NONE;
225 0 : event.pointerWheel.xAxis = deflectEvent.dx / 40.f;
226 0 : event.pointerWheel.yAxis = deflectEvent.dy / 40.f;
227 0 : event.pointerMotion.dx = -deflectEvent.dx;
228 0 : event.pointerMotion.dy = -deflectEvent.dy;
229 0 : break;
230 : case ::deflect::Event::EVT_TAP_AND_HOLD:
231 : {
232 : const Proxy::NavigationMode mode =
233 0 : _proxy->getNavigationMode() == Proxy::MODE_PAN
234 0 : ? Proxy::MODE_ROTATE : Proxy::MODE_PAN;
235 0 : _proxy->setNavigationMode( mode );
236 0 : Event windowEvent;
237 0 : windowEvent.originator = window->getID();
238 0 : windowEvent.serial = window->getSerial();
239 0 : windowEvent.type = Event::WINDOW_EXPOSE;
240 0 : window->processEvent( windowEvent );
241 0 : } break;
242 : case ::deflect::Event::EVT_NONE:
243 : default:
244 0 : break;
245 : }
246 :
247 0 : if( event.type != Event::UNKNOWN )
248 : {
249 : // TODO: compute and use window x,y coordinates
250 0 : if( !window->getRenderContext( x, y, event.context ))
251 0 : LBVERB << "No rendering context for pointer event at " << x
252 0 : << ", " << y << std::endl;
253 0 : channel.processEvent( event );
254 : }
255 0 : }
256 : }
257 :
258 : }
259 42 : }
|