[vlc-devel] [PATCH] Global Hotkeys for windows
Hannes Domani
ssbssa at yahoo.de
Fri Jan 16 10:39:22 CET 2009
--- Laurent Aimar <fenrir at via.ecp.fr> wrote on Do, 15.1.2009:
> +/*****************************************************************************
> > + * Close: destroy interface
> > +
> *****************************************************************************/
> > +static void Close( vlc_object_t *p_this )
> > +{
> > + intf_thread_t *p_intf = (intf_thread_t *)p_this;
> > + intf_sys_t *p_sys = p_intf->p_sys;
> > +
> > + /* stop hotkey window */
> > + PostMessage( p_sys->hotkeyWindow, WM_CLOSE, 0,
> 0 );
> Here you have a race condition between the post of this
> message and the
> creation of the window handle (in case Close is called too
> fast).
> You need to make sure in the Open or in the Close before
> the post that the
> window have been created (or have failed).
> And you probably need to protect( using lock) hotkeyWindow
> access (see below).
>
> >
> +/*****************************************************************************
> > + * Thread: main loop
> > +
> *****************************************************************************/
> > +static void *Thread( void *p_data )
> > +{
> > + /* Window which receives Hotkeys */
> > + p_sys->hotkeyWindow =
> > + (void*)CreateWindow( _T("STATIC"),
> /* name of window class */
> > + _T("VLC ghk ") _T(VERSION),
> /* window title bar text */
> > + 0,
> /* window style */
> > + 0,
> /* default X coordinate */
> > + 0,
> /* default Y coordinate */
> > + 0,
> /* window width */
> > + 0,
> /* window height */
> > + NULL,
> /* no parent window */
> > + NULL, /*
> no menu in this window */
> > + GetModuleHandle(NULL), /* handle
> of this program instance */
> > + NULL );
> /* sent to WM_CREATE */
> > +
> > + if( p_sys->hotkeyWindow == NULL )
> > + return( NULL );
> You should protect p_sys->hotkeyWindow and probably
> signal its creation or
> the failure.
>
> > + /* close window */
> > + DestroyWindow( p_sys->hotkeyWindow );
> You should also protect the destruction (specially if
> GetMessage can fail
> for another reason that your WM_CLOSE post).
>
> For locking and signal, you can have a look at:
> vlc_mutex_t
> vlc_cond_t
>
> vlc_mutex_init/vlc_mutex_destroy
> vlc_mutex_lock/unlock
>
> vlc_cond_init/destroy
> vlc_cond_signal/wait
> (becarefull that vlc_cond_wait can have supurious wake up).
>
> Other than that and courmish comments, it seems fine,
> thanks for your work.
would it work like this (untested code)?:
struct intf_sys_t
{
vlc_thread_t thread;
HWND hotkeyWindow;
vlc_mutex_t lock;
vlc_cond_t wait;
};
/*****************************************************************************
* Open: initialize interface
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
intf_sys_t *p_sys = malloc( sizeof (intf_sys_t) );
if( p_sys == NULL )
return( VLC_ENOMEM );
p_intf->p_sys = p_sys;
p_sys->hotkeyWindow = NULL;
vlc_mutex_init( &p_sys->lock );
vlc_cond_init( &p_sys->wait );
if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
{
vlc_mutex_destroy( &p_sys->lock );
vlc_cond_destroy( &p_sys->wait );
free( p_sys );
p_intf->p_sys = NULL;
return( VLC_ENOMEM );
}
vlc_mutex_lock( &p_sys->lock );
while( p_sys->hotkeyWindow == NULL )
vlc_cond_wait( &p_sys->wait, &p_sys->lock );
if( p_sys->hotkeyWindow == INVALID_HANDLE_VALUE )
{
vlc_mutex_unlock( &p_sys->lock );
vlc_join( p_sys->thread, NULL );
vlc_mutex_destroy( &p_sys->lock );
vlc_cond_destroy( &p_sys->wait );
free( p_sys );
p_intf->p_sys = NULL;
return( VLC_ENOMEM );
}
vlc_mutex_unlock( &p_sys->lock );
return( VLC_SUCCESS );
}
/*****************************************************************************
* Close: destroy interface
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
intf_sys_t *p_sys = p_intf->p_sys;
/* stop hotkey window */
vlc_mutex_lock( &p_sys->lock );
if( p_sys->hotkeyWindow != NULL )
PostMessage( p_sys->hotkeyWindow, WM_CLOSE, 0, 0 );
vlc_mutex_unlock( &p_sys->lock );
vlc_join( p_sys->thread, NULL );
vlc_mutex_destroy( &p_sys->lock );
vlc_cond_destroy( &p_sys->wait );
free( p_sys );
}
/*****************************************************************************
* Thread: main loop
*****************************************************************************/
static void *Thread( void *p_data )
{
MSG message;
UINT i_key, i_keyMod, i_vk;
ATOM atom;
char *psz_hotkey = NULL;
intf_thread_t *p_intf = p_data;
intf_sys_t *p_sys = p_intf->p_sys;
/* Window which receives Hotkeys */
vlc_mutex_lock( &p_sys->lock );
p_sys->hotkeyWindow =
(void*)CreateWindow( _T("STATIC"), /* name of window class */
_T("VLC ghk ") _T(VERSION), /* window title bar text */
0, /* window style */
0, /* default X coordinate */
0, /* default Y coordinate */
0, /* window width */
0, /* window height */
NULL, /* no parent window */
NULL, /* no menu in this window */
GetModuleHandle(NULL), /* handle of this program instance */
NULL ); /* sent to WM_CREATE */
if( p_sys->hotkeyWindow == NULL )
{
p_sys->hotkeyWindow = INVALID_HANDLE_VALUE;
vlc_mutex_unlock( &p_sys->lock );
vlc_cond_signal( &p_sys->wait );
return( NULL );
}
vlc_mutex_unlock( &p_sys->lock );
vlc_cond_signal( &p_sys->wait );
...
/* close window */
vlc_mutex_lock( &p_sys->lock );
DestroyWindow( p_sys->hotkeyWindow );
p_sys->hotkeyWindow = NULL;
vlc_mutex_unlock( &p_sys->lock );
return( NULL );
}
regards
Domani Hannes
More information about the vlc-devel
mailing list