From: Pierre d'Herbemont Date: Thu, 7 Jun 2007 12:34:50 +0000 (+0000) Subject: Libvlc Event: Add support for input event. X-Git-Tag: 0.9.0-test0~7119 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=ff8e2f89378914ac7530b3edd2f3c4647dc6e9f0;p=vlc Libvlc Event: Add support for input event. --- diff --git a/src/control/core.c b/src/control/core.c index b765e96048..cfbc2b06a2 100644 --- a/src/control/core.c +++ b/src/control/core.c @@ -102,13 +102,15 @@ libvlc_instance_t * libvlc_new( int argc, char **argv, p_new->p_callback_list = NULL; vlc_mutex_init(p_libvlc_int, &p_new->instance_lock); vlc_mutex_init(p_libvlc_int, &p_new->event_callback_lock); + + libvlc_event_init(p_new, p_e); return p_new; } void libvlc_destroy( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { - libvlc_event_remove_all_callbacks( p_instance, p_e /* current implementation never triggers it */); + libvlc_event_fini( p_instance, p_e ); vlc_mutex_destroy( &p_instance->instance_lock ); vlc_mutex_destroy( &p_instance->event_callback_lock); libvlc_InternalCleanup( p_instance->p_libvlc_int ); diff --git a/src/control/event.c b/src/control/event.c index 08685ab68f..849b62b29d 100644 --- a/src/control/event.c +++ b/src/control/event.c @@ -5,6 +5,7 @@ * $Id $ * * Authors: Filippo Carone + * Pierre d'Herbemont * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,7 @@ #include "libvlc_internal.h" #include +#include /* @@ -57,6 +59,50 @@ static int handle_event( vlc_object_t *p_this, char const *psz_cmd, return VLC_SUCCESS; } +/* Utility function: Object should be released by vlc_object_release afterwards */ +static input_thread_t * get_input(libvlc_instance_t * p_instance) +{ + libvlc_exception_t p_e_unused; /* FIXME: error checking here */ + libvlc_input_t * p_libvlc_input = libvlc_playlist_get_input( p_instance, &p_e_unused ); + input_thread_t * p_input; + + if( !p_libvlc_input ) + return NULL; + + p_input = libvlc_get_input_thread( p_libvlc_input, &p_e_unused ); + + libvlc_input_free(p_libvlc_input); + + return p_input; +} + +static int install_input_event( vlc_object_t *p_this, char const *psz_cmd, + vlc_value_t oldval, vlc_value_t newval, + void *p_data ) +{ + libvlc_instance_t * p_instance = p_data; + struct libvlc_callback_entry_list_t *p_listitem; + input_thread_t * p_input = get_input( p_instance ); + + vlc_mutex_lock( &p_instance->instance_lock ); + + p_listitem = p_instance->p_callback_list; + + for( ; p_listitem ; p_listitem = p_listitem->next ) + { + if (p_listitem->elmt->i_event_type == INPUT_POSITION_CHANGED) + { + /* FIXME: here we shouldn't listen on intf-change, we have to provide + * in vlc core a more accurate callback */ + var_AddCallback( p_input, "intf-change", handle_event, p_listitem->elmt ); + } + } + + vlc_mutex_unlock( &p_instance->instance_lock ); + vlc_object_release( p_input ); + return VLC_SUCCESS; +} + static inline void add_callback_to_list( struct libvlc_callback_entry_t *entry, struct libvlc_callback_entry_list_t **list ) { @@ -82,25 +128,59 @@ static inline void add_callback_to_list( struct libvlc_callback_entry_t *entry, static int remove_variable_callback( libvlc_instance_t *p_instance, struct libvlc_callback_entry_t * p_entry ) { - const char * callback_name = NULL; - + input_thread_t * p_input = get_input( p_instance ); + int res = VLC_SUCCESS; + /* Note: Appropriate lock should be held by the caller */ switch ( p_entry->i_event_type ) { case VOLUME_CHANGED: - callback_name = "volume-change"; + res = var_DelCallback( p_instance->p_libvlc_int, "volume-change", + handle_event, p_entry ); break; case INPUT_POSITION_CHANGED: + /* We may not be deleting the right p_input callback, in this case this + * will be a no-op */ + var_DelCallback( p_input, "intf-change", + handle_event, p_entry ); break; } + + if (p_input) + vlc_object_release( p_input ); - if (!callback_name) - return VLC_EGENERIC; + return res; +} - return var_DelCallback( p_instance->p_libvlc_int, - callback_name, handle_event, - p_entry ); +/* + * Internal libvlc functions + */ +void libvlc_event_init( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) +{ + playlist_t *p_playlist = p_instance->p_libvlc_int->p_playlist; + + if( !p_playlist ) + RAISEVOID ("Can't listen to input event"); + + /* Install a Callback for input changes, so + * so we can track input event */ + var_AddCallback( p_playlist, "playlist-current", + install_input_event, p_instance ); +} + +void libvlc_event_fini( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) +{ + playlist_t *p_playlist = p_instance->p_libvlc_int->p_playlist; + libvlc_exception_t p_e_unused; + + libvlc_event_remove_all_callbacks( p_instance, &p_e_unused ); + + if( !p_playlist ) + RAISEVOID ("Can't unregister input events"); + + var_DelCallback( p_playlist, "playlist-current", + install_input_event, p_instance ); } /* @@ -114,8 +194,8 @@ void libvlc_event_add_callback( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { struct libvlc_callback_entry_t *entry; - const char * callback_name = NULL; - int res; + vlc_value_t unused1, unused2; + int res = VLC_SUCCESS; if ( !f_callback ) RAISEVOID (" Callback function is null "); @@ -135,20 +215,17 @@ void libvlc_event_add_callback( libvlc_instance_t *p_instance, switch ( i_event_type ) { case VOLUME_CHANGED: - callback_name = "volume-change"; + res = var_AddCallback( p_instance->p_libvlc_int, "volume-change", + handle_event, entry ); break; case INPUT_POSITION_CHANGED: + install_input_event( NULL, NULL, unused1, unused2, p_instance); break; default: free( entry ); RAISEVOID( "Unsupported event." ); } - res = var_AddCallback( p_instance->p_libvlc_int, - callback_name, - handle_event, - entry ); - if (res != VLC_SUCCESS) { free ( entry ); diff --git a/src/control/input.c b/src/control/input.c index 1dbcb6a8d9..793484cca0 100644 --- a/src/control/input.c +++ b/src/control/input.c @@ -34,9 +34,9 @@ void libvlc_input_free( libvlc_input_t *p_input ) /* * Retrieve the input thread. Be sure to release the object - * once you are done with it. + * once you are done with it. (libvlc Internal) */ -static input_thread_t *libvlc_get_input_thread( libvlc_input_t *p_input, +input_thread_t *libvlc_get_input_thread( libvlc_input_t *p_input, libvlc_exception_t *p_e ) { input_thread_t *p_input_thread; diff --git a/src/control/libvlc_internal.h b/src/control/libvlc_internal.h index d762d71b89..d454f70b9c 100644 --- a/src/control/libvlc_internal.h +++ b/src/control/libvlc_internal.h @@ -43,6 +43,9 @@ VLC_EXPORT (int, libvlc_InternalDestroy, ( libvlc_int_t *, vlc_bool_t ) ); VLC_EXPORT (int, libvlc_InternalAddIntf, ( libvlc_int_t *, const char *, vlc_bool_t, vlc_bool_t, int, const char *const * ) ); +VLC_EXPORT (void, libvlc_event_init, ( libvlc_instance_t *, libvlc_exception_t * ) ); +VLC_EXPORT (void, libvlc_event_fini, ( libvlc_instance_t *, libvlc_exception_t * ) ); + /*************************************************************************** * Opaque structures for libvlc API ***************************************************************************/ @@ -79,6 +82,12 @@ struct libvlc_input_t struct libvlc_instance_t *p_instance; ///< Parent instance }; +/*************************************************************************** + * Other internal functions + ***************************************************************************/ +VLC_EXPORT (input_thread_t *, libvlc_get_input_thread, + ( struct libvlc_input_t *, libvlc_exception_t * ) ); + #define RAISENULL( psz,a... ) { libvlc_exception_raise( p_e, psz,##a ); \ return NULL; } #define RAISEVOID( psz,a... ) { libvlc_exception_raise( p_e, psz,##a ); \