1 /*****************************************************************************
2 * os2_loop.cpp
3 *****************************************************************************
4 * Copyright (C) 2003, 2013 the VideoLAN team
5 *
6 * Authors: Cyril Deguet <asmax@via.ecp.fr>
7 * Olivier Teulière <ipkiss@via.ecp.fr>
8 * KO Myung-Hun <komh@chollian.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
24
25 #ifdef OS2_SKINS
26
27 #include "os2_factory.hpp"
28 #include "os2_loop.hpp"
29 #include "../src/generic_window.hpp"
30 #include "../events/evt_key.hpp"
31 #include "../events/evt_leave.hpp"
32 #include "../events/evt_menu.hpp"
33 #include "../events/evt_motion.hpp"
34 #include "../events/evt_mouse.hpp"
35 #include "../events/evt_refresh.hpp"
36 #include "../events/evt_scroll.hpp"
37 #include <vlc_actions.h>
38
39
40 #define GET_X_MP( mp ) ( SHORT1FROMMP( mp ))
41 #define GET_Y_MP( mp ) (( rcl.yTop - 1 ) - SHORT2FROMMP( mp )) /* Invert Y */
42
43 #ifndef WM_MOUSELEAVE
44 #define WM_MOUSELEAVE 0x41F
45 #endif
46
OS2Loop(intf_thread_t * pIntf)47 OS2Loop::OS2Loop( intf_thread_t *pIntf ): OSLoop( pIntf )
48 {
49 // Initialize the map
50 virtKeyToVlcKey[VK_F1] = KEY_F1;
51 virtKeyToVlcKey[VK_F2] = KEY_F2;
52 virtKeyToVlcKey[VK_F3] = KEY_F3;
53 virtKeyToVlcKey[VK_F4] = KEY_F4;
54 virtKeyToVlcKey[VK_F5] = KEY_F5;
55 virtKeyToVlcKey[VK_F6] = KEY_F6;
56 virtKeyToVlcKey[VK_F7] = KEY_F7;
57 virtKeyToVlcKey[VK_F8] = KEY_F8;
58 virtKeyToVlcKey[VK_F9] = KEY_F9;
59 virtKeyToVlcKey[VK_F10] = KEY_F10;
60 virtKeyToVlcKey[VK_F11] = KEY_F11;
61 virtKeyToVlcKey[VK_F12] = KEY_F12;
62 virtKeyToVlcKey[VK_ENTER] = KEY_ENTER;
63 virtKeyToVlcKey[VK_NEWLINE] = KEY_ENTER;
64 virtKeyToVlcKey[VK_SPACE] = ' ';
65 virtKeyToVlcKey[VK_ESC] = KEY_ESC;
66 virtKeyToVlcKey[VK_LEFT] = KEY_LEFT;
67 virtKeyToVlcKey[VK_RIGHT] = KEY_RIGHT;
68 virtKeyToVlcKey[VK_UP] = KEY_UP;
69 virtKeyToVlcKey[VK_DOWN] = KEY_DOWN;
70 virtKeyToVlcKey[VK_INSERT] = KEY_INSERT;
71 virtKeyToVlcKey[VK_DELETE] = KEY_DELETE;
72 virtKeyToVlcKey[VK_HOME] = KEY_HOME;
73 virtKeyToVlcKey[VK_END] = KEY_END;
74 virtKeyToVlcKey[VK_PAGEUP] = KEY_PAGEUP;
75 virtKeyToVlcKey[VK_PAGEDOWN] = KEY_PAGEDOWN;
76 }
77
78
~OS2Loop()79 OS2Loop::~OS2Loop()
80 {
81 }
82
83
instance(intf_thread_t * pIntf)84 OSLoop *OS2Loop::instance( intf_thread_t *pIntf )
85 {
86 if( pIntf->p_sys->p_osLoop == NULL )
87 {
88 OSLoop *pOsLoop = new OS2Loop( pIntf );
89 pIntf->p_sys->p_osLoop = pOsLoop;
90 }
91 return pIntf->p_sys->p_osLoop;
92 }
93
94
destroy(intf_thread_t * pIntf)95 void OS2Loop::destroy( intf_thread_t *pIntf )
96 {
97 delete pIntf->p_sys->p_osLoop;
98 pIntf->p_sys->p_osLoop = NULL;
99 }
100
101
run()102 void OS2Loop::run()
103 {
104 QMSG qm;
105
106 // Compute windows message list
107 while( WinGetMsg( 0, &qm, NULLHANDLE, 0, 0 ))
108 WinDispatchMsg( 0, &qm );
109 }
110
111
processEvent(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)112 MRESULT EXPENTRY OS2Loop::processEvent( HWND hwnd, ULONG msg,
113 MPARAM mp1, MPARAM mp2 )
114 {
115 OS2Factory *pFactory =
116 (OS2Factory*)OS2Factory::instance( getIntf() );
117 GenericWindow *pWin = pFactory->m_windowMap[hwnd];
118
119 // To invert Y
120 RECTL rcl;
121 WinQueryWindowRect( hwnd, &rcl );
122
123 GenericWindow &win = *pWin;
124 switch( msg )
125 {
126 case WM_PAINT:
127 {
128 HPS hps;
129 RECTL rclPaint;
130
131 hps = WinBeginPaint( hwnd, NULLHANDLE, &rclPaint );
132 EvtRefresh evt( getIntf(),
133 rclPaint.xLeft,
134 // Find top and invert it
135 ( rcl.yTop - 1 ) - ( rclPaint.yTop - 1 ),
136 rclPaint.xRight - rclPaint.xLeft + 1,
137 rclPaint.yTop - rclPaint.yBottom + 1 );
138 win.processEvent( evt );
139 WinEndPaint( hps );
140 return 0;
141 }
142 case WM_COMMAND:
143 {
144 EvtMenu evt( getIntf(), SHORT1FROMMP( mp1 ));
145 win.processEvent( evt );
146 return 0;
147 }
148 case WM_MOUSEMOVE:
149 {
150 pFactory->changeCursor( pFactory->getCursorType());
151
152 // Compute the absolute position of the mouse
153 POINTL ptl;
154 WinQueryPointerPos( HWND_DESKTOP, &ptl );
155 int x = ptl.x;
156 int y = ( pFactory->getScreenHeight() - 1 ) - ptl.y;
157 EvtMotion evt( getIntf(), x, y );
158 win.processEvent( evt );
159
160 return MRFROMLONG( TRUE );
161 }
162 case WM_MOUSELEAVE:
163 {
164 EvtLeave evt( getIntf() );
165 win.processEvent( evt );
166 return MRFROMLONG( TRUE );
167 }
168 case WM_BUTTON1DOWN:
169 {
170 WinSetCapture( HWND_DESKTOP, hwnd );
171 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
172 GET_Y_MP( mp1 ), EvtMouse::kLeft,
173 EvtMouse::kDown, getMod( mp2 ) );
174 win.processEvent( evt );
175 return MRFROMLONG( TRUE );
176 }
177 case WM_BUTTON2DOWN:
178 {
179 WinSetCapture( HWND_DESKTOP, hwnd );
180 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
181 GET_Y_MP( mp1 ), EvtMouse::kRight,
182 EvtMouse::kDown, getMod( mp2 ) );
183 win.processEvent( evt );
184 return MRFROMLONG( TRUE );
185 }
186 case WM_BUTTON1UP:
187 {
188 WinSetCapture( HWND_DESKTOP, NULLHANDLE );
189 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
190 GET_Y_MP( mp1 ), EvtMouse::kLeft,
191 EvtMouse::kUp, getMod( mp2 ) );
192 win.processEvent( evt );
193 return MRFROMLONG( TRUE );
194 }
195 case WM_BUTTON2UP:
196 {
197 WinSetCapture( HWND_DESKTOP, NULLHANDLE );
198 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
199 GET_Y_MP( mp1 ), EvtMouse::kRight,
200 EvtMouse::kUp, getMod( mp2 ) );
201 win.processEvent( evt );
202 return MRFROMLONG( TRUE );
203 }
204 case WM_BUTTON1DBLCLK:
205 {
206 WinSetCapture( HWND_DESKTOP, NULLHANDLE );
207 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
208 GET_Y_MP( mp1 ), EvtMouse::kLeft,
209 EvtMouse::kDblClick, getMod( mp2 ) );
210 win.processEvent( evt );
211 return MRFROMLONG( TRUE );
212 }
213 case WM_BUTTON2DBLCLK:
214 {
215 WinSetCapture( HWND_DESKTOP, NULLHANDLE );
216 EvtMouse evt( getIntf(), GET_X_MP( mp1 ),
217 GET_Y_MP( mp1 ), EvtMouse::kRight,
218 EvtMouse::kDblClick, getMod( mp2 ) );
219 win.processEvent( evt );
220 return MRFROMLONG( TRUE );
221 }
222 case WM_CHAR:
223 {
224 // The key events are first processed here and not translated
225 // into WM_CHAR events because we need to know the status of
226 // the modifier keys.
227
228 USHORT fsFlags = SHORT1FROMMP( mp1 );
229 USHORT usCh = SHORT1FROMMP( mp2 );
230 USHORT usVk = SHORT2FROMMP( mp2 );
231
232 // Get VLC key code from the virtual key code
233 int key = ( fsFlags & KC_VIRTUALKEY ) ?
234 virtKeyToVlcKey[ usVk ] : 0;
235 if( !key )
236 {
237 // This appears to be a "normal" (ascii) key
238 key = tolower( usCh );
239 }
240
241 if( key )
242 {
243 // Get the modifier
244 int mod = 0;
245 if( fsFlags & KC_CTRL )
246 {
247 mod |= EvtInput::kModCtrl;
248 }
249 if( fsFlags & KC_SHIFT )
250 {
251 mod |= EvtInput::kModShift;
252 }
253 if( fsFlags & KC_ALT )
254 {
255 mod |= EvtInput::kModAlt;
256 }
257
258 // Get the state
259 EvtKey::ActionType_t state;
260 if( fsFlags & KC_KEYUP )
261 {
262 state = EvtKey::kUp;
263 }
264 else
265 {
266 state = EvtKey::kDown;
267 }
268
269 EvtKey evt( getIntf(), key, state, mod );
270 win.processEvent( evt );
271 }
272 return MRFROMLONG( TRUE );
273 }
274 default:
275 break;
276 }
277 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
278 }
279
280
getMod(MPARAM mp) const281 int OS2Loop::getMod( MPARAM mp ) const
282 {
283 int mod = EvtInput::kModNone;
284 if( SHORT2FROMMP( mp ) & KC_CTRL )
285 mod |= EvtInput::kModCtrl;
286 if( SHORT2FROMMP( mp ) & KC_SHIFT )
287 mod |= EvtInput::kModShift;
288
289 return mod;
290 }
291
292
exit()293 void OS2Loop::exit()
294 {
295 WinPostQueueMsg( HMQ_CURRENT, WM_QUIT, 0, 0 );
296 }
297
298 #endif
299