]> git.sesse.net Git - vlc/blobdiff - modules/codec/cmml/intf.c
* ALL: separation of the SPU engine from the VOUT.
[vlc] / modules / codec / cmml / intf.c
index d572ae40fe195a0b5f9e84b7789f8898a41486e4..1222afb8a611f5460ffa559a72822fb5498a0fbe 100644 (file)
  *****************************************************************************/
 #include <stdlib.h>                                      /* malloc(), free() */
 #include <string.h>
-#include <unistd.h>
 
 #include <vlc/vlc.h>
+
+#ifdef HAVE_UNISTD_H
+#    include <unistd.h>
+#endif
+
 #include <vlc/decoder.h>
+#include <vlc/input.h>
 #include <vlc/intf.h>
 #include <vlc/vout.h>
 
 #include <osd.h>
 
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-
 #include "vlc_keys.h"
 
 #include "browser_open.h"
@@ -85,11 +86,19 @@ static void  FollowAnchor               ( intf_thread_t * );
 static void  GoBack                     ( intf_thread_t * );
 static void  GoForward                  ( intf_thread_t * );
 
+static int   FollowAnchorCallback       ( vlc_object_t *, char const *,
+                                          vlc_value_t, vlc_value_t, void * );
+static int   GoBackCallback             ( vlc_object_t *, char const *,
+                                          vlc_value_t, vlc_value_t, void * );
+static int   GoForwardCallback          ( vlc_object_t *, char const *,
+                                          vlc_value_t, vlc_value_t, void * );
+
 static char *GetTimedURLFromPlaylistItem( intf_thread_t *, playlist_item_t * );
 static char *GetTimedURIFragmentForTime ( int );
 static int   GetCurrentTimeInSeconds    ( input_thread_t * );
 static int   DisplayAnchor              ( intf_thread_t *, vout_thread_t *,
                                           char *, char * );
+static int   DisplayPendingAnchor       ( intf_thread_t *, vout_thread_t * );
 static history_t * GetHistory           ( playlist_t * );
 static void  ReplacePlaylistItem        ( playlist_t *, char * );
 
@@ -110,11 +119,21 @@ int E_(OpenIntf) ( vlc_object_t *p_this )
     };
 
     p_intf->pf_run = RunIntf;
-    
+
     var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
     /* we also need to add the callback for "mouse-clicked", but do that later
      * when we've found a p_vout */
 
+    var_Create( p_intf->p_vlc, "browse-go-back", VLC_VAR_VOID );
+    var_AddCallback( p_intf->p_vlc, "browse-go-back",
+                     GoBackCallback, p_intf );
+    var_Create( p_intf->p_vlc, "browse-go-forward", VLC_VAR_VOID );
+    var_AddCallback( p_intf->p_vlc, "browse-go-forward",
+                     GoForwardCallback, p_intf );
+    var_Create( p_intf->p_vlc, "browse-follow-anchor", VLC_VAR_VOID );
+    var_AddCallback( p_intf->p_vlc, "browse-follow-anchor",
+                     FollowAnchorCallback, p_intf );
+
     return( 0 );
 }
 
@@ -132,24 +151,11 @@ void E_(CloseIntf) ( vlc_object_t *p_this )
 
     /* Erase the anchor text description from the video output if it exists */
     p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
-    if( p_vout != NULL && p_vout->p_subpicture != NULL )
+    if( p_vout )
     {
-        subpicture_t *p_subpic;
-        int          i_subpic;
-
-        for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
-        {
-            p_subpic = &p_vout->p_subpicture[i_subpic];
-
-            if( p_subpic != NULL &&
-              ( p_subpic->i_status == RESERVED_SUBPICTURE
-                || p_subpic->i_status == READY_SUBPICTURE ) )
-            {
-                vout_DestroySubPicture( p_vout, p_subpic );
-            }
-        }
+        spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, DEFAULT_CHAN );
+        vlc_object_release( p_vout );
     }
-    if( p_vout ) vlc_object_release( p_vout );
 
     var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
 
@@ -186,8 +192,6 @@ static void RunIntf( intf_thread_t *p_intf )
     /* Main loop */
     while( !p_intf->b_die )
     {
-        vlc_value_t val;
-        decoder_t *p_cmml_decoder;
         
         /* find a video output if we currently don't have one */
         if( p_vout == NULL )
@@ -223,7 +227,7 @@ static void RunIntf( intf_thread_t *p_intf )
 #ifdef CMML_INTF_DEBUG
             msg_Dbg( p_intf, "Got a keypress: %d", val.i_int );
 #endif
-            
+
             for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
             {
                 if( p_hotkeys[i].i_key == val.i_int )
@@ -248,55 +252,11 @@ static void RunIntf( intf_thread_t *p_intf )
                         break;
                 }
             }
-        }       
+        }
 
         vlc_mutex_unlock( &p_intf->change_lock );
 
-        /*
-         * Get a pending anchor description/URL from the CMML decoder
-         * and display it on screen
-         */
-        p_cmml_decoder = p_intf->p_sys->p_cmml_decoder;
-        if( var_Get( p_cmml_decoder, "psz-current-anchor-description", &val )
-                == VLC_SUCCESS )
-        {
-            if( val.p_address )
-            {
-                char *psz_description = NULL;
-                char *psz_url = NULL;
-
-                psz_description = val.p_address;
-
-                if( var_Get( p_cmml_decoder, "psz-current-anchor-url", &val )
-                        == VLC_SUCCESS )
-                {
-                    psz_url = val.p_address;
-                }
-
-                if( p_vout != NULL )
-                {
-                    if( DisplayAnchor( p_intf, p_vout, psz_description,
-                                psz_url ) != VLC_SUCCESS )
-                    {
-                        /* text render unsuccessful: do nothing */
-                    }
-                    else
-                    {
-                        /* text render successful: clear description */
-                        val.p_address = NULL;
-                        if( var_Set( p_cmml_decoder,
-                                    "psz-current-anchor-description", val ) !=
-                                VLC_SUCCESS )
-                        {
-                            msg_Dbg( p_intf, "reset of "
-                                    "psz-current-anchor-description failed" );
-                        }
-                        free( psz_description );
-                        psz_url = NULL;
-                    }
-                }
-            }
-        }
+        (void) DisplayPendingAnchor( p_intf, p_vout );
 
         /* Wait a bit */
         msleep( INTF_IDLE_SLEEP );
