Commit 5afb060f authored by Clément Stenac's avatar Clément Stenac

Very beginning of the interaction framework (Refs:#27)

parent d93b664a
...@@ -393,6 +393,7 @@ SOURCES_libvlc_common = \ ...@@ -393,6 +393,7 @@ SOURCES_libvlc_common = \
src/libvlc.h \ src/libvlc.h \
src/interface/interface.c \ src/interface/interface.c \
src/interface/intf_eject.c \ src/interface/intf_eject.c \
src/interface/interaction.c \
src/playlist/playlist.c \ src/playlist/playlist.c \
src/playlist/sort.c \ src/playlist/sort.c \
src/playlist/loadsave.c \ src/playlist/loadsave.c \
......
...@@ -29,18 +29,18 @@ while(<STDIN>) ...@@ -29,18 +29,18 @@ while(<STDIN>)
$line =~ /^test\s\-z\s/ || $line =~ /^test\s\-z\s/ ||
$line =~ /^Making\sclean\sin\s\./ || $line =~ /^Making\sclean\sin\s\./ ||
$line =~ /^then\smv/ || $line =~ /^then\smv/ ||
$line =~ /make\s\sall-recursive/ ) $line =~ /make\s\sall-recursive/ ||
$line =~ s/^[A-z0-9-]*ar\s[A-z0-9]*\s([A-z0-9\-_\/\.]*)\s.*//g ||
$line =~ s/^rm\s\-f\s(.*)//g )
{} {}
# Info # Info
elsif( elsif(
$line =~ s/^.* (lib.*\.so).*/ LINK : $1/g || $line =~ s/^.* (lib.*\.so).*/ LINK : $1/g ||
$line =~ s/^.* (lib.*\.o)\s\.\/(.*)/ COMPILE : $2/g || $line =~ s/^.* (lib.*\.o)\s\.\/(.*)/ COMPILE : $2/g ||
$line =~ s/^.* (lib.*\.o)\s`.*`(.*);\ \\/ COMPILE : $2/ || $line =~ s/^.* (lib.*\.o)\s`.*`(.*);\ \\/ COMPILE : $2/ ||
$line =~ s/^[A-z0-9-]*ar\s[A-z0-9]*\s([A-z0-9\-_\/\.]*)\s.*/ ARCHIVE : $1/g ||
$line =~ s/^[A-z0-9-]*ranlib\s(.*)/ RANLIB : $1/g || $line =~ s/^[A-z0-9-]*ranlib\s(.*)/ RANLIB : $1/g ||
$line =~ s/^Making\sall\sin\s(.*)/MAKE : $1/g || $line =~ s/^Making\sall\sin\s(.*)/MAKE : $1/g ||
$line =~ s/^Making\sclean\sin\s(.*)/CLEAN : $1/g || $line =~ s/^Making\sclean\sin\s(.*)/CLEAN : $1/g ||
$line =~ s/^rm\s\-f\s(.*)/ REMOVE : $1/g ||
$line =~ s/.*\-o\s([^\s]*)\s.*/ BUILD : $1/g) $line =~ s/.*\-o\s([^\s]*)\s.*/ BUILD : $1/g)
{ {
......
...@@ -223,7 +223,7 @@ typedef enum { ...@@ -223,7 +223,7 @@ typedef enum {
PLAYLIST_STOP, /**< No arg res=can fail*/ PLAYLIST_STOP, /**< No arg res=can fail*/
PLAYLIST_SKIP, /**< arg1=int, res=can fail*/ PLAYLIST_SKIP, /**< arg1=int, res=can fail*/
PLAYLIST_GOTO, /**< arg1=int res=can fail */ PLAYLIST_GOTO, /**< arg1=int res=can fail */
PLAYLIST_VIEWGOTO, /**< arg1=int res=can fail */ PLAYLIST_VIEWGOTO /**< arg1=int res=can fail */
} playlist_command_t; } playlist_command_t;
...@@ -251,6 +251,9 @@ typedef struct intf_sys_t intf_sys_t; ...@@ -251,6 +251,9 @@ typedef struct intf_sys_t intf_sys_t;
typedef struct intf_console_t intf_console_t; typedef struct intf_console_t intf_console_t;
typedef struct intf_msg_t intf_msg_t; typedef struct intf_msg_t intf_msg_t;
typedef struct intf_channel_t intf_channel_t; typedef struct intf_channel_t intf_channel_t;
typedef struct interaction_t interaction_t;
typedef struct interaction_dialog_t interaction_dialog_t;
typedef struct user_widget_t user_widget_t;
/* Input */ /* Input */
typedef struct input_thread_t input_thread_t; typedef struct input_thread_t input_thread_t;
...@@ -338,7 +341,7 @@ typedef struct session_descriptor_t session_descriptor_t; ...@@ -338,7 +341,7 @@ typedef struct session_descriptor_t session_descriptor_t;
typedef struct announce_method_t announce_method_t; typedef struct announce_method_t announce_method_t;
typedef struct announce_handler_t announce_handler_t; typedef struct announce_handler_t announce_handler_t;
typedef struct sap_handler_t sap_handler_t; typedef struct sap_handler_t sap_handler_t;
//typedef struct slp_session_t slp_session_t; /* typedef struct slp_session_t slp_session_t; */
/* Decoders */ /* Decoders */
typedef struct decoder_t decoder_t; typedef struct decoder_t decoder_t;
......
/*****************************************************************************
* vlc_interaction.h: structures and function for user interaction
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id: vlc_interaction.h 7954 2004-06-07 22:19:12Z fenrir $
*
* Authors: Clément Stenac <zorglub@videolan.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/**
* This structure describes an interaction widget
*/
struct user_widget_t
{
int i_type; //< Type identifier;
char *psz_text; //< Free text
vlc_value_t val;
};
/**
* Possible widget types
*/
enum
{
WIDGET_TEXT, //< Text display
WIDGET_PROGRESS, //< A progress bar
WIDGET_INPUT //< Input (backed up by a variable)
};
/**
* This structure describes a piece of interaction with the user
*/
struct interaction_dialog_t
{
int i_id; //< Unique ID
int i_type; //< Type identifier
char *psz_title; //< Title
char *psz_description; //< Descriptor string
/* For dialogs */
int i_widgets; //< Nu,ber of dialog widgets
user_widget_t **pp_widgets; //< Dialog widgets
vlc_bool_t b_have_answer; //< Has an answer been given ?
vlc_bool_t b_reusable; //< Do we have to reuse this ?
void * p_private; //< Private interface data
};
/**
* This structure contains the active interaction dialogs, and is
* used by teh manager
*/
struct interaction_t
{
VLC_COMMON_MEMBERS
int i_dialogs; //< Number of dialogs
interaction_dialog_t **pp_dialogs; //< Dialogs
};
/**
* Possible interaction types
*/
enum
{
INTERACT_PROGRESS, //< Progress bar
INTERACT_WARNING, //< Warning message ("codec not supported")
INTERACT_FATAL, //< Fatal message ("File not found")
INTERACT_ASK, //< Full-featured dialog box (password)
};
#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_InteractionManage,( playlist_t *) );
VLC_EXPORT( void, intf_UserFatal,( vlc_object_t*, const char*, const char*, ...));
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
typedef struct intf_dialog_args_t intf_dialog_args_t; typedef struct intf_dialog_args_t intf_dialog_args_t;
/** /**
...@@ -64,6 +65,10 @@ struct intf_thread_t ...@@ -64,6 +65,10 @@ struct intf_thread_t
void ( *pf_show_dialog ) ( intf_thread_t *, int, int, void ( *pf_show_dialog ) ( intf_thread_t *, int, int,
intf_dialog_args_t * ); intf_dialog_args_t * );
/** Interaction stuff */
int i_last_id;
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 *,
int *, int *, int *, int *,
......
...@@ -213,6 +213,12 @@ struct playlist_t ...@@ -213,6 +213,12 @@ struct playlist_t
vlc_mutex_t gc_lock; /**< Lock to protect the garbage collection */ vlc_mutex_t gc_lock; /**< Lock to protect the garbage collection */
// The following members are about user interaction
// The playlist manages the user interaction to avoid creating another
// thread
vlc_bool_t b_manage_interaction;
interaction_t *p_interaction;
/*@}*/ /*@}*/
}; };
......
...@@ -2094,6 +2094,7 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2094,6 +2094,7 @@ 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 );
goto error; goto error;
} }
......
/*****************************************************************************
* interaction.c: User interaction functions
*****************************************************************************
* Copyright (C) 1998-2004 VideoLAN
* $Id: interface.c 10147 2005-03-05 17:18:30Z gbazin $
*
* Authors: Clément Stenac <zorglub@videolan.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/**
* \file
* This file contains functions related to user interaction management
*/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* free(), strtol() */
#include <stdio.h> /* FILE */
#include <string.h> /* strerror() */
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "vlc_interaction.h"
#include "vlc_interface.h"
#include "vlc_playlist.h"
static void intf_InteractionInit( playlist_t *p_playlist );
static int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact );
static int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact );
/**
* Send an interaction element to the user
*
* \param p_this the calling vlc_object_t
* \param p_interact the interaction element
* \return VLC_SUCCESS or an error code
*/
int __intf_Interact( vlc_object_t *p_this, interaction_dialog_t *
p_interact )
{
vlc_list_t *p_list;
int i_index;
intf_thread_t *p_chosen_intf;
/* Search a suitable intf */
p_list = vlc_list_find( p_this, VLC_OBJECT_INTF, FIND_ANYWHERE );
if( !p_list )
{
msg_Err( p_this, "Unable to create module list" );
return VLC_FALSE;
}
p_chosen_intf = NULL;
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;
break;
}
}
if( !p_chosen_intf )
{
msg_Dbg( p_this, "No interface suitable for interaction" );
return VLC_FALSE;
}
msg_Dbg( p_this, "found an interface for interaction" );
/* Find id, if we don't already have one */
if( p_interact->i_id == 0 )
{
p_interact->i_id = ++p_chosen_intf->i_last_id;
}
if( p_interact->i_type == INTERACT_ASK )
{
return intf_WaitAnswer( p_chosen_intf, p_interact );
}
else
{
return intf_Send( p_chosen_intf, p_interact );
}
}
int intf_WaitAnswer( intf_thread_t *p_intf, interaction_dialog_t *p_interact )
{
// TODO: Add to queue, wait for answer
return VLC_SUCCESS;
}
int intf_Send( intf_thread_t *p_intf, interaction_dialog_t *p_interact )
{
// TODO: Add to queue, return
return VLC_SUCCESS;
}
// The playlist manages the user interaction to avoid creating another thread
void intf_InteractionManage( playlist_t *p_playlist )
{
if( p_playlist->p_interaction == NULL )
{
intf_InteractionInit( p_playlist );
}
vlc_mutex_lock( &p_playlist->p_interaction->object_lock );
/* Todo:
* - 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 );
}
static void intf_InteractionInit( playlist_t *p_playlist )
{
interaction_t *p_interaction;
p_interaction = vlc_object_create( VLC_OBJECT( p_playlist ), sizeof( interaction_t ) );
if( !p_interaction )
{
msg_Err( p_playlist,"out of memory" );
return;
}
p_interaction->i_dialogs = 0;
p_interaction->pp_dialogs = NULL;
}
/** Helper function to build a progress bar */
interaction_dialog_t *__intf_ProgressBuild( vlc_object_t *p_this,
const char *psz_text )
{
interaction_dialog_t *p_new = (interaction_dialog_t *)malloc(
sizeof( interaction_dialog_t ) );
return p_new;
}
#define INTERACT_INIT( new ) \
interaction_dialog_t *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 */
void intf_UserFatal( vlc_object_t *p_this, const char *psz_title,
const char *psz_format, ... )
{
va_list args;
INTERACT_INIT( p_new );
p_new->i_type = INTERACT_FATAL;
p_new->psz_title = strdup( psz_title );
va_start( args, psz_format );
vasprintf( &p_new->psz_description, psz_format, args );
va_end( args );
intf_Interact( p_this, p_new );
INTERACT_FREE( p_new );
}
...@@ -98,6 +98,7 @@ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module ) ...@@ -98,6 +98,7 @@ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
p_intf->pf_request_window = NULL; p_intf->pf_request_window = NULL;
p_intf->pf_release_window = NULL; p_intf->pf_release_window = NULL;
p_intf->pf_control_window = NULL; p_intf->pf_control_window = NULL;
p_intf->pf_interact = NULL;
p_intf->b_play = VLC_FALSE; p_intf->b_play = VLC_FALSE;
/* Choose the best module */ /* Choose the best module */
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "vlc_playlist.h" #include "vlc_playlist.h"
#include "vlc_interaction.h"
#define TITLE_CATEGORY N_( "By category" ) #define TITLE_CATEGORY N_( "By category" )
#define TITLE_SIMPLE N_( "Manually added" ) #define TITLE_SIMPLE N_( "Manually added" )
#define TITLE_ALL N_( "All items, unsorted" ) #define TITLE_ALL N_( "All items, unsorted" )
...@@ -194,9 +196,14 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent ) ...@@ -194,9 +196,14 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent )
return NULL; return NULL;
} }
// Preparse
p_playlist->p_preparse->i_waiting = 0; p_playlist->p_preparse->i_waiting = 0;
p_playlist->p_preparse->pp_waiting = NULL; p_playlist->p_preparse->pp_waiting = NULL;
// Interaction
p_playlist->b_manage_interaction = VLC_FALSE;
p_playlist->p_interaction = NULL;
vlc_object_attach( p_playlist->p_preparse, p_playlist ); vlc_object_attach( p_playlist->p_preparse, p_playlist );
if( vlc_thread_create( p_playlist->p_preparse, "preparser", if( vlc_thread_create( p_playlist->p_preparse, "preparser",
RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
...@@ -577,6 +584,11 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -577,6 +584,11 @@ static void RunThread ( playlist_t *p_playlist )
while( !p_playlist->b_die ) while( !p_playlist->b_die )
{ {
if( p_playlist->b_manage_interaction )
{
intf_InteractionManage( p_playlist );
}
vlc_mutex_lock( &p_playlist->object_lock ); vlc_mutex_lock( &p_playlist->object_lock );
/* First, check if we have something to do */ /* First, check if we have something to do */
......
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