Commit 1f319885 authored by Clément Stenac's avatar Clément Stenac

Interaction facility (Refs:#27)

parent 0ec68fc6
...@@ -58,10 +58,36 @@ struct interaction_dialog_t ...@@ -58,10 +58,36 @@ struct interaction_dialog_t
vlc_bool_t b_have_answer; //< Has an answer been given ? vlc_bool_t b_have_answer; //< Has an answer been given ?
vlc_bool_t b_reusable; //< Do we have to reuse this ? vlc_bool_t b_reusable; //< Do we have to reuse this ?
vlc_bool_t b_updated; //< Update for this one ?
vlc_bool_t b_finished; //< Hidden by interface
void * p_private; //< Private interface data void * p_private; //< Private interface data
}; };
/**
* Possible interaction types
*/
enum
{
INTERACT_PROGRESS, //< Progress bar
INTERACT_WARNING, //< Warning message ("codec not supported")
INTERACT_FATAL, //< Fatal message ("File not found")
INTERACT_FATAL_LIST, //< List of fatal messages ("File not found")
INTERACT_ASK, //< Full-featured dialog box (password)
};
/**
* Predefined reusable dialogs
*/
enum
{
DIALOG_NOACCESS,
DIALOG_NOCODEC,
DIALOG_NOAUDIO,
DIALOG_LAST_PREDEFINED,
};
/** /**
* This structure contains the active interaction dialogs, and is * This structure contains the active interaction dialogs, and is
* used by teh manager * used by teh manager
...@@ -72,25 +98,30 @@ struct interaction_t ...@@ -72,25 +98,30 @@ struct interaction_t
int i_dialogs; //< Number of dialogs int i_dialogs; //< Number of dialogs
interaction_dialog_t **pp_dialogs; //< Dialogs interaction_dialog_t **pp_dialogs; //< Dialogs
};
intf_thread_t *p_intf; //< Interface to use
int i_last_id; //< Last attributed ID
};
/** /**
* Possible interaction types * Possible actions
*/ */
enum enum
{ {
INTERACT_PROGRESS, //< Progress bar INTERACT_NEW,
INTERACT_WARNING, //< Warning message ("codec not supported") INTERACT_UPDATE,
INTERACT_FATAL, //< Fatal message ("File not found") INTERACT_HIDE
INTERACT_ASK, //< Full-featured dialog box (password)
}; };
/***************************************************************************
* Exported symbols
***************************************************************************/
#define intf_Interact( a,b ) __intf_Interact( VLC_OBJECT(a), b ) #define intf_Interact( a,b ) __intf_Interact( VLC_OBJECT(a), b )
VLC_EXPORT( int,__intf_Interact,( vlc_object_t *,interaction_dialog_t * ) ); VLC_EXPORT( int,__intf_Interact,( vlc_object_t *,interaction_dialog_t * ) );
#if 0 #define intf_UserFatal( a,b, c, d, e... ) __intf_UserFatal( a,b,c,d, ## e )
VLC_NO_EXPORT_YET( int,__intf_InteractionManage,( playlist_t *) ); VLC_EXPORT( void, __intf_UserFatal,( vlc_object_t*, int, const char*, const char*, ...) );
#endif
VLC_EXPORT( void, intf_UserFatal,( vlc_object_t*, const char*, const char*, ...));
VLC_EXPORT( void, intf_InteractionManage,( playlist_t *) );
VLC_EXPORT( void, intf_InteractionDestroy,( interaction_t *) );
...@@ -66,8 +66,7 @@ struct intf_thread_t ...@@ -66,8 +66,7 @@ struct intf_thread_t
intf_dialog_args_t * ); intf_dialog_args_t * );
/** Interaction stuff */ /** Interaction stuff */
int i_last_id; int ( *pf_interact ) ( intf_thread_t *, interaction_dialog_t *, int );
int ( *pf_interact ) ( intf_thread_t *, interaction_dialog_t *, vlc_bool_t );
/** Video window callbacks */ /** Video window callbacks */
void * ( *pf_request_window ) ( intf_thread_t *, vout_thread_t *, void * ( *pf_request_window ) ( intf_thread_t *, vout_thread_t *,
......
...@@ -216,7 +216,6 @@ struct playlist_t ...@@ -216,7 +216,6 @@ struct playlist_t
// The following members are about user interaction // The following members are about user interaction
// The playlist manages the user interaction to avoid creating another // The playlist manages the user interaction to avoid creating another
// thread // thread
vlc_bool_t b_manage_interaction;
interaction_t *p_interaction; interaction_t *p_interaction;
/*@}*/ /*@}*/
......
...@@ -121,6 +121,7 @@ char* httpd_ClientIP (httpd_client_t *cl, char *psz_ip); ...@@ -121,6 +121,7 @@ char* httpd_ClientIP (httpd_client_t *cl, char *psz_ip);
void httpd_FileDelete (httpd_file_t *); void httpd_FileDelete (httpd_file_t *);
module_t * __module_Need (vlc_object_t *, const char *, const char *, vlc_bool_t); module_t * __module_Need (vlc_object_t *, const char *, const char *, vlc_bool_t);
const char * VLC_Changeset (void); const char * VLC_Changeset (void);
void intf_InteractionDestroy (interaction_t *);
void LocaleFree (const char *); void LocaleFree (const char *);
void __vlc_object_attach (vlc_object_t *, vlc_object_t *); void __vlc_object_attach (vlc_object_t *, vlc_object_t *);
stream_t * __stream_UrlNew (vlc_object_t *p_this, const char *psz_url); stream_t * __stream_UrlNew (vlc_object_t *p_this, const char *psz_url);
...@@ -296,6 +297,7 @@ subpicture_t * spu_CreateSubpicture (spu_t *); ...@@ -296,6 +297,7 @@ subpicture_t * spu_CreateSubpicture (spu_t *);
void httpd_MsgAdd (httpd_message_t *, char *psz_name, char *psz_value, ...); void httpd_MsgAdd (httpd_message_t *, char *psz_name, char *psz_value, ...);
int vout_vaControlDefault (vout_thread_t *, int, va_list); int vout_vaControlDefault (vout_thread_t *, int, va_list);
int playlist_NodeEmpty (playlist_t *, playlist_item_t *, vlc_bool_t); int playlist_NodeEmpty (playlist_t *, playlist_item_t *, vlc_bool_t);
void __intf_UserFatal (vlc_object_t*, int, const char*, const char*, ...);
spu_t * __spu_Create (vlc_object_t *); spu_t * __spu_Create (vlc_object_t *);
int playlist_NodeRemoveItem (playlist_t *,playlist_item_t*,playlist_item_t *); int playlist_NodeRemoveItem (playlist_t *,playlist_item_t*,playlist_item_t *);
int __net_Accept (vlc_object_t *, int *, mtime_t); int __net_Accept (vlc_object_t *, int *, mtime_t);
...@@ -325,6 +327,7 @@ int playlist_PreparseEnqueue (playlist_t *, input_item_t *); ...@@ -325,6 +327,7 @@ int playlist_PreparseEnqueue (playlist_t *, input_item_t *);
aout_buffer_t * aout_FifoPop (aout_instance_t * p_aout, aout_fifo_t * p_fifo); aout_buffer_t * aout_FifoPop (aout_instance_t * p_aout, aout_fifo_t * p_fifo);
int __vout_InitPicture (vlc_object_t *p_this, picture_t *p_pic, uint32_t i_chroma, int i_width, int i_height, int i_aspect); int __vout_InitPicture (vlc_object_t *p_this, picture_t *p_pic, uint32_t i_chroma, int i_width, int i_height, int i_aspect);
int playlist_LockClear (playlist_t *); int playlist_LockClear (playlist_t *);
void intf_InteractionManage (playlist_t *);
char * mstrtime (char *psz_buffer, mtime_t date); char * mstrtime (char *psz_buffer, mtime_t date);
void aout_FormatPrepare (audio_sample_format_t * p_format); void aout_FormatPrepare (audio_sample_format_t * p_format);
void spu_DisplaySubpicture (spu_t *, subpicture_t *); void spu_DisplaySubpicture (spu_t *, subpicture_t *);
...@@ -395,7 +398,6 @@ stream_t * __stream_MemoryNew (vlc_object_t *p_obj, uint8_t *p_buffer, int64_t i ...@@ -395,7 +398,6 @@ stream_t * __stream_MemoryNew (vlc_object_t *p_obj, uint8_t *p_buffer, int64_t i
void mwait (mtime_t date); void mwait (mtime_t date);
void __config_ResetAll (vlc_object_t *); void __config_ResetAll (vlc_object_t *);
httpd_redirect_t * httpd_RedirectNew (httpd_host_t *, const char *psz_url_dst, const char *psz_url_src); httpd_redirect_t * httpd_RedirectNew (httpd_host_t *, const char *psz_url_dst, const char *psz_url_src);
void intf_UserFatal (vlc_object_t*, const char*, const char*, ...);
playlist_item_t * playlist_LockItemGetById (playlist_t *, int); playlist_item_t * playlist_LockItemGetById (playlist_t *, int);
mtime_t date_Get (const date_t *); mtime_t date_Get (const date_t *);
int aout_DecPlay (aout_instance_t *, aout_input_t *, aout_buffer_t *); int aout_DecPlay (aout_instance_t *, aout_input_t *, aout_buffer_t *);
...@@ -854,7 +856,9 @@ struct module_symbols_t ...@@ -854,7 +856,9 @@ struct module_symbols_t
void (*__input_Read_inner) (vlc_object_t *, input_item_t *, vlc_bool_t); void (*__input_Read_inner) (vlc_object_t *, input_item_t *, vlc_bool_t);
int (*__net_ConnectUDP_inner) (vlc_object_t *p_this, const char *psz_host, int i_port, int hlim); int (*__net_ConnectUDP_inner) (vlc_object_t *p_this, const char *psz_host, int i_port, int hlim);
int (*__intf_Interact_inner) (vlc_object_t *,interaction_dialog_t *); int (*__intf_Interact_inner) (vlc_object_t *,interaction_dialog_t *);
void (*intf_UserFatal_inner) (vlc_object_t*, const char*, const char*, ...); void (*intf_InteractionManage_inner) (playlist_t *);
void (*intf_InteractionDestroy_inner) (interaction_t *);
void (*__intf_UserFatal_inner) (vlc_object_t*, int, const char*, const char*, ...);
}; };
# if defined (__PLUGIN__) # if defined (__PLUGIN__)
# define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner # define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
...@@ -1267,7 +1271,9 @@ struct module_symbols_t ...@@ -1267,7 +1271,9 @@ struct module_symbols_t
# define __input_Read (p_symbols)->__input_Read_inner # define __input_Read (p_symbols)->__input_Read_inner
# define __net_ConnectUDP (p_symbols)->__net_ConnectUDP_inner # define __net_ConnectUDP (p_symbols)->__net_ConnectUDP_inner
# define __intf_Interact (p_symbols)->__intf_Interact_inner # define __intf_Interact (p_symbols)->__intf_Interact_inner
# define intf_UserFatal (p_symbols)->intf_UserFatal_inner # define intf_InteractionManage (p_symbols)->intf_InteractionManage_inner
# define intf_InteractionDestroy (p_symbols)->intf_InteractionDestroy_inner
# define __intf_UserFatal (p_symbols)->__intf_UserFatal_inner
# elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__) # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
/****************************************************************** /******************************************************************
* STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access. * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
...@@ -1683,7 +1689,9 @@ struct module_symbols_t ...@@ -1683,7 +1689,9 @@ struct module_symbols_t
((p_symbols)->__input_Read_inner) = __input_Read; \ ((p_symbols)->__input_Read_inner) = __input_Read; \
((p_symbols)->__net_ConnectUDP_inner) = __net_ConnectUDP; \ ((p_symbols)->__net_ConnectUDP_inner) = __net_ConnectUDP; \
((p_symbols)->__intf_Interact_inner) = __intf_Interact; \ ((p_symbols)->__intf_Interact_inner) = __intf_Interact; \
((p_symbols)->intf_UserFatal_inner) = intf_UserFatal; \ ((p_symbols)->intf_InteractionManage_inner) = intf_InteractionManage; \
((p_symbols)->intf_InteractionDestroy_inner) = intf_InteractionDestroy; \
((p_symbols)->__intf_UserFatal_inner) = __intf_UserFatal; \
(p_symbols)->net_ConvertIPv4_deprecated = NULL; \ (p_symbols)->net_ConvertIPv4_deprecated = NULL; \
# endif /* __PLUGIN__ */ # endif /* __PLUGIN__ */
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "stream_output.h" #include "stream_output.h"
#include "vlc_playlist.h" #include "vlc_playlist.h"
#include "vlc_interface.h" #include "vlc_interface.h"
#include "vlc_interaction.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -2094,7 +2095,8 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2094,7 +2095,8 @@ static int InputSourceInit( input_thread_t *p_input,
if( in->p_access == NULL ) if( in->p_access == NULL )
{ {
msg_Err( p_input, "no suitable access module for `%s'", psz_mrl ); msg_Err( p_input, "no suitable access module for `%s'", psz_mrl );
intf_UserFatal( p_input, "Unable to open '%s'", psz_mrl ); intf_UserFatal( VLC_OBJECT( p_input), DIALOG_NOACCESS,
"Unable to open '%s'", psz_mrl );
goto error; goto error;
} }
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
* This file contains functions related to user interaction management * This file contains functions related to user interaction management
*/ */
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
...@@ -41,9 +40,18 @@ ...@@ -41,9 +40,18 @@
#include "vlc_interface.h" #include "vlc_interface.h"
#include "vlc_playlist.h" #include "vlc_playlist.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void intf_InteractionInit( playlist_t *p_playlist ); static void intf_InteractionInit( playlist_t *p_playlist );
static int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact ); static interaction_t * intf_InteractionGet( vlc_object_t *p_this );
static int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact ); static void intf_InteractionSearchInterface( interaction_t *
p_interaction );
static int intf_WaitAnswer( interaction_t *p_interact,
interaction_dialog_t *p_dialog );
static int intf_Send( interaction_t *p_interact,
interaction_dialog_t *p_dialog );
static interaction_dialog_t *intf_InteractionGetById( vlc_object_t* , int );
/** /**
* Send an interaction element to the user * Send an interaction element to the user
...@@ -53,92 +61,216 @@ static int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact ); ...@@ -53,92 +61,216 @@ static int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact );
* \return VLC_SUCCESS or an error code * \return VLC_SUCCESS or an error code
*/ */
int __intf_Interact( vlc_object_t *p_this, interaction_dialog_t * int __intf_Interact( vlc_object_t *p_this, interaction_dialog_t *
p_interact ) p_dialog )
{ {
vlc_list_t *p_list;
int i_index;
intf_thread_t *p_chosen_intf;
interaction_t *p_interaction = intf_InteractionGet( p_this );
/* Search a suitable intf */ /* Get an id, if we don't already have one */
p_list = vlc_list_find( p_this, VLC_OBJECT_INTF, FIND_ANYWHERE ); if( p_dialog->i_id == 0 )
if( !p_list )
{ {
msg_Err( p_this, "Unable to create module list" ); p_dialog->i_id = ++p_interaction->i_last_id;
return VLC_FALSE;
} }
p_chosen_intf = NULL; if( p_dialog->i_type == INTERACT_ASK )
for( i_index = 0; i_index < p_list->i_count; i_index ++ )
{
intf_thread_t *p_intf = (intf_thread_t *)
p_list->p_values[i_index].p_object;
if( p_intf->pf_interact != NULL )
{ {
p_chosen_intf = p_intf; return intf_WaitAnswer( p_interaction, p_dialog );
break;
} }
else
{
return intf_Send( p_interaction, p_dialog );
} }
if( !p_chosen_intf ) }
/**
* Destroy the interaction system
*/
void intf_InteractionDestroy( interaction_t *p_interaction )
{
/// \todo Code this, and call it
}
/**
* The main interaction processing loop
* This function is called from the playlist loop
*
* \param p_playlist the parent playlist
* \return nothing
*/
void intf_InteractionManage( playlist_t *p_playlist )
{
int i_index;
interaction_t *p_interaction;
p_interaction = p_playlist->p_interaction;
// Nothing to do
if( p_interaction->i_dialogs == 0 ) return;
vlc_mutex_lock( &p_interaction->object_lock );
intf_InteractionSearchInterface( p_interaction );
if( !p_interaction->p_intf )
{ {
msg_Dbg( p_this, "No interface suitable for interaction" ); vlc_mutex_unlock( &p_interaction->object_lock );
return VLC_FALSE;
/// \todo Remove all dialogs as we can't display them
return;
} }
msg_Dbg( p_this, "found an interface for interaction" );
/* Find id, if we don't already have one */ vlc_object_yield( p_interaction->p_intf );
if( p_interact->i_id == 0 )
for( i_index = 0 ; i_index < p_interaction->i_dialogs; i_index ++ )
{
interaction_dialog_t *p_dialog = p_interaction->pp_dialogs[i_index];
if( p_dialog->b_have_answer )
{ {
p_interact->i_id = ++p_chosen_intf->i_last_id; /// \todo Signal we have an answer
// - If have answer, signal what is waiting
// (vlc_cond ? dangerous in case of pb ?)
// Ask interface to hide it
p_interaction->p_intf->pf_interact( p_interaction->p_intf,
p_dialog, INTERACT_HIDE );
} }
if( p_interact->i_type == INTERACT_ASK ) if( p_dialog->b_updated )
{ {
return intf_WaitAnswer( p_chosen_intf, p_interact ); p_dialog->b_finished = VLC_FALSE;
p_interaction->p_intf->pf_interact( p_interaction->p_intf,
p_dialog, INTERACT_UPDATE );
} }
else
if( p_dialog->b_finished && !p_dialog->b_reusable )
{ {
return intf_Send( p_chosen_intf, p_interact ); /// \todo Destroy the dialog
}
// This is truly a new dialog, send it.
p_interaction->p_intf->pf_interact( p_interaction->p_intf,
p_dialog, INTERACT_NEW );
} }
vlc_object_release( p_interaction->p_intf );
vlc_mutex_unlock( &p_playlist->p_interaction->object_lock );
} }
int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact )
#define INTERACT_INIT( new ) \
new = (interaction_dialog_t*)malloc( \
sizeof( interaction_dialog_t ) ); \
new->i_widgets = 0; \
new->pp_widgets = NULL; \
new->psz_title = NULL; \
new->psz_description = NULL; \
new->i_id = 0;
#define INTERACT_FREE( new ) \
if( new->psz_title ) free( new->psz_title ); \
if( new->psz_description ) free( new->psz_description );
/** Helper function to send a fatal message
* \param p_this Parent vlc_object
* \param i_id A predefined ID, 0 if not applicable
* \param psz_title Title for the dialog
* \param psz_format The message to display
* */
void __intf_UserFatal( vlc_object_t *p_this, int i_id,
const char *psz_title,
const char *psz_format, ... )
{ {
// TODO: Add to queue, wait for answer va_list args;
return VLC_SUCCESS; interaction_dialog_t *p_new = NULL;
user_widget_t *p_widget = NULL;
if( i_id > 0 )
{
p_new = intf_InteractionGetById( p_this, i_id );
}
if( !p_new )
{
INTERACT_INIT( p_new );
}
p_new->i_type = INTERACT_FATAL;
p_new->psz_title = strdup( psz_title );
p_widget = (user_widget_t* )malloc( sizeof( user_widget_t ) );
p_widget->i_type = WIDGET_TEXT;
va_start( args, psz_format );
vasprintf( &p_widget->psz_text, psz_format, args );
va_end( args );
INSERT_ELEM ( p_new->pp_widgets,
p_new->i_widgets,
p_new->i_widgets,
p_widget );
intf_Interact( p_this, p_new );
} }
int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact ) #if 0
/** Helper function to build a progress bar
* \param p_this Parent vlc object
*/
interaction_dialog_t *__intf_ProgressBuild( vlc_object_t *p_this,
const char *psz_text )
{ {
// TODO: Add to queue, return interaction_dialog_t *p_new = (interaction_dialog_t *)malloc(
return VLC_SUCCESS; sizeof( interaction_dialog_t ) );
return p_new;
} }
#endif
// The playlist manages the user interaction to avoid creating another thread
void intf_InteractionManage( playlist_t *p_playlist )
/**********************************************************************
* The following functions are local
**********************************************************************/
/* Get the interaction object. Create it if needed */
static interaction_t * intf_InteractionGet( vlc_object_t *p_this )
{ {
playlist_t *p_playlist;
interaction_t *p_interaction;
p_playlist = (playlist_t*) vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( !p_playlist )
{
return NULL;
}
if( p_playlist->p_interaction == NULL ) if( p_playlist->p_interaction == NULL )
{ {
intf_InteractionInit( p_playlist ); intf_InteractionInit( p_playlist );
} }
vlc_mutex_lock( &p_playlist->p_interaction->object_lock ); p_interaction = p_playlist->p_interaction;
/* Todo: vlc_object_release( p_playlist );
* - Walk the queue
* - If blocking
* - If have answer, signal what is waiting (vlc_cond ? dangerous in case of pb ?)
* And then, if not reusable, destroy
* - If have update, send update
*/
vlc_mutex_unlock( &p_playlist->p_interaction->object_lock ); return p_interaction;
} }
/* Create the interaction object in the given playlist object */
static void intf_InteractionInit( playlist_t *p_playlist ) static void intf_InteractionInit( playlist_t *p_playlist )
{ {
interaction_t *p_interaction; interaction_t *p_interaction;
p_interaction = vlc_object_create( VLC_OBJECT( p_playlist ), sizeof( interaction_t ) );
msg_Dbg( p_playlist, "initializing interaction system" );
p_interaction = vlc_object_create( VLC_OBJECT( p_playlist ),
sizeof( interaction_t ) );
if( !p_interaction ) if( !p_interaction )
{ {
msg_Err( p_playlist,"out of memory" ); msg_Err( p_playlist,"out of memory" );
...@@ -147,47 +279,76 @@ static void intf_InteractionInit( playlist_t *p_playlist ) ...@@ -147,47 +279,76 @@ static void intf_InteractionInit( playlist_t *p_playlist )
p_interaction->i_dialogs = 0; p_interaction->i_dialogs = 0;
p_interaction->pp_dialogs = NULL; p_interaction->pp_dialogs = NULL;
p_interaction->p_intf = NULL;
p_interaction->i_last_id = DIALOG_LAST_PREDEFINED + 1;
vlc_mutex_init( p_interaction , &p_interaction->object_lock );
p_playlist->p_interaction = p_interaction;
} }
/** Helper function to build a progress bar */ /* Look for an interface suitable for interaction */
interaction_dialog_t *__intf_ProgressBuild( vlc_object_t *p_this, static void intf_InteractionSearchInterface( interaction_t *p_interaction )
const char *psz_text )
{ {
interaction_dialog_t *p_new = (interaction_dialog_t *)malloc( vlc_list_t *p_list;
sizeof( interaction_dialog_t ) ); int i_index;
return p_new; p_interaction->p_intf = NULL;
}
#define INTERACT_INIT( new ) \ p_list = vlc_list_find( p_interaction, VLC_OBJECT_INTF, FIND_ANYWHERE );
interaction_dialog_t *new = (interaction_dialog_t*)malloc( \ if( !p_list )
sizeof( interaction_dialog_t ) ); \ {
new->i_widgets = 0; \ msg_Err( p_interaction, "Unable to create module list" );
new->pp_widgets = NULL; \ return;
new->psz_title = NULL; \ }
new->psz_description = NULL; \
new->i_id = 0;
#define INTERACT_FREE( new ) \ for( i_index = 0; i_index < p_list->i_count; i_index ++ )
if( new->psz_title ) free( new->psz_title ); \ {
if( new->psz_description ) free( new->psz_description ); intf_thread_t *p_intf = (intf_thread_t *)
p_list->p_values[i_index].p_object;
if( p_intf->pf_interact != NULL )
{
p_interaction->p_intf = p_intf;
break;
}
}
vlc_list_release ( p_list );
}
/** Helper function to send a fatal message */ /* Add a dialog to the queue and wait for answer */
void intf_UserFatal( vlc_object_t *p_this, const char *psz_title, static int intf_WaitAnswer( interaction_t *p_interact, interaction_dialog_t *p_dialog )
const char *psz_format, ... )
{ {
va_list args; // TODO: Add to queue, wait for answer
return VLC_SUCCESS;
}
INTERACT_INIT( p_new ); /* Add a dialog to the queue and return */
p_new->i_type = INTERACT_FATAL; static int intf_Send( interaction_t *p_interact, interaction_dialog_t *p_dialog )
p_new->psz_title = strdup( psz_title ); {
vlc_mutex_lock( &p_interact->object_lock );
va_start( args, psz_format ); /// \todo Check first it does not exist !!!
vasprintf( &p_new->psz_description, psz_format, args ); INSERT_ELEM( p_interact->pp_dialogs,
va_end( args ); p_interact->i_dialogs,
p_interact->i_dialogs,
p_dialog );
vlc_mutex_unlock( &p_interact->object_lock );
return VLC_SUCCESS;
}
intf_Interact( p_this, p_new ); /* Find an interaction dialog by its id */
static interaction_dialog_t *intf_InteractionGetById( vlc_object_t* p_this,
int i_id )
{
interaction_t *p_interaction = intf_InteractionGet( p_this );
int i;
INTERACT_FREE( p_new ); for( i = 0 ; i< p_interaction->i_dialogs; i++ )
{
if( p_interaction->pp_dialogs[i]->i_id == i_id )
{
return p_interaction->pp_dialogs[i];
}
}
return NULL;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment