No maintainer showed up. It is broken in many ways and there is virtually no streams using that...
* opie, qte and qte_main
* opengllayer
* cddax. Use cdda instead
+ * cmml.
Changes between 1.0.2 and 1.0.3:
])
])
-dnl
-dnl CMML plugin
-dnl
-AC_ARG_ENABLE(cmml,
- [ --enable-cmml CMML support (default enabled)])
-if test "${enable_cmml}" != "no"
-then
- VLC_ADD_PLUGIN([cmml])
-fi
-
dnl
dnl kate decoder plugin
dnl
modules/audio_output/Makefile
modules/codec/Makefile
modules/codec/avcodec/Makefile
- modules/codec/cmml/Makefile
modules/codec/dmo/Makefile
modules/codec/shine/Makefile
modules/codec/subtitles/Makefile
* chorus_flanger: variable delay audio filter
* chroma_neon: ARM NEONv1 chroma conversion module
* clone: Clone video filter
- * cmml: Continuous Media Markup Language annotations/hyperlinks decoder
* colorthres: Theshold color based on similarity to reference color Video filter
* converter_fixed: Fixed-point audio format conversions
* converter_float: Floating-point audio format conversions
-SUBDIRS = cmml dmo avcodec shine subtitles spudec wmafixed
+SUBDIRS = dmo avcodec shine subtitles spudec wmafixed
SOURCES_a52 = a52.c a52.h
SOURCES_dts = dts.c
SOURCES_flac = flac.c
+++ /dev/null
-What's CMML?
-------------
-
-This is an implementation of the Continuous Media Markup Language
-(CMML) for VideoLAN. In short, CMML is a (XML) markup language for
-time-continuous data, which of course includes multimedia such as
-video and audio. It allows one to annotate a media file with both
-structured and unstructured textual data, but one of its distinguishing
-features--and what this code implements--is its support for embedding
-hyperlinks in media files.
-
-So, while viewing some media (e.g. a radio interview with a band),
-you could provide a hyperlink to any URL, including a standard web
-page or other media (e.g. the band's home page). The hyperlinks
-are active only for specific intervals of time while the media is
-playing, so for example during a radio interview, the hyperlinks
-can change depending on what questions the interviewer is asking
-and topic is being discussed.
-
-For more general information on CMML and its role in the bigger
-picture of extending the World Wide Web to properly support multimedia,
-see <http://www.annodex.net/overview.html>. For specifications of
-CMML, see <http://www.annodex.net/specifications.html>.
-
-
-Usage
------
-
-Once you have hyperlinking capability, you take on some of the
-capabilities of a web browser, in particular following hyperlinks,
-and also maintaining a browsing history where you can go backwards
-and forwards between pieces of media you've linked to. So, if you
-are viewing a file with CMML markup:
-
-* Hyperlinks are displayed as a subtitle track
-
-* Hyperlinks are followed with the VLC "activate" hotkey (by default,
- this is just the Enter key)
-
-* Going back and forward are done with the "history-back" and
- "history-forward" keys, by default Cmd-[ and Cmd-] on Mac OS X,
- and Ctrl-[ and Ctrl-] on all other platforms.
-
-Until the media browsing history features are made available outside
-of the CMML plugin, you can only use the history features while
-viewing a file that contains CMML markup: e.g. you cannot navigate
-backwards or forward in the history while viewing a standard MPEG
-video. This is a limitation which may be removed if the media
-browsing code is merged into the VLC core.
-
-
-Overview of the code
---------------------
-
-First: a lot of this code could be implemented, or should be
-implemented, in VLC's core (libvlc) rather than be part of a codec
-plugin, either because it's something which really should belong
-in the core (e.g. media browsing history, system-indepedent interface
-to web browser) or a generally useful thing outside of the codec
-plugin (e.g. XML parser, URL handling library). That's well and
-good, but changes to libvlc are far-reaching and affect all of VLC,
-rather than only affecting a single plugin. It's sensible to
-gradually merge this stuff into libvlc on an as-needs basis, rather
-than trying to refactor out huge amounts of code at once.
-
-Here's a quick overview of what the files do:
-
-* browser_open.[ch]: A very simple attempt to provide a way to
- open the system's web browser.
-
-* history.[ch]: Media browsing history (as described above in
- "Usage").
-
-* xstrcat.h: Simple wrapper around strcat(1) which performs a
- realloc(1) if needed.
-
-* xarray.[ch]: extensible (growable) array, similar to a Vector in
- Java/C++. Could be replaced with a vlc_list_t from libvlc's
- src/misc/objects.c if the vlc_list_t API were made public.
-
-* xlist.[ch]: Yet Another Linked List implementation (sorry guys
- :), only here because XTag (see below) uses it internally.
-
-* xtag.[ch]: A very simple (but working!), lightweight XML
- parser.
-
-* xurl.[ch]: A small URL handling library.
-
-* cmml.c: The actual 'codec' parser, which parses the CMML data
- (demuxed from the incoming media stream, of course), and provides
- two VLC vars ("psz-current-anchor-description" and
- "psz-current-anchor-url") which enable intf plugins to display
- the CMML data to the user and let them interact with it.
-
-* intf.c: Enables media browsing functionality by displaying
- hyperlinks as a subtitle track, and responding to user
- keypresses for following hyperlinks and navigating the media
- browsing history.
-
-So, all the files except for cmml.c and intf.c could be made available
-and re-used outside of this plugin, but currently are not (for the
-reasons given above).
-
+++ /dev/null
-SOURCES_cmml = \
- browser_open.c browser_open.h \
- cmml.c \
- history.c history.h \
- intf.c \
- xarray.c xarray.h \
- xlist.c xlist.h \
- xstrcat.h \
- xtag.c xtag.h \
- xurl.c xurl.h
-
+++ /dev/null
-/*****************************************************************************
- * browser_open.c: platform-independent opening of a web browser
- *****************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "browser_open.h"
-
-#if 0
-int browser_Open( const char *psz_url )
-{
-#ifdef __APPLE__
- char *psz_open_commandline;
- int i_ret;
-
- if( asprintf( &psz_open_commandline, "/usr/bin/open %s", psz_url ) == -1 )
- return -1;
-
- i_ret = system( psz_open_commandline );
- free( psz_open_commandline );
- return i_ret;
-
-#elif defined( UNDER_CE )
- return -1;
-
-#elif defined( WIN32 )
- char *psz_open_commandline;
- int i_ret;
-
- if( asprintf( &psz_open_commandline, "explorer %s", psz_url ) == -1 )
- return -1;
-
- i_ret = system( psz_open_commandline );
- free( psz_open_commandline );
- return i_ret;
-
-#else
- /* Assume we're on a UNIX of some sort */
- char *psz_open_commandline;
- int i_ret;
-
- /* Debian uses www-browser */
- if( asprintf( &psz_open_commandline, "www-browser %s", psz_url ) == -1 )
- return -1;
-
- i_ret = system( psz_open_commandline );
- free( psz_open_commandline );
-
- if( i_ret == 0 )
- return 0;
-
- /* Try mozilla */
- if( asprintf( &psz_open_commandline, "mozilla %s", psz_url ) == -1 )
- return -1;
-
- i_ret = system( psz_open_commandline );
- free( psz_open_commandline );
- return i_ret;
-#endif
-}
-#else
-int browser_Open( const char *psz_url )
-{
- (void)psz_url;
- return -1;
-}
-#endif
-
+++ /dev/null
-/*****************************************************************************
- * browser_open.h: platform-independent opening of a web browser
- *****************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __BROWSER_OPEN_H__
-#define __BROWSER_OPEN_H__
-
-int browser_Open( const char *psz_url );
-
-#endif /* __BROWSER_OPEN_H__ */
-
+++ /dev/null
-/*****************************************************************************
- * cmml.c : CMML annotations/metadata decoder
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Author: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_plugin.h>
-#include <vlc_input.h>
-#include <vlc_codec.h>
-#include <vlc_osd.h>
-#include <vlc_charset.h>
-#include <vlc_interface.h>
-#include "xtag.h"
-
-#undef CMML_DEBUG
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-static void CloseDecoder ( vlc_object_t * );
-
-static subpicture_t *DecodeBlock ( decoder_t *, block_t ** );
-
-static void ParseText ( decoder_t *, block_t * );
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-decoder_sys_t *OpenIntf( vlc_object_t * );
-void CloseIntf( decoder_sys_t * );
-
-/*****************************************************************************
- * Module descriptor.
- *****************************************************************************/
-vlc_module_begin ()
- set_description( N_("CMML annotations decoder") )
- set_capability( "decoder", 50 )
- set_callbacks( OpenDecoder, CloseDecoder )
- add_shortcut( "cmml" )
-
- add_submodule ()
- set_capability( "interface", 0 )
- set_callbacks( OpenIntf, CloseIntf )
- add_shortcut( "cmml" )
-vlc_module_end ()
-
-/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to chose.
- *****************************************************************************/
-static int OpenDecoder( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t*)p_this;
- input_thread_t * p_input;
-
- if( p_dec->fmt_in.i_codec != VLC_CODEC_CMML )
- return VLC_EGENERIC;
-
- p_dec->pf_decode_sub = DecodeBlock;
-
- /* Let other interested modules know that we're a CMML decoder
- * We have to set this variable on the input thread, because there's
- * typically more than one decoder running so we can't find the CMML
- * decoder succesfully with vlc_object_find. (Any hints on how to achieve
- * this would be rather appreciated ;) */
- p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_ANYWHERE );
- if( p_input )
- {
- vlc_value_t val;
-
-#ifdef CMML_DEBUG
- msg_Dbg( p_dec, "p_input is at %p", p_input );
-#endif
- val.p_address = p_dec;
- var_Create( p_input, "has-cmml-decoder",
- VLC_VAR_ADDRESS|VLC_VAR_DOINHERIT );
-
- if( var_Set( p_input, "has-cmml-decoder", val ) != VLC_SUCCESS )
- msg_Dbg( p_dec, "var_Set of has-cmml-decoder failed" );
- vlc_object_release( p_input );
- }
-
- /* initialise the CMML responder interface */
- p_dec->p_sys = OpenIntf( VLC_OBJECT(p_dec) );
- p_dec->fmt_out.i_cat = SPU_ES;
- p_dec->fmt_out.i_codec = 0;
-
- return VLC_SUCCESS;
-}
-
-/****************************************************************************
- * DecodeBlock: the whole thing
- ****************************************************************************
- * This function must be fed with complete subtitles units.
- ****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
-{
- subpicture_t *p_spu;
-
- if( !pp_block || *pp_block == NULL )
- {
- return NULL;
- }
-
- ParseText( p_dec, *pp_block );
-
- block_Release( *pp_block );
- *pp_block = NULL;
-
- /* allocate an empty subpicture to return. the actual subpicture
- * displaying is done in the DisplayAnchor function in intf.c (called from
- * DisplayPendingAnchor, which in turn is called from the main RunIntf
- * loop). */
- p_spu = decoder_NewSubpicture( p_dec );
- if( !p_spu )
- {
- msg_Dbg( p_dec, "couldn't allocate new subpicture" );
- return NULL;
- }
-
- return p_spu;
-}
-
-/*****************************************************************************
- * CloseDecoder: clean up the decoder
- *****************************************************************************/
-static void CloseDecoder( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t *)p_this;
-
- CloseIntf( p_dec->p_sys );
-}
-
-/*****************************************************************************
- * ParseText: parse an text subtitle packet and send it to the video output
- *****************************************************************************/
-static void ParseText( decoder_t *p_dec, block_t *p_block )
-{
- char *psz_subtitle, *psz_cmml, *psz_url;
- XTag *p_clip_parser, *p_anchor;
- vlc_value_t val;
-
- /* We cannot display a subpicture with no date */
- if( p_block->i_pts == 0 )
- {
- msg_Warn( p_dec, "subtitle without a date" );
- return;
- }
-
- /* Check validity of packet data */
- if( p_block->i_buffer <= 1 || p_block->p_buffer[0] == '\0' )
- {
- msg_Warn( p_dec, "empty subtitle" );
- return;
- }
-
- /* get anchor text from CMML */
-
- /* Copy the whole CMML tag into our own buffer:
- allocate i_buffer bytes + 1 for the terminating \0 */
- if( (psz_cmml = malloc( p_block->i_buffer + 1 )) == NULL )
- return;
- memcpy( psz_cmml, p_block->p_buffer, p_block->i_buffer );
- psz_cmml[p_block->i_buffer] = '\0'; /* terminate the string */
-#ifdef CMML_DEBUG
- msg_Dbg( p_dec, "psz_cmml is \"%s\"", psz_cmml );
-#endif
-
- /* Parse the <clip> part of the CMML */
- p_clip_parser = xtag_new_parse( psz_cmml, p_block->i_buffer );
- if( !p_clip_parser )
- {
- msg_Warn( p_dec, "couldn't initialise <clip> parser" );
- free( psz_cmml );
- return;
- }
-
- /* Parse the anchor tag and get its contents */
- p_anchor = xtag_first_child( p_clip_parser, "a" );
- if( p_anchor != NULL )
- {
- psz_subtitle = xtag_get_pcdata( p_anchor );
- }
- else
- {
- psz_subtitle = strdup( " " );
- }
-
-#ifdef CMML_DEBUG
- msg_Dbg( p_dec, "psz_subtitle is \"%s\"", psz_subtitle );
-#endif
-
- /* get URL from the current clip, if one exists */
- psz_url = xtag_get_attribute( p_anchor, "href" );
-#ifdef CMML_DEBUG
- msg_Dbg( p_dec, "psz_url is \"%s\"", psz_url );
-#endif
- if( psz_url )
- {
- char *psz_tmp = strdup( psz_url );
-
- val.p_address = psz_tmp;
- if( var_Set( p_dec, "psz-current-anchor-url", val ) != VLC_SUCCESS )
- {
- var_Create( p_dec, "psz-current-anchor-url",
- VLC_VAR_ADDRESS | VLC_VAR_DOINHERIT );
- msg_Dbg( p_dec, "creating psz-current-anchor-url" );
- if( var_Set( p_dec, "psz-current-anchor-url", val ) != VLC_SUCCESS )
- msg_Dbg( p_dec, "var_Set of psz-current-anchor-url failed" );
- }
- }
-
- if( psz_subtitle )
- {
- char *psz_tmp = strdup( psz_subtitle );
-
- val.p_address = psz_tmp;
- if( var_Set( p_dec, "psz-current-anchor-description", val ) != VLC_SUCCESS )
- {
- var_Create( p_dec, "psz-current-anchor-description",
- VLC_VAR_ADDRESS | VLC_VAR_DOINHERIT );
- msg_Dbg( p_dec, "creating psz-current-anchor-description" );
- if( var_Set( p_dec, "psz-current-anchor-description", val ) != VLC_SUCCESS )
- msg_Dbg( p_dec, "var_Set of psz-current-anchor-description failed" );
- }
-
- }
-
- free( psz_subtitle );
- free( psz_cmml );
- free( p_anchor );
- free( p_clip_parser );
- free( psz_url );
-}
-
+++ /dev/null
-/*****************************************************************************
- * history.c: vlc_history_t (web-browser-like back/forward history) handling
- *****************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_input.h>
-
-#include "history.h"
-
-#include "xarray.h"
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h> /* malloc() */
-#endif
-
-#undef HISTORY_DEBUG
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-#ifdef HISTORY_DEBUG
-static void history_Dump( history_t *p_history );
-#endif
-
-/*****************************************************************************
- * Local structure lock
- *****************************************************************************/
-
-/*****************************************************************************
- * Actual history code
- *****************************************************************************/
-
-history_t *history_New( void )
-{
- history_t *p_new_history;
-
- p_new_history = calloc( 1, sizeof( struct history_t ) );
- if( p_new_history == NULL ) return NULL;
-
- p_new_history->p_xarray = xarray_New( 0 );
- if( p_new_history->p_xarray == NULL )
- {
- free( p_new_history );
- return NULL;
- }
-
- return p_new_history;
-}
-
-bool history_GoBackSavingCurrentItem ( history_t *p_history,
- history_item_t *p_item )
-{
- history_PruneAndInsert( p_history, p_item );
-
- /* PruneAndInsert will increment the index, so we need to go
- * back one position to reset the index to the place we were at
- * before saving the current state, and then go back one more to
- * actually go back */
- p_history->i_index -= 2;
-
-#ifdef HISTORY_DEBUG
- history_Dump( p_history );
-#endif
- return true;
-}
-
-#ifdef HISTORY_DEBUG
-static void history_Dump( history_t *p_history )
-{
- unsigned int i_count;
- int i;
-
- if( xarray_Count( p_history->p_xarray, &i_count ) != XARRAY_SUCCESS )
- return;
-
- for (i = 0; i < (int) i_count; i++)
- {
- history_item_t *p_item;
- void *pv_item;
-
- xarray_ObjectAtIndex( p_history->p_xarray, i, &pv_item );
-
- p_item = (history_item_t *) pv_item;
-
- if( p_item == NULL )
- fprintf( stderr, "HISTORY: [%d] NULL\n", i );
- else
- {
- fprintf( stderr, "HISTORY: [%d] %p (%p->%s)\n", i, p_item,
- p_item->psz_uri, p_item->psz_uri );
- }
- }
-}
-#endif
-
-bool history_GoForwardSavingCurrentItem ( history_t *p_history,
- history_item_t *p_item )
-{
-#ifdef HISTORY_DEBUG
- history_Dump( p_history );
-#endif
-
- if( xarray_ReplaceObject( p_history->p_xarray, p_history->i_index, p_item )
- == XARRAY_SUCCESS )
- {
- p_history->i_index++;
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool history_CanGoBack( history_t *p_history )
-{
- if( p_history->i_index > 0 )
- return true;
- else
- return false;
-}
-
-bool history_CanGoForward( history_t *p_history )
-{
- unsigned int i_count;
-
- if( xarray_Count( p_history->p_xarray, &i_count ) != XARRAY_SUCCESS )
- return false;
-
- if( p_history->i_index < i_count )
- return true;
- else
- return false;
-}
-
-history_item_t *history_Item( history_t *p_history )
-{
- history_item_t *p_item;
- void *pv_item;
-
- if( xarray_ObjectAtIndex( p_history->p_xarray, p_history->i_index,
- &pv_item )
- == XARRAY_SUCCESS )
- {
- p_item = (history_item_t *) pv_item;
- return p_item;
- }
- else
- {
- return NULL;
- }
-}
-
-void history_Prune( history_t *p_history )
-{
- xarray_RemoveObjectsAfter( p_history->p_xarray, p_history->i_index );
- xarray_RemoveObject( p_history->p_xarray, p_history->i_index );
-}
-
-void history_PruneAndInsert( history_t *p_history, history_item_t *p_item )
-{
- unsigned int i_count;
-
- xarray_Count( p_history->p_xarray, &i_count );
-
- if( i_count == 0 )
- {
- xarray_InsertObject( p_history->p_xarray, p_item, 0 );
- p_history->i_index = 1;
- }
- else
- {
- history_Prune( p_history );
- xarray_InsertObject( p_history->p_xarray, p_item, p_history->i_index );
- p_history->i_index++;
- }
-}
-
-unsigned int history_Count( history_t *p_history )
-{
- unsigned int i_count;
- xarray_Count( p_history->p_xarray, &i_count );
- return i_count;
-}
-
-unsigned int history_Index( history_t *p_history )
-{
- return p_history->i_index;
-}
-
-history_item_t * historyItem_New( char *psz_name, char *psz_uri )
-{
- history_item_t *p_history_item = NULL;
-
- p_history_item = (history_item_t *) malloc( sizeof(history_item_t) );
- if( !p_history_item ) return NULL;
-
- p_history_item->psz_uri = strdup( psz_uri );
- p_history_item->psz_name = strdup( psz_name );
-
- return p_history_item;
-}
-
+++ /dev/null
-/*****************************************************************************
- * history.h: vlc_history_t (web-browser-like back/forward history) handling
- *****************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __VLC_HISTORY_H__
-#define __VLC_HISTORY_H__
-
-#include "xarray.h"
-
-struct history_item_t
-{
- char * psz_name;
- char * psz_uri;
-};
-
-struct history_t
-{
- unsigned int i_index; /* current index into history */
- XArray * p_xarray;
-};
-
-typedef struct history_item_t history_item_t;
-typedef struct history_t history_t;
-
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-history_t * history_New ( void );
-bool history_GoBackSavingCurrentItem ( history_t *,
- history_item_t * );
-bool history_GoForwardSavingCurrentItem ( history_t *,
- history_item_t * );
-bool history_CanGoBack ( history_t * );
-bool history_CanGoForward ( history_t * );
-history_item_t * history_Item ( history_t * );
-void history_Prune ( history_t * );
-void history_PruneAndInsert ( history_t *,
- history_item_t * );
-unsigned int history_Count ( history_t * );
-unsigned int history_Index ( history_t * );
-
-history_item_t * historyItem_New ( char *, char * );
-
-#endif /* __VLC_HISTORY_H__ */
-
+++ /dev/null
-/*****************************************************************************
- * intf.c: interface for CMML annotations/hyperlinks
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-
-#include <stdio.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include <vlc_codec.h>
-#include <vlc_playlist.h>
-#include <vlc_osd.h>
-
-#include <vlc_keys.h>
-
-#include "browser_open.h"
-#include "history.h"
-#include "xstrcat.h"
-#include "xurl.h"
-
-#undef CMML_INTF_USE_TIMED_URIS
-
-#undef CMML_INTF_DEBUG
-#undef CMML_INTF_HISTORY_DEBUG
-
-/*****************************************************************************
- * intf_sys_t: description and status of interface
- *****************************************************************************/
-typedef struct decoder_sys_t
-{
- VLC_COMMON_MEMBERS
-
- vlc_mutex_t lock;
- decoder_t * p_cmml_decoder;
- input_thread_t * p_input;
-
- int i_key_action;
-} intf_thread_t;
-
-struct navigation_history_t
-{
- int i_history_size;
- int i_last_item;
-};
-
-/*****************************************************************************
- * Local prototypes.
- *****************************************************************************/
-
-decoder_sys_t *OpenIntf ( vlc_object_t * );
-void CloseIntf ( decoder_sys_t * );
-
-static int InitThread ( intf_thread_t * );
-static int MouseEvent ( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
-static int KeyEvent ( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
-
-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 * );
-#ifdef CMML_INTF_USE_TIMED_URIS
-static int GetCurrentTimeInSeconds ( input_thread_t * );
-static char *GetTimedURIFragmentForTime ( int );
-#endif
-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 * );
-
-static void *RunIntf ( vlc_object_t * );
-
-/*****************************************************************************
- * OpenIntf: initialize CMML interface
- *****************************************************************************/
-decoder_sys_t *OpenIntf ( vlc_object_t *p_this )
-{
- decoder_sys_t *p_intf = vlc_object_create( p_this, sizeof( *p_intf ) );
- if( p_intf == NULL )
- return NULL;
-
- vlc_mutex_init( &p_intf->lock );
-
- var_AddCallback( p_intf->p_libvlc, "key-action", 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_libvlc, "browse-go-back", VLC_VAR_VOID );
- var_AddCallback( p_intf->p_libvlc, "browse-go-back",
- GoBackCallback, p_intf );
- var_Create( p_intf->p_libvlc, "browse-go-forward", VLC_VAR_VOID );
- var_AddCallback( p_intf->p_libvlc, "browse-go-forward",
- GoForwardCallback, p_intf );
- var_Create( p_intf->p_libvlc, "browse-follow-anchor", VLC_VAR_VOID );
- var_AddCallback( p_intf->p_libvlc, "browse-follow-anchor",
- FollowAnchorCallback, p_intf );
-
- int ret = vlc_thread_create( p_intf, "cmml", RunIntf, VLC_THREAD_PRIORITY_LOW );
- if (ret)
- {
- CloseIntf( p_intf);
- return NULL;
- }
- return p_intf;
-}
-
-/*****************************************************************************
- * CloseIntf: destroy dummy interface
- *****************************************************************************/
-void CloseIntf ( decoder_sys_t *p_intf )
-{
- vout_thread_t * p_vout;
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "freeing CMML interface" );
-#endif
-
- /* 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 )
- {
- /* enable CMML as a subtitle track */
- spu_Control( vout_GetSpu( p_vout ), SPU_CHANNEL_CLEAR, DEFAULT_CHAN );
- vlc_object_release( p_vout );
- }
-
- var_DelCallback( p_intf->p_libvlc, "key-action", KeyEvent, p_intf );
- vlc_object_kill( p_intf );
- vlc_thread_join( p_intf );
-
- vlc_object_release( p_intf->p_cmml_decoder );
-
- vlc_mutex_destroy( &p_intf->lock );
- vlc_object_release( p_intf );
-}
-
-
-/*****************************************************************************
- * RunIntf: main loop
- *****************************************************************************/
-static void *RunIntf( vlc_object_t *p_obj )
-{
- decoder_sys_t *p_intf = (decoder_sys_t *)p_obj;
- int canc = vlc_savecancel();
- vout_thread_t * p_vout = NULL;
-
- if( InitThread( p_intf ) < 0 )
- {
- msg_Err( p_intf, "can't initialize CMML interface" );
- return NULL;
- }
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "CMML intf initialized" );
-#endif
-
- /* Main loop */
- while( vlc_object_alive (p_intf) )
- {
- /* if video output is dying, disassociate ourselves from it */
- if( p_vout && !vlc_object_alive (p_vout) )
- {
- var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
- vlc_object_release( p_vout );
- p_vout = NULL;
- }
-
- /* find a video output if we currently don't have one */
- if( p_vout == NULL )
- {
- p_vout = vlc_object_find( p_intf->p_input,
- VLC_OBJECT_VOUT, FIND_CHILD );
- if( p_vout )
- {
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "found vout thread" );
-#endif
- var_AddCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
- }
- }
-
- vlc_mutex_lock( &p_intf->lock );
-
- /*
- * keyboard event
- */
- switch( p_intf->i_key_action )
- {
- case ACTIONID_NAV_ACTIVATE:
- FollowAnchor( p_intf );
- break;
- case ACTIONID_HISTORY_BACK:
- GoBack( p_intf );
- break;
- case ACTIONID_HISTORY_FORWARD:
- GoForward( p_intf );
- break;
- default:
- break;
- }
- p_intf->i_key_action = 0;
- vlc_mutex_unlock( &p_intf->lock );
-
- (void) DisplayPendingAnchor( p_intf, p_vout );
-
- /* Wait a bit */
- msleep( INTF_IDLE_SLEEP );
- }
-
- /* if we're here, the video output is dying: release the vout object */
-
- if( p_vout )
- {
- var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
- vlc_object_release( p_vout );
- }
-
- vlc_object_release( p_intf->p_input );
- vlc_restorecancel( canc );
- return NULL;
-}
-
-/*****************************************************************************
- * 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;
-
- vlc_value_t val;
-
- p_cmml_decoder = p_intf->p_cmml_decoder;
- if( var_Get( p_cmml_decoder, "psz-current-anchor-description", &val )
- != VLC_SUCCESS )
- {
- return true;
- }
-
- if( !val.p_address )
- return 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 )
- {
- /* display anchor as subtitle on-screen */
- if( DisplayAnchor( p_intf, p_vout, psz_description, psz_url )
- != VLC_SUCCESS )
- {
- /* text render unsuccessful: do nothing */
- return 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 true;
-}
-
-
-/*****************************************************************************
- * InitThread:
- *****************************************************************************/
-static int InitThread( intf_thread_t * p_intf )
-{
- /* We might need some locking here */
- if( vlc_object_alive (p_intf) )
- {
- input_thread_t * p_input;
- decoder_t *p_cmml_decoder;
-
- p_cmml_decoder = vlc_object_find( p_intf, VLC_OBJECT_DECODER, FIND_PARENT );
- p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "cmml decoder at %p, input thread at %p",
- p_cmml_decoder, p_input );
-#endif
-
- /* Maybe the input just died */
- if( p_input == NULL )
- {
- return VLC_EGENERIC;
- }
-
- vlc_mutex_lock( &p_intf->lock );
-
- p_intf->p_input = p_input;
- p_intf->p_cmml_decoder = p_cmml_decoder;
-
- p_intf->i_key_action = 0;
-
- vlc_mutex_unlock( &p_intf->lock );
-
- return VLC_SUCCESS;
- }
- else
- {
- return VLC_EGENERIC;
- }
-}
-
-/*****************************************************************************
- * MouseEvent: callback for mouse events
- *****************************************************************************/
-static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
- VLC_UNUSED(oldval); VLC_UNUSED(newval);
- VLC_UNUSED(p_data);
- /* TODO: handle mouse clicks on the anchor text */
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * KeyEvent: callback for keyboard events
- *****************************************************************************/
-static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
- VLC_UNUSED(oldval); VLC_UNUSED(newval);
- intf_thread_t *p_intf = (intf_thread_t *)p_data;
-
-
- vlc_mutex_lock( &p_intf->lock );
- /* FIXME: key presses might get lost here... */
- p_intf->i_key_action = newval.i_int;
-
- vlc_mutex_unlock( &p_intf->lock );
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * FollowAnchor: follow the current anchor being displayed to the user
- *****************************************************************************/
-static void FollowAnchor ( intf_thread_t *p_intf )
-{
- decoder_t *p_cmml_decoder;
- char *psz_url = NULL;
- vlc_value_t val;
-
- msg_Dbg( p_intf, "User followed anchor" );
-
- p_cmml_decoder = p_intf->p_cmml_decoder;
-
- if( var_Get( p_cmml_decoder, "psz-current-anchor-url", &val ) ==
- VLC_SUCCESS )
- {
- if( val.p_address ) psz_url = val.p_address;
- }
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "Current URL is \"%s\"", psz_url );
-#endif
-
- if( psz_url )
- {
- playlist_t *p_playlist;
- playlist_item_t *p_current_item;
- char *psz_uri_to_load;
- mtime_t i_seconds;
- vlc_value_t time;
-
- p_playlist = pl_Hold( p_intf );
-
- /* Get new URL */
- p_current_item = playlist_CurrentPlayingItem( p_playlist );
- char *psz_uri = input_item_GetURI( p_current_item->p_input );
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "Current playlist item URL is \"%s\"", psz_uri );
-#endif
-
- psz_uri_to_load = XURL_Concat( psz_uri, psz_url );
- free( psz_uri );
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "URL to load is \"%s\"", psz_uri_to_load );
-#endif
-
- if( var_Get( p_intf->p_input, "time", &time ) )
- {
- msg_Dbg( p_intf, "couldn't get time from current clip" );
- time.i_time = 0;
- }
- i_seconds = time.i_time / 1000000;
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "Current time is \"%lld\"", i_seconds );
-#endif
-
- /* TODO: we need a (much) more robust way of detecting whether
- * the file's a media file ... */
- if( strstr( psz_uri_to_load, ".anx" ) != NULL )
- {
- history_t *p_history = NULL;
- history_item_t *p_history_item = NULL;
- char *psz_timed_url;
-
- p_history = GetHistory( p_playlist );
-
- /* create history item */
- psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item );
- p_history_item = historyItem_New( psz_timed_url, psz_timed_url );
- free( psz_timed_url );
-
- if( !p_history_item )
- {
- msg_Warn( p_intf, "could not initialise history item" );
- }
- else
- {
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "history pre-index %d", p_history->i_index );
-#endif
- history_PruneAndInsert( p_history, p_history_item );
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "new history item at %p, uri is \"%s\"",
- p_history_item, p_history_item->psz_uri );
- msg_Dbg( p_intf, "history index now %d", p_history->i_index );
-#endif
- }
-
- /* free current-anchor-url */
- free( psz_url );
- val.p_address = NULL;
- if( var_Set( p_cmml_decoder, "psz-current-anchor-url", val ) !=
- VLC_SUCCESS )
- {
- msg_Dbg( p_intf, "couldn't reset psz-current-anchor-url" );
- }
-
- ReplacePlaylistItem( p_playlist, psz_uri_to_load );
- }
- else
- {
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "calling browser_Open with \"%s\"", psz_url );
-#endif
- (void) browser_Open( psz_url );
- playlist_Control( p_playlist, PLAYLIST_PAUSE, pl_Unlocked, 0 );
- }
-
- free( psz_uri_to_load );
-
- pl_Release( p_intf );
- }
-}
-
-static
-char *GetTimedURLFromPlaylistItem( intf_thread_t *p_intf,
- playlist_item_t *p_current_item )
-{
-#ifdef CMML_INTF_USE_TIMED_URIS
- char *psz_url = NULL;
- char *psz_return_value = NULL;
- char *psz_seconds = NULL;
- int i_seconds;
-
- char *psz_uri = input_item_GetURI( p_current_item->p_input );
- psz_url = XURL_GetWithoutFragment( psz_uri );
- free( psz_uri );
-
- /* Get current time as a string */
- if( XURL_IsFileURL( psz_url ) == true )
- psz_url = xstrcat( psz_url, "#" );
- else
- psz_url = xstrcat( psz_url, "?" );
-
- /* jump back to 2 seconds before where we are now */
- i_seconds = GetCurrentTimeInSeconds( p_intf->p_input ) - 2;
- psz_seconds = GetTimedURIFragmentForTime( i_seconds < 0 ? 0 : i_seconds );
- if( psz_seconds )
- {
- psz_url = xstrcat( psz_url, psz_seconds );
- free( psz_seconds );
- psz_return_value = psz_url;
- }
-
- return psz_return_value;
-#else
- VLC_UNUSED(p_intf);
-
- return input_item_GetURI( p_current_item->p_input );
-#endif
-}
-
-
-
-#ifdef CMML_INTF_USE_TIMED_URIS
-/*
- * Get the current time, rounded down to the nearest second
- *
- * http://www.ietf.org/internet-drafts/draft-pfeiffer-temporal-fragments-02.txt
- */
-static
-int GetCurrentTimeInSeconds( input_thread_t *p_input )
-{
- vlc_value_t time;
- mtime_t i_seconds;
-
- var_Get( p_input, "time", &time );
- i_seconds = time.i_time / 1000000;
- return i_seconds;
-}
-
-static
-char *GetTimedURIFragmentForTime( int seconds )
-{
- char *psz_time;
-
- if( asprintf( &psz_time, "%d", seconds ) == -1 )
- return NULL;
- return psz_time;
-}
-#endif
-
-static
-int GoBackCallback( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
- VLC_UNUSED(oldval); VLC_UNUSED(newval);
- 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 )
-{
- VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
- VLC_UNUSED(oldval); VLC_UNUSED(newval);
- 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 )
-{
- VLC_UNUSED(p_this); VLC_UNUSED(psz_var);
- VLC_UNUSED(oldval); VLC_UNUSED(newval);
- intf_thread_t *p_intf = (intf_thread_t *) p_data;
- FollowAnchor( p_intf );
- return VLC_SUCCESS;
-}
-
-static
-void GoBack( intf_thread_t *p_intf )
-{
- vlc_value_t history;
- history_t *p_history = NULL;
- history_item_t *p_history_item = NULL;
- history_item_t *p_new_history_item = NULL;
- playlist_t *p_playlist = NULL;
- char *psz_timed_url = NULL;
- playlist_item_t *p_current_item;
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "Going back in navigation history" );
-#endif
-
- /* Find the playlist */
- p_playlist = pl_Hold( p_intf );
-
- /* Retrieve navigation history from playlist */
- if( var_Get( p_playlist, "navigation-history", &history ) != VLC_SUCCESS ||
- !history.p_address )
- {
- /* History doesn't exist yet: ignore user's request */
- msg_Warn( p_intf, "can't go back: no history exists yet" );
- pl_Release( p_intf );
- return;
- }
-
- p_history = history.p_address;
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "back: nav history retrieved from %p", p_history );
- msg_Dbg( p_intf, "nav history index:%d, p_xarray:%p", p_history->i_index,
- p_history->p_xarray );
-#endif
-
- /* Check whether we can go back in the history */
- if( history_CanGoBack( p_history ) == false )
- {
- msg_Warn( p_intf, "can't go back: already at beginning of history" );
- pl_Release( p_intf );
- return;
- }
-
- p_current_item = playlist_CurrentPlayingItem( p_playlist );
-
- /* Save the currently-playing media in a new history item */
- psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item );
- p_new_history_item = historyItem_New( psz_timed_url, psz_timed_url );
- free( psz_timed_url );
-
- if( !p_new_history_item )
- {
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "back: could not initialise new history item" );
-#endif
- pl_Release( p_intf );
- return;
- }
-
- /* Go back in the history, saving the currently-playing item */
- (void) history_GoBackSavingCurrentItem( p_history, p_new_history_item );
- p_history_item = history_Item( p_history );
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "retrieving item from h index %d", p_history->i_index );
- msg_Dbg( p_intf, "got previous history item: %p", p_history_item );
- msg_Dbg( p_intf, "prev history item URL: \"%s\"", p_history_item->psz_uri );
-#endif
-
- ReplacePlaylistItem( p_playlist, p_history_item->psz_uri );
- pl_Release( p_intf );
-}
-
-static
-void GoForward( intf_thread_t *p_intf )
-{
- vlc_value_t history;
- history_t *p_history = NULL;
- history_item_t *p_history_item = NULL;
- history_item_t *p_new_history_item = NULL;
- playlist_t *p_playlist = NULL;
- playlist_item_t *p_current_item;
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "Going forward in navigation history" );
-#endif
-
- /* Find the playlist */
- p_playlist = pl_Hold( p_intf );
-
- /* Retrieve navigation history from playlist */
- if( var_Get( p_playlist, "navigation-history", &history ) != VLC_SUCCESS ||
- !history.p_address )
- {
- /* History doesn't exist yet: ignore user's request */
- msg_Warn( p_intf, "can't go back: no history exists yet" );
- pl_Release( p_intf );
- return;
- }
-
- p_history = history.p_address;
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "forward: nav history retrieved from %p", p_history );
- msg_Dbg( p_intf, "nav history index:%d, p_xarray:%p", p_history->i_index,
- p_history->p_xarray );
-#endif
-
- /* Check whether we can go forward in the history */
- if( history_CanGoForward( p_history ) == false )
- {
- msg_Warn( p_intf, "can't go forward: already at end of history" );
- pl_Release( p_intf );
- return;
- }
-
- /* Save the currently-playing media in a new history item */
- p_new_history_item = malloc( sizeof(history_item_t) );
- if( !p_new_history_item )
- {
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "forward: could not initialise new history item" );
-#endif
- pl_Release( p_intf );
- return;
- }
- p_current_item = playlist_CurrentPlayingItem( p_playlist );
- p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf,
- p_current_item );
- p_new_history_item->psz_name = p_new_history_item->psz_uri;
-
- /* Go forward in the history, saving the currently-playing item */
- (void) history_GoForwardSavingCurrentItem( p_history, p_new_history_item );
- p_history_item = history_Item( p_history );
-
-#ifdef CMML_INTF_DEBUG
- msg_Dbg( p_intf, "retrieving item from h index %d", p_history->i_index );
- msg_Dbg( p_intf, "got next history item: %p", p_history_item );
- msg_Dbg( p_intf, "next history item URL: \"%s\"", p_history_item->psz_uri );
-#endif
-
- ReplacePlaylistItem( p_playlist, p_history_item->psz_uri );
- pl_Release( p_intf );
-}
-
-static void ReplacePlaylistItem( playlist_t *p_playlist, char *psz_uri )
-{
- playlist_Stop( p_playlist );
- (void) playlist_Add( p_playlist, psz_uri, psz_uri,
- PLAYLIST_INSERT /* FIXME: used to be PLAYLIST_REPLACE */, PLAYLIST_END|PLAYLIST_GO, true /* FIXME: p_playlist->status.i_index */,
- false);
-}
-
-/****************************************************************************
- * DisplayAnchor: displays an anchor on the given video output
- ****************************************************************************/
-static int DisplayAnchor( intf_thread_t *p_intf,
- vout_thread_t *p_vout,
- char *psz_anchor_description,
- char *psz_anchor_url )
-{
- int i_margin_h, i_margin_v;
- mtime_t i_now;
-
- i_margin_h = 0;
- i_margin_v = 10;
-
- i_now = mdate();
-
- if( p_vout )
- {
- if( psz_anchor_url )
- {
- /* Should display subtitle underlined and in blue, but it looks
- * like VLC doesn't implement any text styles yet. D'oh! */
- // p_style = &blue_with_underline;
-
- }
-
- /* 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, DEFAULT_CHAN,
- psz_anchor_description, NULL, OSD_ALIGN_BOTTOM,
- i_margin_h, i_margin_v, i_now, 0 ) == VLC_SUCCESS )
- {
- /* Displayed successfully */
- }
- else
- {
- return VLC_EGENERIC;
- }
- }
- else
- {
- msg_Dbg( p_intf, "DisplayAnchor couldn't find a video output" );
- return VLC_EGENERIC;
- }
-
- return VLC_SUCCESS;
-}
-
-static history_t * GetHistory( playlist_t *p_playlist )
-{
- vlc_value_t val;
- history_t *p_history = NULL;
-
- if( var_Get( p_playlist, "navigation-history", &val ) != VLC_SUCCESS )
- {
- /* history doesn't exist yet: need to create it */
- history_t *new_history = history_New();
- val.p_address = new_history;
- var_Create( p_playlist, "navigation-history",
- VLC_VAR_ADDRESS|VLC_VAR_DOINHERIT );
- if( var_Set( p_playlist, "navigation-history", val ) != VLC_SUCCESS )
- {
- msg_Warn( p_playlist, "could not initialise history" );
- }
- else
- {
- p_history = new_history;
-#ifdef CMML_INTF_HISTORY_DEBUG
- msg_Dbg( p_playlist, "nav history created at %p", new_history );
- msg_Dbg( p_playlist, "nav history index:%d, p_xarray:%p",
- p_history->i_index, p_history->p_xarray );
-#endif
- }
- }
- else
- {
- p_history = val.p_address;
-#ifdef CMML_INTF_HISTORY_DEBUG
- msg_Dbg( p_playlist, "nav history retrieved from %p", p_history );
-#endif
- }
-
- return p_history;
-}
-
+++ /dev/null
-/*************************************************************************
- * xarray.c: Mutable (dynamically growable) array
- *************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- ************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include "xarray.h"
-
-#include <vlc_memory.h>
-
-/* local prototypes */
-XArray * xarray_New (unsigned int);
-
-
-#define XARRAY_ASSERT_NOT_NULL(xarray) \
- { \
- if (xarray == NULL) return XARRAY_ENULLPOINTER; \
- }
-
-#define XARRAY_BOUNDS_CHECK(xarray, index) \
- { \
- if (xarray->last_valid_element != -1 && \
- (int) index > xarray->last_valid_element) \
- return XARRAY_EINDEXTOOLARGE; \
- }
-
-#define XARRAY_GROW_ARRAY(xarray) \
- { \
- xarray->array = realloc_or_free (xarray->array, xarray->size * 2); \
- if (xarray->array == NULL) return XARRAY_ENOMEM; \
- }
-
-XArray * xarray_New (unsigned int initial_size_hint)
-{
- XArray *new_xarray = NULL;
- void *inner_array;
- unsigned int initial_size;
-
- new_xarray = (XArray *) malloc (sizeof(XArray));
- if (new_xarray == NULL) return NULL;
-
- if (initial_size_hint == 0)
- initial_size = XARRAY_DEFAULT_SIZE;
- else
- initial_size = initial_size_hint;
-
- inner_array = calloc (initial_size, sizeof(void *));
-
- new_xarray->last_valid_element = -1;
- new_xarray->size = initial_size;
- new_xarray->last_error = 0;
-
- if (inner_array == NULL)
- {
- free (new_xarray);
- return NULL;
- }
-
- new_xarray->array = inner_array;
-
- return new_xarray;
-}
-
-int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
- void **out_object)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
- XARRAY_BOUNDS_CHECK (xarray, index);
-
- *out_object = xarray->array[index];
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_AddObject (XArray *xarray, void *object)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
-
- ++xarray->last_valid_element;
- if (xarray->last_valid_element >= (int) xarray->size)
- {
- XARRAY_GROW_ARRAY (xarray);
- }
-
- xarray->array[xarray->last_valid_element] = object;
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_InsertObject (XArray *xarray, void *object,
- unsigned int at_index)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
- ++xarray->last_valid_element;
- XARRAY_BOUNDS_CHECK (xarray, at_index);
- if (xarray->last_valid_element >= (int) xarray->size)
- {
- XARRAY_GROW_ARRAY (xarray);
- }
-
- /* Shift everything from a[i] onward one pointer forward */
-
- if ((int) at_index < xarray->last_valid_element)
- {
- (void) memmove (&xarray->array[at_index + 1],
- &xarray->array[at_index],
- (xarray->last_valid_element - at_index) *
- sizeof(void *));
- }
-
- xarray->array[at_index] = object;
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_RemoveLastObject (XArray *xarray)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
-
- if (xarray->last_valid_element == -1)
- return XARRAY_EEMPTYARRAY;
-
- xarray->array[xarray->last_valid_element] = NULL;
- --xarray->last_valid_element;
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
- XARRAY_BOUNDS_CHECK (xarray, at_index);
-
- /* Shift everything from a[i] onward one pointer backward */
-
- if ((int) at_index < xarray->last_valid_element)
- {
- (void) memmove (&xarray->array[at_index],
- &xarray->array[at_index + 1],
- (xarray->last_valid_element - at_index) *
- sizeof(void *));
- }
-
- xarray->array[xarray->last_valid_element] = NULL;
- --xarray->last_valid_element;
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
- int count)
-{
- int i;
-
- XARRAY_ASSERT_NOT_NULL (xarray);
- XARRAY_BOUNDS_CHECK (xarray, at_index);
-
- if (count == 0) return XARRAY_SUCCESS;
-
- if ((int) at_index + (count - 1) > xarray->last_valid_element)
- return XARRAY_ECOUNTOUTOFBOUNDS;
-
- for (i = 0; i < count; i++)
- {
- int e = xarray_RemoveObject (xarray, at_index);
- if (e != XARRAY_SUCCESS) return e;
- }
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
- XARRAY_BOUNDS_CHECK (xarray, index);
-
- index++;
-
- while ((int) index <= xarray->last_valid_element)
- {
- int e = xarray_RemoveObject (xarray, index);
- if (e != XARRAY_SUCCESS) return e;
- }
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_ReplaceObject (XArray *xarray, unsigned int index,
- void *new_object)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
- XARRAY_BOUNDS_CHECK (xarray, index);
-
- xarray->array[index] = new_object;
-
- return XARRAY_SUCCESS;
-}
-
-int xarray_Count (XArray *xarray, unsigned int *out_count)
-{
- XARRAY_ASSERT_NOT_NULL (xarray);
-
- *out_count = xarray->last_valid_element + 1;
-
- return XARRAY_SUCCESS;
-}
-
-
-#undef XARRAY_ASSERT_NOT_NULL
-#undef XARRAY_BOUNDS_CHECK
-#undef XARRAY_GROW_ARRAY
-
+++ /dev/null
-/*************************************************************************
- * xarray.h: Mutable (dynamically growable) array (header file)
- *************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- ************************************************************************/
-
-#ifndef __XARRAY_H__
-#define __XARRAY_H__
-
-#define XARRAY_DEFAULT_SIZE 69
-
-/* Error codes */
-enum xarray_errors
-{
- XARRAY_SUCCESS, XARRAY_ENULLPOINTER, XARRAY_ENEGATIVEINDEX,
- XARRAY_EINDEXTOOLARGE, XARRAY_ENOMEM, XARRAY_EEMPTYARRAY,
- XARRAY_ECOUNTOUTOFBOUNDS
-};
-
-
-typedef struct
-{
- void **array;
- int last_valid_element;
- unsigned int size;
- unsigned int last_error;
-}
-XArray;
-
-/* Mutable methods */
-int xarray_AddObject (XArray *xarray, void *object);
-int xarray_InsertObject (XArray *xarray, void *object,
- unsigned int at_index);
-int xarray_RemoveLastObject (XArray *xarray);
-int xarray_RemoveObject (XArray *xarray, unsigned int at_index);
-int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
- int count);
-int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index);
-int xarray_ReplaceObject (XArray *xarray, unsigned int index,
- void *new_object);
-
-/* Immutable methods */
-XArray * xarray_New ();
-int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
- void **out_object);
-int xarray_Count (XArray *xarray, unsigned int *out_count);
-
-#endif /* __XARRAY_H__ */
-
+++ /dev/null
-/*****************************************************************************
- * xlist.c : a simple doubly linked list in C
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2000-2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Conrad Parker <Conrad.Parker@csiro.au>
- * Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-
-#include "xlist.h"
-
-static XList *
-xlist_node_new (void * data)
-{
- XList * l;
-
- l = (XList *) malloc (sizeof (XList));
- l->prev = l->next = NULL;
- l->data = data;
-
- return l;
-}
-
-XList *
-xlist_new (void)
-{
- return NULL;
-}
-
-XList *
-xlist_clone (XList * list)
-{
- XList * l, * new_list;
-
- if (list == NULL) return NULL;
- new_list = xlist_new ();
-
- for (l = list; l; l = l->next) {
- new_list = xlist_append (new_list, l->data);
- }
-
- return new_list;
-}
-
-XList *
-xlist_clone_with (XList * list, XCloneFunc clone)
-{
- XList * l, * new_list;
- void * new_data;
-
- if (list == NULL) return NULL;
- if (clone == NULL) return xlist_clone (list);
-
- new_list = xlist_new ();
-
- for (l = list; l; l = l->next) {
- new_data = clone (l->data);
- new_list = xlist_append (new_list, new_data);
- }
-
- return new_list;
-}
-
-
-XList *
-xlist_tail (XList * list)
-{
- XList * l;
- for (l = list; l; l = l->next)
- if (l->next == NULL) return l;
- return NULL;
-}
-
-XList *
-xlist_prepend (XList * list, void * data)
-{
- XList * l = xlist_node_new (data);
-
- if (list == NULL) return l;
-
- l->next = list;
- list->prev = l;
-
- return l;
-}
-
-XList *
-xlist_append (XList * list, void * data)
-{
- XList * l = xlist_node_new (data);
- XList * last;
-
- if (list == NULL) return l;
-
- last = xlist_tail (list);
- last->next = l;
- l->prev = last;
- return list;
-}
-
-XList *
-xlist_add_before (XList * list, void * data, XList * node)
-{
- XList * l, * p;
-
- if (list == NULL) return xlist_node_new (data);
- if (node == NULL) return xlist_append (list, data);
- if (node == list) return xlist_prepend (list, data);
-
- l = xlist_node_new (data);
- p = node->prev;
-
- l->prev = p;
- l->next = node;
- if (p) p->next = l;
- node->prev = l;
-
- return list;
-}
-
-XList *
-xlist_add_after (XList * list, void * data, XList * node)
-{
- XList * l, * n;
-
- if (node == NULL) return xlist_prepend (list, data);
-
- l = xlist_node_new (data);
- n = node->next;
-
- l->prev = node;
- l->next = n;
- if (n) n->prev = l;
- node->next = l;
-
- return list;
-}
-
-XList *
-xlist_find (XList * list, void * data)
-{
- XList * l;
-
- for (l = list; l; l = l->next)
- if (l->data == data) return l;
-
- return NULL;
-}
-
-XList *
-xlist_remove (XList * list, XList * node)
-{
- if (node == NULL) return list;
-
- if (node->prev) node->prev->next = node->next;
- if (node->next) node->next->prev = node->prev;
-
- if (node == list) return list->next;
- else return list;
-}
-
-int
-xlist_length (XList * list)
-{
- XList * l;
- int c = 0;
-
- for (l = list; l; l = l->next)
- c++;
-
- return c;
-}
-
-int
-xlist_is_empty (XList * list)
-{
- return (list == NULL);
-}
-
-int
-xlist_is_singleton (XList * list)
-{
- if (list == NULL) return 0;
- if (list->next == NULL) return 1;
- else return 0;
-}
-
-/*
- * xlist_free_with (list, free_func)
- *
- * Step through list 'list', freeing each node using free_func(), and
- * also free the list structure itself.
- */
-XList *
-xlist_free_with (XList * list, XFreeFunc free_func)
-{
- XList * l, * ln;
-
- for (l = list; l; l = ln) {
- ln = l->next;
- free_func (l->data);
- free (l);
- }
-
- return NULL;
-}
-
-/*
- * xlist_free (list)
- *
- * Free the list structure 'list', but not its nodes.
- */
-XList *
-xlist_free (XList * list)
-{
- XList * l, * ln;
-
- for (l = list; l; l = ln) {
- ln = l->next;
- free (l);
- }
-
- return NULL;
-}
-
+++ /dev/null
-/*****************************************************************************
- * xlist.h : a simple doubly linked list in C (header file)
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2000-2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Conrad Parker <Conrad.Parker@csiro.au>
- * Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-
-#ifndef __XLIST__
-#define __XLIST__
-
-/**
- * A doubly linked list
- */
-typedef struct _XList XList;
-
-struct _XList {
- XList * prev;
- XList * next;
- void * data;
-};
-
-/**
- * Signature of a cloning function.
- */
-typedef void * (*XCloneFunc) (void * data);
-
-/**
- * Signature of a freeing function.
- */
-typedef void * (*XFreeFunc) (void * data);
-
-/** Create a new list
- * \return a new list
- */
-XList * xlist_new (void);
-
-/**
- * Clone a list using the default clone function
- * \param list the list to clone
- * \returns a newly cloned list
- */
-XList * xlist_clone (XList * list);
-
-/**
- * Clone a list using a custom clone function
- * \param list the list to clone
- * \param clone the function to use to clone a list item
- * \returns a newly cloned list
- */
-XList * xlist_clone_with (XList * list, XCloneFunc clone);
-
-/**
- * Return the tail element of a list
- * \param list the list
- * \returns the tail element
- */
-XList * xlist_tail (XList * list);
-
-/**
- * Prepend a new node to a list containing given data
- * \param list the list
- * \param data the data element of the newly created node
- * \returns the new list head
- */
-XList * xlist_prepend (XList * list, void * data);
-
-/**
- * Append a new node to a list containing given data
- * \param list the list
- * \param data the data element of the newly created node
- * \returns the head of the list
- */
-XList * xlist_append (XList * list, void * data);
-
-/**
- * Add a new node containing given data before a given node
- * \param list the list
- * \param data the data element of the newly created node
- * \param node the node before which to add the newly created node
- * \returns the head of the list (which may have changed)
- */
-XList * xlist_add_before (XList * list, void * data, XList * node);
-
-/**
- * Add a new node containing given data after a given node
- * \param list the list
- * \param data the data element of the newly created node
- * \param node the node after which to add the newly created node
- * \returns the head of the list
- */
-XList * xlist_add_after (XList * list, void * data, XList * node);
-
-/**
- * Find the first node containing given data in a list
- * \param list the list
- * \param data the data element to find
- * \returns the first node containing given data, or NULL if it is not found
- */
-XList * xlist_find (XList * list, void * data);
-
-/**
- * Remove a node from a list
- * \param list the list
- * \param node the node to remove
- * \returns the head of the list (which may have changed)
- */
-XList * xlist_remove (XList * list, XList * node);
-
-/**
- * Query the number of items in a list
- * \param list the list
- * \returns the number of nodes in the list
- */
-int xlist_length (XList * list);
-
-/**
- * Query if a list is empty, ie. contains no items
- * \param list the list
- * \returns 1 if the list is empty, 0 otherwise
- */
-int xlist_is_empty (XList * list);
-
-/**
- * Query if the list is singleton, ie. contains exactly one item
- * \param list the list
- * \returns 1 if the list is singleton, 0 otherwise
- */
-int xlist_is_singleton (XList * list);
-
-/**
- * Free a list, using a given function to free each data element
- * \param list the list
- * \param free_func a function to free each data element
- * \returns NULL on success
- */
-XList * xlist_free_with (XList * list, XFreeFunc free_func);
-
-/**
- * Free a list, using anx_free() to free each data element
- * \param list the list
- * \returns NULL on success
- */
-XList * xlist_free (XList * list);
-
-#endif /* __XLIST__ */
-
-
+++ /dev/null
-/*****************************************************************************
- * xstrcat.h: strcat with realloc
- *****************************************************************************
- * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __XSTRCAT_H__
-#define __XSTRCAT_H__
-# include <string.h>
-# include <stdlib.h>
-
-/* like strcat, but realloc's enough memory for the new string too */
-
-static inline
-char *xstrcat( char *psz_string, const char *psz_to_append )
-{
- size_t i_new_string_length = strlen( psz_string ) +
- strlen( psz_to_append ) + 1;
-
- psz_string = (char *) realloc( psz_string, i_new_string_length );
-
- return strcat( psz_string, psz_to_append );
-}
-
-#endif /* __XSTRCAT_H__ */
-
+++ /dev/null
-/*****************************************************************************
- * xlist.c : a trivial parser for XML-like tags
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2000-2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Conrad Parker <Conrad.Parker@csiro.au>
- * Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "xlist.h"
-
-#include <assert.h>
-
-#undef XTAG_DEBUG
-
-#undef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-
-#undef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-
-typedef struct _XTag XTag;
-typedef struct _XAttribute XAttribute;
-typedef struct _XTagParser XTagParser;
-
-/*
- * struct _XTag is kind of a union ... it normally represents a whole
- * tag (and its children), but it could alternatively represent some
- * PCDATA. Basically, if tag->pcdata is non-NULL, interpret only it and
- * ignore the name, attributes and inner_tags.
- */
-struct _XTag {
- char * name;
- char * pcdata;
- XTag * parent;
- XList * attributes;
- XList * children;
- XList * current_child;
-};
-
-struct _XAttribute {
- char * name;
- char * value;
-};
-
-struct _XTagParser {
- int valid; /* boolean */
- XTag * current_tag;
- char * start;
- char * end;
-};
-
-void xtag_free (XTag * xtag);
-XTag * xtag_new_parse (const char * s, int n);
-char * xtag_get_name (XTag * xtag);
-char * xtag_get_pcdata (XTag * xtag);
-char * xtag_get_attribute (XTag * xtag, const char* attribute);
-XTag * xtag_first_child (XTag * xtag, const char * name);
-XTag * xtag_next_child (XTag * xtag, char * name);
-int xtag_snprint (char * buf, int n, XTag * xtag);
-
-/* Character classes */
-#define X_NONE 0
-#define X_WHITESPACE 1<<0
-#define X_OPENTAG 1<<1
-#define X_CLOSETAG 1<<2
-#define X_DQUOTE 1<<3
-#define X_SQUOTE 1<<4
-#define X_EQUAL 1<<5
-#define X_SLASH 1<<6
-
-static int
-xtag_cin (char c, int char_class)
-{
- if (char_class & X_WHITESPACE)
- if (isspace(c)) return true;
-
- if (char_class & X_OPENTAG)
- if (c == '<') return true;
-
- if (char_class & X_CLOSETAG)
- if (c == '>') return true;
-
- if (char_class & X_DQUOTE)
- if (c == '"') return true;
-
- if (char_class & X_SQUOTE)
- if (c == '\'') return true;
-
- if (char_class & X_EQUAL)
- if (c == '=') return true;
-
- if (char_class & X_SLASH)
- if (c == '/') return true;
-
- return false;
-}
-
-static int
-xtag_index (XTagParser * parser, int char_class)
-{
- char * s;
- int i;
-
- s = parser->start;
-
- for (i = 0; s[i] && s != parser->end; i++) {
- if (xtag_cin(s[i], char_class)) return i;
- }
-
- return -1;
-}
-
-static void
-xtag_skip_over (XTagParser * parser, int char_class)
-{
- char * s;
- int i;
-
- if (!parser->valid) return;
-
- s = (char *)parser->start;
-
- for (i = 0; s[i] && s != parser->end; i++) {
- if (!xtag_cin(s[i], char_class)) {
- parser->start = &s[i];
- return;
- }
- }
-
- return;
-}
-
-static void
-xtag_skip_whitespace (XTagParser * parser)
-{
- xtag_skip_over (parser, X_WHITESPACE);
-}
-
-#if 0
-static void
-xtag_skip_to (XTagParser * parser, int char_class)
-{
- char * s;
- int i;
-
- if (!parser->valid) return;
-
- s = (char *)parser->start;
-
- for (i = 0; s[i] && s != parser->end; i++) {
- if (xtag_cin(s[i], char_class)) {
- parser->start = &s[i];
- return;
- }
- }
-
- return;
-}
-#endif
-
-static char *
-xtag_slurp_to (XTagParser * parser, int good_end, int bad_end)
-{
- char * s, * ret;
- int xi;
-
- if (!parser->valid) return NULL;
-
- s = parser->start;
-
- xi = xtag_index (parser, good_end | bad_end);
-
- if (xi > 0 && xtag_cin (s[xi], good_end)) {
- ret = malloc (xi+1);
- strncpy (ret, s, xi);
- ret[xi] = '\0';
- parser->start = &s[xi];
- return ret;
- }
-
- return NULL;
-}
-
-static int
-xtag_assert_and_pass (XTagParser * parser, int char_class)
-{
- char * s;
-
- if (!parser->valid) return false;
-
- s = parser->start;
-
- if (!xtag_cin (s[0], char_class)) {
- parser->valid = false;
- return false;
- }
-
- parser->start = &s[1];
-
- return true;
-}
-
-static char *
-xtag_slurp_quoted (XTagParser * parser)
-{
- char * s, * ret;
- int quote = X_DQUOTE; /* quote char to match on */
- int xi;
-
- if (!parser->valid) return NULL;
-
- xtag_skip_whitespace (parser);
-
- s = parser->start;
-
- if (xtag_cin (s[0], X_SQUOTE)) quote = X_SQUOTE;
-
- if (!xtag_assert_and_pass (parser, quote)) return NULL;
-
- s = parser->start;
-
- for (xi = 0; s[xi]; xi++) {
- if (xtag_cin (s[xi], quote)) {
- if (!(xi > 1 && s[xi-1] == '\\')) break;
- }
- }
-
- ret = malloc (xi+1);
- strncpy (ret, s, xi);
- ret[xi] = '\0';
- parser->start = &s[xi];
-
- if (!xtag_assert_and_pass (parser, quote))
- {
- free( ret );
- return NULL;
- }
-
- return ret;
-}
-
-static XAttribute *
-xtag_parse_attribute (XTagParser * parser)
-{
- XAttribute * attr;
- char * name, * value;
- char * s;
-
- if (!parser->valid) return NULL;
-
- xtag_skip_whitespace (parser);
-
- name = xtag_slurp_to (parser, X_WHITESPACE | X_EQUAL, X_SLASH | X_CLOSETAG);
-
- if (name == NULL) return NULL;
-
- xtag_skip_whitespace (parser);
- s = parser->start;
-
- if (!xtag_assert_and_pass (parser, X_EQUAL)) {
-#ifdef XTAG_DEBUG
- printf ("xtag: attr failed EQUAL on <%s>\n", name);
-#endif
- goto err_free_name;
- }
-
- xtag_skip_whitespace (parser);
-
- value = xtag_slurp_quoted (parser);
-
- if (value == NULL) {
-#ifdef XTAG_DEBUG
- printf ("Got NULL quoted attribute value\n");
-#endif
- goto err_free_name;
- }
-
- attr = malloc (sizeof (*attr));
- attr->name = name;
- attr->value = value;
-
- return attr;
-
- err_free_name:
- free (name);
-
- parser->valid = false;
-
- return NULL;
-}
-
-static XTag *
-xtag_parse_tag (XTagParser * parser)
-{
- XTag * tag, * inner;
- XAttribute * attr;
- char * name;
- char * pcdata;
- char * s;
-
- if (!parser->valid) return NULL;
-
- if ((pcdata = xtag_slurp_to (parser, X_OPENTAG, X_NONE)) != NULL) {
- tag = malloc (sizeof (*tag));
- tag->name = NULL;
- tag->pcdata = pcdata;
- tag->parent = parser->current_tag;
- tag->attributes = NULL;
- tag->children = NULL;
- tag->current_child = NULL;
-
- return tag;
- }
-
- s = parser->start;
-
- /* if this starts a close tag, return NULL and let the parent take it */
- if (xtag_cin (s[0], X_OPENTAG) && xtag_cin (s[1], X_SLASH))
- return NULL;
-
- if (!xtag_assert_and_pass (parser, X_OPENTAG)) return NULL;
-
- name = xtag_slurp_to (parser, X_WHITESPACE | X_SLASH | X_CLOSETAG, X_NONE);
-
- if (name == NULL) return NULL;
-
-#ifdef XTAG_DEBUG
- printf ("<%s ...\n", name);
-#endif
-
- tag = malloc (sizeof (*tag));
- tag->name = name;
- tag->pcdata = NULL;
- tag->parent = parser->current_tag;
- tag->attributes = NULL;
- tag->children = NULL;
- tag->current_child = NULL;
-
- s = parser->start;
-
- if (xtag_cin (s[0], X_WHITESPACE)) {
- while ((attr = xtag_parse_attribute (parser)) != NULL) {
- tag->attributes = xlist_append (tag->attributes, attr);
- }
- }
-
- xtag_skip_whitespace (parser);
-
- s = parser->start;
-
- if (xtag_cin (s[0], X_CLOSETAG)) {
- parser->current_tag = tag;
-
- xtag_assert_and_pass (parser, X_CLOSETAG);
-
- while ((inner = xtag_parse_tag (parser)) != NULL) {
- tag->children = xlist_append (tag->children, inner);
- }
-
- xtag_skip_whitespace (parser);
-
- xtag_assert_and_pass (parser, X_OPENTAG);
- xtag_assert_and_pass (parser, X_SLASH);
- name = xtag_slurp_to (parser, X_WHITESPACE | X_CLOSETAG, X_NONE);
- if (name) {
- if (name && tag->name && strcmp (name, tag->name)) {
-#ifdef XTAG_DEBUG
- printf ("got %s expected %s\n", name, tag->name);
-#endif
- parser->valid = false;
- }
- free (name);
- }
-
- xtag_skip_whitespace (parser);
- xtag_assert_and_pass (parser, X_CLOSETAG);
-
- } else {
- xtag_assert_and_pass (parser, X_SLASH);
- xtag_assert_and_pass (parser, X_CLOSETAG);
- }
-
-
- return tag;
-}
-
-void xtag_free (XTag * xtag)
-{
- XList * l;
- XAttribute * attr;
- XTag * child;
-
- if( !xtag )
- return;
-
- free( xtag->name );
- free( xtag->pcdata );
-
- for( l = xtag->attributes; l; l = l->next) {
- if((attr = (XAttribute *)l->data) != NULL) {
- free( attr->name );
- free( attr->value );
- free( attr );
- }
- }
- xlist_free (xtag->attributes);
-
- for (l = xtag->children; l; l = l->next) {
- child = (XTag *)l->data;
- xtag_free( child );
- }
- xlist_free (xtag->children);
-
- free( xtag );
-}
-
-XTag *
-xtag_new_parse (const char * s, int n)
-{
- XTagParser parser;
- XTag * tag, * ttag, * wrapper;
-
- parser.valid = true;
- parser.current_tag = NULL;
- parser.start = (char *)s;
-
- if (n == -1)
- parser.end = NULL;
- else if (n == 0)
- return NULL;
- else
- parser.end = (char *)&s[n];
-
- tag = xtag_parse_tag (&parser);
-
- if (!parser.valid) {
- xtag_free (tag);
- return NULL;
- }
-
- if ((ttag = xtag_parse_tag (&parser)) != NULL) {
-
- if (!parser.valid) {
- xtag_free (ttag);
- return tag;
- }
-
- wrapper = malloc (sizeof (XTag));
- wrapper->name = NULL;
- wrapper->pcdata = NULL;
- wrapper->parent = NULL;
- wrapper->attributes = NULL;
- wrapper->children = NULL;
- wrapper->current_child = NULL;
-
- wrapper->children = xlist_append (wrapper->children, tag);
- wrapper->children = xlist_append (wrapper->children, ttag);
-
- while ((ttag = xtag_parse_tag (&parser)) != NULL) {
-
- if (!parser.valid) {
- xtag_free (ttag);
- return wrapper;
- }
-
- wrapper->children = xlist_append (wrapper->children, ttag);
- }
- return wrapper;
- }
-
- return tag;
-}
-
-char *
-xtag_get_name (XTag * xtag)
-{
- return xtag ? xtag->name : NULL;
-}
-
-char *
-xtag_get_pcdata (XTag * xtag)
-{
- XList * l;
- XTag * child;
-
- if (xtag == NULL) return NULL;
-
- for (l = xtag->children; l; l = l->next) {
- child = (XTag *)l->data;
- if (child->pcdata != NULL) {
- return child->pcdata;
- }
- }
-
- return NULL;
-}
-
-char* xtag_get_attribute (XTag * xtag, const char * attribute)
-{
- XList * l;
- XAttribute * attr;
-
- if( !xtag )
- return NULL;
-
- for( l = xtag->attributes; l; l = l->next )
- {
- if( ( attr = (XAttribute *)l->data ) != NULL )
- {
- if( attr->name && attribute && !strcmp( attr->name, attribute ) )
- return attr->value;
- }
- }
- return NULL;
-}
-
-XTag* xtag_first_child (XTag * xtag, const char * name)
-{
- XList * l;
- XTag * child;
-
- if( !xtag )
- return NULL;
-
- if( ( l = xtag->children ) == NULL )
- return NULL;
-
- if( !name )
- {
- xtag->current_child = l;
- return (XTag *)l->data;
- }
-
- for( ; l; l = l->next )
- {
- child = (XTag *)l->data;
-
- if( child->name && name && !strcmp( child->name, name ) )
- {
- xtag->current_child = l;
- return child;
- }
- }
-
- xtag->current_child = NULL;
- return NULL;
-}
-
-XTag *
-xtag_next_child (XTag * xtag, char * name)
-{
- XList * l;
- XTag * child;
-
- if (xtag == NULL) return NULL;
-
- if ((l = xtag->current_child) == NULL)
- return xtag_first_child (xtag, name);
-
- if ((l = l->next) == NULL)
- return NULL;
-
- if (name == NULL) {
- xtag->current_child = l;
- return (XTag *)l->data;
- }
-
- for (; l; l = l->next) {
- child = (XTag *)l->data;
-
- if (child->name && name && !strcmp(child->name, name)) {
- xtag->current_child = l;
- return child;
- }
- }
-
- xtag->current_child = NULL;
-
- return NULL;
-}
-
-/*
- * This snprints function takes a variable list of char *, the last of
- * which must be NULL, and prints each in turn to buf.
- * Returns C99-style total length that would have been written, even if
- * this is larger than n.
- */
-static int
-xtag_snprints (char * buf, int n, ...)
-{
- va_list ap;
- char * s;
- int len, to_copy, total = 0;
-
- va_start (ap, n);
-
- for (s = va_arg (ap, char *); s; s = va_arg (ap, char *)) {
- len = strlen (s);
-
- if ((to_copy = MIN (n, len)) > 0) {
- memcpy (buf, s, to_copy);
- buf += to_copy;
- n -= to_copy;
- }
-
- total += len;
- }
-
- va_end (ap);
-
- return total;
-}
-
-int
-xtag_snprint (char * buf, int n, XTag * xtag)
-{
- int nn, written = 0;
- XList * l;
- XAttribute * attr;
- XTag * child;
-
-#define FORWARD(N) \
- buf += MIN (n, N); \
- n = MAX (n-N, 0); \
- written += N;
-
- if (xtag == NULL) {
- if (n > 0) buf[0] = '\0';
- return 0;
- }
-
- if (xtag->pcdata) {
- nn = xtag_snprints (buf, n, xtag->pcdata, NULL);
- FORWARD(nn);
-
- return written;
- }
-
- if (xtag->name) {
- nn = xtag_snprints (buf, n, "<", xtag->name, NULL);
- FORWARD(nn);
-
- for (l = xtag->attributes; l; l = l->next) {
- attr = (XAttribute *)l->data;
-
- nn = xtag_snprints (buf, n, " ", attr->name, "=\"", attr->value, "\"",
- NULL);
- FORWARD(nn);
- }
-
- if (xtag->children == NULL) {
- nn = xtag_snprints (buf, n, "/>", NULL);
- FORWARD(nn);
-
- return written;
- }
-
- nn = xtag_snprints (buf, n, ">", NULL);
- FORWARD(nn);
- }
-
- for (l = xtag->children; l; l = l->next) {
- child = (XTag *)l->data;
-
- nn = xtag_snprint (buf, n, child);
- FORWARD(nn);
- }
-
- if (xtag->name) {
- nn = xtag_snprints (buf, n, "</", xtag->name, ">", NULL);
- FORWARD(nn);
- }
-
- return written;
-}
-
+++ /dev/null
-/*****************************************************************************
- * xlist.h : a trivial parser for XML-like tags (header file)
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2000-2004 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Conrad Parker <Conrad.Parker@csiro.au>
- * Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __XTAG_H__
-#define __XTAG_H__
-
-typedef void XTag;
-
-XTag * xtag_new_parse (const char * s, int n);
-
-char * xtag_get_name (XTag * xtag);
-
-char * xtag_get_pcdata (XTag * xtag);
-
-char * xtag_get_attribute (XTag * xtag, const char * attribute);
-
-XTag * xtag_first_child (XTag * xtag, const char * name);
-
-XTag * xtag_next_child (XTag * xtag, char * name);
-
-XTag * xtag_free (XTag * xtag);
-
-int xtag_snprint (char * buf, int n, XTag * xtag);
-
-#endif /* __XTAG_H__ */
+++ /dev/null
-/*****************************************************************************
- * xurl.c: URL manipulation functions
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004-2008 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-
-#include "xurl.h"
-
-static char *streallocat( char *psz_string, const char *psz_to_append );
-
-char *XURL_FindQuery ( char *psz_url );
-static char *XURL_FindHostname ( char *psz_url );
-static char *XURL_FindPath ( char *psz_url );
-static char *XURL_FindFragment ( char *psz_url );
-
-
-char *XURL_Join( char *psz_url1, char *psz_url2 )
-{
- if( XURL_IsAbsolute( psz_url1 ) )
- return XURL_Concat( psz_url1, psz_url2 );
- else
- return XURL_Concat( psz_url2, psz_url1 );
-}
-
-/* TODO: replace XURL_Concat's rel/absolute calculation with the one
- * specified by RFC2396, and also test it on their test suite :) */
-
-
-char *XURL_Concat( char *psz_url, char *psz_append )
-{
- char *psz_return_value = NULL;
-
- if( XURL_IsAbsolute( psz_append ) )
- return strdup( psz_append );
-
- if( XURL_IsAbsolute( psz_url ) )
- {
- if( XURL_HasAbsolutePath( psz_append ) )
- {
- char *psz_concat_url;
-
- psz_concat_url = XURL_GetSchemeAndHostname( psz_url );
-
- psz_concat_url = streallocat( psz_concat_url, psz_append );
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_Concat: concat is \"%s\"\n",
- psz_concat_url );
-#endif
- psz_return_value = psz_concat_url;
- }
- else
- {
- /* psz_append is a relative URL */
- char *psz_new_url;
-
- /* strip off last path component */
- psz_new_url = XURL_GetHead( psz_url );
- psz_new_url = streallocat( psz_new_url, psz_append );
-
- psz_return_value = psz_new_url;
- }
- }
- else
- {
- /* not an absolute URL */
- if( XURL_HasAbsolutePath( psz_append ) == false )
- {
- char *psz_new_url = XURL_GetHead( psz_url );
-
- psz_new_url = streallocat( psz_new_url, psz_append );
- psz_return_value = psz_new_url;
- }
- else
- {
- /* URL to append has an absolute path -- just use that instead */
- psz_return_value = strdup( psz_append );
- }
- }
-
- return psz_return_value;
-}
-
-
-bool XURL_IsAbsolute( char *psz_url )
-{
- if( XURL_FindHostname( psz_url ) == NULL )
- {
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_IsAbsolute(%s) returning false\n", psz_url );
-#endif
- return false;
- }
- else
- {
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_IsAbsolute(%s) returning true\n", psz_url );
-#endif
- return true;
- }
-}
-
-
-bool XURL_HasFragment( char *psz_url )
-{
- if( XURL_FindFragment( psz_url ) == NULL )
- return false;
- else
- return true;
-}
-
-
-char *XURL_FindHostname( char *psz_url )
-{
- char *psz_return_value = NULL;
-
- char *psz_scheme_separator = strstr( psz_url, "://" );
- if( psz_scheme_separator != NULL)
- {
- char *psz_hostname = psz_scheme_separator + strlen( "://" );
- if( *psz_hostname != '\0')
- psz_return_value = psz_hostname;
-
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_FindHostname(%s): returning \"%s\"\n",
- psz_url, psz_return_value );
-#endif
- }
-
- return psz_return_value;
-}
-
-
-bool XURL_HasAbsolutePath( char *psz_url )
-{
-#ifdef XURL_WIN32_PATHING
- if( psz_url[0] == '/' || psz_url[0] == '\\' )
-#else
- if( psz_url[0] == '/' )
-#endif
- return true;
- else
- return false;
-}
-
-
-char *XURL_GetHostname( char *psz_url )
-{
- char *psz_return_value = NULL;
- char *psz_hostname = XURL_FindHostname( psz_url );
-
- if( psz_hostname != NULL )
- {
- char *psz_new_hostname;
- size_t i_hostname_length;
-
- char *psz_one_past_end_of_hostname = strchr( psz_hostname, '/' );
- if( psz_one_past_end_of_hostname != NULL)
- {
- /* Found a '/' after the hostname, so copy characters between
- * the hostname and the '/' to a new string */
- i_hostname_length = psz_one_past_end_of_hostname -
- psz_hostname;
- }
- else
- {
- /* Didn't find a '/', so copy from the start of the hostname
- * until the end of the string */
- i_hostname_length = strlen( psz_url ) - ( psz_hostname - psz_url );
- }
-
- /* Copy hostname to a new string */
- psz_new_hostname = malloc( i_hostname_length );
- if( psz_new_hostname == NULL )
- return NULL;
- strncpy( psz_new_hostname, psz_hostname, i_hostname_length );
-
-#ifdef XURL_DEBUG
- fprintf (stderr, "XURL_GetHostname: psz_new_hostname is \"%s\"\n",
- psz_new_hostname );
-#endif
- psz_return_value = psz_new_hostname;
- }
- else
- {
- /* Didn't find a hostname */
- return NULL;
- }
-
- return psz_return_value;
-}
-
-
-char *XURL_GetSchemeAndHostname( char *psz_url )
-{
- char *psz_scheme = NULL,
- *psz_hostname = NULL,
- *psz_scheme_and_hostname = NULL;
-
- psz_scheme = XURL_GetScheme( psz_url );
- psz_hostname = XURL_GetHostname( psz_url );
- if( psz_hostname && psz_scheme )
- {
- if( asprintf( &psz_scheme_and_hostname, "%s://%s", psz_scheme, psz_hostname ) == -1)
- psz_scheme_and_hostname = NULL;
- }
-
- free( psz_hostname );
- free( psz_scheme );
- return psz_scheme_and_hostname;
-}
-
-static char *XURL_FindFragment( char *psz_url )
-{
- char *pc_hash = NULL;
- char *pc_return_value = NULL;
-
- pc_hash = strchr( psz_url, '#' );
- if( pc_hash != NULL )
- pc_return_value = pc_hash;
-
- return pc_return_value;
-}
-
-char *XURL_FindQuery( char *psz_url )
-{
- char *pc_question_mark = NULL;
- char *pc_return_value = NULL;
-
- pc_question_mark = strchr( psz_url, '?' );
- if( pc_question_mark != NULL )
- pc_return_value = pc_question_mark;
-
- return pc_return_value;
-}
-
-
-char *XURL_GetScheme( char *psz_url )
-{
- char *psz_colon;
- size_t i_scheme_length;
- char *new_scheme;
-
- if( XURL_IsAbsolute( psz_url ) == false )
- return strdup( "file" );
-
- /* this strchr will always succeed since we have an absolute URL, and thus
- * a scheme */
- psz_colon = strchr( psz_url, ':' );
-
- i_scheme_length = psz_colon - psz_url;
-
- new_scheme = malloc( i_scheme_length );
- if( new_scheme == NULL )
- return NULL;
-
- strncpy( new_scheme, psz_url, i_scheme_length );
- return new_scheme;
-}
-
-
-bool XURL_IsFileURL( char *psz_url )
-{
- bool b_return_value;
- char *psz_scheme = XURL_GetScheme( psz_url );
-
- if( strcasecmp( psz_scheme, "file" ) == 0 )
- b_return_value = true;
- else
- b_return_value = false;
-
- free( psz_scheme );
-
- return b_return_value;
-}
-
-
-static char *XURL_FindPath( char *psz_url )
-{
- if( XURL_IsAbsolute( psz_url ) )
- {
- char *psz_start_of_hostname = XURL_FindHostname( psz_url );
- if( psz_start_of_hostname != NULL )
- return strchr( psz_start_of_hostname, '/' );
- else
- return NULL;
- }
- else
- {
- if( XURL_HasAbsolutePath( psz_url ) == true )
- return psz_url;
- else
- return strdup (".");
- }
-}
-
-
-char *XURL_GetPath( char *psz_url )
-{
- char *psz_return_value = NULL;
- char *psz_path = NULL;
- char *pc_question_mark = NULL;
- char *pc_fragment = NULL;
-
- psz_path = strdup( XURL_FindPath( psz_url ) );
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_GetPath: XURL_FindPath returning \"%s\"\n",
- psz_path );
-#endif
- psz_return_value = psz_path;
-
- pc_question_mark = XURL_FindQuery( psz_path );
- if( pc_question_mark != NULL )
- {
- int i_path_length = pc_question_mark - psz_path;
- *( psz_path + i_path_length ) = '\0';
- }
-
- pc_fragment = XURL_FindFragment( psz_path );
- if( pc_fragment != NULL )
- {
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_GetPath: XURL_FindFragment returned \"%s\"\n",
- pc_fragment );
-#endif
- int i_path_length = pc_fragment - psz_path;
- *( psz_path + i_path_length ) = '\0';
- }
-
-#ifdef XURL_DEBUG
- fprintf( stderr, "XURL_GetPath returning \"%s\"\n", psz_return_value );
-#endif
-
- return psz_return_value;
-}
-
-
-char *XURL_GetHead( const char *psz_path )
-{
- char *psz_path_head;
- char *pc_last_slash;
-
- /* kill everything up to the last / (including the /) */
-#ifdef XURL_WIN32_PATHING
- /* Windows: Try looking for a \ first; if we don't find one, look for / */
- pc_last_slash = strrchr( psz_path, '\\' );
- if( pc_last_slash == NULL )
- pc_last_slash = strrchr( psz_path, '/' );
-#else
- pc_last_slash = strrchr( psz_path, '/' );
-#endif
- if( pc_last_slash == NULL )
- {
- psz_path_head = strdup( psz_path );
- }
- else
- {
- size_t i_characters_until_last_slash;
-
- i_characters_until_last_slash = pc_last_slash - psz_path;
- psz_path_head = xmalloc( i_characters_until_last_slash + 1 );
- strncpy( psz_path_head, psz_path, i_characters_until_last_slash + 1 );
-
- /* terminate the resulting string with '\0' */
- *(psz_path_head +
- i_characters_until_last_slash) = '\0';
- }
-
- /* append a trailing / */
- streallocat( psz_path_head, "/" );
-
- return psz_path_head;
-}
-
-
-char *XURL_GetWithoutFragment( char *psz_url )
-{
- char *psz_return_value = NULL;
- char *psz_fragment;
-
- psz_fragment = XURL_FindFragment( psz_url );
- if( psz_fragment == NULL )
- {
- psz_return_value = strdup( psz_url );
- }
- else
- {
- size_t i_pre_fragment_length;
- char *psz_without_fragment;
-
- i_pre_fragment_length = psz_fragment - psz_url;
-
- psz_without_fragment = malloc( i_pre_fragment_length + 1 );
- if( psz_without_fragment == NULL )
- {
- psz_return_value = NULL;
- }
- else
- {
- memcpy( psz_without_fragment, psz_url, i_pre_fragment_length );
- *( psz_without_fragment + i_pre_fragment_length ) = '\0';
- psz_return_value = psz_without_fragment;
- }
- }
-
- return psz_return_value;
-}
-
-static char *streallocat( char *psz_string, const char *psz_to_append )
-{
- size_t i_new_string_length = strlen( psz_string ) +
- strlen( psz_to_append ) + 1;
-
- psz_string = xrealloc( psz_string, i_new_string_length );
-
- return strcat( psz_string, psz_to_append );
-}
-
+++ /dev/null
-/*****************************************************************************
- * xurl.h: URL manipulation functions (header file)
- *****************************************************************************
- * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
- * Organisation (CSIRO) Australia
- * Copyright (C) 2004-2008 the VideoLAN team
- *
- * $Id$
- *
- * Authors: Andre Pang <Andre.Pang@csiro.au>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __XURL_H__
-#define __XURL_H__
-
-#include <vlc_common.h>
-
-/* Use DOS/Windows path separators? */
-#ifdef WIN32
-# define XURL_WIN32_PATHING
-#else
-# undef XURL_WIN32_PATHING
-#endif
-
-/* Debugging */
-#undef XURL_DEBUG
-
-char* XURL_Join ( char *psz_url1, char *psz_url2 );
-char* XURL_Concat ( char *psz_url, char *psz_append );
-
-bool XURL_IsAbsolute ( char *psz_url );
-bool XURL_HasAbsolutePath ( char *psz_url );
-bool XURL_IsFileURL ( char *psz_url );
-bool XURL_HasFragment ( char *psz_url );
-
-char* XURL_GetHostname ( char *psz_url );
-char* XURL_GetSchemeAndHostname ( char *psz_url );
-char* XURL_GetScheme ( char *psz_url );
-char* XURL_GetPath ( char *psz_url );
-char* XURL_GetWithoutFragment ( char *psz_url );
-
-char* XURL_GetHead ( const char *psz_path );
-
-#endif /* __XURL_H__ */
-
modules/codec/cc.c
modules/codec/cc.h
modules/codec/cdg.c
-modules/codec/cmml/browser_open.c
-modules/codec/cmml/browser_open.h
-modules/codec/cmml/cmml.c
-modules/codec/cmml/history.c
-modules/codec/cmml/history.h
-modules/codec/cmml/intf.c
-modules/codec/cmml/xarray.c
-modules/codec/cmml/xarray.h
-modules/codec/cmml/xlist.c
-modules/codec/cmml/xlist.h
-modules/codec/cmml/xstrcat.h
-modules/codec/cmml/xtag.c
-modules/codec/cmml/xtag.h
-modules/codec/cmml/xurl.c
-modules/codec/cmml/xurl.h
modules/codec/cvdsub.c
modules/codec/dirac.c
modules/codec/dmo/buffer.c