Input-Slave: remove .txt and .utf8 as auto-loaded subtitles
[vlc.git] / modules / video_output / win32 / win32touch.c
blobece54d57084dcbfef6d6378c74906be442d0e272
1 /*****************************************************************************
2 * win32touch.c: touch gestures recognition
3 *****************************************************************************
4 * Copyright © 2013-2014 VideoLAN
6 * Authors: Ludovic Fauvet <etix@videolan.org>
7 * Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include "win32touch.h"
30 #include <vlc_actions.h>
32 #include <assert.h>
34 static BOOL DecodeGestureAction( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi );
35 static BOOL DecodeGestureProjection( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi );
37 LRESULT DecodeGesture( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture,
38 HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
40 if( !p_gesture )
41 return DefWindowProc( hWnd, message, wParam, lParam );
43 GESTUREINFO gi;
44 ZeroMemory( &gi, sizeof( GESTUREINFO ) );
45 gi.cbSize = sizeof( GESTUREINFO );
47 BOOL bResult = p_gesture->OurGetGestureInfo((HGESTUREINFO)lParam, &gi);
48 BOOL bHandled = FALSE; /* Needed to release the handle */
50 if( bResult )
51 bHandled = p_gesture->DecodeGestureImpl(p_this, p_gesture, &gi);
52 else
54 DWORD dwErr = GetLastError();
55 if( dwErr > 0 )
56 msg_Err( p_this, "Could not retrieve a valid GESTUREINFO structure" );
59 if( bHandled )
61 /* Close the Handle, if we handled the gesture, a contrario
62 * from the doc example */
63 p_gesture->OurCloseGestureInfoHandle((HGESTUREINFO)lParam);
64 return 0;
66 else
67 return DefWindowProc( hWnd, message, wParam, lParam );
70 static BOOL DecodeGestureAction( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi )
72 BOOL bHandled = FALSE; /* Needed to release the handle */
73 switch ( p_gi->dwID )
75 case GID_BEGIN:
76 /* Set the win32_gesture_sys_t values */
77 p_gesture->i_beginx = p_gi->ptsLocation.x;
78 p_gesture->i_beginy = p_gi->ptsLocation.y;
79 p_gesture->i_lasty = p_gesture->i_beginy;
80 p_gesture->b_2fingers = false;
81 break;
82 case GID_END:
83 if( p_gesture->i_type != 0 &&
84 p_gesture->i_action == GESTURE_ACTION_JUMP )
86 int action_id;
87 if( p_gesture->i_beginx > p_gi->ptsLocation.x )
89 if( p_gesture->b_2fingers )
90 action_id = ACTIONID_JUMP_BACKWARD_MEDIUM;
91 else
92 action_id = ACTIONID_JUMP_BACKWARD_SHORT;
94 else
96 if( p_gesture->b_2fingers )
97 action_id = ACTIONID_JUMP_FORWARD_MEDIUM;
98 else
99 action_id = ACTIONID_JUMP_FORWARD_SHORT;
101 var_SetInteger( p_this->obj.libvlc, "key-action", action_id );
103 /* Reset the values */
104 p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
105 p_gesture->i_type = p_gesture->i_beginx = p_gesture->i_beginy = -1;
106 p_gesture->b_2fingers = false;
107 break;
108 case GID_PAN:
109 p_gesture->i_type = GID_PAN;
110 bHandled = TRUE;
112 if (p_gi->dwFlags & GF_BEGIN) {
113 p_gesture->i_beginx = p_gi->ptsLocation.x;
114 p_gesture->i_beginy = p_gi->ptsLocation.y;
117 if( (DWORD)p_gi->ullArguments > 0 )
118 p_gesture->b_2fingers = true;
120 if( p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
122 if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) +
123 abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) > 50 )
125 if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) >
126 abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) )
127 p_gesture->i_action = GESTURE_ACTION_JUMP;
128 else if ( p_gesture->b_2fingers )
129 p_gesture->i_action = GESTURE_ACTION_BRIGHTNESS;
130 else
131 p_gesture->i_action = GESTURE_ACTION_VOLUME;
135 if( p_gesture->i_action == GESTURE_ACTION_VOLUME )
137 int offset = p_gesture->i_lasty - p_gi->ptsLocation.y;
139 if( offset > 100)
140 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_UP );
141 else if( offset < -100)
142 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_DOWN );
143 else
144 break;
146 p_gesture->i_lasty = p_gi->ptsLocation.y;
148 else if ( p_gesture->i_action == GESTURE_ACTION_BRIGHTNESS )
150 /* Currently unimplemented
151 if( p_gesture->i_lasty == -1 )
152 p_gesture->i_lasty = p_gesture->i_beginy;
154 if( p_gesture->i_lasty - p_gesture->i_beginy > 80 )
156 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_DOWN );
157 p_gesture->i_lasty = p_gi->ptsLocation.y;
159 else if ( p_gesture->i_lasty - p_gesture->i_beginy < 80 )
161 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_UP );
162 p_gesture->i_lasty = p_gi->ptsLocation.y;
163 } */
165 break;
166 case GID_TWOFINGERTAP:
167 p_gesture->i_type = GID_TWOFINGERTAP;
168 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_PLAY_PAUSE );
169 bHandled = TRUE;
170 break;
171 case GID_ZOOM:
172 p_gesture->i_type = GID_ZOOM;
173 switch( p_gi->dwFlags )
175 case GF_BEGIN:
176 p_gesture->i_ullArguments = p_gi->ullArguments;
177 break;
178 case GF_END:
180 double k = (double)(p_gi->ullArguments) /
181 (double)(p_gesture->i_ullArguments);
182 if( k > 1 )
183 var_SetInteger( p_this->obj.libvlc, "key-action",
184 ACTIONID_TOGGLE_FULLSCREEN );
185 else
186 var_SetInteger( p_this->obj.libvlc, "key-action",
187 ACTIONID_LEAVE_FULLSCREEN );
189 break;
190 default:
191 msg_Err( p_this, "Unmanaged dwFlag: %lx", p_gi->dwFlags );
193 bHandled = TRUE;
194 break;
195 case WM_VSCROLL:
196 bHandled = TRUE;
197 break;
198 default:
199 break;
201 return bHandled;
205 static BOOL DecodeGestureProjection( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi )
207 //vout_display_t *vd = (vout_display_t *)p_this;
209 BOOL bHandled = FALSE; /* Needed to release the handle */
210 switch ( p_gi->dwID )
212 case GID_BEGIN:
213 /* Set the win32_gesture_sys_t values */
214 p_gesture->i_beginx = p_gi->ptsLocation.x;
215 p_gesture->i_beginy = p_gi->ptsLocation.y;
216 p_gesture->i_lasty = p_gesture->i_beginy;
217 p_gesture->b_2fingers = false;
218 break;
219 case GID_END:
220 if( p_gesture->i_type != 0 &&
221 p_gesture->i_action == GESTURE_ACTION_JUMP )
223 int action_id;
224 if( p_gesture->b_2fingers )
226 if( p_gesture->i_beginx > p_gi->ptsLocation.x )
227 action_id = ACTIONID_JUMP_BACKWARD_SHORT;
228 else
229 action_id = ACTIONID_JUMP_FORWARD_SHORT;
230 var_SetInteger( p_this->obj.libvlc, "key-action", action_id );
233 /* Reset the values */
234 p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
235 p_gesture->i_type = p_gesture->i_beginx = p_gesture->i_beginy = -1;
236 p_gesture->b_2fingers = false;
237 break;
238 case GID_PAN:
239 //vd->cfg->display.width;
240 p_gesture->i_type = GID_PAN;
241 bHandled = TRUE;
242 if (p_gi->dwFlags & GF_BEGIN) {
243 p_gesture->i_beginx = p_gi->ptsLocation.x;
244 p_gesture->i_beginy = p_gi->ptsLocation.y;
247 if( (DWORD)p_gi->ullArguments > 0 )
248 p_gesture->b_2fingers = true;
250 if( p_gesture->b_2fingers && p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
252 if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) +
253 abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) > 50 )
255 if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) >
256 abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) )
257 p_gesture->i_action = GESTURE_ACTION_JUMP;
258 else
259 p_gesture->i_action = GESTURE_ACTION_VOLUME;
263 if( p_gesture->i_action == GESTURE_ACTION_VOLUME )
265 int offset = p_gesture->i_lasty - p_gi->ptsLocation.y;
267 if( offset > 100)
268 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_UP );
269 else if( offset < -100)
270 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_DOWN );
271 else
272 break;
274 p_gesture->i_lasty = p_gi->ptsLocation.y;
276 break;
277 case GID_TWOFINGERTAP:
278 p_gesture->i_type = GID_TWOFINGERTAP;
279 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_PLAY_PAUSE );
280 bHandled = TRUE;
281 break;
282 case GID_ZOOM:
283 p_gesture->i_type = GID_ZOOM;
284 bHandled = TRUE;
285 switch( p_gi->dwFlags )
287 case GF_BEGIN:
288 p_gesture->i_ullArguments = p_gi->ullArguments;
289 p_gesture->f_lastzoom = 1.0;
290 break;
291 default:
293 double k = (double)(p_gi->ullArguments) /
294 (double)(p_gesture->i_ullArguments);
296 if (k > p_gesture->f_lastzoom * 1.01)
298 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VIEWPOINT_FOV_IN );
299 p_gesture->f_lastzoom = k;
301 else if (k < p_gesture->f_lastzoom * 0.99)
303 var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VIEWPOINT_FOV_OUT );
304 p_gesture->f_lastzoom = k;
306 break;
309 break;
310 case WM_VSCROLL:
311 bHandled = TRUE;
312 break;
313 default:
314 break;
316 return bHandled;
319 BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **pp_gesture, bool b_isProjected )
321 BOOL result = FALSE;
322 GESTURECONFIG config = { 0, 0, 0 };
323 if (b_isProjected)
325 //don't handle single finger pan in projected mode, it will be interpreted
326 //as mouse events.
327 config.dwID = GID_PAN;
328 config.dwWant = GC_PAN;
329 config.dwBlock = GC_PAN_WITH_INERTIA;
331 else
333 config.dwID = GID_PAN;
334 config.dwWant = GC_PAN |
335 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY |
336 GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
337 config.dwBlock = GC_PAN_WITH_INERTIA;
340 win32_gesture_sys_t *p_gesture = malloc( sizeof(win32_gesture_sys_t) );
341 if( !p_gesture )
343 *pp_gesture = NULL;
344 return FALSE;
347 HINSTANCE h_user32_dll = LoadLibrary(TEXT("user32.dll"));
348 if( !h_user32_dll )
350 *pp_gesture = NULL;
351 free( p_gesture );
352 return FALSE;
355 BOOL (WINAPI *OurSetGestureConfig) (HWND, DWORD, UINT, PGESTURECONFIG, UINT);
356 OurSetGestureConfig = (void *)GetProcAddress(h_user32_dll, "SetGestureConfig");
358 p_gesture->OurCloseGestureInfoHandle =
359 (void *)GetProcAddress(h_user32_dll, "CloseGestureInfoHandle" );
360 p_gesture->OurGetGestureInfo =
361 (void *)GetProcAddress(h_user32_dll, "GetGestureInfo");
362 if( OurSetGestureConfig )
364 result = OurSetGestureConfig(
365 hwnd,
368 &config,
369 sizeof( GESTURECONFIG )
372 if (b_isProjected)
373 p_gesture->DecodeGestureImpl = DecodeGestureProjection;
374 else
375 p_gesture->DecodeGestureImpl = DecodeGestureAction;
377 p_gesture->i_type = 0;
378 p_gesture->b_2fingers = false;
379 p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
380 p_gesture->i_beginx = p_gesture->i_beginy = -1;
381 p_gesture->i_lasty = -1;
382 p_gesture->huser_dll = h_user32_dll;
384 *pp_gesture = p_gesture;
385 return result;
388 void CloseGestures( win32_gesture_sys_t *p_gesture )
390 if (p_gesture && p_gesture->huser_dll )
391 FreeLibrary( p_gesture->huser_dll );
392 free( p_gesture );