<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman,new york,times,serif;font-size:12pt"><div>Hello All,<br><br>This patch is created to support windows special key functionality even when the application is in system tray/minimized/not interacted by the user. This is added in windows globalhotkey module. This will enable the user to interact with VLC even when it is system tray. This is implemented using windows hook concept to detect the user key press of PLAY,PAUSE, NEXT and PREVIOUS keys. Here am used WH_KEYBOARD_LL instead of WH_KEYBOARD which eliminates the need of DLL and makes it as Window Global hook which does not require any dependencies and can be part of any exe. This Current implementation only handles the This can be extended to other keys when needed.<br><br><br>/*****************************************************************************<br> * win32.c:
 Global-Hotkey WIN32 handling for vlc<br> *****************************************************************************<br> * Copyright (C) 2008-2009 the VideoLAN team<br> *<br> * Authors: Domani Hannes <ssbssa at yahoo dot de><br>+  *             Elangovan <elangovv at gmail dot com><br> *<br> * This program is free software; you can redistribute it and/or modify<br> * it under the terms of the GNU General Public License as published by<br><br><br>#ifdef HAVE_CONFIG_H<br># include "config.h"<br>#endif<br><br>#include <ctype.h><br><br>#include <vlc_common.h><br>#include <vlc_plugin.h><br>#include <vlc_interface.h><br>#include <vlc_keys.h><br><br>/*****************************************************************************<br> * Local
 prototypes<br> *****************************************************************************/<br>    static int Open( vlc_object_t *p_this );<br>    static void Close( vlc_object_t *p_this );<br>    static void *Thread( void *p_data );<br>    LRESULT CALLBACK WMHOTKEYPROC( HWND, UINT, WPARAM, LPARAM );<br>+  LRESULT  CALLBACK WINTRAYSUPPORTPROC( int nCode, WPARAM wParam,  LPARAM lParam);<br><br>    /*****************************************************************************<br>     * Module descriptor<br>     *****************************************************************************/<br>    vlc_module_begin()<br>        set_shortname( N_("Global Hotkeys") )<br>        set_category( CAT_INTERFACE )<br>       
 set_subcategory( SUBCAT_INTERFACE_HOTKEYS )<br>        set_description( N_("Global Hotkeys interface") )<br>        set_capability( "interface", 0 )<br>        set_callbacks( Open, Close )<br>    vlc_module_end()<br>    <br>    struct intf_sys_t<br>    {<br>        vlc_thread_t thread;<br>        HWND hotkeyWindow;<br>        vlc_mutex_t lock;<br>        vlc_cond_t wait;<br>        HHOOK hHook;<br>    };<br><br>    /*****************************************************************************<br>     * Open: initialize interface<br>   
  *****************************************************************************/<br>    static int Open( vlc_object_t *p_this )<br>    {<br>        intf_thread_t *p_intf = (intf_thread_t *)p_this;<br>        intf_sys_t *p_sys = malloc( sizeof (intf_sys_t) );<br>    <br>        if( p_sys == NULL )<br>        return VLC_ENOMEM;<br><br>        p_intf->p_sys = p_sys;<br>        p_sys->hotkeyWindow = NULL;<br>        vlc_mutex_init( &p_sys->lock );<br>        vlc_cond_init( &p_sys->wait );<br><br>        if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )<br>   
     {<br>            vlc_mutex_destroy( &p_sys->lock );<br>            vlc_cond_destroy( &p_sys->wait );<br>            free( p_sys );<br>            p_intf->p_sys = NULL;<br>    <br>            return VLC_ENOMEM;<br>        }<br><br>        vlc_mutex_lock( &p_sys->lock );<br>        while( p_sys->hotkeyWindow == NULL )<br>            vlc_cond_wait( &p_sys->wait, &p_sys->lock );<br>        if( p_sys->hotkeyWindow == INVALID_HANDLE_VALUE )<br>   
     {<br>            vlc_mutex_unlock( &p_sys->lock );<br>            vlc_join( p_sys->thread, NULL );<br>            vlc_mutex_destroy( &p_sys->lock );<br>            vlc_cond_destroy( &p_sys->wait );<br>            free( p_sys );<br>            p_intf->p_sys = NULL;<br>    <br>            return VLC_ENOMEM;<br>        }<br>        vlc_mutex_unlock( &p_sys->lock );<br>    <br>        return VLC_SUCCESS;<br>   
 }    <br><br>    /*****************************************************************************<br>     *Close: destroy interface<br>     *****************************************************************************/<br>    static void Close( vlc_object_t *p_this )<br>    {<br>        intf_thread_t *p_intf = (intf_thread_t *)p_this;<br>        intf_sys_t *p_sys = p_intf->p_sys;<br>+        /* Unregister the HOOK Procedure */<br>+        if( p_sys->hHook !=NULL )<br>+           UnhookWindowsHookEx(p_sys->hHook);<br><br>        /* stop hotkey window */<br>    vlc_mutex_lock( &p_sys->lock );<br>    if( p_sys->hotkeyWindow !=
 NULL )<br>        PostMessage( p_sys->hotkeyWindow, WM_CLOSE, 0, 0 );<br>    vlc_mutex_unlock( &p_sys->lock );<br><br>    vlc_join( p_sys->thread, NULL );<br>    vlc_mutex_destroy( &p_sys->lock );<br>    vlc_cond_destroy( &p_sys->wait );<br>    free( p_sys );<br>}<br><br>/*****************************************************************************<br> * Thread: main loop<br> *****************************************************************************/<br>static void *Thread( void *p_data )<br>{<br>    MSG message;<br>    UINT i_key, i_keyMod, i_vk;<br>    ATOM atom;<br>    char *psz_hotkey = NULL;<br><br>    intf_thread_t *p_intf = p_data;<br>    intf_sys_t *p_sys = p_intf->p_sys;<br><br>    /* Window
 which receives Hotkeys */<br>    vlc_mutex_lock( &p_sys->lock );<br>    p_sys->hotkeyWindow =<br>        (void*)CreateWindow( _T("STATIC"),           /* name of window class */<br>                _T("VLC ghk ") _T(VERSION),         /* window title bar text */<br>                0,                                           /* window style */<br>               
 0,                                   /* default X coordinate */<br>                0,                                   /* default Y coordinate */<br>                0,                                           /* window width
 */<br>                0,                                          /* window height */<br>                NULL,                                    /* no parent window */<br>               
 NULL,                              /* no menu in this window */<br>                GetModuleHandle(NULL),    /* handle of this program instance */<br>                NULL );                                 /* sent to WM_CREATE */<br><br>+    //Get Module handle and register the HOOK<br>+   HINSTANCE hExe = GetModuleHandle(NULL);<br>+    if (hExe !=NULL)<br>+    {<br>+        p_sys->hHook = SetWindowsHookEx(
 WH_KEYBOARD_LL, (HOOKPROC)WINTRAYSUPPORTPROC, hExe, NULL);<br>+    }<br>    if( p_sys->hotkeyWindow == NULL )<br>    {<br>        p_sys->hotkeyWindow = INVALID_HANDLE_VALUE;<br>        vlc_cond_signal( &p_sys->wait );<br>        vlc_mutex_unlock( &p_sys->lock );<br>        return NULL;<br>    }<br>    vlc_cond_signal( &p_sys->wait );<br>    vlc_mutex_unlock( &p_sys->lock );<br><br>    SetWindowLongPtr( p_sys->hotkeyWindow, GWLP_WNDPROC,<br>            (LONG_PTR)WMHOTKEYPROC );<br>    SetWindowLongPtr( p_sys->hotkeyWindow, GWLP_USERDATA,<br>           
 (LONG_PTR)p_intf );<br><br>    /* Registering of Hotkeys */<br>    for( const struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;<br>            p_hotkey->psz_action != NULL;<br>            p_hotkey++ )<br>    {<br>        if( asprintf( &psz_hotkey, "global-%s", p_hotkey->psz_action ) < 0 )<br>            break;<br><br>        i_key = var_InheritInteger( p_intf, psz_hotkey );<br><br>        free( psz_hotkey );<br><br>        i_keyMod = 0;<br>        if( i_key & KEY_MODIFIER_SHIFT ) i_keyMod |= MOD_SHIFT;<br>       
 if( i_key & KEY_MODIFIER_ALT ) i_keyMod |= MOD_ALT;<br>        if( i_key & KEY_MODIFIER_CTRL ) i_keyMod |= MOD_CONTROL;<br><br>#define HANDLE( key ) case KEY_##key: i_vk = VK_##key; break<br>#define HANDLE2( key, key2 ) case KEY_##key: i_vk = VK_##key2; break<br><br>#define KEY_SPACE ' '<br><br>#ifndef VK_VOLUME_DOWN<br>#define VK_VOLUME_DOWN          0xAE<br>#define VK_VOLUME_UP            0xAF<br>#endif<br><br>#ifndef VK_MEDIA_NEXT_TRACK<br>#define VK_MEDIA_NEXT_TRACK     0xB0<br>#define VK_MEDIA_PREV_TRACK     0xB1<br>#define VK_MEDIA_STOP           0xB2<br>#define VK_MEDIA_PLAY_PAUSE     0xB3<br>#endif<br><br>#ifndef VK_PAGEUP<br>#define
 VK_PAGEUP               0x21<br>#define VK_PAGEDOWN             0x22<br>#endif<br><br>        i_vk = 0;<br>        switch( i_key & ~KEY_MODIFIER )<br>        {<br>            HANDLE( LEFT );<br>            HANDLE( RIGHT );<br>            HANDLE( UP );<br>            HANDLE( DOWN );<br>            HANDLE( SPACE );<br>            HANDLE2( ESC, ESCAPE
 );<br>            HANDLE2( ENTER, RETURN );<br>            HANDLE( F1 );<br>            HANDLE( F2 );<br>            HANDLE( F3 );<br>            HANDLE( F4 );<br>            HANDLE( F5 );<br>            HANDLE( F6 );<br>            HANDLE( F7 );<br>            HANDLE( F8 );<br>            HANDLE( F9 );<br>            HANDLE( F10
 );<br>            HANDLE( F11 );<br>            HANDLE( F12 );<br>            HANDLE( PAGEUP );<br>            HANDLE( PAGEDOWN );<br>            HANDLE( HOME );<br>            HANDLE( END );<br>            HANDLE( INSERT );<br>            HANDLE( DELETE );<br>            HANDLE( VOLUME_DOWN );<br>            HANDLE( VOLUME_UP );<br>            HANDLE(
 MEDIA_PLAY_PAUSE );<br>            HANDLE( MEDIA_STOP );<br>            HANDLE( MEDIA_PREV_TRACK );<br>            HANDLE( MEDIA_NEXT_TRACK );<br><br>            default:<br>                i_vk = toupper( i_key & ~KEY_MODIFIER );<br>                break;<br>        }<br>        if( !i_vk ) continue;<br><br>#undef HANDLE<br>#undef HANDLE2<br><br>        atom = GlobalAddAtomA( p_hotkey->psz_action );<br>        if( !atom )
 continue;<br><br>        if( !RegisterHotKey( p_sys->hotkeyWindow, atom, i_keyMod, i_vk ) )<br>            GlobalDeleteAtom( atom );<br>    }<br><br>    /* Main message loop */<br>    while( GetMessage( &message, NULL, 0, 0 ) )<br>        DispatchMessage( &message );<br><br>    /* Unregistering of Hotkeys */<br>    for( const struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;<br>            p_hotkey->psz_action != NULL;<br>            p_hotkey++ )<br>    {<br>        atom = GlobalFindAtomA( p_hotkey->psz_action );<br>        if( !atom )
 continue;<br><br>        if( UnregisterHotKey( p_sys->hotkeyWindow, atom ) )<br>            GlobalDeleteAtom( atom );<br>    }<br><br>    /* close window */<br>    vlc_mutex_lock( &p_sys->lock );<br>    DestroyWindow( p_sys->hotkeyWindow );<br>    p_sys->hotkeyWindow = NULL;<br>    vlc_mutex_unlock( &p_sys->lock );<br><br>    return NULL;<br>}<br><br>/*****************************************************************************<br> * WMHOTKEYPROC: event callback<br> *****************************************************************************/<br>LRESULT CALLBACK WMHOTKEYPROC( HWND hwnd, UINT uMsg, WPARAM wParam,<br>        LPARAM lParam )<br>{<br>    switch( uMsg
 )<br>    {<br>        case WM_HOTKEY:<br>            {<br>                char psz_atomName[40];<br><br>                LONG_PTR ret = GetWindowLongPtr( hwnd, GWLP_USERDATA );<br>                intf_thread_t *p_intf = (intf_thread_t*)ret;<br>                const struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;<br><br>                if(
 !GlobalGetAtomNameA(<br>                        wParam, psz_atomName, sizeof( psz_atomName ) ) )<br>                    return 0;<br><br>                /* search for key associated with VLC */<br>                for( int i = 0; p_hotkeys[i].psz_action != NULL; i++ )<br>                {<br>                    if( strcmp( p_hotkeys[i].psz_action, psz_atomName )
 )<br>                        continue;<br><br>                    var_SetInteger( p_intf->p_libvlc,<br>                            "key-action", p_hotkeys[i].i_action );<br><br>                    return 1;<br>                }<br>            }<br>            break;<br><br>        case
 WM_DESTROY:<br>            PostQuitMessage( 0 );<br>            break;<br><br>        default:<br>            return DefWindowProc( hwnd, uMsg, wParam, lParam );<br>    }<br><br>    return 0;<br>}<br><br>+    /*****************************************************************************<br>+     * WINTRAYSUPPORTPROC: event callback method<br>+     *****************************************************************************/<br> +   LRESULT  CALLBACK WINTRAYSUPPORTPROC( int nCode, WPARAM wParam,  LPARAM lParam)<br> +   {<br>+        #ifndef VK_MEDIA_NEXT_TRACK<br> +       #define
 VK_MEDIA_NEXT_TRACK     0xB0<br>+        #define VK_MEDIA_PREV_TRACK     0xB1<br>+        #define VK_MEDIA_STOP           0xB2<br>+        #define VK_MEDIA_PLAY_PAUSE     0xB3<br>+        #endif<br> +       static HHOOK hkb=NULL;<br>+        if  ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))<br>+        {<br>+           KBDLLHOOKSTRUCT hookstruct = *((KBDLLHOOKSTRUCT*)lParam);<br>+           if( VK_MEDIA_PLAY_PAUSE == hookstruct.vkCode || VK_MEDIA_NEXT_TRACK == hookstruct.vkCode || VK_MEDIA_STOP == hookstruct.vkCode || VK_MEDIA_PREV_TRACK ==
 hookstruct.vkCode)<br>+          {<br>+             HANDLE hotkeyWindow = FindWindow(_T("STATIC"), _T("VLC ghk ") _T(VERSION));<br>+                if(hotkeyWindow !=NULL)<br>+                {<br>+                    LONG_PTR ret = GetWindowLongPtr( hotkeyWindow, GWLP_USERDATA );<br>+                    intf_thread_t *p_intf = (intf_thread_t*)ret;<br>+                    switch(hookstruct.vkCode)<br>+                   
 {<br>+                        case VK_MEDIA_PLAY_PAUSE:<br>+                            var_SetInteger( p_intf->p_libvlc,"key-action", ACTIONID_PLAY_PAUSE );<br>+                            break;<br>+                        case VK_MEDIA_STOP:<br>+                            var_SetInteger( p_intf->p_libvlc,"key-action", ACTIONID_STOP );<br>+                       
     break;<br>+                        case VK_MEDIA_PREV_TRACK:<br>+                            var_SetInteger( p_intf->p_libvlc,"key-action", ACTIONID_PREV );<br>+                            break;<br>+                        case VK_MEDIA_NEXT_TRACK:<br>+                            var_SetInteger( p_intf->p_libvlc,"key-action", ACTIONID_NEXT );<br>+                   
 }<br>+                }<br>+            }<br>+        }<br>+        return   CallNextHookEx( hkb, nCode, wParam, lParam );<br>+    }    <br><br><br>Regards<br>Elangovan<br></div>
</div><br></body></html>