@@ -313,6 +273,76 @@ static void RunIntf( intf_thread_t *p_intf )
     vlc_object_release( p_intf->p_sys->p_input );
 }
 
+/*****************************************************************************
+ * DisplayPendingAnchor: get a pending anchor description/URL from the CMML
+ * decoder and display it on screen
+ *****************************************************************************/
+static int DisplayPendingAnchor( intf_thread_t *p_intf, vout_thread_t *p_vout )
+{
+    decoder_t *p_cmml_decoder;
+    char *psz_description = NULL;
+    char *psz_url = NULL;
+
+    intf_thread_t *p_primary_intf;
+    vlc_value_t val;
+
+    p_cmml_decoder = p_intf->p_sys->p_cmml_decoder;
+    if( var_Get( p_cmml_decoder, "psz-current-anchor-description", &val )
+            != VLC_SUCCESS )
+    {
+        return VLC_TRUE;
+    }
+
+    if( !val.p_address )
+        return VLC_TRUE;
+
+    psz_description = val.p_address;
+
+    if( var_Get( p_cmml_decoder, "psz-current-anchor-url", &val )
+            == VLC_SUCCESS )
+    {
+        psz_url = val.p_address;
+    }
+
+    if( p_vout != NULL )
+    {
+        /* don't display anchor if main interface can display it */
+        p_primary_intf = vlc_object_find( p_intf->p_vlc, VLC_OBJECT_INTF,
+                FIND_CHILD );
+
+        if( p_primary_intf )
+        {
+            if( var_Get( p_primary_intf, "intf-displays-cmml-description", &val )
+                    == VLC_SUCCESS )
+            {
+                if( val.b_bool == VLC_TRUE ) return VLC_TRUE;
+            }
+        }
+
+        /* display anchor as subtitle on-screen */
+        if( DisplayAnchor( p_intf, p_vout, psz_description, psz_url )
+                != VLC_SUCCESS )
+        {
+            /* text render unsuccessful: do nothing */
+            return VLC_FALSE;
+        }
+
+        /* text render successful: clear description */
+        val.p_address = NULL;
+        if( var_Set( p_cmml_decoder, "psz-current-anchor-description", val )
+                != VLC_SUCCESS )
+        {
+            msg_Dbg( p_intf,
+                     "reset of psz-current-anchor-description failed" );
+        }
+        free( psz_description );
+        psz_url = NULL;
+    }
+
+    return VLC_TRUE;
+}
+
+
 /*****************************************************************************
  * InitThread:
  *****************************************************************************/
@@ -427,7 +457,7 @@ static void FollowAnchor ( intf_thread_t *p_intf )
         p_current_item = p_playlist->pp_items[p_playlist->i_index];
 #ifdef CMML_INTF_DEBUG
         msg_Dbg( p_intf, "Current playlist item URL is \"%s\"",
-                p_current_item->psz_uri );
+                p_current_item->input.psz_uri );
 #endif
 
         psz_uri_to_load = XURL_Concat( p_current_item->input.psz_uri,
@@ -492,6 +522,9 @@ static void FollowAnchor ( intf_thread_t *p_intf )
         }
         else
         {
+#ifdef CMML_INTF_DEBUG
+            msg_Dbg( p_intf, "calling browser_Open with \"%s\"", psz_url );
+#endif
             (void) browser_Open( psz_url );
             playlist_Command( p_playlist, PLAYLIST_PAUSE, 0 );
         }
@@ -570,6 +603,34 @@ char *GetTimedURIFragmentForTime( int seconds )
     return psz_time;
 }
 
+static
+int GoBackCallback( vlc_object_t *p_this, char const *psz_var,
+                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *) p_data;
+    GoBack( p_intf );
+    return VLC_SUCCESS;
+}
+
+static
+int GoForwardCallback( vlc_object_t *p_this, char const *psz_var,
+                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *) p_data;
+    GoForward( p_intf );
+    return VLC_SUCCESS;
+}
+
+static
+int FollowAnchorCallback( vlc_object_t *p_this, char const *psz_var,
+                          vlc_value_t oldval, vlc_value_t newval,
+                          void *p_data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *) p_data;
+    FollowAnchor( p_intf );
+    return VLC_SUCCESS;
+}
+
 static
 void GoBack( intf_thread_t *p_intf )
 {
@@ -770,8 +831,8 @@ static int DisplayAnchor( intf_thread_t *p_intf,
         /* TODO: p_subpicture doesn't have the proper i_x and i_y
          * coordinates.  Need to look at the subpicture display system to
          * work out why. */
-        if ( vout_ShowTextAbsolute( p_vout,
-                psz_anchor_description, p_style, OSD_ALIGN_BOTTOM, 
+        if ( vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,
+                psz_anchor_description, p_style, OSD_ALIGN_BOTTOM,
                 i_margin_h, i_margin_v, i_now, 0 ) == VLC_SUCCESS )
         {
             /* Displayed successfully */