[vlc-devel] [PATCH] Global Hotkeys for windows

Rémi Denis rdenis at simphalempin.com
Fri Jan 16 12:19:55 CET 2009


Looks OK. It might be simpler to create/destroy the window in Open/Close.

-original message-
Subject: Re: [vlc-devel] [PATCH] Global Hotkeys for windows
From: Hannes Domani <ssbssa at yahoo.de>
Date: 16/01/2009 11:39

--- 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


      
_______________________________________________
vlc-devel mailing list
To unsubscribe or modify your subscription options:
http://mailman.videolan.org/listinfo/vlc-devel




More information about the vlc-devel mailing list