win32.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * win32.c: Global-Hotkey WIN32 handling for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2008-2009 the VideoLAN team
  5.  *
  6.  * Authors: Domani Hannes <ssbssa at yahoo dot de>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  21.  *****************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. # include "config.h"
  24. #endif
  25. #include <ctype.h>
  26. #include <vlc_common.h>
  27. #include <vlc_plugin.h>
  28. #include <vlc_interface.h>
  29. #include <vlc_keys.h>
  30. /*****************************************************************************
  31.  * Local prototypes
  32.  *****************************************************************************/
  33. static int Open( vlc_object_t *p_this );
  34. static void Close( vlc_object_t *p_this );
  35. static void *Thread( void *p_data );
  36. LRESULT CALLBACK WMHOTKEYPROC( HWND, UINT, WPARAM, LPARAM );
  37. /*****************************************************************************
  38.  * Module descriptor
  39.  *****************************************************************************/
  40. vlc_module_begin()
  41.     set_shortname( N_("Global Hotkeys") )
  42.     set_category( CAT_INTERFACE )
  43.     set_subcategory( SUBCAT_INTERFACE_HOTKEYS )
  44.     set_description( N_("Global Hotkeys interface") )
  45.     set_capability( "interface", 0 )
  46.     set_callbacks( Open, Close )
  47. vlc_module_end()
  48. struct intf_sys_t
  49. {
  50.     vlc_thread_t thread;
  51.     HWND hotkeyWindow;
  52.     vlc_mutex_t lock;
  53.     vlc_cond_t wait;
  54. };
  55. /*****************************************************************************
  56.  * Open: initialize interface
  57.  *****************************************************************************/
  58. static int Open( vlc_object_t *p_this )
  59. {
  60.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  61.     intf_sys_t *p_sys = malloc( sizeof (intf_sys_t) );
  62.     if( p_sys == NULL )
  63.         return VLC_ENOMEM;
  64.     p_intf->p_sys = p_sys;
  65.     p_sys->hotkeyWindow = NULL;
  66.     vlc_mutex_init( &p_sys->lock );
  67.     vlc_cond_init( &p_sys->wait );
  68.     if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
  69.     {
  70.         vlc_mutex_destroy( &p_sys->lock );
  71.         vlc_cond_destroy( &p_sys->wait );
  72.         free( p_sys );
  73.         p_intf->p_sys = NULL;
  74.         return VLC_ENOMEM;
  75.     }
  76.     vlc_mutex_lock( &p_sys->lock );
  77.     while( p_sys->hotkeyWindow == NULL )
  78.         vlc_cond_wait( &p_sys->wait, &p_sys->lock );
  79.     if( p_sys->hotkeyWindow == INVALID_HANDLE_VALUE )
  80.     {
  81.         vlc_mutex_unlock( &p_sys->lock );
  82.         vlc_join( p_sys->thread, NULL );
  83.         vlc_mutex_destroy( &p_sys->lock );
  84.         vlc_cond_destroy( &p_sys->wait );
  85.         free( p_sys );
  86.         p_intf->p_sys = NULL;
  87.         return VLC_ENOMEM;
  88.     }
  89.     vlc_mutex_unlock( &p_sys->lock );
  90.     return VLC_SUCCESS;
  91. }
  92. /*****************************************************************************
  93.  * Close: destroy interface
  94.  *****************************************************************************/
  95. static void Close( vlc_object_t *p_this )
  96. {
  97.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  98.     intf_sys_t *p_sys = p_intf->p_sys;
  99.     /* stop hotkey window */
  100.     vlc_mutex_lock( &p_sys->lock );
  101.     if( p_sys->hotkeyWindow != NULL )
  102.         PostMessage( p_sys->hotkeyWindow, WM_CLOSE, 0, 0 );
  103.     vlc_mutex_unlock( &p_sys->lock );
  104.     vlc_join( p_sys->thread, NULL );
  105.     vlc_mutex_destroy( &p_sys->lock );
  106.     vlc_cond_destroy( &p_sys->wait );
  107.     free( p_sys );
  108. }
  109. /*****************************************************************************
  110.  * Thread: main loop
  111.  *****************************************************************************/
  112. static void *Thread( void *p_data )
  113. {
  114.     MSG message;
  115.     UINT i_key, i_keyMod, i_vk;
  116.     ATOM atom;
  117.     char *psz_hotkey = NULL;
  118.     intf_thread_t *p_intf = p_data;
  119.     intf_sys_t *p_sys = p_intf->p_sys;
  120.     /* Window which receives Hotkeys */
  121.     vlc_mutex_lock( &p_sys->lock );
  122.     p_sys->hotkeyWindow =
  123.         (void*)CreateWindow( _T("STATIC"),           /* name of window class */
  124.                 _T("VLC ghk ") _T(VERSION),         /* window title bar text */
  125.                 0,                                           /* window style */
  126.                 0,                                   /* default X coordinate */
  127.                 0,                                   /* default Y coordinate */
  128.                 0,                                           /* window width */
  129.                 0,                                          /* window height */
  130.                 NULL,                                    /* no parent window */
  131.                 NULL,                              /* no menu in this window */
  132.                 GetModuleHandle(NULL),    /* handle of this program instance */
  133.                 NULL );                                 /* sent to WM_CREATE */
  134.     if( p_sys->hotkeyWindow == NULL )
  135.     {
  136.         p_sys->hotkeyWindow = INVALID_HANDLE_VALUE;
  137.         vlc_cond_signal( &p_sys->wait );
  138.         vlc_mutex_unlock( &p_sys->lock );
  139.         return NULL;
  140.     }
  141.     vlc_cond_signal( &p_sys->wait );
  142.     vlc_mutex_unlock( &p_sys->lock );
  143.     SetWindowLongPtr( p_sys->hotkeyWindow, GWL_WNDPROC,
  144.             (LONG_PTR)WMHOTKEYPROC );
  145.     SetWindowLongPtr( p_sys->hotkeyWindow, GWL_USERDATA,
  146.             (LONG_PTR)p_intf );
  147.     /* Registering of Hotkeys */
  148.     for( struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;
  149.             p_hotkey->psz_action != NULL;
  150.             p_hotkey++ )
  151.     {
  152.         if( asprintf( &psz_hotkey, "global-%s", p_hotkey->psz_action ) < 0 )
  153.             break;
  154.         i_key = config_GetInt( p_intf, psz_hotkey );
  155.         free( psz_hotkey );
  156.         i_keyMod = 0;
  157.         if( i_key & KEY_MODIFIER_SHIFT ) i_keyMod |= MOD_SHIFT;
  158.         if( i_key & KEY_MODIFIER_ALT ) i_keyMod |= MOD_ALT;
  159.         if( i_key & KEY_MODIFIER_CTRL ) i_keyMod |= MOD_CONTROL;
  160. #define HANDLE( key ) case KEY_##key: i_vk = VK_##key; break
  161. #define HANDLE2( key, key2 ) case KEY_##key: i_vk = VK_##key2; break
  162. #ifndef VK_VOLUME_DOWN
  163. #define VK_VOLUME_DOWN          0xAE
  164. #define VK_VOLUME_UP            0xAF
  165. #endif
  166. #ifndef VK_MEDIA_NEXT_TRACK
  167. #define VK_MEDIA_NEXT_TRACK     0xB0
  168. #define VK_MEDIA_PREV_TRACK     0xB1
  169. #define VK_MEDIA_STOP           0xB2
  170. #define VK_MEDIA_PLAY_PAUSE     0xB3
  171. #endif
  172. #ifndef VK_PAGEUP
  173. #define VK_PAGEUP               0x21
  174. #define VK_PAGEDOWN             0x22
  175. #endif
  176.         i_vk = 0;
  177.         switch( i_key & ~KEY_MODIFIER )
  178.         {
  179.             HANDLE( LEFT );
  180.             HANDLE( RIGHT );
  181.             HANDLE( UP );
  182.             HANDLE( DOWN );
  183.             HANDLE( SPACE );
  184.             HANDLE2( ESC, ESCAPE );
  185.             HANDLE2( ENTER, RETURN );
  186.             HANDLE( F1 );
  187.             HANDLE( F2 );
  188.             HANDLE( F3 );
  189.             HANDLE( F4 );
  190.             HANDLE( F5 );
  191.             HANDLE( F6 );
  192.             HANDLE( F7 );
  193.             HANDLE( F8 );
  194.             HANDLE( F9 );
  195.             HANDLE( F10 );
  196.             HANDLE( F11 );
  197.             HANDLE( F12 );
  198.             HANDLE( PAGEUP );
  199.             HANDLE( PAGEDOWN );
  200.             HANDLE( HOME );
  201.             HANDLE( END );
  202.             HANDLE( INSERT );
  203.             HANDLE( DELETE );
  204.             HANDLE( VOLUME_DOWN );
  205.             HANDLE( VOLUME_UP );
  206.             HANDLE( MEDIA_PLAY_PAUSE );
  207.             HANDLE( MEDIA_STOP );
  208.             HANDLE( MEDIA_PREV_TRACK );
  209.             HANDLE( MEDIA_NEXT_TRACK );
  210.             default:
  211.                 i_vk = toupper( i_key & ~KEY_MODIFIER );
  212.                 break;
  213.         }
  214.         if( !i_vk ) continue;
  215. #undef HANDLE
  216. #undef HANDLE2
  217.         atom = GlobalAddAtomA( p_hotkey->psz_action );
  218.         if( !atom ) continue;
  219.         if( !RegisterHotKey( p_sys->hotkeyWindow, atom, i_keyMod, i_vk ) )
  220.             GlobalDeleteAtom( atom );
  221.     }
  222.     /* Main message loop */
  223.     while( GetMessage( &message, NULL, 0, 0 ) )
  224.         DispatchMessage( &message );
  225.     /* Unregistering of Hotkeys */
  226.     for( struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;
  227.             p_hotkey->psz_action != NULL;
  228.             p_hotkey++ )
  229.     {
  230.         atom = GlobalFindAtomA( p_hotkey->psz_action );
  231.         if( !atom ) continue;
  232.         if( UnregisterHotKey( p_sys->hotkeyWindow, atom ) )
  233.             GlobalDeleteAtom( atom );
  234.     }
  235.     /* close window */
  236.     vlc_mutex_lock( &p_sys->lock );
  237.     DestroyWindow( p_sys->hotkeyWindow );
  238.     p_sys->hotkeyWindow = NULL;
  239.     vlc_mutex_unlock( &p_sys->lock );
  240.     return NULL;
  241. }
  242. /*****************************************************************************
  243.  * WMHOTKEYPROC: event callback
  244.  *****************************************************************************/
  245. LRESULT CALLBACK WMHOTKEYPROC( HWND hwnd, UINT uMsg, WPARAM wParam,
  246.         LPARAM lParam )
  247. {
  248.     switch( uMsg )
  249.     {
  250.         case WM_HOTKEY:
  251.             {
  252.                 int i;
  253.                 char psz_atomName[40];
  254.                 intf_thread_t *p_intf =
  255.                     (intf_thread_t*)GetWindowLongPtr( hwnd, GWL_USERDATA );
  256.                 struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
  257.                 i = GlobalGetAtomNameA(
  258.                         wParam, psz_atomName, sizeof( psz_atomName ) );
  259.                 if( !i ) return 0;
  260.                 /* search for key associated with VLC */
  261.                 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
  262.                 {
  263.                     if( strcmp( p_hotkeys[i].psz_action, psz_atomName ) )
  264.                         continue;
  265.                     var_SetInteger( p_intf->p_libvlc,
  266.                             "key-action", p_hotkeys[i].i_action );
  267.                     return 1;
  268.                 }
  269.             }
  270.             break;
  271.         case WM_DESTROY:
  272.             PostQuitMessage( 0 );
  273.             break;
  274.         default:
  275.             return DefWindowProc( hwnd, uMsg, wParam, lParam );
  276.     }
  277.     return 0;
  278. }