From 995e4d548fdfc8dc52604c972677b04049ede605 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?S=C3=A9bastien=20Escudier?= <sebastien-devel@celeos.eu>
Date: Tue, 13 Jan 2009 09:22:22 +0100
Subject: [PATCH] Put a libvlc event manager in VLM

---
 include/vlc/libvlc_vlm.h      |   13 +++++++++
 include/vlc_vlm.h             |   12 ++++++++
 src/control/libvlc_internal.h |    5 +++
 src/control/vlm.c             |   59 +++++++++++++++++++++++++++++++++++++++-
 src/input/vlm.c               |   29 ++++++++++++++++++++
 src/libvlc.sym                |    1 +
 6 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/include/vlc/libvlc_vlm.h b/include/vlc/libvlc_vlm.h
index c3305ba..04ce4e9 100644
--- a/include/vlc/libvlc_vlm.h
+++ b/include/vlc/libvlc_vlm.h
@@ -333,6 +333,19 @@ VLC_PUBLIC_API int libvlc_vlm_get_media_instance_seekable( libvlc_instance_t *,
                                                            const char *, int,
                                                            libvlc_exception_t * );
 
+/**
+ * Get libvlc_event_manager from a vlm media.
+ * The p_event_manager is immutable, so you don't have to hold the lock
+ *
+ * \param p_instance a libvlc instance
+ * \param psz_name name of vlm media instance
+ * \param p_exception an initialized exception pointer
+ * \return libvlc_event_manager
+ */
+VLC_PUBLIC_API libvlc_event_manager_t *
+    libvlc_vlm_get_media_event_manager( libvlc_instance_t *, const char *,
+                                        libvlc_exception_t * );
+
 /** @} */
 
 # ifdef __cplusplus
diff --git a/include/vlc_vlm.h b/include/vlc_vlm.h
index 4abe29a..aa62d18 100644
--- a/include/vlc_vlm.h
+++ b/include/vlc_vlm.h
@@ -40,7 +40,10 @@
  * @{
  */
 
+typedef struct libvlc_vlm_media_t libvlc_vlm_media_t;
+
 /** VLM media */
+
 typedef struct
 {
     int64_t     id;     /*< numeric id for vlm_media_t item */
@@ -66,6 +69,9 @@ typedef struct
         char *psz_mux;  /*< name of muxer to use */
     } vod;              /*< VOD specific information */
 
+    /* To be used, this has to be set by VLM_SET_MEDIA_LIBVLC */
+    libvlc_vlm_media_t *libvlc_vlm_media;
+
 } vlm_media_t;
 
 /** VLM media instance */
@@ -107,6 +113,10 @@ enum vlm_query_e
     /* Get media ID from its name */
     VLM_GET_MEDIA_ID,                   /* arg1=const char *psz_name arg2=int64_t*  */
 
+    /* Get media libvlc_vlm_media */
+    VLM_GET_MEDIA_LIBVLC,               /* arg1=int64_t id arg2=libvlc_vlm_media_t**  */
+    /* Set media libvlc_vlm_media */
+    VLM_SET_MEDIA_LIBVLC,               /* arg1=int64_t id arg2=libvlc_vlm_media_t*  */
     /* Media instance control XXX VOD control are for internal use only */
     /* Get all media instances */
     VLM_GET_MEDIA_INSTANCES,            /* arg1=int64_t id arg2=vlm_media_instance_t *** arg3=int *pi_instance */
@@ -185,6 +195,7 @@ static inline void vlm_media_Init( vlm_media_t *p_media )
 
     p_media->vod.psz_mux = NULL;
     p_media->broadcast.b_loop = false;
