Very beginning of the interaction framework (Refs:#27)
authorClément Stenac <zorglub@videolan.org>
Mon, 5 Dec 2005 15:51:39 +0000 (15:51 +0000)
committerClément Stenac <zorglub@videolan.org>
Mon, 5 Dec 2005 15:51:39 +0000 (15:51 +0000)
Makefile.am
extras/make.pl
include/vlc_common.h
include/vlc_interaction.h [new file with mode: 0644]
include/vlc_interface.h
include/vlc_playlist.h
src/input/input.c
src/interface/interaction.c [new file with mode: 0644]
src/interface/interface.c
src/playlist/playlist.c

index 6109e05..3ff67dc 100644 (file)
@@ -393,6 +393,7 @@ SOURCES_libvlc_common = \
        src/libvlc.h \
        src/interface/interface.c \
        src/interface/intf_eject.c \
+       src/interface/interaction.c \
        src/playlist/playlist.c \
        src/playlist/sort.c \
        src/playlist/loadsave.c \
index b23bc19..ee5663a 100755 (executable)
@@ -29,18 +29,18 @@ while(<STDIN>)
         $line =~ /^test\s\-z\s/ || 
         $line =~ /^Making\sclean\sin\s\./ ||
        $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 
      elsif( 
           $line =~ s/^.* (lib.*\.so).*/ LINK    : $1/g ||
           $line =~ s/^.* (lib.*\.o)\s\.\/(.*)/ COMPILE : $2/g ||
           $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/^Making\sall\sin\s(.*)/MAKE     : $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)
 
      {
index abecaea..5841bc0 100644 (file)
@@ -223,7 +223,7 @@ typedef enum {
     PLAYLIST_STOP,      /**< No arg                             res=can fail*/
     PLAYLIST_SKIP,      /**< 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;
 
 
@@ -251,6 +251,9 @@ typedef struct intf_sys_t intf_sys_t;
 typedef struct intf_console_t intf_console_t;
 typedef struct intf_msg_t intf_msg_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 */
 typedef struct input_thread_t input_thread_t;
@@ -338,7 +341,7 @@ typedef struct session_descriptor_t session_descriptor_t;
 typedef struct announce_method_t announce_method_t;
 typedef struct announce_handler_t announce_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 */
 typedef struct decoder_t      decoder_t;
diff --git a/include/vlc_interaction.h b/include/vlc_interaction.h
new file mode 100644 (file)
index 0000000..b7b2bdd
--- /dev/null
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * 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*, ...));
index 4dab195..533aff2 100644 (file)
@@ -23,6 +23,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+
 typedef struct intf_dialog_args_t intf_dialog_args_t;
 
 /**
@@ -64,6 +65,10 @@ struct intf_thread_t
     void ( *pf_show_dialog ) ( intf_thread_t *, int, int,
                                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 */
     void * ( *pf_request_window ) ( intf_thread_t *, vout_thread_t *,
                                     int *, int *,
index aabd612..3bd4ebb 100644 (file)
@@ -213,6 +213,12 @@ struct playlist_t
 
     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;
+
     /*@}*/
 };
 
index 9606115..5d19925 100644 (file)
@@ -2094,6 +2094,7 @@ static int InputSourceInit( input_thread_t *p_input,
         if( in->p_access == NULL )
         {
             msg_Err( p_input, "no suitable access module for `%s'", psz_mrl );
+            intf_UserFatal( p_input, "Unable to open '%s'", psz_mrl );
             goto error;
         }
 
diff --git a/src/interface/interaction.c b/src/interface/interaction.c
new file mode 100644 (file)
index 0000000..662d7bc
--- /dev/null
@@ -0,0 +1,193 @@
+/*****************************************************************************
+ * 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 );
+}
index e0fd705..a01fd64 100644 (file)
@@ -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_release_window = NULL;
     p_intf->pf_control_window = NULL;
+    p_intf->pf_interact       = NULL;
     p_intf->b_play = VLC_FALSE;
 
     /* Choose the best module */
index c7621c8..2e3c52c 100644 (file)
@@ -32,6 +32,8 @@
 
 #include "vlc_playlist.h"
 
+#include "vlc_interaction.h"
+
 #define TITLE_CATEGORY N_( "By category" )
 #define TITLE_SIMPLE   N_( "Manually added" )
 #define TITLE_ALL      N_( "All items, unsorted" )
@@ -194,9 +196,14 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent )
         return NULL;
     }
 
+    // Preparse
     p_playlist->p_preparse->i_waiting = 0;
     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 );
     if( vlc_thread_create( p_playlist->p_preparse, "preparser",
                            RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
@@ -577,6 +584,11 @@ static void RunThread ( playlist_t *p_playlist )
 
     while( !p_playlist->b_die )
     {
+        if( p_playlist->b_manage_interaction )
+        {
+            intf_InteractionManage( p_playlist );
+        }
+
         vlc_mutex_lock( &p_playlist->object_lock );
 
         /* First, check if we have something to do */