+    p_media->libvlc_vlm_media = NULL;
 }
 
 /**
@@ -220,6 +231,7 @@ static inline void vlm_media_Copy( vlm_media_t *p_dst, vlm_media_t *p_src )
     {
         p_dst->broadcast.b_loop = p_src->broadcast.b_loop;
     }
+    p_dst->libvlc_vlm_media = p_src->libvlc_vlm_media;
 }
 
 /**
diff --git a/src/control/libvlc_internal.h b/src/control/libvlc_internal.h
index d54b437..92bc683 100644
--- a/src/control/libvlc_internal.h
+++ b/src/control/libvlc_internal.h
@@ -71,6 +71,11 @@ struct libvlc_instance_t
     struct libvlc_callback_entry_list_t *p_callback_list;
 };
 
+struct libvlc_vlm_media_t
+{
+    libvlc_event_manager_t *p_event_manager;
+};
+
 struct libvlc_media_t
 {
     libvlc_event_manager_t * p_event_manager;
diff --git a/src/control/vlm.c b/src/control/vlm.c
index cafd8dc..151c162 100644
--- a/src/control/vlm.c
+++ b/src/control/vlm.c
@@ -156,6 +156,31 @@ static vlm_media_instance_t *libvlc_vlm_get_media_instance( libvlc_instance_t *p
     return p_minstance;
 }
 
+static int set_libvlc_vlm_media( libvlc_instance_t *p_instance, vlm_t *p_vlm, int64_t id, libvlc_exception_t *p_exception )
+{
+    int n;
+    libvlc_vlm_media_t *libvlc_vlm_media = malloc( sizeof *libvlc_vlm_media );
+    if( !libvlc_vlm_media )
+        return VLC_ENOMEM;
+    libvlc_vlm_media->p_event_manager = libvlc_event_manager_new( libvlc_vlm_media, p_instance, p_exception );
+
+    n = vlm_Control( p_vlm, VLM_SET_MEDIA_LIBVLC, id, libvlc_vlm_media );
+    if ( n )
+    {
+        libvlc_event_manager_release( libvlc_vlm_media->p_event_manager );
+        free( libvlc_vlm_media );
+        return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static void unset_libvlc_vlm_media( libvlc_vlm_media_t *libvlc_vlm_media )
+{
+    if( !libvlc_vlm_media )
+        return;
+    libvlc_event_manager_release( libvlc_vlm_media->p_event_manager );
+    free( libvlc_vlm_media );
+}
 
 void libvlc_vlm_release( libvlc_instance_t *p_instance, libvlc_exception_t *p_exception)
 {
@@ -177,6 +202,7 @@ void libvlc_vlm_add_broadcast( libvlc_instance_t *p_instance,
     vlm_t *p_vlm;
     vlm_media_t m;
     int n;
+    int64_t id;
 
     VLM(p_vlm);
 
@@ -192,10 +218,11 @@ void libvlc_vlm_add_broadcast( libvlc_instance_t *p_instance,
     for( n = 0; n < i_options; n++ )
         TAB_APPEND( m.i_option, m.ppsz_option, strdup(ppsz_options[n]) );
 
-    n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, NULL );
+    n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, &id );
     vlm_media_Clean( &m );
     if( n )
         libvlc_exception_raise( p_exception, "Media %s creation failed", psz_name );
+    set_libvlc_vlm_media( p_instance, p_vlm, id, p_exception );
 }
 
 void libvlc_vlm_add_vod( libvlc_instance_t *p_instance, const char *psz_name,
@@ -206,6 +233,7 @@ void libvlc_vlm_add_vod( libvlc_instance_t *p_instance, const char *psz_name,
     vlm_t *p_vlm;
     vlm_media_t m;
     int n;
+    int64_t id;
 
     VLM(p_vlm);
 
@@ -219,10 +247,12 @@ void libvlc_vlm_add_vod( libvlc_instance_t *p_instance, const char *psz_name,
     for( n = 0; n < i_options; n++ )
         TAB_APPEND( m.i_option, m.ppsz_option, strdup(ppsz_options[n]) );
 
-    n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, NULL );
+    n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, &id );
     vlm_media_Clean( &m );
     if( n )
         libvlc_exception_raise( p_exception, "Media %s creation failed", psz_name );
+    else if( set_libvlc_vlm_media( p_instance, p_vlm, id, p_exception ) )
+        libvlc_exception_raise( p_exception, "Media %s : unable to set libvlc event manager", psz_name );
 }
 
 void libvlc_vlm_del_media( libvlc_instance_t *p_instance, const char *psz_name,
@@ -230,14 +260,18 @@ void libvlc_vlm_del_media( libvlc_instance_t *p_instance, const char *psz_name,
 {
     vlm_t *p_vlm;
     int64_t id;
+    libvlc_vlm_media_t *libvlc_vlm_media;
 
     VLM(p_vlm);
 
     if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
+        vlm_Control( p_vlm, VLM_GET_MEDIA_LIBVLC, id, &libvlc_vlm_media ) ||
         vlm_Control( p_vlm, VLM_DEL_MEDIA, id ) )
     {
         libvlc_exception_raise( p_exception, "Unable to delete %s", psz_name );
+        return;
     }
+    unset_libvlc_vlm_media( libvlc_vlm_media );
 }
 
 #define VLM_CHANGE(psz_error, code ) do {   \
@@ -529,3 +563,24 @@ int libvlc_vlm_get_media_instance_seekable( libvlc_instance_t *p_instance,
     libvlc_exception_raise( p_exception, "Unable to get seekable attribute" );
     return result;
 }
+
+libvlc_event_manager_t *
+    libvlc_vlm_get_media_event_manager( libvlc_instance_t *p_instance,
+                                        const char *psz_name,
+                                        libvlc_exception_t *p_exception )
+{
+    vlm_t *p_vlm;
+    int64_t id;
+    libvlc_vlm_media_t *libvlc_vlm_media;
+
+    VLM_RET( p_vlm, NULL);
+
+    if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
+        vlm_Control( p_vlm, VLM_GET_MEDIA_LIBVLC, id, &libvlc_vlm_media ) )
+        return NULL;
+
+    if( libvlc_vlm_media )
+        return libvlc_vlm_media->p_event_manager;
+
+    return NULL;
+}
diff --git a/src/input/vlm.c b/src/input/vlm.c
index 9816a4b..de1aa1f 100644
--- a/src/input/vlm.c
+++ b/src/input/vlm.c
@@ -731,6 +731,24 @@ static int vlm_ControlMediaGetId( vlm_t *p_vlm, const char *psz_name, int64_t *p
     return VLC_SUCCESS;
 }
 
+static int vlm_ControlMediaGetLibvlc( vlm_t *p_vlm, int64_t id, libvlc_vlm_media_t **pp_libvlc_vlm_media )
+{
+    vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+    if( !p_media )
+        return VLC_EGENERIC;
+    *pp_libvlc_vlm_media = p_media->cfg.libvlc_vlm_media;
+    return VLC_SUCCESS;
+}
+
+static int vlm_ControlMediaSetLibvlc( vlm_t *p_vlm, int64_t id, libvlc_vlm_media_t *p_libvlc_vlm_media )
+{
+    vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+    if( !p_media )
+        return VLC_EGENERIC;
+    p_media->cfg.libvlc_vlm_media = p_libvlc_vlm_media;
+    return VLC_SUCCESS;
+}
+
 static vlm_media_instance_sys_t *vlm_ControlMediaInstanceGetByName( vlm_media_sys_t *p_media, const char *psz_id )
 {
     int i;
@@ -1022,6 +1040,8 @@ static int vlm_vaControlInternal( vlm_t *p_vlm, int i_query, va_list args )
     vlm_media_t **pp_dsc;
     vlm_media_t ***ppp_dsc;
     vlm_media_instance_t ***ppp_idsc;
+    libvlc_vlm_media_t *p_libvlc_vlm_media;
+    libvlc_vlm_media_t **pp_libvlc_vlm_media;
     const char *psz_id;
     const char *psz_vod;
     int64_t *p_id;
@@ -1068,6 +1088,15 @@ static int vlm_vaControlInternal( vlm_t *p_vlm, int i_query, va_list args )
         p_id = (int64_t*)va_arg( args, int64_t * );
         return vlm_ControlMediaGetId( p_vlm, psz_id, p_id );
 
+    case VLM_SET_MEDIA_LIBVLC:
+        id = (int64_t)va_arg( args, int64_t );
+        p_libvlc_vlm_media = (libvlc_vlm_media_t *)va_arg( args, libvlc_vlm_media_t * );
+        return vlm_ControlMediaSetLibvlc( p_vlm, id, p_libvlc_vlm_media );
+
+    case VLM_GET_MEDIA_LIBVLC:
+        id = (int64_t)va_arg( args, int64_t );
+        pp_libvlc_vlm_media = (libvlc_vlm_media_t **)va_arg( args, libvlc_vlm_media_t ** );
+        return vlm_ControlMediaGetLibvlc( p_vlm, id, pp_libvlc_vlm_media );
 
     /* Media instance control */
     case VLM_GET_MEDIA_INSTANCES:
diff --git a/src/libvlc.sym b/src/libvlc.sym
index 759744d..69736d7 100644
--- a/src/libvlc.sym
+++ b/src/libvlc.sym
@@ -229,6 +229,7 @@ libvlc_vlm_get_media_instance_rate
 libvlc_vlm_get_media_instance_seekable
 libvlc_vlm_get_media_instance_time
 libvlc_vlm_get_media_instance_title
+libvlc_vlm_get_media_event_manager
 libvlc_vlm_pause_media
 libvlc_vlm_play_media
 libvlc_vlm_release
-- 
1.5.4.3

