Port the http interface to the Lua Interface Module framework.
authorAntoine Cellerier <dionoea@videolan.org>
Sat, 10 Nov 2007 16:34:53 +0000 (16:34 +0000)
committerAntoine Cellerier <dionoea@videolan.org>
Sat, 10 Nov 2007 16:34:53 +0000 (16:34 +0000)
 * share/luaintf/http.lua: Equivalent of the legacy modules/control/http/
   module. (The new module takes 272 lines of Lua, instead of 5475 lines for
   the old one.) Functionality is basically the same except for CGI support
   which is missing.
 * share/http-lua/: The HTML files using the new <?vlc [lua code] ?> syntax.
 * modules/misc/lua/: Add Lua bindings for a few VLC function, the most
   important being the HTTPd high level functions, ACLs, stat and opendir.

The Lua code still needs to be cleaned up a bit.

94 files changed:
Makefile.am
modules/misc/lua/Modules.am
modules/misc/lua/acl.c [new file with mode: 0644]
modules/misc/lua/callbacks.c
modules/misc/lua/httpd.c [new file with mode: 0644]
modules/misc/lua/intf.c
modules/misc/lua/net.c
modules/misc/lua/vlc.c
modules/misc/lua/vlc.h
share/Makefile.am
share/http-lua/.hosts [new file with mode: 0644]
share/http-lua/custom.lua [new file with mode: 0644]
share/http-lua/dialogs/.hosts [new file with mode: 0644]
share/http-lua/dialogs/browse [new file with mode: 0644]
share/http-lua/dialogs/footer [new file with mode: 0644]
share/http-lua/dialogs/input [new file with mode: 0644]
share/http-lua/dialogs/main [new file with mode: 0644]
share/http-lua/dialogs/mosaic [new file with mode: 0644]
share/http-lua/dialogs/playlist [new file with mode: 0644]
share/http-lua/dialogs/sout [new file with mode: 0644]
share/http-lua/dialogs/vlm [new file with mode: 0644]
share/http-lua/favicon.ico [new file with mode: 0644]
share/http-lua/flash.html [new file with mode: 0644]
share/http-lua/iehacks.css [new file with mode: 0644]
share/http-lua/images/delete.png [new file with mode: 0644]
share/http-lua/images/delete_small.png [new file with mode: 0644]
share/http-lua/images/eject.png [new file with mode: 0644]
share/http-lua/images/empty.png [new file with mode: 0644]
share/http-lua/images/fullscreen.png [new file with mode: 0644]
share/http-lua/images/help.png [new file with mode: 0644]
share/http-lua/images/info.png [new file with mode: 0644]
share/http-lua/images/loop.png [new file with mode: 0644]
share/http-lua/images/minus.png [new file with mode: 0644]
share/http-lua/images/next.png [new file with mode: 0644]
share/http-lua/images/pause.png [new file with mode: 0644]
share/http-lua/images/play.png [new file with mode: 0644]
share/http-lua/images/playlist.png [new file with mode: 0644]
share/http-lua/images/playlist_small.png [new file with mode: 0644]
share/http-lua/images/plus.png [new file with mode: 0644]
share/http-lua/images/prev.png [new file with mode: 0644]
share/http-lua/images/refresh.png [new file with mode: 0644]
share/http-lua/images/repeat.png [new file with mode: 0644]
share/http-lua/images/sd.png [new file with mode: 0644]
share/http-lua/images/shuffle.png [new file with mode: 0644]
share/http-lua/images/slider_bar.png [new file with mode: 0644]
share/http-lua/images/slider_left.png [new file with mode: 0644]
share/http-lua/images/slider_point.png [new file with mode: 0644]
share/http-lua/images/slider_right.png [new file with mode: 0644]
share/http-lua/images/slow.png [new file with mode: 0644]
share/http-lua/images/snapshot.png [new file with mode: 0644]
share/http-lua/images/sort.png [new file with mode: 0644]
share/http-lua/images/sout.png [new file with mode: 0644]
share/http-lua/images/speaker.png [new file with mode: 0644]
share/http-lua/images/speaker_mute.png [new file with mode: 0644]
share/http-lua/images/stop.png [new file with mode: 0644]
share/http-lua/images/vlc16x16.png [new file with mode: 0644]
share/http-lua/images/volume_down.png [new file with mode: 0644]
share/http-lua/images/volume_up.png [new file with mode: 0644]
share/http-lua/images/white.png [new file with mode: 0644]
share/http-lua/images/white_cross_small.png [new file with mode: 0644]
share/http-lua/index.html [new file with mode: 0644]
share/http-lua/js/functions.js [new file with mode: 0644]
share/http-lua/js/mosaic.js [new file with mode: 0644]
share/http-lua/js/vlm.js [new file with mode: 0644]
share/http-lua/mosaic.html [new file with mode: 0644]
share/http-lua/old/.hosts [new file with mode: 0644]
share/http-lua/old/admin/.access [new file with mode: 0644]
share/http-lua/old/admin/browse.html [new file with mode: 0644]
share/http-lua/old/admin/dboxfiles.html [new file with mode: 0644]
share/http-lua/old/admin/index.html [new file with mode: 0644]
share/http-lua/old/cone_minus.png [new file with mode: 0644]
share/http-lua/old/cone_plus.png [new file with mode: 0644]
share/http-lua/old/index.html [new file with mode: 0644]
share/http-lua/old/info.html [new file with mode: 0644]
share/http-lua/old/style.css [new file with mode: 0644]
share/http-lua/old/vlm/edit.html [new file with mode: 0644]
share/http-lua/old/vlm/index.html [new file with mode: 0644]
share/http-lua/old/vlm/new.html [new file with mode: 0644]
share/http-lua/old/vlm/show.html [new file with mode: 0644]
share/http-lua/old/webcam.html [new file with mode: 0644]
share/http-lua/requests/browse.xml [new file with mode: 0644]
share/http-lua/requests/playlist.xml [new file with mode: 0644]
share/http-lua/requests/readme [new file with mode: 0644]
share/http-lua/requests/status.xml [new file with mode: 0644]
share/http-lua/requests/vlm.xml [new file with mode: 0644]
share/http-lua/requests/vlm_cmd.xml [new file with mode: 0644]
share/http-lua/style.css [new file with mode: 0644]
share/http-lua/vlm.html [new file with mode: 0644]
share/http-lua/vlm_export.html [new file with mode: 0644]
share/luaintf/http.lua [new file with mode: 0644]
share/luaintf/modules/acl.lua [new file with mode: 0644]
share/luaintf/modules/common.lua
share/luaintf/modules/httpd.lua [new file with mode: 0644]
share/luaintf/rc.lua

index df1373c..6c4fab7 100644 (file)
@@ -441,6 +441,38 @@ VLC-release.app: vlc
        for i in $(srcdir)/share/luaintf/modules/*.* ; do \
          $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/luaintf/modules/`basename $${i}` ; \
        done ; \
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/dialogs
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/js
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/admin
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/vlm
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/images
+       $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests
+       for i in $(srcdir)/share/http-lua/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/dialogs/* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/dialogs/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/js/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/js/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/old/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/old/admin/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/admin/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/old/vlm/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/vlm/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/images/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/images/`basename $${i}` ; \
+       done ; \
+       for i in $(srcdir)/share/http-lua/requests/*.* ; do \
+         $(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests/`basename $${i}` ; \
+       done ; \
+       $(INSTALL) -m 644 $(srcdir)/share/http-lua/requests/readme $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests/readme.txt
        $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/dialogs
        $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/js
        $(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/old
@@ -646,6 +678,43 @@ package-win-common:
             || true ; \
        done
 
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/images"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/requests"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/js"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/dialogs"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old/vlm"
+       mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old/admin"
+       cp $(srcdir)/share/http-lua/*.html $(top_builddir)/vlc-${VERSION}/http-lua/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/*.html ;
+       cp $(srcdir)/share/http-lua/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/.hosts ;
+       cp $(srcdir)/share/http-lua/*.css $(top_builddir)/vlc-${VERSION}/http-lua/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/*.css ;
+       cp $(srcdir)/share/http-lua/js/*.js $(top_builddir)/vlc-${VERSION}/http-lua/js/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/js/*.js ;
+       cp $(srcdir)/share/http-lua/dialogs/* $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/* ;
+       cp $(srcdir)/share/http-lua/dialogs/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/.hosts ;
+       cp $(srcdir)/share/http-lua/*.ico $(top_builddir)/vlc-${VERSION}/http-lua/ ;
+       cp $(srcdir)/share/http-lua/images/*.png $(top_builddir)/vlc-${VERSION}/http-lua/images/
+       cp $(srcdir)/share/http-lua/requests/*.xml $(top_builddir)/vlc-${VERSION}/http-lua/requests/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/requests/*.xml ;
+       cp $(srcdir)/share/http-lua/requests/readme $(top_builddir)/vlc-${VERSION}/http-lua/requests/readme.txt ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/requests/readme.txt ;
+
+       cp $(srcdir)/share/http-lua/old/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/*.html ;
+       cp $(srcdir)/share/http-lua/old/*.css $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
+       cp $(srcdir)/share/http-lua/old/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
+       cp $(srcdir)/share/http-lua/old/*.png $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
+       cp $(srcdir)/share/http-lua/old/vlm/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/vlm/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/vlm/*.html ;
+       cp $(srcdir)/share/http-lua/old/admin/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/ ;
+       unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/*.html ;
+       cp $(srcdir)/share/http-lua/old/admin/.access $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/ ;
+
        mkdir -p "$(top_builddir)/vlc-${VERSION}/http/images"
        mkdir -p "$(top_builddir)/vlc-${VERSION}/http/requests"
        mkdir -p "$(top_builddir)/vlc-${VERSION}/http/js"
index f01c536..efb12a8 100644 (file)
@@ -1 +1 @@
-SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c
+SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c httpd.c acl.c
diff --git a/modules/misc/lua/acl.c b/modules/misc/lua/acl.c
new file mode 100644 (file)
index 0000000..72d738a
--- /dev/null
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * acl.c: Access list related functions
+ *****************************************************************************
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea at videolan tod org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#ifndef  _GNU_SOURCE
+#   define  _GNU_SOURCE
+#endif
+
+#include <vlc/vlc.h>
+#include <vlc_acl.h>
+
+#include <lua.h>        /* Low level lua C API */
+#include <lauxlib.h>    /* Higher level C API */
+#include <lualib.h>     /* Lua libs */
+
+#include "vlc.h"
+
+/*****************************************************************************
+ *
+ *****************************************************************************/
+int vlclua_acl_create( lua_State *L )
+{
+    vlc_object_t *p_this = vlclua_get_this( L );
+    vlc_bool_t b_allow = luaL_checkboolean( L, 1 ) ? VLC_TRUE : VLC_FALSE;
+    vlc_acl_t *p_acl = ACL_Create( p_this, b_allow );
+    if( !p_acl )
+        return luaL_error( L, "ACL creation failed." );
+    lua_pushlightuserdata( L, p_acl ); /* FIXME */
+    return 1;
+}
+
+int vlclua_acl_delete( lua_State *L )
+{
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    ACL_Destroy( p_acl );
+    return 0;
+}
+
+int vlclua_acl_check( lua_State *L )
+{
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    const char *psz_ip = luaL_checkstring( L, 2 );
+    lua_pushinteger( L, ACL_Check( p_acl, psz_ip ) );
+    return 1;
+}
+
+int vlclua_acl_duplicate( lua_State *L )
+{
+    vlc_object_t *p_this = vlclua_get_this( L );
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    vlc_acl_t *p_acl_new = ACL_Duplicate( p_this, p_acl );
+    lua_pushlightuserdata( L, p_acl_new );
+    return 1;
+}
+
+int vlclua_acl_add_host( lua_State *L )
+{
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    const char *psz_ip = luaL_checkstring( L, 2 );
+    vlc_bool_t b_allow = luaL_checkboolean( L, 3 ) ? VLC_TRUE : VLC_FALSE;
+    lua_pushinteger( L, ACL_AddHost( p_acl, psz_ip, b_allow ) );
+    return 1;
+}
+
+int vlclua_acl_add_net( lua_State *L )
+{
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    const char *psz_ip = luaL_checkstring( L, 2 );
+    int i_len = luaL_checkint( L, 3 );
+    vlc_bool_t b_allow = luaL_checkboolean( L, 4 ) ? VLC_TRUE : VLC_FALSE;
+    lua_pushinteger( L, ACL_AddNet( p_acl, psz_ip, i_len, b_allow ) );
+    return 1;
+}
+
+int vlclua_acl_load_file( lua_State *L )
+{
+    vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
+    const char *psz_path = luaL_checkstring( L, 2 );
+    lua_pushinteger( L, ACL_LoadFile( p_acl, psz_path ) );
+    return 1;
+}
index 10c2732..2023b74 100644 (file)
@@ -159,7 +159,7 @@ int vlclua_add_callback( lua_State *L )
      * the function in the stack to nil) */
     p_callback->i_index = i_index;
     p_callback->i_type = var_Type( p_obj, psz_var );
-    p_callback->L = lua_newthread( L );
+    p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */
 
     var_AddCallback( p_obj, psz_var, vlclua_callback, p_callback );
     return 0;
diff --git a/modules/misc/lua/httpd.c b/modules/misc/lua/httpd.c
new file mode 100644 (file)
index 0000000..17a5fd0
--- /dev/null
@@ -0,0 +1,300 @@
+/*****************************************************************************
+ * httpd.c: HTTPd wrapper
+ *****************************************************************************
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea at videolan tod org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#ifndef  _GNU_SOURCE
+#   define  _GNU_SOURCE
+#endif
+
+#include <vlc/vlc.h>
+#include <vlc_httpd.h>
+
+#include <lua.h>        /* Low level lua C API */
+#include <lauxlib.h>    /* Higher level C API */
+#include <lualib.h>     /* Lua libs */
+
+#include "vlc.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static uint8_t *vlclua_todata( lua_State *L, int narg, int *i_data );
+
+/*****************************************************************************
+ * HTTPD Host
+ *****************************************************************************/
+#if 0
+/* This is kind of a useless function since TLS with the 4 last args
+ * unset does the same thing as far as I know. */
+int vlclua_httpd_host_new( lua_State *L )
+{
+    vlc_object_t *p_this = vlclua_get_this( L );
+    const char *psz_host = luaL_checkstring( L, 1 );
+    int i_port = luaL_checkint( L, 2 );
+    httpd_host_t *p_httpd_host = httpd_HostNew( p_this, psz_host, i_port );
+    if( !p_httpd_host )
+        return luaL_error( L, "Failed to create HTTP host \"%s:%d\".",
+                           psz_host, i_port );
+    vlclua_push_vlc_object( L, p_httpd_host, vlclua_httpd_host_delete );
+    return 1;
+}
+#endif
+
+int vlclua_httpd_tls_host_new( lua_State *L )
+{
+    vlc_object_t *p_this = vlclua_get_this( L );
+    const char *psz_host = luaL_checkstring( L, 1 );
+    int i_port = luaL_checkint( L, 2 );
+    const char *psz_cert = luaL_optstring( L, 3, NULL );
+    const char *psz_key = luaL_optstring( L, 4, NULL );
+    const char *psz_ca = luaL_optstring( L, 5, NULL );
+    const char *psz_crl = luaL_optstring( L, 6, NULL );
+    httpd_host_t *p_httpd_host = httpd_TLSHostNew( p_this, psz_host, i_port,
+                                                   psz_cert, psz_key,
+                                                   psz_ca, psz_crl );
+    if( !p_httpd_host )
+        return luaL_error( L, "Failed to create HTTP TLS host \"%s:%d\" "
+                           "(cert: \"%s\", key: \"%s\", ca: \"%s\", "
+                           "crl: \"%s\").", psz_host, i_port,
+                           psz_cert, psz_key, psz_ca, psz_crl );
+    vlclua_push_vlc_object( L, (vlc_object_t*)p_httpd_host, vlclua_httpd_host_delete );
+    return 1;
+}
+
+#define ARG_1_IS_HTTPD_HOST httpd_host_t *p_httpd_host = \
+    (httpd_host_t*)vlclua_checkobject( L, 1, VLC_OBJECT_HTTPD_HOST );
+int vlclua_httpd_host_delete( lua_State *L )
+{
+    ARG_1_IS_HTTPD_HOST
+    httpd_HostDelete( p_httpd_host );
+    return 0;
+}
+
+/*****************************************************************************
+ * HTTPd Handler
+ *****************************************************************************/
+struct httpd_handler_sys_t
+{
+    lua_State *L;
+    int ref;
+};
+
+static int vlclua_httpd_handler_callback(
+     httpd_handler_sys_t *p_sys, httpd_handler_t *p_handler, char *psz_url,
+     uint8_t *psz_request, int i_type, uint8_t *p_in, int i_in,
+     char *psz_remote_addr, char *psz_remote_host,
+     uint8_t **pp_data, int *pi_data )
+{
+    lua_State *L = p_sys->L;
+
+    /* function data */
+    lua_pushvalue( L, 1 );
+    lua_pushvalue( L, 2 );
+    /* function data function data */
+    lua_pushstring( L, psz_url );
+    /* function data function data url */
+    lua_pushstring( L, (const char *)psz_request );
+    /* function data function data url request */
+    lua_pushinteger( L, i_type ); /* Q: what does i_type stand for? */
+    /* function data function data url request type */
+    lua_pushlstring( L, (const char *)p_in, i_in ); /* Q: what do p_in contain? */
+    /* function data function data url request type in */
+    lua_pushstring( L, psz_remote_addr );
+    /* function data function data url request type in addr */
+    lua_pushstring( L, psz_remote_host );
+    /* function data function data url request type in addr host */
+    if( lua_pcall( L, 7, 1, 0 ) )
+    {
+        /* function data err */
+        vlc_object_t *p_this = vlclua_get_this( L );
+        const char *psz_err = lua_tostring( L, -1 );
+        msg_Err( p_this, "Error while runing the lua HTTPd handler "
+                 "callback: %s", psz_err );
+        lua_settop( L, 2 );
+        /* function data */
+        return VLC_EGENERIC;
+    }
+    /* function data outdata */
+    *pp_data = vlclua_todata( L, -1, pi_data );
+    lua_pop( L, 1 );
+    /* function data */
+    return VLC_SUCCESS;
+}
+
+int vlclua_httpd_handler_new( lua_State * L )
+{
+    ARG_1_IS_HTTPD_HOST
+    const char *psz_url = luaL_checkstring( L, 2 );
+    const char *psz_user = luaL_nilorcheckstring( L, 3 );
+    const char *psz_password = luaL_nilorcheckstring( L, 4 );
+    const vlc_acl_t *p_acl = NULL; /* FIXME 5 */
+    /* Stack item 6 is the callback function */
+    luaL_argcheck( L, lua_isfunction( L, 6 ), 6, "Should be a function" );
+    /* Stack item 7 is the callback data */
+    lua_settop( L, 7 );
+    httpd_handler_sys_t *p_sys = (httpd_handler_sys_t*)
+                                 malloc( sizeof( httpd_handler_sys_t ) );
+    if( !p_sys )
+        return luaL_error( L, "Failed to allocate private buffer." );
+    p_sys->L = lua_newthread( L );
+    p_sys->ref = luaL_ref( L, LUA_REGISTRYINDEX ); /* pops the object too */
+    /* use lua_xmove to move the lua callback function and data to
+     * the callback's stack. */
+    lua_xmove( L, p_sys->L, 2 );
+    httpd_handler_t *p_handler = httpd_HandlerNew(
+                            p_httpd_host, psz_url, psz_user, psz_password,
+                            p_acl, vlclua_httpd_handler_callback, p_sys );
+    if( !p_handler )
+        return luaL_error( L, "Failed to create HTTPd handler." );
+    lua_pushlightuserdata( L, p_handler ); /* FIXME */
+    return 1;
+}
+
+int vlclua_httpd_handler_delete( lua_State *L )
+{
+    httpd_handler_t *p_handler = (httpd_handler_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
+    httpd_handler_sys_t *p_sys = httpd_HandlerDelete( p_handler );
+    luaL_unref( p_sys->L, LUA_REGISTRYINDEX, p_sys->ref );
+    free( p_sys );
+    return 0;
+}
+
+/*****************************************************************************
+ * HTTPd File
+ *****************************************************************************/
+struct httpd_file_sys_t
+{
+    lua_State *L;
+    int ref;
+};
+
+static int vlclua_httpd_file_callback(
+    httpd_file_sys_t *p_sys, httpd_file_t *p_file, uint8_t *psz_request,
+    uint8_t **pp_data, int *pi_data )
+{
+    lua_State *L = p_sys->L;
+
+    /* function data */
+    lua_pushvalue( L, 1 );
+    lua_pushvalue( L, 2 );
+    /* function data function data */
+    lua_pushstring( L, (const char *)psz_request );
+    /* function data function data request */
+    if( lua_pcall( L, 2, 1, 0 ) )
+    {
+        /* function data err */
+        vlc_object_t *p_this = vlclua_get_this( L );
+        const char *psz_err = lua_tostring( L, -1 );
+        msg_Err( p_this, "Error while runing the lua HTTPd file callback: %s",
+                 psz_err );
+        lua_settop( L, 2 );
+        /* function data */
+        return VLC_EGENERIC;
+    }
+    /* function data outdata */
+    *pp_data = vlclua_todata( L, -1, pi_data );
+    lua_pop( L, 1 );
+    /* function data */
+    return VLC_SUCCESS;
+}
+
+int vlclua_httpd_file_new( lua_State *L )
+{
+    ARG_1_IS_HTTPD_HOST
+    const char *psz_url = luaL_checkstring( L, 2 );
+    const char *psz_mime = luaL_nilorcheckstring( L, 3 );
+    const char *psz_user = luaL_nilorcheckstring( L, 4 );
+    const char *psz_password = luaL_nilorcheckstring( L, 5 );
+    const vlc_acl_t *p_acl = lua_isnil( L, 6 ) ? NULL : luaL_checklightuserdata( L, 6 );
+    /* Stack item 7 is the callback function */
+    luaL_argcheck( L, lua_isfunction( L, 7 ), 7, "Should be a function" );
+    /* Stack item 8 is the callback data */
+    httpd_file_sys_t *p_sys = (httpd_file_sys_t *)
+                              malloc( sizeof( httpd_file_sys_t ) );
+    if( !p_sys )
+        return luaL_error( L, "Failed to allocate private buffer." );
+    p_sys->L = lua_newthread( L );
+    p_sys->ref = luaL_ref( L, LUA_REGISTRYINDEX ); /* pops the object too */
+    lua_xmove( L, p_sys->L, 2 );
+    httpd_file_t *p_file = httpd_FileNew( p_httpd_host, psz_url, psz_mime,
+                                          psz_user, psz_password, p_acl,
+                                          vlclua_httpd_file_callback, p_sys );
+    if( !p_file )
+        return luaL_error( L, "Failed to create HTTPd file." );
+    lua_pushlightuserdata( L, p_file ); /* FIXME */
+    return 1;
+}
+
+int vlclua_httpd_file_delete( lua_State *L )
+{
+    httpd_file_t *p_file = (httpd_file_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
+    /* FIXME: How do we delete p_sys ? the struct is hidden in the VLC core */
+    httpd_file_sys_t *p_sys = httpd_FileDelete( p_file );
+    luaL_unref( p_sys->L, LUA_REGISTRYINDEX, p_sys->ref );
+    free( p_sys );
+    return 0;
+}
+
+/*****************************************************************************
+ * HTTPd Redirect
+ *****************************************************************************/
+int vlclua_httpd_redirect_new( lua_State *L )
+{
+    ARG_1_IS_HTTPD_HOST
+    const char *psz_url_dst = luaL_checkstring( L, 2 );
+    const char *psz_url_src = luaL_checkstring( L, 3 );
+    httpd_redirect_t *p_redirect = httpd_RedirectNew( p_httpd_host,
+                                                      psz_url_dst,
+                                                      psz_url_src );
+    if( !p_redirect )
+        return luaL_error( L, "Failed to create HTTPd redirect." );
+    lua_pushlightuserdata( L, p_redirect ); /* FIXME */
+    return 1;
+}
+
+int vlclua_httpd_redirect_delete( lua_State *L )
+{
+    httpd_redirect_t *p_redirect = (httpd_redirect_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
+    httpd_RedirectDelete( p_redirect );
+    return 0;
+}
+
+/*****************************************************************************
+ * Utils
+ *****************************************************************************/
+static uint8_t *vlclua_todata( lua_State *L, int narg, int *pi_data )
+{
+    size_t i_data;
+    const char *psz_data = lua_tolstring( L, narg, &i_data );
+    uint8_t *p_data = (uint8_t*)malloc( i_data * sizeof(uint8_t) );
+    *pi_data = (int)i_data;
+    if( !p_data )
+    {
+        luaL_error( L, "Error while allocating buffer." );
+        return NULL; /* To please gcc even though luaL_error longjmp-ed out of here */
+    }
+    memcpy( p_data, psz_data, i_data );
+    return p_data;
+}
index 95d8111..e6ad115 100644 (file)
@@ -122,7 +122,7 @@ static int vlclua_input_info( lua_State *L )
     int i_cat;
     int i;
     if( !p_input ) return vlclua_error( L );
-    vlc_mutex_lock( &input_GetItem(p_input)->lock );
+    //vlc_mutex_lock( &input_GetItem(p_input)->lock );
     i_cat = input_GetItem(p_input)->i_categories;
     lua_createtable( L, 0, i_cat );
     for( i = 0; i < i_cat; i++ )
@@ -141,7 +141,7 @@ static int vlclua_input_info( lua_State *L )
         }
         lua_settable( L, -3 );
     }
-    vlc_object_release( p_input );
+    //vlc_object_release( p_input );
     return 1;
 }
 
@@ -165,6 +165,36 @@ static int vlclua_get_title( lua_State *L )
     return 1;
 }
 
+static int vlclua_input_stats( lua_State *L )
+{
+    input_thread_t *p_input = vlclua_get_input_internal( L );
+    input_item_t *p_item = p_input && p_input->p ? input_GetItem( p_input ) : NULL;
+    lua_newtable( L );
+    if( p_item )
+    {
+#define STATS_INT( n ) lua_pushinteger( L, p_item->p_stats->i_ ## n ); \
+                       lua_setfield( L, -2, #n );
+#define STATS_FLOAT( n ) lua_pushnumber( L, p_item->p_stats->f_ ## n ); \
+                         lua_setfield( L, -2, #n );
+        STATS_INT( read_bytes )
+        STATS_FLOAT( input_bitrate )
+        STATS_INT( demux_read_bytes )
+        STATS_FLOAT( demux_bitrate )
+        STATS_INT( decoded_video )
+        STATS_INT( displayed_pictures )
+        STATS_INT( lost_pictures )
+        STATS_INT( decoded_audio )
+        STATS_INT( played_abuffers )
+        STATS_INT( lost_abuffers )
+        STATS_INT( sent_packets )
+        STATS_INT( sent_bytes )
+        STATS_FLOAT( send_bitrate )
+#undef STATS_INT
+#undef STATS_FLOAT
+    }
+    return 1;
+}
+
 /*****************************************************************************
  * Vout control
  *****************************************************************************/
@@ -454,7 +484,10 @@ static int vlclua_playlist_get( lua_State *L )
         lua_setfield( L, -2, "name" );
         lua_pushstring( L, p_input->psz_uri );
         lua_setfield( L, -2, "path" );
-        lua_pushnumber( L, ((double)p_input->i_duration)*1e-6 );
+        if( p_input->i_duration < 0 )
+            lua_pushnumber( L, -1 );
+        else
+            lua_pushnumber( L, ((double)p_input->i_duration)*1e-6 );
         lua_setfield( L, -2, "duration" );
         lua_pushinteger( L, p_input->i_nb_played );
         lua_setfield( L, -2, "nb_played" );
@@ -476,15 +509,16 @@ static int vlclua_playlist_status( lua_State *L )
 {
     intf_thread_t *p_intf = (intf_thread_t *)vlclua_get_this( L );
     playlist_t *p_playlist = pl_Yield( p_intf );
+    /*
     int i_count = 0;
-    lua_settop( L, 0 );
+    lua_settop( L, 0 );*/
     if( p_playlist->p_input )
     {
-        char *psz_uri =
+        /*char *psz_uri =
             input_item_GetURI( input_GetItem( p_playlist->p_input ) );
         lua_pushstring( L, psz_uri );
         free( psz_uri );
-        lua_pushnumber( L, config_GetInt( p_intf, "volume" ) );
+        lua_pushnumber( L, config_GetInt( p_intf, "volume" ) );*/
         vlc_mutex_lock( &p_playlist->object_lock );
         switch( p_playlist->status.i_status )
         {
@@ -492,7 +526,7 @@ static int vlclua_playlist_status( lua_State *L )
                 lua_pushstring( L, "stopped" );
                 break;
             case PLAYLIST_RUNNING:
-                lua_pushstring( L, "running" );
+                lua_pushstring( L, "playing" );
                 break;
             case PLAYLIST_PAUSED:
                 lua_pushstring( L, "paused" );
@@ -502,10 +536,14 @@ static int vlclua_playlist_status( lua_State *L )
                 break;
         }
         vlc_mutex_unlock( &p_playlist->object_lock );
-        i_count += 3;
+        /*i_count += 3;*/
+    }
+    else
+    {
+        lua_pushstring( L, "stopped" );
     }
     vlc_object_release( p_playlist );
-    return i_count;
+    return 1;
 }
 
 
@@ -552,15 +590,23 @@ static luaL_Reg p_reg[] =
 
     { "decode_uri", vlclua_decode_uri },
     { "resolve_xml_special_chars", vlclua_resolve_xml_special_chars },
+    { "convert_xml_special_chars", vlclua_convert_xml_special_chars },
 
     { "lock_and_wait", vlclua_lock_and_wait },
     { "signal", vlclua_signal },
 
     { "version", vlclua_version },
     { "license", vlclua_license },
+    { "copyright", vlclua_copyright },
     { "should_die", vlclua_intf_should_die },
     { "quit", vlclua_quit },
 
+    { "homedir", vlclua_homedir },
+    { "datadir", vlclua_datadir },
+    { "configdir", vlclua_configdir },
+    { "cachedir", vlclua_cachedir },
+    { "datadir_list", vlclua_datadir_list },
+
     { NULL, NULL }
 };
 
@@ -620,6 +666,7 @@ static luaL_Reg p_reg_playlist[] =
     { "add", vlclua_playlist_add },
     { "enqueue", vlclua_playlist_enqueue },
     { "get", vlclua_playlist_get },
+    { "stats", vlclua_input_stats },
 
     { NULL, NULL }
 };
@@ -664,6 +711,9 @@ static luaL_Reg p_reg_fd[] =
 /*    { "open", vlclua_fd_open },*/
     { "read", vlclua_fd_read },
     { "write", vlclua_fd_write },
+    { "stat", vlclua_stat },
+
+    { "opendir", vlclua_opendir },
 
     { "new_fd_set", vlclua_fd_set_new },
     { "fd_clr", vlclua_fd_clr },
@@ -683,6 +733,32 @@ static luaL_Reg p_reg_vlm[] =
     { NULL, NULL }
 };
 
+static luaL_Reg p_reg_httpd[] =
+{
+    { "host_new", vlclua_httpd_tls_host_new },
+    { "host_delete", vlclua_httpd_host_delete },
+    { "handler_new", vlclua_httpd_handler_new },
+    { "handler_delete", vlclua_httpd_handler_delete },
+    { "file_new", vlclua_httpd_file_new },
+    { "file_delete", vlclua_httpd_file_delete },
+    { "redirect_new", vlclua_httpd_redirect_new },
+    { "redirect_delete", vlclua_httpd_redirect_delete },
+
+    { NULL, NULL }
+};
+
+static luaL_Reg p_reg_acl[] =
+{
+    { "create", vlclua_acl_create },
+    { "delete", vlclua_acl_delete },
+    { "check", vlclua_acl_check },
+    { "duplicate", vlclua_acl_duplicate },
+    { "add_host", vlclua_acl_add_host },
+    { "add_net", vlclua_acl_add_net },
+    { "load_file", vlclua_acl_load_file },
+
+    { NULL, NULL }
+};
 
 static void Run( intf_thread_t *p_intf );
 
@@ -817,6 +893,8 @@ int E_(Open_LuaIntf)( vlc_object_t *p_this )
     luaL_register_submodule( L, "net", p_reg_net );
     luaL_register_submodule( L, "fd", p_reg_fd );
     luaL_register_submodule( L, "vlm", p_reg_vlm );
+    luaL_register_submodule( L, "httpd", p_reg_httpd );
+    luaL_register_submodule( L, "acl", p_reg_acl );
     /* clean up */
     lua_pop( L, 1 );
 
index 345d0f1..607fdae 100644 (file)
@@ -205,3 +205,89 @@ int vlclua_fd_read( lua_State *L )
     lua_pushlstring( L, psz_buffer, i_len );
     return 1;
 }
+
+int vlclua_stat( lua_State *L )
+{
+#ifdef HAVE_SYS_STAT_H
+    const char *psz_path = luaL_checkstring( L, 1 );
+    struct stat s;
+    if( utf8_stat( psz_path, &s ) )
+        return 0;
+        //return luaL_error( L, "Couldn't stat %s.", psz_path );
+    lua_newtable( L );
+    if( S_ISREG( s.st_mode ) )
+        lua_pushstring( L, "file" );
+    else if( S_ISDIR( s.st_mode ) )
+        lua_pushstring( L, "dir" );
+#ifdef S_ISCHR
+    else if( S_ISCHR( s.st_mode ) )
+        lua_pushstring( L, "character device" );
+#endif
+#ifdef S_ISBLK
+    else if( S_ISBLK( s.st_mode ) )
+        lua_pushstring( L, "block device" );
+#endif
+#ifdef S_ISFIFO
+    else if( S_ISFIFO( s.st_mode ) )
+        lua_pushstring( L, "fifo" );
+#endif
+#ifdef S_ISLNK
+    else if( S_ISLNK( s.st_mode ) )
+        lua_pushstring( L, "symbolic link" );
+#endif
+#ifdef S_ISSOCK
+    else if( S_ISSOCK( s.st_mode ) )
+        lua_pushstring( L, "socket" );
+#endif
+    else
+        lua_pushstring( L, "unknown" );
+    lua_setfield( L, -2, "type" );
+    lua_pushinteger( L, s.st_mode );
+    lua_setfield( L, -2, "mode" );
+    lua_pushinteger( L, s.st_uid );
+    lua_setfield( L, -2, "uid" );
+    lua_pushinteger( L, s.st_gid );
+    lua_setfield( L, -2, "gid" );
+    lua_pushinteger( L, s.st_size );
+    lua_setfield( L, -2, "size" );
+    lua_pushinteger( L, s.st_atime );
+    lua_setfield( L, -2, "access_time" );
+    lua_pushinteger( L, s.st_mtime );
+    lua_setfield( L, -2, "modification_time" );
+    lua_pushinteger( L, s.st_ctime );
+    lua_setfield( L, -2, "creation_time" );
+    return 1;
+#else
+#   warning "Woops, looks like we don't have stat on your platform"
+    return luaL_error( L, "System is missing <sys/stat.h>" );
+#endif
+}
+
+int vlclua_opendir( lua_State *L )
+{
+    const char *psz_dir = luaL_checkstring( L, 1 );
+    DIR *p_dir;
+    int i = 0;
+#ifdef HAVE_SYS_STAT_H
+    struct stat s;
+    if( utf8_stat( psz_dir, &s ) == -1 )
+        return luaL_error( L, "Error while trying to stat `%s'.", psz_dir );
+    if( !S_ISDIR( s.st_mode ) )
+        return luaL_error( L, "`%s' is not a directory.", psz_dir );
+#endif
+    if( ( p_dir = utf8_opendir( psz_dir ) ) == NULL )
+        return luaL_error( L, "cannot open directory `%s'.", psz_dir );
+
+    lua_newtable( L );
+    for( ;; )
+    {
+        char *psz_filename = utf8_readdir( p_dir );
+        if( !psz_filename ) break;
+        i++;
+        lua_pushstring( L, psz_filename );
+        lua_rawseti( L, -2, i );
+        free( psz_filename );
+    }
+    closedir( p_dir );
+    return 1;
+}
index 0fd8db7..12b8870 100644 (file)
@@ -118,6 +118,15 @@ int vlclua_version( lua_State *L )
     return 1;
 }
 
+/*****************************************************************************
+ * Get the VLC copyright
+ *****************************************************************************/
+int vlclua_copyright( lua_State *L )
+{
+    lua_pushstring( L, COPYRIGHT_MESSAGE );
+    return 1;
+}
+
 /*****************************************************************************
  * Get the VLC license msg/disclaimer
  *****************************************************************************/
@@ -139,6 +148,49 @@ int vlclua_quit( lua_State *L )
     return 0;
 }
 
+/*****************************************************************************
+ * Global properties getters
+ *****************************************************************************/
+int vlclua_datadir( lua_State *L )
+{
+    lua_pushstring( L, config_GetDataDir() );
+    return 1;
+}
+int vlclua_homedir( lua_State *L )
+{
+    lua_pushstring( L, vlclua_get_this( L )->p_libvlc->psz_homedir );
+    return 1;
+}
+int vlclua_configdir( lua_State *L )
+{
+    lua_pushstring( L, vlclua_get_this( L )->p_libvlc->psz_configdir );
+    return 1;
+}
+int vlclua_cachedir( lua_State *L )
+{
+    lua_pushstring( L, vlclua_get_this( L )->p_libvlc->psz_cachedir );
+    return 1;
+}
+int vlclua_datadir_list( lua_State *L )
+{
+    const char *psz_dirname = luaL_checkstring( L, 1 );
+    vlc_object_t *p_this = vlclua_get_this( L );
+    char  *ppsz_dir_list[] = { NULL, NULL, NULL, NULL };
+    char **ppsz_dir = ppsz_dir_list;
+    int i = 1;
+
+    if( vlclua_dir_list( p_this, psz_dirname, ppsz_dir_list ) != VLC_SUCCESS )
+        return 0;
+    lua_newtable( L );
+    for( ; *ppsz_dir; ppsz_dir++ )
+    {
+        lua_pushstring( L, *ppsz_dir );
+        lua_rawseti( L, -2, i );
+        i ++;
+    }
+    return 1;
+}
+
 /*****************************************************************************
  * Volume related
  *****************************************************************************/
@@ -275,6 +327,20 @@ int vlclua_resolve_xml_special_chars( lua_State *L )
     return i_top;
 }
 
+int vlclua_convert_xml_special_chars( lua_State *L )
+{
+    int i_top = lua_gettop( L );
+    int i;
+    for( i = 1; i <= i_top; i++ )
+    {
+        char *psz_string = convert_xml_special_chars( luaL_checkstring(L,1) );
+        lua_remove( L, 1 );
+        lua_pushstring( L, psz_string );
+        free( psz_string );
+    }
+    return i_top;
+}
+
 /*****************************************************************************
  * Messaging facilities
  *****************************************************************************/
index 2eba1b6..77d61f1 100644 (file)
@@ -100,6 +100,13 @@ static inline const void *luaL_checkuserdata( lua_State *L, int narg, size_t siz
     return lua_topointer( L, narg );
 }
 
+static inline const char *luaL_nilorcheckstring( lua_State *L, int narg )
+{
+    if( lua_isnil( L, narg ) )
+        return NULL;
+    return luaL_checkstring( L, narg );
+}
+
 /*****************************************************************************
  * Lua vlc_object_t wrapper
  *****************************************************************************/
@@ -132,10 +139,31 @@ int vlclua_fd_zero( lua_State * );
 int vlclua_fd_read( lua_State * );
 int vlclua_fd_write( lua_State * );
 
+int vlclua_stat( lua_State * );
+int vlclua_opendir( lua_State * );
+
 int vlclua_vlm_new( lua_State * );
 int vlclua_vlm_delete( lua_State * );
 int vlclua_vlm_execute_command( lua_State * );
 
+int vlclua_httpd_tls_host_new( lua_State *L );
+int vlclua_httpd_host_delete( lua_State *L );
+int vlclua_httpd_handler_new( lua_State * L );
+int vlclua_httpd_handler_delete( lua_State *L );
+int vlclua_httpd_file_new( lua_State *L );
+int vlclua_httpd_file_delete( lua_State *L );
+int vlclua_httpd_redirect_new( lua_State *L );
+int vlclua_httpd_redirect_delete( lua_State *L );
+
+int vlclua_acl_create( lua_State * );
+int vlclua_acl_delete( lua_State * );
+int vlclua_acl_check( lua_State * );
+int vlclua_acl_duplicate( lua_State * );
+int vlclua_acl_add_host( lua_State * );
+int vlclua_acl_add_net( lua_State * );
+int vlclua_acl_load_file( lua_State * );
+
+
 /*****************************************************************************
  * Lua function bridge
  *****************************************************************************/
@@ -145,8 +173,15 @@ int vlclua_push_ret( lua_State *, int i_error );
 
 int vlclua_version( lua_State * );
 int vlclua_license( lua_State * );
+int vlclua_copyright( lua_State * );
 int vlclua_quit( lua_State * );
 
+int vlclua_datadir( lua_State * );
+int vlclua_homedir( lua_State * );
+int vlclua_configdir( lua_State * );
+int vlclua_cachedir( lua_State * );
+int vlclua_datadir_list( lua_State * );
+
 int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val ); /* internal use only */
 int vlclua_var_get( lua_State * );
 int vlclua_var_get_list( lua_State * );
@@ -169,6 +204,7 @@ int vlclua_stream_delete( lua_State * );
 
 int vlclua_decode_uri( lua_State * );
 int vlclua_resolve_xml_special_chars( lua_State * );
+int vlclua_convert_xml_special_chars( lua_State * );
 
 int vlclua_msg_dbg( lua_State * );
 int vlclua_msg_warn( lua_State * );
index a604fe0..baf66cc 100644 (file)
@@ -263,3 +263,83 @@ DIST_lua= \
        luaintf/modules/host.lua \
        luaintf/telnet.lua \
        luaintf/dummy.lua
+
+DIST_http_lua = \
+       http-lua/.hosts \
+       http-lua/dialogs/.hosts \
+       http-lua/dialogs/browse \
+       http-lua/dialogs/footer \
+       http-lua/dialogs/input \
+       http-lua/dialogs/main \
+       http-lua/dialogs/mosaic \
+       http-lua/dialogs/playlist \
+       http-lua/dialogs/sout \
+       http-lua/dialogs/vlm \
+       http-lua/favicon.ico \
+       http-lua/images/delete.png \
+       http-lua/images/delete_small.png \
+       http-lua/images/eject.png \
+       http-lua/images/empty.png \
+       http-lua/images/fullscreen.png \
+       http-lua/images/help.png \
+       http-lua/images/info.png \
+       http-lua/images/loop.png \
+       http-lua/images/minus.png \
+       http-lua/images/next.png \
+       http-lua/images/pause.png \
+       http-lua/images/play.png \
+       http-lua/images/playlist.png \
+       http-lua/images/playlist_small.png \
+       http-lua/images/plus.png \
+       http-lua/images/prev.png \
+       http-lua/images/refresh.png \
+       http-lua/images/repeat.png \
+       http-lua/images/sd.png \
+       http-lua/images/shuffle.png \
+       http-lua/images/slider_bar.png \
+       http-lua/images/slider_left.png \
+       http-lua/images/slider_point.png \
+       http-lua/images/slider_right.png \
+       http-lua/images/snapshot.png \
+       http-lua/images/slow.png \
+       http-lua/images/sort.png \
+       http-lua/images/sout.png \
+       http-lua/images/speaker.png \
+       http-lua/images/speaker_mute.png \
+       http-lua/images/stop.png \
+       http-lua/images/vlc16x16.png \
+       http-lua/images/volume_down.png \
+       http-lua/images/volume_up.png \
+       http-lua/images/white.png \
+       http-lua/images/white_cross_small.png \
+       http-lua/index.html \
+       http-lua/js/functions.js \
+       http-lua/js/mosaic.js \
+       http-lua/js/vlm.js \
+       http-lua/mosaic.html \
+       http-lua/old/.hosts \
+       http-lua/old/admin/.access \
+       http-lua/old/admin/browse.html \
+       http-lua/old/admin/dboxfiles.html \
+       http-lua/old/admin/index.html \
+       http-lua/old/cone_minus.png \
+       http-lua/old/cone_plus.png \
+       http-lua/old/index.html \
+       http-lua/old/info.html \
+       http-lua/old/style.css \
+       http-lua/old/vlm/edit.html \
+       http-lua/old/vlm/index.html \
+       http-lua/old/vlm/new.html \
+       http-lua/old/vlm/show.html \
+       http-lua/old/webcam.html \
+       http-lua/requests/browse.xml \
+       http-lua/requests/playlist.xml \
+       http-lua/requests/status.xml \
+       http-lua/requests/vlm.xml \
+       http-lua/requests/vlm_cmd.xml \
+       http-lua/requests/readme \
+       http-lua/style.css \
+       http-lua/iehacks.css \
+       http-lua/vlm.html \
+       http-lua/vlm_export.html \
+       http-lua/flash.html
diff --git a/share/http-lua/.hosts b/share/http-lua/.hosts
new file mode 100644 (file)
index 0000000..6f54ae0
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Access-list for VLC HTTP interface
+# $Id$
+#
+
+# localhost
+::1
+127.0.0.1
+
+# link-local addresses
+#fe80::/64
+
+# private addresses
+#fc00::/7
+#fec0::/10
+#10.0.0.0/8
+#172.16.0.0/12
+#192.168.0.0/16
+#169.254.0.0/16
+
+# The world (uncommenting these 2 lines is not quite safe)
+#::/0
+#0.0.0.0/0
+
diff --git a/share/http-lua/custom.lua b/share/http-lua/custom.lua
new file mode 100644 (file)
index 0000000..962a04d
--- /dev/null
@@ -0,0 +1,25 @@
+local _G = _G
+module("custom",package.seeall)
+
+local dialogs_cache = {}
+
+function dialog_preload(name)
+    if not dialogs_cache[name] then
+        -- Cache the dialogs
+        dialogs_cache[name] = process(http_dir.."/dialogs/"..name)
+    end
+end
+
+function dialog(name)
+    dialog_preload(name)
+    dialogs_cache[name]()
+end
+
+function dialogs(...)
+    for i=1,select("#",...) do
+        dialog(select(i,...))
+    end
+end
+
+_G.dialogs = dialogs
+_G.vlm = vlc.vlm.new()
diff --git a/share/http-lua/dialogs/.hosts b/share/http-lua/dialogs/.hosts
new file mode 100644 (file)
index 0000000..bec63ac
--- /dev/null
@@ -0,0 +1,2 @@
+# This file is an empty access list. Leave it as is.
+# You are not supposed to access files from this directory directly.
diff --git a/share/http-lua/dialogs/browse b/share/http-lua/dialogs/browse
new file mode 100644 (file)
index 0000000..35377f7
--- /dev/null
@@ -0,0 +1,45 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  browse: VLC media player web interface - remote file browse dialog
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: <none>
+]]?>
+
+<div id="browse" class="popup" style="display: none;">
+  <div class="title">
+    Browse
+    <img class="close" src="images/white_cross_small.png" alt="Close" onclick="hide('browse');"/>
+  </div>
+  <div id="browser">
+    <a href="javascript:browse_dir(document.getElementById( 'browse_lastdir' ).value);">Click here to browse</a>
+    ( or <a href="javascript:browse_dir('');">here</a> if it doesn't work )
+  </div>
+  <div class="controls">
+    <button id="btn_browse_close" onclick="hide('browse');">
+      Close
+    </button>
+    <input type="hidden" id="browse_lastdir" value="~" />
+    <input type="hidden" id="browse_dest" value="" />
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/footer b/share/http-lua/dialogs/footer
new file mode 100644 (file)
index 0000000..dd48313
--- /dev/null
@@ -0,0 +1,37 @@
+<?vlc  --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  footer: VLC media player web interface - VLC copyright footer
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: <none>
+]]?>
+
+<div id="footer" class="dialog" >
+  <a href="/">main VLC interface</a> -
+  <a href="/vlm.html">VLM interface</a> -
+  <a href="/mosaic.html">Mosaic wizard</a> -
+  <a href="/flash.html">Flash based remote playback</a> -
+  <a href="http://www.videolan.org">VideoLAN website</a>
+  <br />
+  <?vlc print(vlc.copyright()) ?>
+</div>
diff --git a/share/http-lua/dialogs/input b/share/http-lua/dialogs/input
new file mode 100644 (file)
index 0000000..fd09943
--- /dev/null
@@ -0,0 +1,224 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  input: VLC media player web interface - input selection dialog
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: browse
+]]?>
+
+<div id="input" class="dialog" style="display: none">
+  <div class="title">
+    Input
+    <img class="close" src="images/white_cross_small.png" alt="Close" onclick="hide('input');"/>
+  </div>
+  <div class="controls">
+    <label for="input_mrl">Input (MRL)</label>
+    <?vlc if current_page == "vlm" then ?>
+      <input type="text" name="input_mrl" id="input_mrl" size="60" onkeypress="if( event.keyCode == 13 ) vlm_input_change();"/>
+      <input type="button" value="Ok" onclick="vlm_input_change();" />
+      <input type="button" value="Cancel" onclick="hide('input');" />
+      <input type="hidden" id="input_dest" value="" />
+    <?vlc else ?>
+      <input type="text" name="input_mrl" id="input_mrl" size="60" onkeypress="if( event.keyCode == 13 ) in_play();"/>
+      <input type="button" value="Play" onclick="in_play();" />
+      <input type="button" value="Enqueue" onclick="in_enqueue();" />
+    <?vlc end ?>
+    <br/>
+    <!--<button id="btn_inhide" onclick="hide_input();">
+      Hide
+    </button>-->
+    <button id="btn_file" onclick="hide_input();show('input_file');update_input_file();">
+      File
+    </button>
+    <button id="btn_disc" onclick="hide_input();show('input_disc');update_input_disc();">
+      Disc
+    </button>
+    <button id="btn_network" onclick="hide_input();show('input_network');update_input_net();">
+      Network
+    </button>
+    <button id="btn_fake" onclick="hide_input();show('input_fake');update_input_fake();">
+      Fixed image
+    </button>
+  </div>
+  <div id="input_helper" class="helper" >
+    <div id="input_file" style="display: block">
+      Open File
+      <hr/>
+      <label for="input_file_filename">File name</label>
+      <input type="text" id="input_file_filename" size="60" onchange="update_input_file();" onfocus="update_input_file();"/>
+      <input type="button" id="input_file_browse" value="Browse" onclick="browse( 'input_file_filename' );" />
+      <!-- <hr/>
+      <input type="checkbox" id="input_sub_options" />
+      <label for="input_sub_options">Subtitle options *TODO/FIXME/FIXHTTPD*</label>
+      <br/>
+      <label for="input_sub_file">Subtitles file</label>
+      <input type="text" id="input_sub_file" size="60" />
+      <br/>
+      <label for="input_sub_enc">Subtitles encoding</label>
+      <select id="input_sub_enc">
+        <option></option>
+      </select>
+      <br/>
+      <label for="input_sub_size">Font size</label>
+      <select id="input_sub_size">
+        <option></option>
+      </select>
+      <label for="input_sub_justification">Justification</label>
+      <select id="input_sub_justification">
+        <option></option>
+      </select>
+      <br/>
+      <label for="input_sub_fps">Frames per second</label>
+      <input type="text" id="input_sub_fps" />
+      <label for="input_sub_delay">Delay</label>
+      <input type="text" id="input_sub_delay" />-->
+    </div>
+    <div id="input_disc" style="display: none">
+      Open Disc
+      <hr/>
+      Disc type :
+      <input type="radio" name="input_disc_type" id="input_disc_dvdmenu" value="dvd" onchange="update_input_disc();" />
+      <label for="input_disc_dvdmenu">DVD (menus)</label>
+      <input type="radio" name="input_disc_type" id="input_disc_dvd" value="dvdsimple" onchange="update_input_disc();" />
+      <label for="input_disc_dvd">DVD</label>
+      <input type="radio" name="input_disc_type" id="input_disc_vcd" value="vcd" onchange="update_input_disc();" />
+      <label for="input_disc_vcd">VCD</label>
+      <input type="radio" name="input_disc_type" id="input_disc_cdda" value="cdda" onchange="update_input_disc();" />
+      <label for="input_disc_cdda">Audio CD</label>
+      <hr/>
+      <table>
+        <tr>
+          <td>
+            <label for="input_disc_dev">Device name</label>
+          </td>
+          <td>
+            <input type="text" id="input_disc_dev" onchange="update_input_disc();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <label for="input_disc_title">Title</label>
+          </td>
+          <td>
+            <input type="text" id="input_disc_title" onchange="update_input_disc();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <label for="input_disc_chapter">Chapter</label>
+          </td>
+          <td>
+            <input type="text" id="input_disc_chapter" onchange="update_input_disc();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <label for="input_disc_subtrack">Subtitles track</label>
+          </td>
+          <td>
+             <input type="text" id="input_disc_subtrack" onchange="update_input_disc();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <label for="input_disc_audiotrack">Audio track</label>
+          </td>
+          <td>
+            <input type="text" id="input_disc_audiotrack" onchange="update_input_disc();" />
+          </td>
+        </tr>
+      </table>
+    </div>
+    <div id="input_network" style="display: none">
+      Open Network
+      <hr/>
+      <table>
+        <tr>
+          <td>
+            <input type="radio" name="input_net_type" id="input_net_udp" value="udp" onchange="update_input_net();" />
+            <label for="input_net_udp">UDP/RTP</label>
+          </td>
+          <td>
+            <label for="input_net_udp_port">Port</label>
+            <input type="text" id="input_net_udp_port" size="6" onchange="update_input_net();" />
+            <input type="checkbox" id="input_net_udp_forceipv6" onchange="update_input_net();" />
+            <label for="input_net_udp_forceipv6">Force IPv6</label>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="radio" name="input_net_type" id="input_net_udpmcast" value="udpmcast" onchange="update_input_net();" />
+            <label for="input_net_udpmcast">UDP/RTP Multicast</label>
+          </td>
+          <td>
+            <label for="input_net_udpmcast_address">Address</label>
+            <input type="text" id="input_net_udpmcast_address" onchange="update_input_net();" />
+            <label for="input_net_udpmcast_port">Port</label>
+            <input type="text" id="input_net_udpmcast_port" size="6" onchange="update_input_net();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="radio" name="input_net_type" id="input_net_http" value="http" onchange="update_input_net();" />
+            <label for="input_net_http">HTTP/HTTPS/FTP/MMS</label>
+          </td>
+          <td>
+            <label for="input_net_http_url">URL</label>
+            <input type="text" id="input_net_http_url" onchange="update_input_net();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="radio" name="input_net_type" id="input_net_rtsp" value="rtsp" onchange="update_input_net();" />
+            <label for="input_net_rtsp">RTSP</label>
+          </td>
+          <td>
+            <label for="input_net_rtsp_url">URL</label>
+            <input type="text" id="input_net_rtsp_url" value="rtsp://" onchange="update_input_net();" />
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="input_net_timeshift" onchange="update_input_net();" />
+            <label for="input_net_timeshift">Allow timeshifting</label>
+          </td>
+          <td></td>
+        </tr>
+      </table>
+    </div>
+    <div id="input_fake" style="display: none">
+      Fixed image stream (fake)
+      <hr/>
+      <label for="input_fake_filename">Image file name</label>
+      <input type="text" id="input_fake_filename" size="60" onchange="update_input_fake();" onfocus="update_input_fake();"/>
+      <input type="button" id="input_fake_browse" value="Browse" onclick="browse( 'input_fake_filename' );" />
+      <hr/>
+      <label for="input_fake_width">Width</label>
+      <input type="text" id="input_fake_width" size="8" onchange="update_input_fake();" />
+      <label for="input_fake_height">Height</label>
+      <input type="text" id="input_fake_height" size="8" onchange="update_input_fake();" />
+      <label for="input_fake_ar">Aspect ratio</label>
+      <input type="text" id="input_fake_ar" size="8" onchange="update_input_fake();" />
+    </div>
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/main b/share/http-lua/dialogs/main
new file mode 100644 (file)
index 0000000..e213b4b
--- /dev/null
@@ -0,0 +1,120 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  main: VLC media player web interface - main VLC controler
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: input,
+sout and playlist .
+]]?>
+
+<div id="main" class="dialog" >
+  <div class="title">
+    VLC media player
+    <button id="btn_toggle_text" onclick="toggle_btn_text();" title="Help" >
+      <img src="images/help.png" alt="Help" />
+      Help
+    </button>
+  </div>
+  <div class="controls">
+    <button id="btn_open" onclick="toggle_show('input');" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Open" >
+      <img src="images/eject.png" alt="Open" />
+      <span class="btn_text">Open</span>
+    </button>
+    &nbsp;
+    <button id="btn_stop" onclick="pl_stop();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Stop" >
+      <img src="images/stop.png" alt="Stop" />
+      <span class="btn_text">Stop</span>
+    </button>
+    <!--<button id="btn_play" onclick="alert('FIXME');" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Play" >
+      <img src="images/play.png" alt="Play" />
+      <span class="btn_text">Play</span>
+    </button>-->
+    <button id="btn_pause" onclick="pl_pause();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Pause" >
+      <img src="images/pause.png" alt="Pause" id="btn_pause_img" />
+      <span class="btn_text">Pause</span>
+    </button>
+    &nbsp;
+    <button id="btn_previous" onclick="pl_previous();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Previous" >
+      <img src="images/prev.png" alt="Previous" />
+      <span class="btn_text">Previous</span>
+    </button>
+    <button id="btn_next" onclick="pl_next();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Next" >
+      <img src="images/next.png" alt="Next" />
+      <span class="btn_text">Next</span>
+    </button>
+    &nbsp;
+    <button id="btn_sout" onclick="toggle_show('sout');" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Stream Output" >
+      <img src="images/sout.png" alt="Stream Output" />
+      <span class="btn_text">Stream Output</span>
+    </button>
+    <button id="btn_playlist" onclick="toggle_show('playlist');" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Playlist" >
+      <img src="images/playlist.png" alt="Playlist" />
+      <span class="btn_text">Playlist</span>
+    </button>
+    <button id="btn_info" onclick="toggle_show('info');" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Info" >
+      <img src="images/info.png" alt="Info" />
+      <span class="btn_text">Info</span>
+    </button>
+    &nbsp;
+    <button id="btn_fullscreen" onclick="fullscreen();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Fullscreen" >
+      <img src="images/fullscreen.png" alt="Fullscreen" />
+      <span class="btn_text">Fullscreen</span>
+    </button>
+    &nbsp;
+    <button id="btn_snapshot" onclick="snapshot();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Take video snapshot" >
+      <img src="images/snapshot.png" alt="Take video snapshot" />
+      <span class="btn_text">Take video snapshot</span>
+    </button>
+    &nbsp;
+    <button id="btn_volume_down" onclick="volume_down();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Decrease Volume" >
+      <img src="images/volume_down.png" alt="Decrease Volume" />
+      <span class="btn_text">Decrease Volume</span>
+    </button>
+    <button id="btn_volume_up" onclick="volume_up();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Increase Volume" >
+      <img src="images/volume_up.png" alt="Increase Volume" />
+      <span class="btn_text">Increase Volume</span>
+    </button>
+  </div>
+  <div id="status">
+    <span id="state">(?)</span>
+    -
+    Time : <span id="time">(?)</span>/<span id="length">(?)</span>
+    -
+    Volume : <span id="volume">(?)</span>
+    <br/>
+    <!-- progress bar -->
+    <img src="images/slider_left.png" alt="slider left" /><span id="progressbar" style="background-image: url( 'images/slider_bar.png' ); width: 408px; height:16px; position:absolute;" onclick="slider_seek( event, this );" onmousemove="slider_move( event, this );"><img src="images/slider_point.png" alt="slider point" style="position:relative; left:0px;" id="main_slider_point" onmousedown="slider_down( event, this );" onmouseup="slider_up( event, this.parentNode );" onmouseout="slider_up( event, this.parentNode );"/></span><img src="images/slider_right.png" alt="slider right" style="position:relative;left:408px;" />
+    <br/>
+    <span id="nowplaying">(?)</span>
+    <img id="albumart" alt="" src="/art" style="float: right" onclick="refresh_albumart(true);"/>
+  </div>
+</div>
+
+<div id="info" class="dialog" style="display: none;" >
+  <div class="title">
+    Stream and media info
+    <img class="close" src="images/white_cross_small.png" alt="Close" onclick="hide('info');"/>
+  </div>
+  <div id="infotree">
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/mosaic b/share/http-lua/dialogs/mosaic
new file mode 100644 (file)
index 0000000..cf7bfd1
--- /dev/null
@@ -0,0 +1,116 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  mosaic: VLC media player web interface - mosaic wizard
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: input and
+sout.
+]]?>
+
+<div id="mosaic" class="dialog">
+  <div class="title">
+    VLC media player - Mosaic wizard
+    <button id="btn_toggle_text" onclick="toggle_btn_text();">
+      <img src="images/help.png" alt="Help" />
+      Help
+    </button>
+  </div>
+  <div class="controls">
+    <b>Mosaic dimensions:</b><br/>
+    <table style="text-align: right;">
+      <tr>
+        <td>
+          <label for="bg_width">Background width*:</label> <input class="mosaic_bg" type="text" id="bg_width" value="400" size="8" onchange="mosaic_size_change();" />
+        </td>
+        <td>
+          <label for="bg_height">Background height*:</label> <input class="mosaic_bg" type="text" id="bg_height" value="300" size="8" onchange="mosaic_size_change();" />
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="mosaic_width">Width:</label> <input class="mosaic_tbl" type="text" id="mosaic_width" value="200" size="8" onchange="mosaic_size_change();" />
+        </td>
+        <td>
+          <label for="mosaic_height">Height:</label> <input class="mosaic_tbl" type="text" id="mosaic_height" value="200" size="8" onchange="mosaic_size_change();" />
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="mosaic_xoffset">X offset (left):</label> <input class="mosaic_tbl" type="text" id="mosaic_xoffset" value="10" size="8" onchange="mosaic_size_change();" />
+        </td>
+        <td>
+          <label for="mosaic_yoffset">Y offset (top):</label> <input class="mosaic_tbl" type="text" id="mosaic_yoffset" value="10" size="8" onchange="mosaic_size_change();" />
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="mosaic_cols">Columns:</label> <input class="mosaic_itm" type="text" id="mosaic_cols" value="2" size="8" onchange="mosaic_size_change();" />
+        </td>
+        <td>
+          <label for="mosaic_rows">Rows:</label> <input class="mosaic_itm" type="text" id="mosaic_rows" value="2" size="8" onchange="mosaic_size_change();" />
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="mosaic_hborder">Horizontal border:</label> <input class="mosaic_itm" type="text" id="mosaic_hborder" value="10" size="8" onchange="mosaic_size_change();" />
+        </td>
+        <td>
+          <label for="mosaic_vborder">Vertical border:</label> <input class="mosaic_itm" type="text" id="mosaic_vborder" value="5" size="8" onchange="mosaic_size_change();" />
+        </td>
+      </tr>
+      <tr>
+        <td colspan="2">
+        *: these values aren't used by the mosaic code.<br/> They're only here to adapt the preview's size.
+        </td>
+      </tr>
+    </table>
+    <b>Background:</b><br/>
+    <label for="mosaic_bg_input">Input:<label> <input type="text" id="mosaic_bg_input" class="mosaic_bg" value="" size="60" onblur="mosaic_code_update();" /> <input type="button" value="Edit" onclick="vlm_input_edit( 'mosaic_bg_input' );" /><br/>
+    <b>Item:</b><br/>
+    <label for="mosaic_input_name">Name:</label> <input type="text" id="mosaic_input_name" value="" class="mosaic_itm" />
+    <label for="mosaic_input">Input:</label> <input type="text" id="mosaic_input" value="" class="mosaic_itm" /> <input type="button" value="Edit" onclick="vlm_input_edit( 'mosaic_input' );" /> <input type="button" value="Add to input list" onclick="mosaic_add_input();" /><br/>
+    <b>Stream:</b> (leave this empty to display locally)<br/>
+    <label for="mosaic_output">Output:</label> <input type="text" id="mosaic_output" value="" size="60" onblur="mosaic_code_update();" /> <input type="button" value="Edit" onclick="vlm_output_edit( 'mosaic_output' );" /><br/>
+    <div id="mosaic_feedback"></div>
+  </div>
+  <div  id="mosaic_list" class="popup">[<a href="javascript:hide('mosaic_list');">hide</a>] - Select a stream:<br/><div id="mosaic_list_content"></div></div>
+  <div class="controls">
+    Click on each of the cells to assign inputs. (<a href="javascript:document.getElementById('mosaic_list').value='';show('mosaic_list');">Show input list</a>)
+  </div>
+</div>
+
+<div id="mosaic_layout" class="mosaic_bg"></div>
+
+<div class="dialog" style="overflow:visible;">
+  <div class="controls">
+    <input type="button" value="Let's go!" onclick="mosaic_batch(document.getElementById('mosaic_code').value);" />
+    <input type="button" value="Stop" onclick="mosaic_stop()" />
+    <input type="button" id="mosaic_code_show" value="Show VLM code" onclick="show('mosaic_code_div');hide('mosaic_code_show');showinline('mosaic_code_hide');" />
+    <input type="button" id="mosaic_code_hide" style="display:none" value="Hide VLM code" onclick="hide('mosaic_code_div');hide('mosaic_code_hide');showinline('mosaic_code_show');" />
+    <br/><br/>
+  </div>
+  <div id="mosaic_code_div" style="display:none;" >
+    Edit the following VLM command batch if you want to fine tune your mosaic settings:
+  <textarea id="mosaic_code" cols="80" rows="30"></textarea>
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/playlist b/share/http-lua/dialogs/playlist
new file mode 100644 (file)
index 0000000..dbb8500
--- /dev/null
@@ -0,0 +1,94 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  playlist: VLC media player web interface - playlist dialog
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+This dialog needs the following dialogs to be fully functional: <none>
+]]?>
+
+<div id="playlist" class="dialog" >
+  <div class="title">
+    Playlist
+    <img class="close" src="images/white_cross_small.png" alt="Close" onclick="hide('playlist');"/>
+  </div>
+  <div class="controls">
+    <table>
+      <tr>
+        <td>
+          <!--<button id="btn_delete" onmouseover="button_over(this);" onmouseout="button_out(this);">
+            <img src="images/delete.png" alt="Delete" />
+            <span class="btn_text">Delete</span>
+          </button>-->
+          <button id="btn_empty" onclick="pl_empty();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Empty" >
+            <img src="images/empty.png" alt="Empty" />
+            <span class="btn_text">Empty</span>
+          </button>
+          <button id="btn_shuffle" onclick="pl_shuffle();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Shuffle" >
+            <img src="images/shuffle.png" alt="Shuffle" />
+            <span class="btn_text">Shuffle</span>
+          </button>
+          <button id="btn_loop" onclick="pl_loop();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Loop" >
+            <img src="images/loop.png" alt="Loop" />
+            <span class="btn_text">Loop</span>
+          </button>
+          <button id="btn_repeat" onclick="pl_repeat();" onmouseover="button_over(this);" onmouseout="button_out(this);" title="Repeat" >
+            <img src="images/repeat.png" alt="Repeat" />
+            <span class="btn_text">Repeat</span>
+          </button>
+        </td>
+        <td onmouseout="hide_menu('menu_sort');" onmouseover="show_menu('menu_sort');" >
+          <button id="btn_sort" title="Sort" >
+            <img src="images/sort.png" alt="Sort" />
+            <span class="btn_text">Sort</span>
+          </button>
+          <div id="menu_sort" class="menu" >
+            <button class="menuout" onclick="pl_sort(1,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Name ascending" >Name</button><br/>
+            <button class="menuout" onclick="pl_sort(1,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Name descending" >Name reverse</button><br/>
+            <button class="menuout" onclick="pl_sort(3,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Author ascending" >Author</button><br/>
+            <button class="menuout" onclick="pl_sort(3,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Author ascending" >Author reverse</button><br/>
+            <button class="menuout" onclick="pl_sort(5,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Randomize" >Random</button><br/>
+            <button class="menuout" onclick="pl_sort(7,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Track number" >Track number</button><br/>
+            <button class="menuout" onclick="pl_sort(0,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id ascending" >Id</button><br/>
+            <button class="menuout" onclick="pl_sort(0,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id descending" >Id reverse</button><br/>
+          </div>
+        </td>
+        <td onmouseover="show_menu('menu_sd');" onmouseout="hide_menu('menu_sd');">
+          <button id="btn_sd" title="Services Discovery" >
+            <img src="images/sd.png" alt="Services Discovery" />
+            <span class="btn_text">Services Discovery</span>
+          </button>
+          <div id="menu_sd" class="menu" >
+          <?vlc --[[ FIXME
+            <vlc id="rpn" param1="services_discovery" />
+            <vlc id="foreach" param1="sd" param2="object" />
+            <button onclick="pl_sd('<vlc id="value" param1="sd" />');hide_menu('menu_sd');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" class="menuout" title="Toggle <vlc id="value" param1="sd.name" />" ><vlc id="value" param1="sd.name" /></button><br/>
+            <vlc id="end" />
+          ]] ?>
+          </div>
+        </td>
+      </tr>
+    </table>
+  </div>
+  <div id="playtree">
+    (?)
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/sout b/share/http-lua/dialogs/sout
new file mode 100644 (file)
index 0000000..d8a64d5
--- /dev/null
@@ -0,0 +1,294 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  sout: VLC media player web interface - stream output dialog
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: <none>
+Note that the sout chain is used and sent to VLC by the input dialog
+]]?>
+
+<div id="sout" class="dialog" style="display: none">
+  <div class="title">
+    Stream Output
+    <img class="close" src="images/white_cross_small.png" alt="Close" onclick="hide('sout');"/>
+  </div>
+  <div class="controls">
+    <label for="sout_mrl">Destination (MRL)</label>
+    <?vlc if current_page == "vlm" then ?>
+      <input type="text" name="sout_mrl" id="sout_mrl" size="60" onkeypress="if( event.keyCode == 13 ) vlm_output_change();"/>
+      <br/>
+      <input type="button" value="Ok" onclick="vlm_output_change();" />
+      <input type="button" value="Cancel" onclick="hide('sout');" />
+      <input type="hidden" id="sout_dest" />
+    <?vlc else ?>
+      <input type="text" name="sout_mrl" id="sout_mrl" size="60" onkeypress="if( event.keyCode == 13 ) save_sout();" />
+      <br/>
+      <input type="button" value="Save" onclick="save_sout();" />
+    <?vlc end ?>
+    <input type="button" value="Reset" onclick="reset_sout();"/>
+    <input type="hidden" id="sout_old_mrl" value="" /> <!-- FIXME -->
+    <input type="button" id="sout_helper_toggle" onclick="toggle_show_sout_helper()" value="Hide sout interface" />
+  </div>
+  <div id="sout_helper" class="helper">
+    Stream Output Helper
+    <hr/>
+    <div id="sout_method">
+      <table>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_display" onchange="update_sout()"/>
+            <label for="sout_display">Display</label>
+          </td>
+          <td></td>
+          <td></td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_file" onchange="update_sout()"/>
+            <label for="sout_file">File</label>
+          </td>
+          <td>
+            <label for="sout_file_filename">File name</label>
+            <input type="text" id="sout_file_filename" onchange="update_sout()"/>
+          </td>
+          <td></td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_http" onchange="update_sout()"/>
+            <label for="sout_http">HTTP</label>
+          </td>
+          <td>
+            <label for="sout_http_addr">Address</label>
+            <input type="text" id="sout_http_addr" onchange="update_sout()"/>
+          </td>
+          <td>
+            <label for="sout_http_port">Port</label>
+            <input type="text" id="sout_http_port" onchange="update_sout()"/>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_mmsh" onchange="update_sout()"/>
+            <label for="sout_mmsh">MMSH</label>
+          </td>
+          <td>
+            <label for="sout_mmsh_addr">Address</label>
+            <input type="text" id="sout_mmsh_addr" onchange="update_sout()"/>
+          </td>
+          <td>
+            <label for="sout_mmsh_port">Port</label>
+            <input type="text" id="sout_mmsh_port" onchange="update_sout()"/>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_rtp" onchange="update_sout()"/>
+            <label for="sout_rtp">RTP</label>
+          </td>
+          <td>
+            <label for="sout_rtp_addr">Address</label>
+            <input type="text" id="sout_rtp_addr" onchange="update_sout()"/>
+          </td>
+          <td>
+            <label for="sout_rtp_port">Port</label>
+            <input type="text" id="sout_rtp_port" onchange="update_sout()"/>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_udp" onchange="update_sout()"/>
+            <label for="sout_udp">UDP</label>
+          </td>
+          <td>
+            <label for="sout_udp_addr">Address</label>
+            <input type="text" id="sout_udp_addr" onchange="update_sout()"/>
+          </td>
+          <td>
+            <label for="sout_udp_port">Port</label>
+            <input type="text" id="sout_udp_port" onchange="update_sout()"/>
+          </td>
+        </tr>
+      </table>
+    </div>
+    <hr/>
+    <div id="sout_muxh">
+      <input type="radio" name="sout_mux" id="sout_mux_default" value="" onchange="update_sout()" />
+      <label for="sout_mux_default">Default</label>
+      <input type="radio" name="sout_mux" id="sout_mux_ts" value="ts" onchange="update_sout()"/>
+      <label for="sout_mux_ts">MPEG TS</label>
+      <input type="radio" name="sout_mux" id="sout_mux_ps" value="ps" onchange="update_sout()"/>
+      <label for="sout_mux_ps">MPEG PS</label>
+      <input type="radio" name="sout_mux" id="sout_mux_mpeg1" value="mpeg1" onchange="update_sout()"/>
+      <label for="sout_mux_ts">MPEG 1</label>
+      <input type="radio" name="sout_mux" id="sout_mux_ogg" value="ogg" onchange="update_sout()"/>
+      <label for="sout_mux_ts">OGG</label>
+      <br/>
+      <input type="radio" name="sout_mux" id="sout_mux_asf" value="asf" onchange="update_sout()"/>
+      <label for="sout_mux_ts">ASF</label>
+      <input type="radio" name="sout_mux" id="sout_mux_mp4" value="mp4" onchange="update_sout()"/>
+      <label for="sout_mux_ts">MP4</label>
+      <input type="radio" name="sout_mux" id="sout_mux_mov" value="mov" onchange="update_sout()"/>
+      <label for="sout_mux_ts">MOV</label>
+      <input type="radio" name="sout_mux" id="sout_mux_wav" value="wav" onchange="update_sout()"/>
+      <label for="sout_mux_ts">WAV</label>
+      <input type="radio" name="sout_mux" id="sout_mux_raw" value="raw" onchange="update_sout()"/>
+      <label for="sout_mux_ts">Raw</label>
+    </div>
+    <hr/>
+    <div id="sout_transcode">
+      <input type="hidden" id="sout_transcode_extra" value="" />
+      <table>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_vcodec_s" onchange="update_sout()"/>
+            <label for="sout_vcodec_s">Video Codec</label>
+          </td>
+          <td>
+            <select id="sout_vcodec" onchange="update_sout()">
+              <option value="mp1v">mp1v</option>
+              <option value="mp2v">mp2v</option>
+              <option value="mp4v">mp4v</option>
+              <option value="DIV1">DIV1</option>
+              <option value="DIV2">DIV2</option>
+              <option value="DIV3">DIV3</option>
+              <option value="H263">H263</option>
+              <option value="H264">H264</option>
+              <option value="WMV1">WMV1</option>
+              <option value="WMV2">WMV2</option>
+              <option value="MJPG">MJPG</option>
+              <option value="theo">theo</option>
+            </select>
+          </td>
+          <td>
+            <label for="sout_vb">Bitrate (kb/s)</label>
+            <select id="sout_vb" onchange="update_sout()">
+              <option value="4096">4096</option>
+              <option value="3072">3072</option>
+              <option value="2048">2048</option>
+              <option value="1024">1024</option>
+              <option value="768">768</option>
+              <option value="512">512</option>
+              <option value="384">384</option>
+              <option value="256">256</option>
+              <option value="192">192</option>
+              <option value="128">128</option>
+              <option value="96">96</option>
+              <option value="64">64</option>
+              <option value="32">32</option>
+              <option value="16">16</option>
+            </select>
+          </td>
+          <td>
+            <label for="sout_scale">Scale</label>
+            <select id="sout_scale" onchange="update_sout()">
+              <option value="0.25">0.25</option>
+              <option value="0.5">0.5</option>
+              <option value="0.75">0.75</option>
+              <option value="1" selected="selected">1</option>
+              <option value="1.25">1.25</option>
+              <option value="1.5">1.5</option>
+              <option value="1.75">1.75</option>
+              <option value="2">2</option>
+            </select>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_acodec_s" onchange="update_sout()"/>
+            <label for="sout_acodec_s">Audio Codec</label>
+          </td>
+          <td>
+            <select id="sout_acodec" onchange="update_sout()">
+              <option value="mpga">mpga</option>
+              <option value="mp2a">mp2a</option>
+              <option value="mp3">mp3</option>
+              <option value="mp4a">mp4a</option>
+              <option value="a52">a52</option>
+              <option value="vorb">vorb</option>
+              <option value="flac">flac</option>
+              <option value="spx">spx</option>
+              <option value="s16l">s16l</option>
+              <option value="fl32">fl32</option>
+            </select>
+          </td>
+          <td>
+            <label for="sout_ab">Bitrate (kb/s)</label>
+            <select id="sout_ab" onchange="update_sout()">
+              <option value="512">512</option>
+              <option value="384">384</option>
+              <option value="256">256</option>
+              <option value="192">192</option>
+              <option value="128">128</option>
+              <option value="96">96</option>
+              <option value="64">64</option>
+              <option value="32">32</option>
+              <option value="16">16</option>
+            </select>
+          </td>
+          <td>
+            <label for="sout_channels">Channels</label>
+            <select id="sout_channels" onchange="update_sout()">
+              <option value="">default</option>
+              <option value="1">1</option>
+              <option value="2">2</option>
+              <option value="4">4</option>
+              <option value="6">6</option>
+            </select>
+          </td>
+        </tr>
+        <tr>
+          <td>
+            <input type="checkbox" id="sout_sub" onchange="update_sout()"/>
+            <label for="sout_sub">Subtitles Codec</label>
+          </td>
+          <td>
+            <select id="sout_scodec" onchange="update_sout()">
+              <option value="dvbs">dvbs</option>
+            </select>
+          </td>
+          <td colspan="2">
+            <input type="checkbox" id="sout_soverlay" onchange="update_sout()"/>
+            <label for="sout_soverlay">Subtitles overlay</label>
+          </td>
+        </tr>
+      </table>
+    </div>
+    <hr/>
+    <div id="sout_misc">
+      <input type="checkbox" id="sout_sap" onchange="update_sout()"/>
+      <label for="sout_sap">SAP announce</label>
+      <br/>
+      <label for="sout_sap_group">Group name</label>
+      <input type="text" id="sout_sap_group" onchange="update_sout()"/>
+      <label for="sout_sap_name">Channel name</label>
+      <input type="text" id="sout_sap_name" onchange="update_sout()"/>
+      <hr/>
+      <input type="checkbox" id="sout_all" onchange="update_sout()"/>
+      <label for="sout_all">Select all elementary streams</label>
+      <hr/>
+      <label for="sout_ttl">Time-To-Live (TTL)</label>
+      <input type="text" id="sout_ttl" onchange="update_sout()"/>
+    </div>
+  </div>
+</div>
diff --git a/share/http-lua/dialogs/vlm b/share/http-lua/dialogs/vlm
new file mode 100644 (file)
index 0000000..d2394dc
--- /dev/null
@@ -0,0 +1,184 @@
+<?vlc --[[
+vim:syntax=html
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  vlm: VLC media player web interface - VLM controler
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+This dialog needs the following dialogs to be fully functional: input,
+sout and vlmelements .
+]]?>
+
+<div id="vlm" class="dialog" >
+  <div class="title">
+    VLC media player - VLM interface
+    <!--
+    <button id="btn_toggle_text" onclick="toggle_btn_text();">
+      <img src="images/help.png" alt="Help" />
+      Help
+    </button>
+    -->
+  </div>
+  <div class="controls">
+    <label for="vlm_command">VLM command:</label>
+    <input type="text" id="vlm_command" size="60" onkeypress="if( event.keyCode == 13 ) vlm_send();" />
+    <input type="button" value="Send" onclick="vlm_send();" />
+    <br />
+    <span id="vlm_error"></span>
+    <br />
+    <span id="vlm_helper_controls">
+      <button id="btn_broadcast" onclick="hide_vlm_add();show('vlm_add_broadcast');update_vlm_add_broadcast();" onmouseover="button_over(this);" onmouseout="button_out(this);">
+        Broadcast
+      </button>
+      <button id="btn_vod" onclick="hide_vlm_add();show('vlm_add_vod');update_vlm_add_vod();" onmouseover="button_over(this);" onmouseout="button_out(this);">
+        Video on Demand
+      </button>
+      <button id="btn_schedule" onclick="hide_vlm_add();show('vlm_add_schedule');update_vlm_add_schedule();" onmouseover="button_over(this);" onmouseout="button_out(this);">
+        Schedule
+      </button>
+      <button id="btn_other" onclick="hide_vlm_add();show('vlm_add_other');update_vlm_add_other();" onmouseover="button_over(this);" onmouseout="button_out(this);">
+        Other
+      </button>
+    </span>
+    <button id="btn_vlm_helper_toggle" onclick="toggle_show_vlm_helper();" onmouseover="button_over(this);" onmouseout="button_out(this);">
+      Hide VLM helper
+    </button>
+  </div>
+  <div id="vlm_helper" class="helper" >
+    <div id="vlm_add_broadcast" style="display: block">
+      New broadcast element
+      <hr />
+      <label for="vlm_broadcast_name">Name</label>
+      <input type="text" id="vlm_broadcast_name" size="20" onchange="update_vlm_add_broadcast();" />
+      <input type="checkbox" id="vlm_broadcast_enabled" onchange="update_vlm_add_broadcast();" />
+      <label for="vlm_broadcast_enabled">Enable</label>
+      <input type="checkbox" id="vlm_broadcast_loop" onchange="update_vlm_add_broadcast();" />
+      <label for="vlm_broadcast_loop">Loop</label>
+      <br/>
+      <label for="vlm_broadcast_input">Input</label>
+      <input type="text" id="vlm_broadcast_input" size="60" onblur="update_vlm_add_broadcast();" />
+      <input type="button" value="Edit" onclick="vlm_input_edit('vlm_broadcast_input');" />
+      <br/>
+      <label for="vlm_broadcast_output">Output</label>
+      <input type="text" id="vlm_broadcast_output" size="60" onblur="update_vlm_add_broadcast();" />
+      <input type="button" value="Edit" onclick="vlm_output_edit('vlm_broadcast_output');" />
+      <br/>
+    </div>
+    <div id="vlm_add_vod" style="display: none">
+      New video on demand element
+      <hr />
+      <label for="vlm_vod_name">Name</label>
+      <input type="text" id="vlm_vod_name" size="20" onchange="update_vlm_add_vod();" />
+      <input type="checkbox" id="vlm_vod_enabled" onchange="update_vlm_add_vod();" />
+      <label for="vlm_vod_enabled">Enable</label>
+      <br/>
+      <label for="vlm_vod_input">Input</label>
+      <input type="text" id="vlm_vod_input" size="60" onblur="update_vlm_add_vod();" />
+      <input type="button" value="Edit" onclick="vlm_input_edit('vlm_vod_input');" />
+      <br/>
+      <label for="vlm_vod_output">Output (leave empty unless you want to transcode)</label>
+      <input type="text" id="vlm_vod_output" size="60" onblur="update_vlm_add_vod();" />
+      <input type="button" value="Edit" onclick="vlm_output_edit('vlm_vod_output');" />
+      <br/>
+    </div>
+    <div id="vlm_add_schedule" style="display: none">
+      New schedule
+      <hr />
+      <label for="vlm_schedule_name">Name</label>
+      <input type="text" id="vlm_schedule_name" size="20" onchange="update_vlm_add_schedule();" />
+      <input type="checkbox" id="vlm_schedule_enabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_enabled">Enable</label>
+      <br />
+      Schedule date:
+      <input type="checkbox" id="vlm_schedule_now" onchange="toggle_schedule_date();update_vlm_add_schedule();" />
+      <label for="vlm_schedule_now">Now</label>
+      <br/>
+      <label for="vlm_schedule_year">Year:</label>
+      <input type="text" id="vlm_schedule_year" value="1970" size="4" maxlength="4" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_month">Month:</label>
+      <input type="text" id="vlm_schedule_month" value="01" size="2" maxlength="2" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_day">Day:</label>
+      <input type="text" id="vlm_schedule_day" value="01" size="2" maxlength="2" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_hour">Hour:</label>
+      <input type="text" id="vlm_schedule_hour" value="00" size="2" maxlength="2" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_minute">Minute:</label>
+      <input type="text" id="vlm_schedule_minute" value="59" size="2" maxlength="2" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_second">Second:</label>
+      <input type="text" id="vlm_schedule_second" value="59" size="2" maxlength="2" onchange="update_vlm_add_schedule();" />
+      <br/>
+      Schedule period:<br/>
+      <input type="checkbox" id="vlm_schedule_repeat" onchange="toggle_schedule_repeat();update_vlm_add_schedule();" />
+      <label for="vlm_schedule_repeat">Repeat</label>
+      <br />
+      <label for="vlm_schedule_period_year">Year:</label>
+      <input type="text" id="vlm_schedule_period_year" value="0" size="4" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_period_month">Month:</label>
+      <input type="text" id="vlm_schedule_period_month" value="0" size="2" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_period_day">Day:</label>
+      <input type="text" id="vlm_schedule_period_day" value="0" size="2" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_period_hour">Hour:</label>
+      <input type="text" id="vlm_schedule_period_hour" value="0" size="2" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_period_minute">Minute:</label>
+      <input type="text" id="vlm_schedule_period_minute" value="0" size="4" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <label for="vlm_schedule_period_second">Second:</label>
+      <input type="text" id="vlm_schedule_period_second" value="0" size="4" disabled="disabled" onchange="update_vlm_add_schedule();" />
+      <br />
+      <label for="vlm_schedule_repeat_times">Number of repetitions (use 0 to repeat endlessly):</label>
+      <input type="text" id="vlm_schedule_repeat_times" size="8" disabled="disabled" value="0" onchange="update_vlm_add_schedule();" />
+    </div>
+    <div id="vlm_add_other" style="display: none">
+      <input type="button" id="btn_import" onclick="vlm_batch(document.getElementById('vlm_batch_text').value);" value="Send command batch" />
+      <input type="button" id="btn_export" onclick="document.location.assign('vlm_export.html');" value="Export VLM commands (new page)" />
+      <br/>
+      <textarea cols="70" rows="20" id="vlm_batch_text">#paste your VLM commands here</textarea>
+    </div>
+  </div>
+</div>
+
+<div id="vlm_broadcast" class="dialog" >
+  <div class="title">
+    Broadcast Elements
+    <button id="btn_refresh_broadcast" onclick="vlm_get_elements();" title="Refresh" >
+      <img src="images/refresh.png" alt="Refresh" />
+    </button>
+  </div>
+  <div id="vlm_broadcast_list" class="list"></div>
+</div>
+
+<div id="vlm_vod" class="dialog" >
+  <div class="title">
+    Video on Demand Elements
+    <button id="btn_refresh_vod" onclick="vlm_get_elements();" title="Refresh" >
+      <img src="images/refresh.png" alt="Refresh" />
+    </button>
+  </div>
+  <div id="vlm_vod_list" class="list"></div>
+</div>
+
+<div id="vlm_schedule" class="dialog" >
+  <div class="title">
+    Schedule Elements
+    <button id="btn_refresh_schedule" onclick="vlm_get_elements();" title="Refresh" >
+      <img src="images/refresh.png" alt="Refresh" />
+    </button>
+  </div>
+  <div id="vlm_schedule_list" class="list"></div>
+</div>
diff --git a/share/http-lua/favicon.ico b/share/http-lua/favicon.ico
new file mode 100644 (file)
index 0000000..a7d6288
Binary files /dev/null and b/share/http-lua/favicon.ico differ
diff --git a/share/http-lua/flash.html b/share/http-lua/flash.html
new file mode 100644 (file)
index 0000000..a12ac69
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+\r
+<html xmlns="http://www.w3.org/1999/xhtml">\r
+\r
+<head>\r
+  <title>VLC media player - Web Interface with Flash Viewer</title>\r
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
+  <link href="style.css" rel="stylesheet" type="text/css" />\r
+  <!--[if IE ]>\r
+  <link href="iehacks.css" rel="stylesheet" type="text/css" />\r
+  <![endif]-->\r
+  <script type="text/javascript" src="js/functions.js"></script>\r
+<script type="text/javascript">\r
+// <![CDATA[\r
+host = document.location.toString().replace( /http:\/\//, '' ).replace( /[:/].*/, '' );\r
+// ]]>\r
+</script>\r
+</head>\r
+\r
+<body onload="hide('playlist');">\r
+<?vlc\r
+current_page = "index"\r
+dialogs("browse","main","input","playlist") ?>\r
+\r
+  <input id="sout_mrl" type="hidden" value=":sout=#transcode{vcodec=FLV1,acodec=mp3,channels=2,samplerate=44100}:std{access=http,mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/stream.flv} :no-sout-keep" />\r
+\r
+  <div style='height: 100%; width: 100%; text-align: center;'>\r
+  <object type="application/x-shockwave-flash" data="http://flowplayer.sourceforge.net/video/FlowPlayer.swf" width="800px" height="600px" id="FlowPlayer" style="z-index: 0">\r
+         <param name="allowScriptAccess" value="sameDomain" />\r
+         <param name="movie" value="http://flowplayer.sourceforge.net/video/FlowPlayer.swf" />\r
+         <param name="quality" value="high" />\r
+    <!--         <param name="scale" value="noScale" />-->\r
+         <param name="wmode" value="transparent" />\r
+       <!--  <param name="flashvars" value="config={ loop: false, initialScale: \'fit\', autoPlay: false, configInject: true}" />-->\r
+  <script type="text/javascript">\r
+// <![CDATA[\r
+  document.write( '' +\r
+'        <param name="flashvars" value="config={ loop: false, initialScale: \'fit\', autoPlay: false, playList: [{ url: \'http://' + host + ':8081/stream.flv\', controlEnabled: true}] }" />' );\r
+// ]]>\r
+</script>\r
+  </object>\r
+  <p style="font-size: small;">Uses the <a href="http://flowplayer.sourceforge.net/">Flow Player</a> free flash video player for playback (client side).</p>\r
+  </div>\r
+\r
+<?vlc dialogs("footer") ?>\r
+</body>\r
+\r
+</html>\r
diff --git a/share/http-lua/iehacks.css b/share/http-lua/iehacks.css
new file mode 100644 (file)
index 0000000..2d51ff1
--- /dev/null
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * iehacks.css: VLC media player web interface
+ *****************************************************************************
+ * Copyright (C) 2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+div.menu {
+       margin-left: -30px;
+       margin-top: 15px;
+       background: #fff;
+}
+div.menu button {
+        background: #fff;
+}
+div.menu button.menuout {
+        border: 1px solid #fff;
+}
+
+div#mosaic_list {
+       background: #fff;
+}
diff --git a/share/http-lua/images/delete.png b/share/http-lua/images/delete.png
new file mode 100644 (file)
index 0000000..d1fab0f
Binary files /dev/null and b/share/http-lua/images/delete.png differ
diff --git a/share/http-lua/images/delete_small.png b/share/http-lua/images/delete_small.png
new file mode 100644 (file)
index 0000000..43287f6
Binary files /dev/null and b/share/http-lua/images/delete_small.png differ
diff --git a/share/http-lua/images/eject.png b/share/http-lua/images/eject.png
new file mode 100644 (file)
index 0000000..53eaacc
Binary files /dev/null and b/share/http-lua/images/eject.png differ
diff --git a/share/http-lua/images/empty.png b/share/http-lua/images/empty.png
new file mode 100644 (file)
index 0000000..3925da2
Binary files /dev/null and b/share/http-lua/images/empty.png differ
diff --git a/share/http-lua/images/fullscreen.png b/share/http-lua/images/fullscreen.png
new file mode 100644 (file)
index 0000000..e3fe7fd
Binary files /dev/null and b/share/http-lua/images/fullscreen.png differ
diff --git a/share/http-lua/images/help.png b/share/http-lua/images/help.png
new file mode 100644 (file)
index 0000000..5b18b03
Binary files /dev/null and b/share/http-lua/images/help.png differ
diff --git a/share/http-lua/images/info.png b/share/http-lua/images/info.png
new file mode 100644 (file)
index 0000000..3f77f1e
Binary files /dev/null and b/share/http-lua/images/info.png differ
diff --git a/share/http-lua/images/loop.png b/share/http-lua/images/loop.png
new file mode 100644 (file)
index 0000000..acc5499
Binary files /dev/null and b/share/http-lua/images/loop.png differ
diff --git a/share/http-lua/images/minus.png b/share/http-lua/images/minus.png
new file mode 100644 (file)
index 0000000..0c504cc
Binary files /dev/null and b/share/http-lua/images/minus.png differ
diff --git a/share/http-lua/images/next.png b/share/http-lua/images/next.png
new file mode 100644 (file)
index 0000000..67136ff
Binary files /dev/null and b/share/http-lua/images/next.png differ
diff --git a/share/http-lua/images/pause.png b/share/http-lua/images/pause.png
new file mode 100644 (file)
index 0000000..4c33caf
Binary files /dev/null and b/share/http-lua/images/pause.png differ
diff --git a/share/http-lua/images/play.png b/share/http-lua/images/play.png
new file mode 100644 (file)
index 0000000..7b47c69
Binary files /dev/null and b/share/http-lua/images/play.png differ
diff --git a/share/http-lua/images/playlist.png b/share/http-lua/images/playlist.png
new file mode 100644 (file)
index 0000000..b96e2b0
Binary files /dev/null and b/share/http-lua/images/playlist.png differ
diff --git a/share/http-lua/images/playlist_small.png b/share/http-lua/images/playlist_small.png
new file mode 100644 (file)
index 0000000..23f37d7
Binary files /dev/null and b/share/http-lua/images/playlist_small.png differ
diff --git a/share/http-lua/images/plus.png b/share/http-lua/images/plus.png
new file mode 100644 (file)
index 0000000..c866a0c
Binary files /dev/null and b/share/http-lua/images/plus.png differ
diff --git a/share/http-lua/images/prev.png b/share/http-lua/images/prev.png
new file mode 100644 (file)
index 0000000..988c08a
Binary files /dev/null and b/share/http-lua/images/prev.png differ
diff --git a/share/http-lua/images/refresh.png b/share/http-lua/images/refresh.png
new file mode 100644 (file)
index 0000000..6453350
Binary files /dev/null and b/share/http-lua/images/refresh.png differ
diff --git a/share/http-lua/images/repeat.png b/share/http-lua/images/repeat.png
new file mode 100644 (file)
index 0000000..9c7e2b0
Binary files /dev/null and b/share/http-lua/images/repeat.png differ
diff --git a/share/http-lua/images/sd.png b/share/http-lua/images/sd.png
new file mode 100644 (file)
index 0000000..6e72704
Binary files /dev/null and b/share/http-lua/images/sd.png differ
diff --git a/share/http-lua/images/shuffle.png b/share/http-lua/images/shuffle.png
new file mode 100644 (file)
index 0000000..f47a59d
Binary files /dev/null and b/share/http-lua/images/shuffle.png differ
diff --git a/share/http-lua/images/slider_bar.png b/share/http-lua/images/slider_bar.png
new file mode 100644 (file)
index 0000000..ad03479
Binary files /dev/null and b/share/http-lua/images/slider_bar.png differ
diff --git a/share/http-lua/images/slider_left.png b/share/http-lua/images/slider_left.png
new file mode 100644 (file)
index 0000000..342c570
Binary files /dev/null and b/share/http-lua/images/slider_left.png differ
diff --git a/share/http-lua/images/slider_point.png b/share/http-lua/images/slider_point.png
new file mode 100644 (file)
index 0000000..07acc75
Binary files /dev/null and b/share/http-lua/images/slider_point.png differ
diff --git a/share/http-lua/images/slider_right.png b/share/http-lua/images/slider_right.png
new file mode 100644 (file)
index 0000000..1b15f8b
Binary files /dev/null and b/share/http-lua/images/slider_right.png differ
diff --git a/share/http-lua/images/slow.png b/share/http-lua/images/slow.png
new file mode 100644 (file)
index 0000000..78d0376
Binary files /dev/null and b/share/http-lua/images/slow.png differ
diff --git a/share/http-lua/images/snapshot.png b/share/http-lua/images/snapshot.png
new file mode 100644 (file)
index 0000000..6890d02
Binary files /dev/null and b/share/http-lua/images/snapshot.png differ
diff --git a/share/http-lua/images/sort.png b/share/http-lua/images/sort.png
new file mode 100644 (file)
index 0000000..786efba
Binary files /dev/null and b/share/http-lua/images/sort.png differ
diff --git a/share/http-lua/images/sout.png b/share/http-lua/images/sout.png
new file mode 100644 (file)
index 0000000..a6763ec
Binary files /dev/null and b/share/http-lua/images/sout.png differ
diff --git a/share/http-lua/images/speaker.png b/share/http-lua/images/speaker.png
new file mode 100644 (file)
index 0000000..85f87b1
Binary files /dev/null and b/share/http-lua/images/speaker.png differ
diff --git a/share/http-lua/images/speaker_mute.png b/share/http-lua/images/speaker_mute.png
new file mode 100644 (file)
index 0000000..977e395
Binary files /dev/null and b/share/http-lua/images/speaker_mute.png differ
diff --git a/share/http-lua/images/stop.png b/share/http-lua/images/stop.png
new file mode 100644 (file)
index 0000000..d905a49
Binary files /dev/null and b/share/http-lua/images/stop.png differ
diff --git a/share/http-lua/images/vlc16x16.png b/share/http-lua/images/vlc16x16.png
new file mode 100644 (file)
index 0000000..ce7633e
Binary files /dev/null and b/share/http-lua/images/vlc16x16.png differ
diff --git a/share/http-lua/images/volume_down.png b/share/http-lua/images/volume_down.png
new file mode 100644 (file)
index 0000000..8de46a1
Binary files /dev/null and b/share/http-lua/images/volume_down.png differ
diff --git a/share/http-lua/images/volume_up.png b/share/http-lua/images/volume_up.png
new file mode 100644 (file)
index 0000000..f489246
Binary files /dev/null and b/share/http-lua/images/volume_up.png differ
diff --git a/share/http-lua/images/white.png b/share/http-lua/images/white.png
new file mode 100644 (file)
index 0000000..3d3841b
Binary files /dev/null and b/share/http-lua/images/white.png differ
diff --git a/share/http-lua/images/white_cross_small.png b/share/http-lua/images/white_cross_small.png
new file mode 100644 (file)
index 0000000..4a47e63
Binary files /dev/null and b/share/http-lua/images/white_cross_small.png differ
diff --git a/share/http-lua/index.html b/share/http-lua/index.html
new file mode 100644 (file)
index 0000000..fa4bb7b
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  index.html: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+
+  <title>VLC media player - Web Interface</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=<?vlc --[[ <vlc id="value" param1="charset"/> ]] ?>" />
+  <link href="style.css" rel="stylesheet" type="text/css" />
+  <!--[if IE ]>
+  <link href="iehacks.css" rel="stylesheet" type="text/css" />
+  <![endif]-->
+  <script type="text/javascript" src="js/functions.js"></script>
+
+</head>
+
+<body onload="loop_refresh();">
+
+<noscript>
+  <hr/>
+  <p>
+  Warning: Your browser doesn't support javascript.
+  You should use the <a href="old/">old http interface</a>.
+  </p>
+  <hr/>
+</noscript>
+
+<?vlc
+current_page = "index"
+
+dialogs("browse","main","input","sout","playlist","footer")
+?>
+
+</body>
+
+</html>
diff --git a/share/http-lua/js/functions.js b/share/http-lua/js/functions.js
new file mode 100644 (file)
index 0000000..1a141d4
--- /dev/null
@@ -0,0 +1,1077 @@
+/*****************************************************************************
+ * functions.js: VLC media player web interface
+ *****************************************************************************
+ * Copyright (C) 2005-2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/**********************************************************************
+ * Global variables
+ *********************************************************************/
+
+var old_time = 0;
+var pl_cur_id;
+var albumart_id = -1;
+
+/**********************************************************************
+ * Slider functions
+ *********************************************************************/
+var slider_mouse_down = 0;
+var slider_dx = 0;
+
+/* findPosX() from http://www.quirksmode.rg/js/indpos.html */
+function findPosX(obj)
+{
+    var curleft = 0;
+    if (obj.offsetParent)
+    {
+        while (obj.offsetParent)
+        {
+            curleft += obj.offsetLeft
+            obj = obj.offsetParent;
+        }
+    }
+    else if (obj.x)
+        curleft += obj.x;
+    return curleft;
+}
+
+function slider_seek( e, bar )
+{
+    seek(Math.floor(( e.clientX + document.body.scrollLeft - findPosX( bar )) / 4)+"%25");
+}
+function slider_down( e, point )
+{
+    slider_mouse_down = 1;
+    slider_dx = e.clientX - findPosX( point );
+}
+function slider_up( e, bar )
+{
+    slider_mouse_down = 0;
+    /* slider_seek( e, bar ); */
+}
+function slider_move( e, bar )
+{
+    if( slider_mouse_down == 1 )
+    {
+        var slider_position  = Math.floor( e.clientX - slider_dx + document.body.scrollLeft - findPosX( bar ));
+        document.getElementById( 'main_slider_point' ).style.left = slider_position+"px";
+        slider_seek( e, bar );
+    }
+}
+
+/**********************************************************************
+ * Misc utils
+ *********************************************************************/
+
+/* XMLHttpRequest wrapper */
+function loadXMLDoc( url, callback )
+{
+  // branch for native XMLHttpRequest object
+  if ( window.XMLHttpRequest )
+  {
+    req = new XMLHttpRequest();
+    req.onreadystatechange = callback;
+    req.open( "GET", url, true );
+    req.send( null );
+  // branch for IE/Windows ActiveX version
+  }
+  else if ( window.ActiveXObject )
+  {
+    req = new ActiveXObject( "Microsoft.XMLHTTP" );
+    if ( req )
+    {
+      req.onreadystatechange = callback;
+      req.open( "GET", url, true );
+      req.send();
+    }
+  }
+}
+
+/* fomat time in second as hh:mm:ss */
+function format_time( s )
+{
+    var hours = Math.floor(s/3600);
+    var minutes = Math.floor((s/60)%60);
+    var seconds = Math.floor(s%60);
+    if( hours < 10 ) hours = "0"+hours;
+    if( minutes < 10 ) minutes = "0"+minutes;
+    if( seconds < 10 ) seconds = "0"+seconds;
+    return hours+":"+minutes+":"+seconds;
+}
+
+/* delete all a tag's children and add a text child node */
+function set_text( id, val )
+{
+    var elt = document.getElementById( id );
+    while( elt.hasChildNodes() )
+        elt.removeChild( elt.firstChild );
+    elt.appendChild( document.createTextNode( val ) );
+}
+
+/* set item's 'element' attribute to value */
+function set_css( item, element, value )
+{
+    for( var j = 0; j < document.styleSheets.length; j++ )
+    {
+        var cssRules = document.styleSheets[j].cssRules;
+        if( !cssRules ) cssRules = document.styleSheets[j].rules;
+        for( var i = 0; i < cssRules.length; i++)
+        {
+            if( cssRules[i].selectorText == item )
+            {
+                if( cssRules[i].style.setProperty )
+                    cssRules[i].style.setProperty( element, value, null );
+                else
+                    cssRules[i].style.setAttribute( toCamelCase( element ), value );
+                return;
+            }
+        }
+    }
+}
+
+/* get item's 'element' attribute */
+function get_css( item, element )
+{
+    for( var j = 0; j < document.styleSheets.length; j++ )
+    {
+        var cssRules = document.styleSheets[j].cssRules;
+        if( !cssRules ) cssRules = document.styleSheets[j].rules;
+        for( var i = 0; i < cssRules.length; i++)
+        {
+            if( cssRules[i].selectorText == item )
+            {
+                if( cssRules[i].style.getPropertyValue )
+                    return cssRules[i].style.getPropertyValue( element );
+                else
+                    return cssRules[i].style.getAttribute( toCamelCase( element ) );
+            }
+        }
+    }
+}
+
+function toggle_show( id )
+{
+    var element = document.getElementById( id );
+    if( element.style.display == 'block' || element.style.display == '' )
+    {
+        element.style.display = 'none';
+    }
+    else
+    {
+        element.style.display = 'block';
+    }
+}
+function toggle_show_node( id )
+{
+    var element = document.getElementById( 'pl_'+id );
+    var img = document.getElementById( 'pl_img_'+id );
+    if( element.style.display == 'block' || element.style.display == '' )
+    {
+        element.style.display = 'none';
+        img.setAttribute( 'src', 'images/plus.png' );
+        img.setAttribute( 'alt', '[+]' );
+    }
+    else
+    {
+        element.style.display = 'block';
+        img.setAttribute( 'src', 'images/minus.png' );
+        img.setAttribute( 'alt', '[-]' );
+    }
+}
+
+function show( id ){ document.getElementById( id ).style.display = 'block'; }
+function showinline( id ){ document.getElementById( id ).style.display = 'inline'; }
+
+function hide( id ){ document.getElementById( id ).style.display = 'none'; }
+
+function checked( id ){ return document.getElementById( id ).checked; }
+
+function value( id ){ return document.getElementById( id ).value; }
+
+function setclass( obj, value )
+{
+    obj.setAttribute( 'class', value ); /* Firefox */
+    obj.setAttribute( 'className', value ); /* IE */
+}
+
+function radio_value( name )
+{
+    var radio = document.getElementsByName( name );
+    for( var i = 0; i < radio.length; i++ )
+    {
+        if( radio[i].checked )
+        {
+            return radio[i].value;
+        }
+    }
+    return "";
+}
+
+function check_and_replace_int( id, val )
+{
+    var objRegExp = /^\d+$/;
+    if( value( id ) != ''
+        && ( !objRegExp.test( value( id ) )
+             || parseInt( value( id ) ) < 1 ) )
+        return document.getElementById( id ).value = val;
+    return document.getElementById( id ).value;
+}
+
+function addslashes( str ){ return str.replace(/\'/g, '\\\''); }
+function escapebackslashes( str ){ return str.replace(/\\/g, '\\\\'); }
+
+function toCamelCase( str )
+{
+    str = str.split( '-' );
+    var cml = str[0];
+    for( var i=1; i<str.length; i++)
+        cml += str[i].charAt(0).toUpperCase()+str[i].substring(1);
+    return cml;
+}
+
+function disable( id ){ document.getElementById( id ).disabled = true; }
+
+function enable( id ){ document.getElementById( id ).disabled = false; }
+
+function button_over( element ){ element.style.border = "1px solid #000"; }
+
+function button_out( element ){ element.style.border = "1px solid #fff"; }
+function button_out_menu( element ){ element.style.border = "1px solid transparent"; }
+
+function show_menu( id ){ document.getElementById(id).style.display = 'block'; }
+function hide_menu( id ){ document.getElementById(id).style.display = 'none'; }
+
+/* toggle show help under the buttons */
+function toggle_btn_text()
+{
+    if( get_css( '.btn_text', 'display' ) == 'none' )
+    {
+        set_css( '.btn_text', 'display', 'block' );
+    }
+    else
+    {
+        set_css( '.btn_text', 'display', 'none' );
+    }
+}
+
+function clear_children( elt )
+{   
+    if( elt )
+        while( elt.hasChildNodes() )
+            elt.removeChild( elt.firstChild );
+}
+
+/**********************************************************************
+ * Interface actions
+ *********************************************************************/
+/* input actions */
+function in_play()
+{
+    var input = value('input_mrl');
+    if( value('sout_mrl') != '' )
+        input += ' '+value('sout_mrl');
+    var url = 'requests/status.xml?command=in_play&input='+encodeURIComponent( addslashes(escapebackslashes(input)) );
+    loadXMLDoc( url, parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function in_enqueue()
+{
+    var input = value('input_mrl');
+    if( value('sout_mrl') != '' )
+        input += ' '+value('sout_mrl');
+    var url = 'requests/status.xml?command=in_enqueue&input='+encodeURIComponent( addslashes(escapebackslashes(input)) );
+    loadXMLDoc( url, parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+
+/* playlist actions */
+function pl_play( id )
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_play&id='+id, parse_status );
+    pl_cur_id = id;
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_pause()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_pause&id='+pl_cur_id, parse_status );
+}
+function pl_stop()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_stop', parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_next()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_next', parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_previous()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_previous', parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_delete( id )
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_delete&id='+id, parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_empty()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_empty', parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_sort( sort, order )
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_sort&id='+order+'&val='+sort, parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_shuffle()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_random', parse_status );
+    setTimeout( 'update_playlist()', 1000 );
+}
+function pl_loop()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_loop', parse_status );
+}
+function pl_repeat()
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_repeat', parse_status );
+}
+function pl_sd( value )
+{
+    loadXMLDoc( 'requests/status.xml?command=pl_sd&val='+value, parse_status );
+}
+
+/* misc actions */
+function volume_down()
+{
+    loadXMLDoc( 'requests/status.xml?command=volume&val=-20', parse_status );
+}
+function volume_up()
+{
+    loadXMLDoc( 'requests/status.xml?command=volume&val=%2B20', parse_status );
+}
+function seek( pos )
+{
+    loadXMLDoc( 'requests/status.xml?command=seek&val='+pos, parse_status );
+}
+function fullscreen()
+{
+    loadXMLDoc( 'requests/status.xml?command=fullscreen', parse_status );
+}
+function snapshot()
+{
+    loadXMLDoc( 'requests/status.xml?command=snapshot', parse_status );
+}
+function hotkey( str )
+{
+    /* Use hotkey name (without the "key-" part) as the argument to simulate a hotkey press */
+    loadXMLDoc( 'requests/status.xml?command=key&val='+str, parse_status );
+}
+function update_status()
+{
+    loadXMLDoc( 'requests/status.xml', parse_status );
+}
+function update_playlist()
+{
+    loadXMLDoc( 'requests/playlist.xml', parse_playlist );
+}
+
+/**********************************************************************
+ * Parse xml replies to XMLHttpRequests
+ *********************************************************************/
+/* parse request/status.xml */
+function parse_status()
+{
+    if( req.readyState == 4 )
+    {
+        if( req.status == 200 )
+        {
+            var status = req.responseXML.documentElement;
+            var timetag = status.getElementsByTagName( 'time' );
+            if( timetag.length > 0 )
+            {
+                var new_time = timetag[0].firstChild.data;
+            }
+            else
+            {
+                new_time = old_time;
+            }
+            var lengthtag = status.getElementsByTagName( 'length' );
+            var length;
+            if( lengthtag.length > 0 )
+            {
+                length = lengthtag[0].firstChild.data;
+            }
+            else
+            {
+                length = 0;
+            }
+            var slider_position;
+            positiontag = status.getElementsByTagName( 'position' );
+            if( length < 100 && positiontag.length > 0 )
+            {
+                slider_position = ( positiontag[0].firstChild.data * 4 ) + "px";
+            }
+            else if( length > 0 )
+            {
+                /* this is more precise if length > 100 */
+                slider_position = Math.floor( ( new_time * 400 ) / length ) + "px";
+            }
+            else
+            {
+                slider_position = 0;
+            }
+            if( old_time > new_time )
+                setTimeout('update_playlist()',50);
+            old_time = new_time;
+            set_text( 'time', format_time( new_time ) );
+            set_text( 'length', format_time( length ) );
+            if( status.getElementsByTagName( 'volume' ).length != 0 )
+                set_text( 'volume', Math.floor(status.getElementsByTagName( 'volume' )[0].firstChild.data/5.12)+'%' );
+            var statetag = status.getElementsByTagName( 'state' );
+            if( statetag.length > 0 )
+            {
+               set_text( 'state', statetag[0].firstChild.data );
+            }
+            else
+            {
+                set_text( 'state', '(?)' );
+            }
+            if( slider_mouse_down == 0 )
+            {
+                document.getElementById( 'main_slider_point' ).style.left = slider_position;
+            }
+            var statustag = status.getElementsByTagName( 'state' );
+            if( statustag.length > 0 ? statustag[0].firstChild.data == "playing" : 0 )
+            {
+                document.getElementById( 'btn_pause_img' ).setAttribute( 'src', 'images/pause.png' );
+                document.getElementById( 'btn_pause_img' ).setAttribute( 'alt', 'Pause' );
+                document.getElementById( 'btn_pause' ).setAttribute( 'title', 'Pause' );
+            }
+            else
+            {
+                document.getElementById( 'btn_pause_img' ).setAttribute( 'src', 'images/play.png' );
+                document.getElementById( 'btn_pause_img' ).setAttribute( 'alt', 'Play' );
+                document.getElementById( 'btn_pause' ).setAttribute( 'title', 'Play' );
+            }
+
+            var randomtag = status.getElementsByTagName( 'random' );
+            if( randomtag.length > 0 ? randomtag[0].firstChild.data == "1" : 0)
+                setclass( document.getElementById( 'btn_shuffle'), 'on' );
+            else
+                setclass( document.getElementById( 'btn_shuffle'), 'off' );
+               
+            var looptag = status.getElementsByTagName( 'loop' );
+            if( looptag.length > 0 ? looptag[0].firstChild.data == "1" : 0)
+                setclass( document.getElementById( 'btn_loop'), 'on' );
+            else
+                setclass( document.getElementById( 'btn_loop'), 'off' );
+
+            var repeattag = status.getElementsByTagName( 'repeat' );
+            if( repeattag.length > 0 ? repeattag[0].firstChild.data == "1" : 0 )
+                setclass( document.getElementById( 'btn_repeat'), 'on' );
+            else
+                setclass( document.getElementById( 'btn_repeat'), 'off' );
+
+            var tree = document.createElement( "ul" );
+            var categories = status.getElementsByTagName( 'category' );
+            var i;
+            for( i = 0; i < categories.length; i++ )
+            {
+                var item = document.createElement( "li" );
+                item.appendChild( document.createTextNode( categories[i].getAttribute( 'name' ) ) );
+                var subtree = document.createElement( "dl" );
+                var infos = categories[i].getElementsByTagName( 'info' );
+                var j;
+                for( j = 0; j < infos.length; j++ )
+                {
+                    var subitem = document.createElement( "dt" );
+                    subitem.appendChild( document.createTextNode( infos[j].getAttribute( 'name' ) ) );
+                    subtree.appendChild( subitem );
+                    if( infos[j].hasChildNodes() )
+                    {
+                        var subitem = document.createElement( "dd" );
+                        subitem.appendChild( document.createTextNode( infos[j].firstChild.data ) );
+                        subtree.appendChild( subitem );
+                    }
+                }
+                item.appendChild( subtree );
+                tree.appendChild( item );
+            }
+            var infotree = document.getElementById('infotree' );
+            clear_children( infotree );
+            infotree.appendChild( tree );
+            
+        }
+        else
+        {
+            /*alert( 'Error! HTTP server replied: ' + req.status );*/
+        }
+    }
+}
+
+/* parse playlist.xml */
+function parse_playlist()
+{
+    if( req.readyState == 4 )
+    {
+        if( req.status == 200 )
+        {
+            var answer = req.responseXML.documentElement;
+            var playtree = document.getElementById( 'playtree' );
+            var pos = document.createElement( "div" );
+            var pos_top = pos;
+            var elt = answer.firstChild;
+            
+            pl_cur_id = 0;  /* changed to the current id is there actually
+                             * is a current id */
+            while( elt )
+            {
+                if( elt.nodeName == "node" )
+                {
+                    if( pos.hasChildNodes() )
+                        pos.appendChild( document.createElement( "br" ) );
+                    var nda = document.createElement( 'a' );
+                    nda.setAttribute( 'href', 'javascript:toggle_show_node(\''+elt.getAttribute( 'id' )+'\');' );
+                    var ndai = document.createElement( 'img' );
+                    ndai.setAttribute( 'src', 'images/minus.png' );
+                    ndai.setAttribute( 'alt', '[-]' );
+                    ndai.setAttribute( 'id', 'pl_img_'+elt.getAttribute( 'id' ) );
+                    nda.appendChild( ndai );
+                    pos.appendChild( nda );
+                    pos.appendChild( document.createTextNode( ' ' + elt.getAttribute( 'name' ) ) );
+
+                    if( elt.getAttribute( 'ro' ) == 'rw' )
+                    {
+                        pos.appendChild( document.createTextNode( ' ' ) );
+                        var del = document.createElement( "a" );
+                        del.setAttribute( 'href', 'javascript:pl_delete('+elt.getAttribute( 'id' )+')' );
+                            var delimg = document.createElement( "img" );
+                            delimg.setAttribute( 'src', 'images/delete_small.png' );
+                            delimg.setAttribute( 'alt', '(delete)' );
+                        del.appendChild( delimg );
+                        pos.appendChild( del );
+                    }
+
+                    var nd = document.createElement( "div" );
+                    setclass( nd, 'pl_node' );
+                    nd.setAttribute( 'id', 'pl_'+elt.getAttribute( 'id' ) );
+                    pos.appendChild( nd );
+                }
+                else if( elt.nodeName == "leaf" )
+                {
+                    if( pos.hasChildNodes() )
+                    pos.appendChild( document.createElement( "br" ) );
+                    var pl = document.createElement( "a" );
+                    setclass( pl, 'pl_leaf' );
+                    pl.setAttribute( 'href', 'javascript:pl_play('+elt.getAttribute( 'id' )+');' );
+                    pl.setAttribute( 'id', 'pl_'+elt.getAttribute( 'id' ) );
+                    if( elt.getAttribute( 'current' ) == 'current' )
+                    {
+                        pl.style.fontWeight = 'bold';
+                        var nowplaying = document.getElementById( 'nowplaying' );
+                        clear_children( nowplaying );
+                        nowplaying.appendChild( document.createTextNode( elt.getAttribute( 'name' ) ) );
+                        pl.appendChild( document.createTextNode( '* '));
+                        pl_cur_id = elt.getAttribute( 'id' );
+                    }
+                    pl.setAttribute( 'title', elt.getAttribute( 'uri' ));
+                    pl.appendChild( document.createTextNode( elt.getAttribute( 'name' ) ) );
+                    var duration = elt.getAttribute( 'duration' );
+                    if( duration > 0 )
+                        pl.appendChild( document.createTextNode( " (" + format_time( elt.getAttribute( 'duration' ) / 1000000 ) + ")" ) );
+                    pos.appendChild( pl );
+
+                    if( elt.getAttribute( 'ro' ) == 'rw' )
+                    {
+                        pos.appendChild( document.createTextNode( ' ' ) );
+                        var del = document.createElement( "a" );
+                        del.setAttribute( 'href', 'javascript:pl_delete('+elt.getAttribute( 'id' )+')' );
+                            var delimg = document.createElement( "img" );
+                            delimg.setAttribute( 'src', 'images/delete_small.png' );
+                            delimg.setAttribute( 'alt', '(delete)' );
+                        del.appendChild( delimg );
+                        pos.appendChild( del );
+                    }
+                }
+                if( elt.firstChild )
+                {
+                    elt = elt.firstChild;
+                    pos = pos.lastChild;
+                }
+                else if( elt.nextSibling )
+                {
+                    elt = elt.nextSibling;
+                    pos = pos;
+                }
+                else
+                {
+                    while( ! elt.parentNode.nextSibling )
+                    {
+                        elt = elt.parentNode;
+                        if( ! elt.parentNode ) break;
+                    }
+                    if( ! elt.parentNode ) break;
+                    elt = elt.parentNode.nextSibling;
+                    pos = pos.parentNode;
+                }
+            }
+            clear_children( playtree );
+            playtree.appendChild( pos_top );
+        }
+        else
+        {
+            /*alert( 'Error! HTTP server replied: ' + req.status );*/
+        }
+    }
+}
+
+/* parse browse.xml */
+function parse_browse_dir( )
+{
+    if( req.readyState == 4 )
+    {
+        if( req.status == 200 )
+        {
+            var answer = req.responseXML.documentElement;
+            if( !answer ) return;
+            var browser = document.getElementById( 'browser' );
+            var pos = document.createElement( "div" );
+            var elt = answer.firstChild;
+            while( elt )
+            {
+                if( elt.nodeName == "element" )
+                {
+                    var item = document.createElement( "a" );
+                    setclass( item, 'browser' );
+                    if( elt.getAttribute( 'type' ) == 'dir' )
+                    {
+                        item.setAttribute( 'href', 'javascript:browse_dir(\''+addslashes(escapebackslashes(elt.getAttribute( 'path' )))+'\');');
+                    }
+                    else
+                    {
+                        item.setAttribute( 'href', 'javascript:browse_path(\''+addslashes(escapebackslashes(elt.getAttribute( 'path' )))+'\');' );
+                    }
+                    item.appendChild( document.createTextNode( elt.getAttribute( 'name' ) ) );
+                    pos.appendChild( item );
+                    if( elt.getAttribute( 'type' ) == 'dir' )
+                    {
+                        pos.appendChild( document.createTextNode( ' ' ) );
+                        var item = document.createElement( "a" );
+                        setclass( item, 'browser' );
+                        item.setAttribute( 'href', 'javascript:browse_path(\''+addslashes(escapebackslashes(elt.getAttribute( 'path' )))+'\');');
+                        item.appendChild( document.createTextNode( '(select)' ) );
+                        pos.appendChild( item );
+                    }
+                    pos.appendChild( document.createElement( "br" ) );
+                }
+                elt = elt.nextSibling;
+            }
+            clear_children( browser );
+            browser.appendChild( pos );
+        }
+        else
+        {
+            /*alert( 'Error! HTTP server replied: ' + req.status );*/
+        }
+    }
+}
+
+/**********************************************************************
+ * Input dialog functions
+ *********************************************************************/
+function hide_input( )
+{
+    document.getElementById( 'input_file' ).style.display = 'none';
+    document.getElementById( 'input_disc' ).style.display = 'none';
+    document.getElementById( 'input_network' ).style.display = 'none';
+    document.getElementById( 'input_fake' ).style.display = 'none';
+}
+
+/* update the input MRL using data from the input file helper */
+/* FIXME ... subs support */
+function update_input_file()
+{
+    var mrl = document.getElementById( 'input_mrl' );
+
+    mrl.value = value( 'input_file_filename' );
+}
+
+/* update the input MRL using data from the input disc helper */
+function update_input_disc()
+{
+    var mrl     = document.getElementById( 'input_mrl' );
+    var type    = radio_value( "input_disc_type" );
+    var device  = value( "input_disc_dev" );
+
+    var title   = check_and_replace_int( 'input_disc_title', 0 );
+    var chapter = check_and_replace_int( 'input_disc_chapter', 0 );
+    var subs    = check_and_replace_int( 'input_disc_subtrack', '' );
+    var audio   = check_and_replace_int( 'input_disc_audiotrack', 0 );
+
+    mrl.value = "";
+
+    if( type == "dvd" )
+    {
+        mrl.value += "dvd://";
+    }
+    else if( type == "dvdsimple" )
+    {
+        mrl.value += "dvdsimple://";
+    }
+    else if( type == "vcd" )
+    {
+        mrl.value += "vcd://";
+    }
+    else if( type == "cdda" )
+    {
+        mrl.value += "cdda://";
+    }
+
+    mrl.value += device;
+
+    if( title )
+    {
+        mrl.value += "@"+title;
+        if( chapter && type != "cdda" )
+            mrl.value += ":"+chapter;
+    }
+
+    if( type != "cdda" )
+    {
+        if( subs != '' )
+            mrl.value += " :sub-track="+subs;
+        if( audio != '' )
+            mrl.value += " :audio-track="+audio;
+    }
+
+}
+
+/* update the input MRL using data from the input network helper */
+function update_input_net()
+{
+    var mrl = document.getElementById( 'input_mrl' );
+    var type = radio_value( "input_net_type" );
+    
+    check_and_replace_int( 'input_net_udp_port', 1234 );
+    check_and_replace_int( 'input_net_udpmcast_port', 1234 );
+
+    mrl.value = "";
+
+    if( type == "udp" )
+    {
+        mrl.value += "udp://";
+        if( checked( 'input_net_udp_forceipv6' ) )
+            mrl.value += "[::]";
+        if( value( 'input_net_udp_port' ) )
+            mrl.value += ":"+value( 'input_net_udp_port' );
+    }
+    else if( type == "udpmcast" )
+    {
+        mrl.value += "udp://@"+value( 'input_net_udpmcast_address');
+        if( value( 'input_net_udpmcast_port' ) )
+            mrl.value += ":"+value( 'input_net_udpmcast_port' );
+    }
+    else if( type == "http" )
+    {
+        var url = value( 'input_net_http_url' );
+        if( url.substring(0,7) != "http://"
+            && url.substring(0,8) != "https://"
+            && url.substring(0,6) != "ftp://"
+            && url.substring(0,6) != "mms://"
+            && url.substring(0,7) != "mmsh://" )
+            mrl.value += "http://";
+        mrl.value += url;
+    }
+    else if( type == "rtsp" )
+    {
+        var url = value( 'input_net_rtsp_url' );
+        if( url.substring(0,7) != "rtsp://" )
+            mrl.value += "rtsp://";
+        mrl.value += url;
+    }
+
+    if( checked( "input_net_timeshift" ) )
+        mrl.value += " :access-filter=timeshift";
+}
+
+/* update the input MRL using data from the input fake helper */
+function update_input_fake()
+{
+    var mrl = document.getElementById( 'input_mrl' );
+
+    mrl.value = "fake:";
+    mrl.value += " :fake-file=" + value( "input_fake_filename" );
+
+    if( value( "input_fake_width" ) )
+        mrl.value += " :fake-width=" + value( "input_fake_width" );
+    if( value( "input_fake_height" ) )
+        mrl.value += " :fake-height=" + value( "input_fake_height" );
+    if( value( "input_fake_ar" ) )
+        mrl.value += " :fake-ar=" + value( "input_fake_ar" );
+}
+
+/**********************************************************************
+ * Sout dialog functions
+ *********************************************************************/
+/* toggle show the full sout interface */
+function toggle_show_sout_helper()
+{
+    var element = document.getElementById( "sout_helper" );
+    if( element.style.display == 'block' )
+    {
+        element.style.display = 'none';
+        document.getElementById( "sout_helper_toggle" ).value = 'Full sout interface';
+    }
+    else
+    {
+        element.style.display = 'block';
+        document.getElementById( "sout_helper_toggle" ).value = 'Hide sout interface';
+    }
+}
+
+/* update the sout MRL using data from the sout_helper */
+function update_sout()
+{
+    var mrl = document.getElementById( 'sout_mrl' );
+    mrl.value = "";
+
+    check_and_replace_int( 'sout_http_port', 8080 );
+    check_and_replace_int( 'sout_mmsh_port', 8080 );
+    check_and_replace_int( 'sout_rtp_port', 1234 );
+    check_and_replace_int( 'sout_udp_port', 1234 );
+    check_and_replace_int( 'sout_ttl', 1 );
+
+    if( checked( 'sout_soverlay' ) )
+    {
+        disable( 'sout_scodec' );
+        disable( 'sout_sub' );
+    }
+    else
+    {
+        enable( 'sout_scodec' );
+        enable( 'sout_sub' );
+    }
+
+    var transcode =  checked( 'sout_vcodec_s' ) || checked( 'sout_acodec_s' )
+                  || checked( 'sout_sub' )      || checked( 'sout_soverlay' );
+
+    if( transcode )
+    {
+        mrl.value += ":sout=#transcode{";
+        var alot = false; /* alot == at least one transcode */
+        if( checked( 'sout_vcodec_s' ) )
+        {
+            mrl.value += "vcodec="+value( 'sout_vcodec' )+",vb="+value( 'sout_vb' )+",scale="+value( 'sout_scale' );
+            alot = true;
+        }
+        if( checked( 'sout_acodec_s' ) )
+        {
+            if( alot ) mrl.value += ",";
+            mrl.value += "acodec="+value( 'sout_acodec' )+",ab="+value( 'sout_ab' );
+            if( value( 'sout_channels' ) )
+                mrl.value += ",channels="+value( 'sout_channels' );
+            alot = true;
+        }
+        if( checked( 'sout_soverlay' ) )
+        {
+            if( alot ) mrl.value += ",";
+            mrl.value += "soverlay";
+            alot = true;
+        }
+        else if( checked( 'sout_sub' ) )
+        {
+            if( alot ) mrl.value += ",";
+            mrl.value += "scodec="+value( 'sout_scodec' );
+            alot = true;
+        }
+        mrl.value += value( 'sout_transcode_extra' );
+            
+        mrl.value += "}";
+    }
+
+    var output = checked( 'sout_display' ) + checked( 'sout_file' )
+               + checked( 'sout_http' )    + checked( 'sout_mmsh' )
+               + checked( 'sout_rtp' )     + checked( 'sout_udp' );
+
+    if( output )
+    {
+        if( transcode )
+            mrl.value += ":";
+        else
+            mrl.value += ":sout=#";
+        var aloo = false; /* aloo == at least one output */
+        var mux = radio_value( 'sout_mux' );
+        var ttl = parseInt( value( 'sout_ttl' ) );
+        if( output > 1 ) mrl.value += "duplicate{";
+        if( checked( 'sout_display' ) )
+        {
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "display";
+            aloo = true;
+        }
+        if( checked( 'sout_file' ) )
+        {
+            if( aloo ) mrl.value += ",";
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "std{access=file,mux="+mux+",dst="+value( 'sout_file_filename' )+"}";
+            aloo = true;
+        }
+        if( checked( 'sout_http' ) )
+        {
+            if( aloo ) mrl.value += ",";
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "std{access=http,mux="+mux+",dst="+value( 'sout_http_addr' );
+            if( value( 'sout_http_port' ) )
+                mrl.value += ":"+value( 'sout_http_port' );
+            mrl.value += "}";
+            aloo = true;
+        }
+        if( checked( 'sout_mmsh' ) )
+        {
+            if( aloo ) mrl.value += ",";
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "std{access=mmsh,mux="+mux+",dst="+value( 'sout_mmsh_addr' );
+            if( value( 'sout_mmsh_port' ) )
+                mrl.value += ":"+value( 'sout_mmsh_port' );
+            mrl.value += "}";
+            aloo = true;
+        }
+        if( checked( 'sout_rtp' ) )
+        {
+            if( aloo ) mrl.value += ",";
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "std{access=rtp";
+            if( ttl ) mrl.value += "{ttl="+ttl+"}";
+            mrl.value += ",mux="+mux+",dst="+value( 'sout_rtp_addr' );
+            if( value( 'sout_rtp_port' ) )
+                mrl.value += ":"+value( 'sout_rtp_port' );
+            if( checked( 'sout_sap' ) )
+            {
+                mrl.value += ",sap";
+                if( value( 'sout_sap_group' ) != '' )
+                {
+                    mrl.value += ",group=\""+value( 'sout_sap_group' )+"\"";
+                }
+                mrl.value += ",name=\""+value( 'sout_sap_name' )+"\"";
+            }
+            mrl.value += "}";
+            aloo = true;
+        }
+        if( checked( 'sout_udp' ) )
+        {
+            if( aloo ) mrl.value += ",";
+            if( output > 1 ) mrl.value += "dst="
+            mrl.value += "std{access=udp";
+            if( ttl ) mrl.value += "{ttl="+ttl+"}";
+            mrl.value += ",mux="+mux+",dst="+value( 'sout_udp_addr' );
+            if( value('sout_udp_port' ) )
+                mrl.value += ":"+value( 'sout_udp_port' );
+            if( checked( 'sout_sap' ) )
+            {
+                mrl.value += ",sap";
+                if( value( 'sout_sap_group' ) != '' )
+                {
+                    mrl.value += ",group=\""+value( 'sout_sap_group' )+"\"";
+                }
+                mrl.value += ",name=\""+value( 'sout_sap_name' )+"\"";
+            }
+            mrl.value += "}";
+            aloo = true;
+        }
+        if( output > 1 ) mrl.value += "}";
+    }
+
+    if( ( transcode || output ) && checked( 'sout_all' ) )
+        mrl.value += " :sout-all";
+}
+
+/* reset sout mrl value */
+function reset_sout()
+{
+    document.getElementById('sout_mrl').value = value('sout_old_mrl');
+}
+
+/* save sout mrl value */
+function save_sout()
+{
+    document.getElementById('sout_old_mrl').value = value('sout_mrl');
+}
+
+/**********************************************************************
+ * Browser dialog functions
+ *********************************************************************/
+/* only browse() should be called directly */
+function browse( dest )
+{
+    document.getElementById( 'browse_dest' ).value = dest;
+    document.getElementById( 'browse_lastdir' ).value;
+    browse_dir( document.getElementById( 'browse_lastdir' ).value );
+    show( 'browse' );
+}
+function browse_dir( dir )
+{
+    document.getElementById( 'browse_lastdir' ).value = dir;
+    loadXMLDoc( 'requests/browse.xml?dir='+encodeURIComponent(dir), parse_browse_dir );
+}
+function browse_path( p )
+{
+    document.getElementById( value( 'browse_dest' ) ).value = p;
+    hide( 'browse' );
+    document.getElementById( value( 'browse_dest' ) ).focus();
+}
+function refresh_albumart( force )
+{
+    if( albumart_id != pl_cur_id || force )
+    {
+        var now = new Date();
+        var albumart = document.getElementById( 'albumart' );
+        albumart.src = '/art?timestamp=' + now.getTime();
+        albumart_id = pl_cur_id;
+    }
+}
+/**********************************************************************
+ * Periodically update stuff in the interface
+ *********************************************************************/
+function loop_refresh_status()
+{
+    setTimeout( 'loop_refresh_status()', 1000 );
+    update_status();
+}
+function loop_refresh_playlist()
+{
+    /* setTimeout( 'loop_refresh_playlist()', 10000 ); */
+    update_playlist();
+}
+function loop_refresh_albumart()
+{
+    setTimeout( 'loop_refresh_albumart()', 1000 );
+    refresh_albumart( false );
+}
+function loop_refresh()
+{
+    setTimeout( 'loop_refresh_status()', 1 );
+    setTimeout( 'loop_refresh_playlist()', 1 );
+    setTimeout( 'loop_refresh_albumart()', 1 );
+}
+
diff --git a/share/http-lua/js/mosaic.js b/share/http-lua/js/mosaic.js
new file mode 100644 (file)
index 0000000..5b9c3e3
--- /dev/null
@@ -0,0 +1,333 @@
+/*****************************************************************************
+ * mosaic.js: VLC media player web interface - Mosaic specific functions
+ *****************************************************************************
+ * Copyright (C) 2005-2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/**********************************************************************
+ * 
+ *********************************************************************/
+
+var mosaic_alpha    = 255;
+var mosaic_height   = 0;
+var mosaic_width    = 0;
+var mosaic_align    = 5;
+var mosaic_xoffset  = 0;
+var mosaic_yoffset  = 0;
+var mosaic_vborder  = 0;
+var mosaic_hborder  = 0;
+var mosaic_position = 1;
+var mosaic_rows     = 0;
+var mosaic_cols     = 0;
+var mosaic_delay    = 0;
+
+var cell_width  = 0;
+var cell_height = 0;
+
+var streams = Object();
+var cells   = Object();
+
+function mosaic_init()
+{
+    document.getElementById( 'sout_transcode_extra' ).value = ",sfilter=mosaic}:bridge-in{offset=100";
+    mosaic_size_change();
+
+    /* Force usage of transcode in sout */
+    document.getElementById( 'sout_vcodec_s' ).checked = 'checked';
+    disable( 'sout_vcodec_s' );
+    update_sout();
+}
+
+function mosaic_size_change()
+{
+    var x,y;
+
+    var bg_width    = check_and_replace_int( "bg_width", "400" );
+    var bg_height   = check_and_replace_int( "bg_height", "300" );
+
+    mosaic_height   = check_and_replace_int( "mosaic_height", "100" );
+    mosaic_width    = check_and_replace_int( "mosaic_width", "100" );
+    mosaic_xoffset  = check_and_replace_int( "mosaic_xoffset", "10" );
+    mosaic_yoffset  = check_and_replace_int( "mosaic_yoffset", "10" );
+    mosaic_vborder  = check_and_replace_int( "mosaic_vborder", "5" );
+    mosaic_hborder  = check_and_replace_int( "mosaic_hborder", "10" );
+    mosaic_rows     = check_and_replace_int( "mosaic_rows", "1" );
+    mosaic_cols     = check_and_replace_int( "mosaic_cols", "1" );
+    
+    cell_width  = Math.floor((mosaic_width-(mosaic_cols-1)*mosaic_hborder)/mosaic_cols);
+    cell_height = Math.floor((mosaic_height-(mosaic_rows-1)*mosaic_vborder)/mosaic_rows);
+    
+    var mlayout = document.getElementById( "mosaic_layout" );
+
+    while( mlayout.hasChildNodes() )
+        mlayout.removeChild( mlayout.firstChild );
+
+    mlayout.style.width = bg_width + "px";
+    mlayout.style.height = bg_height + "px";
+    if( mosaic_cols && mosaic_rows )
+    {
+        var mdt = document.createElement( 'div' );
+        mdt.setAttribute( 'id',    'mosaic_dt'  );
+        setclass( mdt, 'mosaic_tbl' );
+        
+        mdt.style.width  = mosaic_width   + "px";
+        mdt.style.height = mosaic_height  + "px";
+        mdt.style.top    = mosaic_yoffset + "px";
+        mdt.style.left   = mosaic_xoffset + "px";
+
+        var mtable = document.createElement( 'table' );
+        mtable.setAttribute( 'id', 'mosaic_table' );
+        mtable.style.top    = "-" + mosaic_vborder + "px";
+        mtable.style.left   = "-" + mosaic_hborder + "px";
+        mtable.style.width  = (1*mosaic_width +2*mosaic_hborder)  + "px";
+        mtable.style.height = (1*mosaic_height+2*mosaic_vborder) + "px";
+        mtable.style.borderSpacing = mosaic_hborder + "px " +
+                                     mosaic_vborder + "px";
+
+        var mtbody = document.createElement( 'tbody' );
+
+        for( y = 0; y < mosaic_rows; y++ )
+        {
+            var mrow = document.createElement( 'tr' );
+            for( x = 0; x < mosaic_cols; x++ )
+            {
+                var mcell = document.createElement( 'td' );
+                setclass( mcell, 'mosaic_itm' );
+                mcell.style.width  = cell_width  + "px";
+                mcell.style.height = cell_height + "px";
+                
+                var id = x+'_'+y;
+                var melt = create_button( cells[id] ? cells[id] : '?', 'mosaic_elt_choose(\"'+id+'\");' );
+                melt.setAttribute( 'id', id );
+                melt.setAttribute( 'title', 'Click to choose stream' );
+                
+                mcell.appendChild( melt );
+                mrow.appendChild( mcell );
+            }
+            mtbody.appendChild( mrow );
+        }
+        mtable.appendChild( mtbody );
+        mdt.appendChild( mtable );
+        mlayout.appendChild( mdt );
+    }
+    mosaic_code_update();
+}
+
+function mosaic_add_input()
+{
+    streams[ addunderscores( value('mosaic_input_name') ) ] =
+        value('mosaic_input');
+
+    mosaic_feedback( addunderscores( value('mosaic_input_name') ) + " ( " + value('mosaic_input') + " ) added to input list.", true );
+
+    var mlist = document.getElementById( "mosaic_list_content" );
+    while( mlist.hasChildNodes() )
+        mlist.removeChild( mlist.firstChild );
+    
+    for( var name in streams )
+    {
+        var mrl = streams[name];
+        
+        var minput = document.createElement( 'a' );
+        minput.setAttribute( 'href', 'javascript:mosaic_elt_select(\''+name+'\');');
+        minput.setAttribute( 'id', name );
+        minput.setAttribute( 'value', mrl );
+        
+        var minputtxt = document.createTextNode( name );
+
+        minput.appendChild( minputtxt );
+        mlist.appendChild( minput );
+        mlist.appendChild( document.createTextNode( " ( "+mrl+" )" ) );
+        mlist.appendChild( document.createElement( 'br' ) );
+    }
+}
+
+function mosaic_elt_select( id )
+{
+    hide( 'mosaic_list' );
+    var ml = document.getElementById( 'mosaic_list' ).value;
+    if( ml )
+    {
+        document.getElementById( ml ).value = id;
+        cells[ ml ] = id;
+        mosaic_code_update();
+    }
+}
+
+function mosaic_elt_choose( id )
+{
+    document.getElementById( 'mosaic_list' ).value = id;
+    show( 'mosaic_list' );
+}
+
+function mosaic_code_update()
+{
+
+    var code = document.getElementById( 'mosaic_code' );
+    code.value =
+"##################################\n"+
+"## HTTP interface mosaic wizard ##\n"+
+"##################################\n"+
+"\n"+
+"# Comment the following line if you don't want to reset your VLM configuration\n"+
+"del all\n"+
+"\n"+
+"# Background options\n"+
+"new   bg broadcast enabled\n"+
+"setup bg input     " + sanitize_input( value( 'mosaic_bg_input' ) ) + "\n";
+    if( value( 'mosaic_output' ) )
+    {
+        code.value +=
+"setup bg output    " + value( 'mosaic_output' )+ "\n";
+    }
+    var o = /.*transcode.*/;
+    if(! o.test( value( 'mosaic_output' ) ) )
+    {
+        code.value +=
+"setup bg option    sub-filter=mosaic\n"+
+"setup bg output    #bridge-in{offset=100}:display\n";
+    }
+    code.value+=
+"\n"+
+"# Mosaic options\n"+
+"setup bg option mosaic-alpha="    + mosaic_alpha    + "\n"+
+"setup bg option mosaic-height="   + mosaic_height   + "\n"+
+"setup bg option mosaic-width="    + mosaic_width    + "\n"+
+"setup bg option mosaic-align="    + mosaic_align    + "\n"+
+"setup bg option mosaic-xoffset="  + mosaic_xoffset  + "\n"+
+"setup bg option mosaic-yoffset="  + mosaic_yoffset  + "\n"+
+"setup bg option mosaic-vborder="  + mosaic_vborder  + "\n"+
+"setup bg option mosaic-hborder="  + mosaic_hborder  + "\n"+
+"setup bg option mosaic-position=" + mosaic_position + "\n"+
+"setup bg option mosaic-rows="     + mosaic_rows     + "\n"+
+"setup bg option mosaic-cols="     + mosaic_cols     + "\n"+
+"setup bg option mosaic-order=";
+    for( y = 0; y < mosaic_rows; y++ )
+    {
+        for( x = 0; x < mosaic_cols; x++ )
+        {
+            var id = x+'_'+y;
+            if( cells[id] )
+                code.value += cells[id];
+            else
+                code.value += '_';
+            if( y != mosaic_rows - 1 || x != mosaic_cols - 1 )
+                code.value += ',';
+        }
+    }
+    code.value += "\n"+
+"setup bg option mosaic-delay="    + mosaic_delay    + "\n"+
+"setup bg option mosaic-keep-picture\n"+
+"\n"+
+"# Input options\n";
+    var x, y;
+    for( y = 0; y < mosaic_rows; y++ )
+    {
+        for( x = 0; x < mosaic_cols; x++ )
+        {
+            var id = x+'_'+y;
+            if( cells[id] )
+            {
+                var s = cells[id];
+                code.value +=
+"new   " + s + " broadcast enabled\n"+
+"setup " + s + " input     " + sanitize_input( streams[s] ) + "\n"+
+"setup " + s + " output #duplicate{dst=mosaic-bridge{id=" + s + ",width="+cell_width+",height="+cell_height+"},select=video,dst=bridge-out{id="+(y*mosaic_cols+x)+"},select=audio}\n"+
+"\n";
+            }
+        }
+    }
+    code.value +=
+"# Launch everything\n"+
+"control bg play\n";
+    for( y = 0; y < mosaic_rows; y++ )
+    {
+        for( x = 0; x < mosaic_cols; x++ )
+        {
+            var id = x+'_'+y;
+            if( cells[id] )
+            {
+                var s = cells[id];
+                code.value +=
+"control " + s + " play\n";
+            }
+        }
+    }
+    code.value +=
+"\n"+
+"# end of mosaic batch\n";
+}
+
+function mosaic_batch( batch )
+{
+    var i;
+    var commands = batch.split( '\n' );
+    for( i = 0; i < commands.length; i++ )
+    {
+        mosaic_cmd( commands[i] );
+    }
+}
+
+function mosaic_cmd( cmd )
+{
+    loadXMLDoc( 'requests/vlm_cmd.xml?command='+cmd.replace(/\#/g, '%23'), parse_mosaic_cmd );
+}
+
+function parse_mosaic_cmd()
+{
+    /* TODO */
+}
+
+function mosaic_stop()
+{
+    var cmd;
+    cmd = "control bg stop\n";
+    var x,y;
+    for( y = 0; y < mosaic_rows; y++ )
+    {
+        for( x = 0; x < mosaic_cols; x++ )
+        {
+            var id = x+'_'+y;
+            if( cells[id] )
+            {
+                var s = cells[id];
+                cmd += "control " + s + " stop\n";
+            }
+        }
+    }
+    mosaic_batch( cmd );
+}
+
+function mosaic_feedback( msg, ok )
+{
+    var f = document.getElementById( "mosaic_feedback" );
+    while( f.hasChildNodes() )
+        f.removeChild( f.firstChild );
+
+    f.style.fontWeight = "bold";
+    if( ok )
+        f.style.color = "#0f0";
+    else
+        f.style.color = "#f00";
+
+    var t = document.createTextNode( ( ok ? "Info: " : "Error: " ) + msg );
+    f.appendChild( t );
+
+}
diff --git a/share/http-lua/js/vlm.js b/share/http-lua/js/vlm.js
new file mode 100644 (file)
index 0000000..daa3f2a
--- /dev/null
@@ -0,0 +1,755 @@
+/*****************************************************************************
+ * vlm.js: VLC media player web interface
+ *****************************************************************************
+ * Copyright (C) 2005-2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/* replace quotes and spaces by underscores */
+function addunderscores( str ){ return str.replace(/\'|\"| /g, '_'); }
+
+/**********************************************************************
+ * Input dialog functions
+ *********************************************************************/
+
+function toggle_show_vlm_helper()
+{
+    var vlmh = document.getElementById( "vlm_helper" );
+    var vlmhctrl = document.getElementById( "vlm_helper_controls" );
+    var btn = document.getElementById( "btn_vlm_helper_toggle" );
+    if( vlmh.style.display == 'block' || vlmh.style.display == '')
+    {
+        vlmh.style.display = 'none';
+        vlmhctrl.style.display = 'none';
+        btn.removeChild( btn.firstChild );
+        btn.appendChild( document.createTextNode( 'Show VLM helper' ) );
+    }
+    else
+    {
+        vlmh.style.display = 'block';
+        vlmhctrl.style.display = 'inline';
+        btn.removeChild( btn.firstChild );
+        btn.appendChild( document.createTextNode( 'Hide VLM helper' ) );
+    }
+}
+
+function vlm_input_edit( dest )
+{
+    document.getElementById( 'input_dest' ).value = dest;
+    show( 'input' );
+}
+
+function vlm_input_change()
+{
+    document.getElementById( value( 'input_dest' ) ).value = value( 'input_mrl' ).replace( /\ :/g, " option " );
+    hide( 'input' );
+    document.getElementById( value( 'input_dest' ) ).focus();
+}
+
+function vlm_output_edit( dest )
+{
+    document.getElementById( 'sout_dest' ).value = dest;
+    show( 'sout' );
+}
+
+function vlm_output_change()
+{
+    document.getElementById( value( 'sout_dest' ) ).value = value( 'sout_mrl' ).substr(6).replace( /\ :/g, " option " ); /* substr <-> remove :sout= */
+    hide( 'sout' );
+    document.getElementById( value( 'sout_dest' ) ).focus();
+}
+
+function hide_vlm_add()
+{
+    document.getElementById( 'vlm_add_broadcast' ).style.display = 'none';
+    document.getElementById( 'vlm_add_vod' ).style.display = 'none';
+    document.getElementById( 'vlm_add_schedule' ).style.display = 'none';
+    document.getElementById( 'vlm_add_other' ).style.display = 'none';
+}
+
+function toggle_schedule_date()
+{
+    if( checked( 'vlm_schedule_now' ) )
+    {
+        disable( 'vlm_schedule_year' );
+        disable( 'vlm_schedule_month' );
+        disable( 'vlm_schedule_day' );
+        disable( 'vlm_schedule_hour' );
+        disable( 'vlm_schedule_minute' );
+        disable( 'vlm_schedule_second' );
+    }
+    else
+    {
+        enable( 'vlm_schedule_year' );
+        enable( 'vlm_schedule_month' );
+        enable( 'vlm_schedule_day' );
+        enable( 'vlm_schedule_hour' );
+        enable( 'vlm_schedule_minute' );
+        enable( 'vlm_schedule_second' );
+    }
+}
+
+function toggle_schedule_repeat()
+{
+    if( checked( 'vlm_schedule_repeat' ) )
+    {
+        enable( 'vlm_schedule_period_year' );
+        enable( 'vlm_schedule_period_month' );
+        enable( 'vlm_schedule_period_day' );
+        enable( 'vlm_schedule_period_hour' );
+        enable( 'vlm_schedule_period_minute' );
+        enable( 'vlm_schedule_period_second' );
+        enable( 'vlm_schedule_repeat_times' );
+    }
+    else
+    {
+        disable( 'vlm_schedule_period_year' );
+        disable( 'vlm_schedule_period_month' );
+        disable( 'vlm_schedule_period_day' );
+        disable( 'vlm_schedule_period_hour' );
+        disable( 'vlm_schedule_period_minute' );
+        disable( 'vlm_schedule_period_second' );
+        disable( 'vlm_schedule_repeat_times' );
+    }
+}
+
+function vlm_schedule_type_change( name )
+{
+    var act = document.getElementById( 'vlm_elt_' + name + '_action' ).value;
+    var itemname = document.getElementById( 'vlm_elt_' + name + '_name' );
+    var opt = document.getElementById( 'vlm_elt_' + name + '_opt' );
+    if( act == "play" || act == "pause" || act == "stop" )
+    {
+        itemname.style.display = "";
+        opt.style.display = "none";
+    }
+    else if( act == "seek" )
+    {
+        itemname.style.display = "";
+        opt.style.display = "";
+    }
+    else
+    {
+        itemname.style.display = "none";
+        opt.style.display = "";
+    }
+}
+
+function sanitize_input( str )
+{
+    return str.replace( /\"/g, '\\\"' ).replace( /^/, '"' ).replace( /$/, '"' ).replace( /\ option\ /g, '" option "' );
+}
+
+function update_vlm_add_broadcast()
+{
+    var cmd = document.getElementById( 'vlm_command' );
+
+    if( value( 'vlm_broadcast_name' ) )
+    {
+        cmd.value = "new " + addunderscores( value( 'vlm_broadcast_name' ) )
+                    + " broadcast";
+
+        if( checked( 'vlm_broadcast_enabled' ) )
+        {
+            cmd.value += " enabled";
+        }
+        
+        if( checked( 'vlm_broadcast_loop' ) )
+        {
+            cmd.value += " loop";
+        }
+
+        if( value( 'vlm_broadcast_input' ) )
+        {
+            cmd.value += " input " + sanitize_input( value( 'vlm_broadcast_input' ) );
+        }
+
+        if( value( 'vlm_broadcast_output' ) )
+        {
+            cmd.value += " output " + value( 'vlm_broadcast_output' );
+        }
+    }
+    else
+    {
+        cmd.value = "";
+    }
+}
+
+function update_vlm_add_vod()
+{
+    var cmd = document.getElementById( 'vlm_command' );
+
+    if( value( 'vlm_vod_name' ) )
+    {
+        cmd.value = "new " + addunderscores( value( 'vlm_vod_name' ) )
+                    + " vod";
+
+        if( checked( 'vlm_vod_enabled' ) )
+        {
+            cmd.value += " enabled";
+        }
+        
+        if( value( 'vlm_vod_input' ) )
+        {
+            cmd.value += " input " + sanitize_input( value( 'vlm_vod_input' ) );
+        }
+
+        if( value( 'vlm_vod_output' ) )
+        {
+            cmd.value += " output " + value( 'vlm_vod_output' );
+        }
+    }
+    else
+    {
+        cmd.value = "";
+    }
+}
+
+function update_vlm_add_schedule()
+{
+    var cmd = document.getElementById( 'vlm_command' );
+
+    check_and_replace_int( 'vlm_schedule_year', '0000' );
+    check_and_replace_int( 'vlm_schedule_month', '00' );
+    check_and_replace_int( 'vlm_schedule_day', '00' );
+    check_and_replace_int( 'vlm_schedule_hour', '00' );
+    check_and_replace_int( 'vlm_schedule_minute', '00' );
+    check_and_replace_int( 'vlm_schedule_second', '00' );
+    check_and_replace_int( 'vlm_schedule_period_year', '0000' );
+    check_and_replace_int( 'vlm_schedule_period_month', '00' );
+    check_and_replace_int( 'vlm_schedule_period_day', '00' );
+    check_and_replace_int( 'vlm_schedule_period_hour', '00' );
+    check_and_replace_int( 'vlm_schedule_period_minute', '00' );
+    check_and_replace_int( 'vlm_schedule_period_second', '00' );
+
+    if( value( 'vlm_schedule_name' ) )
+    {
+        cmd.value = "new " + addunderscores( value( 'vlm_schedule_name' ) ) + " schedule";
+
+        if( checked( 'vlm_schedule_enabled' ) )
+        {
+            cmd.value += " enabled";
+        }
+
+        if( checked( 'vlm_schedule_now' ) )
+        {
+            cmd.value += " date now";
+        }
+        else
+        {
+            cmd.value += " date " + value( 'vlm_schedule_year' ) + "/" + value( 'vlm_schedule_month' ) + "/" + value( 'vlm_schedule_day' ) + '-' + value( 'vlm_schedule_hour' ) + ':' + value( 'vlm_schedule_minute' ) + ':' + value( 'vlm_schedule_second' );
+        }
+
+        if( checked( 'vlm_schedule_repeat' ) )
+        {
+            cmd.value += " period " + value( 'vlm_schedule_period_year' ) + "/" + value( 'vlm_schedule_period_month' ) + "/" + value( 'vlm_schedule_period_day' ) + '-' + value( 'vlm_schedule_period_hour' ) + ':' + value( 'vlm_schedule_period_minute' ) + ':' + value( 'vlm_schedule_period_second' );
+
+            if( value( 'vlm_schedule_repeat_times' ) != 0 )
+            {
+                cmd.value += " repeat " + (value( 'vlm_schedule_repeat_times' ) - 1 );
+            }
+        }
+            
+    }
+    else
+    {
+        cmd.value = "";
+    }
+}
+
+function update_vlm_add_other()
+{
+    var cmd = document.getElementById( 'vlm_command' );
+    cmd.value = "";
+}
+
+function clear_vlm_add()
+{
+    document.getElementById( 'vlm_command' ).value = "";
+    document.getElementById( 'vlm_broadcast_name' ).value = "";
+    document.getElementById( 'vlm_vod_name' ).value = "";
+}
+
+function create_button( caption, action )
+{
+/*    var link = document.createElement( "input" );
+    link.setAttribute( 'type', 'button' );*/
+    /* link.setAttribute( 'onclick', action ); */
+    /* Above doesn't work on ie. You need to use something like
+     * link.onclick = function() { alert( 'pouet' ); };
+     * instead ... conclusion: IE is crap */
+   /* link.setAttribute( 'value', caption );*/
+
+    var d = document.createElement( 'div' );
+    d.innerHTML = "<input type='button' onclick='"+action+"' value='"+caption+"' />"; /* other IE work around  ... still crap. Use double quotes only in action */
+    var link = d.firstChild;
+    return link;
+}
+function create_option( caption, value )
+{
+    var opt = document.createElement( 'option' );
+    opt.setAttribute( 'value', value );
+    opt.appendChild( document.createTextNode( caption ) );
+    return opt;
+}
+
+function parse_vlm_cmd()
+{
+    if( req.readyState == 4 )
+    {
+        if( req.status == 200 )
+        {
+            var vlm_answer = req.responseXML.documentElement;
+            var error_tag = vlm_answer.getElementsByTagName( 'error' )[0];
+            var vlme = document.getElementById( 'vlm_error' );
+            clear_children( vlme );
+            if( error_tag.hasChildNodes() )
+            {
+                vlme.appendChild( document.createTextNode( 'Error: ' + error_tag.firstChild.data ) );
+                vlme.style.color = "#f00";
+            }
+            else
+            {
+                vlme.appendChild( document.createTextNode( 'Command succesful (' + value( 'vlm_command' ) + ') ' ) );
+                vlme.style.color = "#0f0";
+                clear_vlm_add();
+            }
+            vlme.appendChild( create_button( 'clear', 'clear_children( document.getElementById( "vlm_error" ) );' ) );
+
+            vlm_get_elements();
+        }
+    }
+}
+
+function parse_vlm_elements()
+{
+    if( req.readyState == 4 )
+    {
+        if( req.status == 200 )
+        {
+            var vlmb = document.getElementById( 'vlm_broadcast_list' );
+            var vlmv = document.getElementById( 'vlm_vod_list' );
+            var vlms = document.getElementById( 'vlm_schedule_list' );
+
+            clear_children( vlmb );
+            clear_children( vlmv );
+            clear_children( vlms );
+
+            answer = req.responseXML.documentElement;
+
+            var elt = answer.firstChild;
+
+            while( elt )
+            {
+                if( elt.nodeName == "broadcast" || elt.nodeName == "vod" )
+                {
+                    var nb = document.createElement( 'div' );
+                    setclass( nb, 'list_element' );
+                    if( elt.nodeName == "broadcast" )
+                    {
+                        vlmb.appendChild( nb );
+                    }
+                    else
+                    {
+                        vlmv.appendChild( nb );
+                    }
+                    var nbname = document.createElement( 'b' );
+                    nbname.appendChild( document.createTextNode( elt.getAttribute( 'name' ) ) );
+                    nb.appendChild( nbname );
+                    
+                    if( elt.getAttribute( 'enabled' ) == 'yes' )
+                    {
+                        nb.appendChild( document.createTextNode( " enabled " ) );
+                        nb.appendChild( create_button( "Disable", 'vlm_disable("'+elt.getAttribute( 'name' ) + '");' ) );
+                    }
+                    else
+                    {
+                        nb.appendChild( document.createTextNode( " disabled " ) );
+                        nb.appendChild( create_button( "Enable", 'vlm_enable("'+elt.getAttribute( 'name' ) + '");' ) );
+                    }
+                    
+                    if( elt.nodeName == "broadcast" )
+                    {
+                        if( elt.getAttribute( 'loop' ) == 'yes' )
+                        {
+                            nb.appendChild( document.createTextNode( " loop " ) );
+
+                            nb.appendChild( create_button( 'Un-loop', 'vlm_unloop("'+elt.getAttribute( 'name' ) + '");' ) );
+                        }
+                        else
+                        {
+                            nb.appendChild( document.createTextNode( " play once " ) );
+                            nb.appendChild( create_button( 'Loop', 'vlm_loop("'+elt.getAttribute( 'name' ) + '");' ) );
+                            
+                        }
+
+                        if( elt.getAttribute( 'enabled' ) == 'yes' )
+                        {
+                            nb.appendChild( document.createTextNode( " " ) );
+                            nb.appendChild( create_button( 'Play', 'vlm_play("'+elt.getAttribute('name')+'");' ) );
+                        }
+
+                        nb.appendChild( document.createTextNode( " " ) );
+                        nb.appendChild( create_button( 'Pause', 'vlm_pause("'+elt.getAttribute('name')+'");' ) );
+
+                        nb.appendChild( document.createTextNode( " " ) );
+                        nb.appendChild( create_button( 'Stop', 'vlm_stop("'+elt.getAttribute('name')+'");' ) );
+                    }
+                    
+                    nb.appendChild( document.createTextNode( " " ) );
+                    nb.appendChild( create_button( 'Delete', 'vlm_delete("'+elt.getAttribute( 'name' ) + '");' ) );
+
+                    var list = document.createElement( "ul" );
+
+                    /* begin input list */
+                    var item = document.createElement( "li" );
+                    list.appendChild( item );
+                    item.appendChild( document.createTextNode( "Inputs: " ) );
+                    var text = document.createElement( "input" );
+                    text.setAttribute( 'type', 'text' );
+                    text.setAttribute( 'size', '40' );
+                    text.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_input' );
+                    text.setAttribute( 'onkeypress', 'if( event.keyCode == 13 ) vlm_add_input("'+elt.getAttribute('name')+'",document.getElementById("vlm_elt_'+elt.getAttribute('name')+'_input").value );' );
+                    item.appendChild( text );
+                    item.appendChild( document.createTextNode( ' ' ) );
+                    item.appendChild( create_button( 'Edit', 'vlm_input_edit("vlm_elt_'+elt.getAttribute('name')+'_input");') );
+                    item.appendChild( document.createTextNode( ' ' ) );
+                    item.appendChild( create_button( 'Add input', 'vlm_add_input("'+elt.getAttribute('name')+'",document.getElementById("vlm_elt_'+elt.getAttribute('name')+'_input").value );' ) );
+                    
+                    var inputs = elt.getElementsByTagName( 'input' );
+                    if( inputs.length > 0 )
+                    {
+                        var ilist = document.createElement( "ol" );
+                        ilist.setAttribute( 'start', '1' );
+                        item.appendChild( ilist );
+                        for( i = 0; i < inputs.length; i++ )
+                        {
+                            var item = document.createElement( "li" );
+                            item.appendChild( document.createTextNode( inputs[i].firstChild.data + " " ) );
+                            item.appendChild( create_button( "Delete", 'vlm_delete_input("' + elt.getAttribute( 'name' ) + '", '+(i+1)+' );' ) );
+                            ilist.appendChild( item );
+                        }
+                    }
+                    /* end of input list */
+                    
+                    /* output */
+                    var item = document.createElement( "li" );
+                    outputelt = elt.getElementsByTagName( 'output' )[0];
+                    if( outputelt.hasChildNodes() )
+                    {
+                        output = outputelt.firstChild.data;
+                    }
+                    else
+                    {
+                        output = "";
+                    }
+                    item.appendChild( document.createTextNode( 'Output: ' ) );
+                    var text = document.createElement( "input" );
+                    text.setAttribute( 'type', 'text' );
+                    text.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_output' );
+                    text.setAttribute( 'value', output );
+                    text.setAttribute( 'onkeypress', 'if( event.keyCode == 13 )  vlm_output("'+elt.getAttribute( 'name' )+ '",document.getElementById("vlm_elt_'+elt.getAttribute( 'name' )+'_output").value);' );
+                    item.appendChild( text );
+
+                    item.appendChild( document.createTextNode( ' ' ) );
+
+                    item.appendChild( create_button( 'Edit', 'vlm_output_edit("vlm_elt_'+elt.getAttribute('name')+'_output");' ) );
+                    item.appendChild( document.createTextNode( ' ' ) );
+                    item.appendChild( create_button( 'Change output', 'vlm_output("'+elt.getAttribute( 'name' )+ '",document.getElementById("vlm_elt_'+elt.getAttribute( 'name' )+'_output").value);' ) );
+                    list.appendChild( item );
+                    /* end of output */
+
+                    /* begin options list */
+                    var item = document.createElement( "li" );
+                    list.appendChild( item );
+                    item.appendChild( document.createTextNode( "Options: " ) );
+                    /* Add option */
+                    var text = document.createElement( "input" );
+                    text.setAttribute( 'type', 'text' );
+                    text.setAttribute( 'size', '40' );
+                    text.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_option' );
+                    text.setAttribute( 'onkeypress', 'if( event.keyCode == 13 ) vlm_option("'+elt.getAttribute('name')+'",document.getElementById("vlm_elt_'+elt.getAttribute('name')+'_option").value );' );
+                    item.appendChild( text );
+                    item.appendChild( document.createTextNode( ' ' ) );
+                    item.appendChild( create_button( 'Add option', 'vlm_option("'+elt.getAttribute('name')+'",document.getElementById("vlm_elt_'+elt.getAttribute('name')+'_option").value );' ) );
+                    
+                    var options = elt.getElementsByTagName( 'option' );
+                    if( options.length > 0 )
+                    {
+                        var olist = document.createElement( "ul" );
+                        item.appendChild( olist );
+                        for( i = 0; i < options.length; i++ )
+                        {
+                            var item = document.createElement( "li" );
+                            item.appendChild( document.createTextNode( options[i].firstChild.data ) );
+                            olist.appendChild( item );
+                        }
+                    }
+                    /* end of options */
+
+                    /* Instances list */
+                    var instances = elt.getElementsByTagName( 'instance' );
+                    if( instances.length > 0 )
+                    {
+                        var item = document.createElement("li");
+                        var ilist = document.createElement("ul");
+                        list.appendChild( item );
+                        item.appendChild(document.createTextNode("Instances:")); 
+                        item.appendChild( ilist );
+                        for( i = 0; i < instances.length; i++ )
+                        {
+                            var iname = instances[i].getAttribute( 'name' );
+                            var istate = instances[i].getAttribute( 'state' );
+                            var iposition = Number( instances[i].getAttribute( 'position' ) * 100);
+                            var itime = Math.floor( instances[i].getAttribute( 'time' ) / 1000000);
+                            var ilength = Math.floor( instances[i].getAttribute( 'length' ) / 1000000);
+                            var irate = instances[i].getAttribute( 'rate' );
+                            var ititle = instances[i].getAttribute( 'title' );
+                            var ichapter = instances[i].getAttribute( 'chapter' );
+                            var iseekable = instances[i].getAttribute( 'seekable' );
+                            var iplaylistindex = instances[i].getAttribute( 'playlistindex' );
+                            
+                            var item = document.createElement( "li" );
+                            item.appendChild( document.createTextNode( iname + ": " + istate + " (" + iplaylistindex + ") " + (iposition.toFixed(2)) + "%" + " " + format_time( itime ) + "/" + format_time( ilength ) ) );
+                            ilist.appendChild( item );
+                        }
+                    }
+                    /* end of instances list */
+                    
+                    nb.appendChild( list );
+                    
+                }
+                else if( elt.nodeName == "schedule" )
+                {
+                    var nb = document.createElement( 'div' );
+                    setclass( nb, 'list_element' );
+                    vlms.appendChild( nb );
+
+                    var nbname = document.createElement( 'b' );
+                    nbname.appendChild( document.createTextNode( elt.getAttribute( 'name' ) ) );
+                    nb.appendChild( nbname );
+                    
+                    if( elt.getAttribute( 'enabled' ) == 'yes' )
+                    {
+                        nb.appendChild( document.createTextNode( " enabled " ) );
+                        nb.appendChild( create_button( "Disable", 'vlm_disable("'+elt.getAttribute( 'name' ) + '");' ) );
+                    }
+                    else
+                    {
+                        nb.appendChild( document.createTextNode( " disabled " ) );
+                        nb.appendChild( create_button( "Enable", 'vlm_enable("'+elt.getAttribute( 'name' ) + '");' ) );
+                    }
+
+                    nb.appendChild( document.createTextNode( " " ) );
+                    nb.appendChild( create_button( "Delete", 'vlm_delete("'+elt.getAttribute( 'name' ) + '");' ) );
+
+                    var list = document.createElement( 'ul' );
+
+                    var item = document.createElement( 'li' );
+                    item.appendChild( document.createTextNode( "Date: " + elt.getAttribute( 'date' ) ) );
+                    list.appendChild( item );
+
+                    var item = document.createElement( 'li' );
+                    item.appendChild( document.createTextNode( "Period (in seconds): " + elt.getAttribute( 'period' ) ) );
+                    list.appendChild( item );
+                    
+                    var item = document.createElement( 'li' );
+                    if( elt.getAttribute( 'repeat' ) == -1 )
+                    {
+                        item.appendChild( document.createTextNode( "Number of repeats left: for ever" ) );
+                    }
+                    else
+                    {
+                        item.appendChild( document.createTextNode( "Number of repeats left: " + elt.getAttribute( 'repeat' ) ) );
+                    }
+                    list.appendChild( item );
+                    
+                    var commands = elt.getElementsByTagName( 'command' );
+                    for( i = 0; i < commands.length; i++ )
+                    {
+                        var item = document.createElement( "li" );
+                        item.appendChild( document.createTextNode( "Command: " + commands[i].firstChild.data + " " ) );
+                        list.appendChild( item );
+                    }
+                    
+                    var item = document.createElement( 'li' );
+                    var sel = document.createElement( 'select' );
+                    sel.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_action' );
+                    sel.setAttribute( 'onchange', 'vlm_schedule_type_change("'+elt.getAttribute('name')+'");');
+                    sel.appendChild( create_option( 'play', 'play' ) );
+                    sel.appendChild( create_option( 'pause', 'pause' ) );
+                    sel.appendChild( create_option( 'stop', 'stop' ) );
+                    sel.appendChild( create_option( 'seek', 'seek' ) );
+                    sel.appendChild( create_option( '(other)', '' ) );
+                    item.appendChild( sel );
+
+                    item.appendChild( document.createTextNode( " " ) );
+                    var text = document.createElement( 'input' );
+                    text.setAttribute( 'type', 'text' );
+                    text.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_name' );
+                    text.setAttribute( 'size', '10' );
+                    text.setAttribute( 'value', '(name)' );
+                    text.setAttribute( 'onfocus', 'if( this.value == "(name)" ) this.value = "";' );
+                    text.setAttribute( 'onblur', 'if( this.value == "" ) this.value = "(name)";' );
+                    item.appendChild( text );
+
+                    item.appendChild( document.createTextNode( " " ) );
+                    text = document.createElement( 'input' );
+                    text.setAttribute( 'type', 'text' );
+                    text.setAttribute( 'id', 'vlm_elt_'+elt.getAttribute('name')+'_opt' );
+                    text.setAttribute( 'size', '30' );
+                    text.setAttribute( 'value', '(options)' );
+                    text.setAttribute( 'onfocus', 'if( this.value == "(options)" ) this.value = "";' );
+                    text.setAttribute( 'onblur', 'if( this.value == "" ) this.value = "(options)";' );
+                    item.appendChild( text );
+                    item.appendChild( document.createTextNode( " " ) );
+                    item.appendChild( create_button( "Append command", 'vlm_schedule_append("' + elt.getAttribute( 'name' ) + '");') );
+                    
+                    list.appendChild( item );
+
+                    nb.appendChild( list );
+                    vlm_schedule_type_change( elt.getAttribute('name') );
+                    
+                }
+                elt = elt.nextSibling;
+            }
+        }
+    }
+}
+
+function vlm_cmd( cmd )
+{
+    loadXMLDoc( 'requests/vlm_cmd.xml?command='+encodeURIComponent(cmd), parse_vlm_cmd );
+}
+
+function vlm_get_elements( )
+{
+    loadXMLDoc( 'requests/vlm.xml', parse_vlm_elements );
+}
+
+/* helper functions */
+
+function vlm_disable( name )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" disabled";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_enable( name )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" enabled";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_loop( name )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" loop";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_unloop( name )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" unloop";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_play( name )
+{
+    document.getElementById( 'vlm_command' ).value = "control "+name+" play";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_pause( name )
+{
+    document.getElementById( 'vlm_command' ).value = "control "+name+" pause";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_stop( name )
+{
+    document.getElementById( 'vlm_command' ).value = "control "+name+" stop";
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_delete( name )
+{
+    document.getElementById( 'vlm_command' ).value = "del "+name;
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_delete_input( name, num )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" inputdeln "+num;
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_add_input( name, input )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" input "+sanitize_input( input );
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_output( name, output )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" output "+output;
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_option( name, option )
+{
+    document.getElementById( 'vlm_command' ).value = "setup "+name+" option "+option;
+    vlm_cmd( value( 'vlm_command' ) );
+}
+
+function vlm_batch( batch )
+{
+    var i;
+    var commands = batch.split( '\n' );
+    for( i = 0; i < commands.length; i++ )
+    {
+        document.getElementById( 'vlm_command' ).value = commands[i];
+        vlm_cmd( value( 'vlm_command' ) );
+    }
+}
+
+function vlm_schedule_append( name )
+{
+    var act = document.getElementById( 'vlm_elt_' + name + '_action' ).value;
+    document.getElementById( 'vlm_command' ).value = "setup " + name + " append ";
+
+    var itemname = document.getElementById( 'vlm_elt_' + name + '_name' ).value;
+    if( itemname == "(name)" ) itemname = "";
+
+    var opt = document.getElementById( 'vlm_elt_' + name + '_opt' ).value;
+    if( opt == "(options)" ) opt = "";
+        
+    if( act == '' )
+    {
+        document.getElementById( 'vlm_command' ).value += opt;
+    }
+    else
+    {
+        document.getElementById( 'vlm_command' ).value += 'control ' + itemname + " " + act + " " + opt;
+    }
+    vlm_cmd( value( 'vlm_command' ) );
+}
+function vlm_send( )
+{
+    vlm_cmd( value( 'vlm_command' ) );
+}
diff --git a/share/http-lua/mosaic.html b/share/http-lua/mosaic.html
new file mode 100644 (file)
index 0000000..770f8ae
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  vlm.html: VLC media player web interface - VLM
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+
+  <title>VLC media player - Web Interface - Mosaic Wizard</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=<?vlc --[[FIXME charset]]?>" />
+  <link href="style.css" rel="stylesheet" type="text/css" />
+  <script type="text/javascript" src="js/functions.js"></script>
+  <script type="text/javascript" src="js/vlm.js"></script>
+  <script type="text/javascript" src="js/mosaic.js"></script>
+
+</head>
+
+<body onload="mosaic_init();">
+
+<h1>Mosaic wizard</h1>
+
+<?vlc
+current_page = "vlm"
+
+dialogs("browse","input","sout","mosaic","footer")
+?>
+
+</body>
+
+</html>
diff --git a/share/http-lua/old/.hosts b/share/http-lua/old/.hosts
new file mode 100644 (file)
index 0000000..7996904
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Default access-list for VLC HTTP interface
+# $Id$
+#
+
+# localhost
+::1
+127.0.0.1
+
+# link-local addresses
+#fe80::/64
+
+# private addresses
+#fc00::/7
+#fec0::/10
+#10.0.0.0/8
+#172.16.0.0/12
+#192.168.0.0/16
+
+# The world
+# (comment this out to obtain a safe default)
+::/0
+0.0.0.0/0
+
diff --git a/share/http-lua/old/admin/.access b/share/http-lua/old/admin/.access
new file mode 100644 (file)
index 0000000..8a5c9a6
--- /dev/null
@@ -0,0 +1 @@
+admin:admin
diff --git a/share/http-lua/old/admin/browse.html b/share/http-lua/old/admin/browse.html
new file mode 100644 (file)
index 0000000..9eb5057
--- /dev/null
@@ -0,0 +1,51 @@
+<html>
+<head>
+    <title>VLC media player - Browser</title>
+    <link href="../style.css" title="Default" rel="stylesheet" type="text/css" />
+
+    <vlc id="if" param1="'control' url_extract strlen"/>
+        <meta http-equiv="refresh" content="0;URL=/old/admin/browse.html?dir=<vlc id="value" param1="'dir' url_extract" />" />
+    <vlc id="end" />
+
+    <vlc id="control" param1="add"/>
+</head>
+<body>
+    <h2><center><a href="/old/">VLC media player <vlc id="value" param1="version" /></a></center></h2>
+    <hr/>
+    <table  width="100%" border=0 cellspacing=1 cellpadding=2>
+    <tr>
+        <th align="left" bgcolor="#88ff88" colspan="2">File (<vlc id="value" param1="'dir' url_extract" />)</th>
+        <th align="left" bgcolor="#cccccc">Size</th>
+        <th align="left" bgcolor="#cccccc">Date</th>
+    </tr>
+    <p>This page is default disabled for security reasons (change _directory_ into directory to enable it).</p>
+    <vlc id="rpn" param1="counter 0 store" />
+    <vlc id="rpn" param1="'dir' url_extract" />
+    <vlc id="foreach" param1="file" param2="_directory_" />
+        <vlc id="rpn" param1="counter counter value 1 + store" />
+        <tr class="<vlc id="if" param1="counter value 2 % 0 =" />line1<vlc id="else" />line2<vlc id="end" />">
+            <td>
+                <vlc id="if" param1="file.type value 'directory' strcmp 0 =" />
+                    <img src="/icons/dir.gif" alt=[DIR]" border="0" width="20" height="22">
+                    <a href="?dir=<vlc id="value" param1="file.name" />"><vlc id="value" param1="file.name" /></a>
+                <vlc id="else" /> 
+                    <img src="/icons/text.gif" alt=[FILE]" border="0" width="20" height="22">
+                    <vlc id="value" param1="file.name" />
+                <vlc id="end" />
+            </td>
+            <td align="right">
+                <form method="get" action="">
+                    <input type="hidden" name="dir" value="<vlc id="value" param1="'dir' url_extract" />"/>
+                    <input type="hidden" name="mrl" value="<vlc id="value" param1="file.name" />"/>
+                    <input type="submit" name="control" value="add" />
+                </form>
+            </td>
+            <td align="right"><vlc id="value" param1="file.size" /></td>
+            <td align="center"><vlc id="value" param1="file.date" /></td>
+        </tr>
+    <vlc id="end" />
+    </table>
+    <hr/>
+    <p><vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/admin/dboxfiles.html b/share/http-lua/old/admin/dboxfiles.html
new file mode 100644 (file)
index 0000000..e9d0f7b
--- /dev/null
@@ -0,0 +1,2 @@
+<vlc id="rpn" param1="'stream_position' url_extract" /><vlc id="if" param1="value 'true' strcmp 0 =" /><vlc id="value" param1="stream_position" /><vlc id="end" /><vlc id="rpn" param1="'stream_time' url_extract" /><vlc id="if" param1="value 'true' strcmp 0 =" /><vlc id="value" param1="stream_time" /><vlc id="end" /><vlc id="rpn" param1="'stream_length' url_extract" /><vlc id="if" param1="value 'true' strcmp 0 =" /><vlc id="value" param1="stream_length" /><vlc id="end" /><vlc id="rpn" param1="'dir' url_extract" /><vlc id="foreach" param1="file" param2="directory" /><vlc id="if" param1="file.type value 'directory' strcmp 0 =" />DIR:<vlc id="value" param1="file.name" /><vlc id="else" /><vlc id="value" param1="file.name" /><vlc id="end" />
+<vlc id="end" />
\ No newline at end of file
diff --git a/share/http-lua/old/admin/index.html b/share/http-lua/old/admin/index.html
new file mode 100644 (file)
index 0000000..0641f09
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+    <title>VLC media player</title>
+    <style>
+        body {font-family:Verdana, Arial, Sans Serif; }
+        h2 { text-align:center; }
+       td {border:1pt black solid;margin:0em; }
+        table.border {border:1pt black solid;}
+        div.section {background-color:#DDDDFF;
+             border:1pt black solid;
+             margin-bottom:2em;
+            padding:0.5em; }
+       div.section-ctr {background-color:#CCCCFF;
+             border:1pt black solid;
+             margin-bottom:2em;
+             padding:0.5em;
+            font-size:1.2em;
+            text-align:center; }
+
+        div.sectitle {  background-color:#5A5ABB;
+                        color:#FFFFFF;
+                        border:1pt black solid;
+                        width:20%;
+                        font-weight:bold;}
+        tr.ligne1 { background-color:#EEFFFF; }
+        tr.ligne2 { background-color:#CCCCFF; }
+    </style>
+    <vlc id="if" param1="url_param"/>
+        <meta http-equiv="refresh" content="0;URL=/old/admin/" />
+    <vlc id="end" />
+
+    <vlc id="control" />
+    <vlc id="set" param1="sout" param2="string" />
+</head>
+<body>
+    <h2><a href="/old/">VLC media player - Admin <vlc id="value" param1="version" /></a></h2>
+
+<div class="section-ctr">Shutdown VLC<br /> <form method="get" action=""> <input type="submit" name="control" value="shutdown" /> </form></div>
+
+  <div class="sectitle">Host list</div>
+  <div class="section">
+    <table class="border" >
+    <tr>
+        <th>Id</th><th>Host</th><th>IP</th><th>Port</th>
+    </tr>
+    <vlc id="foreach" param1="host" param2="hosts" />
+        <tr>
+        <td><vlc id="value" param1="host.id" /></td>
+        <td><vlc id="value" param1="host.host" /> </td>
+        <td><vlc id="value" param1="host.ip" /> </td>
+        <td><vlc id="value" param1="host.port" /> </td>
+        </tr>
+    <vlc id="end" />
+    </table>
+   </div>
+   <div class="sectitle">File list</div>
+   <div class="section">
+    <table border="1" cellspacing="0" >
+    <tr>
+        <th>Id</th><th>URL</th><th>Mime</th><th>Protected</th><th>Usage</th>
+    </tr>
+    <vlc id="foreach" param1="url" param2="urls" />
+        <vlc id="if" param1="url.stream 0 =" /> 
+            <tr>
+            <td><vlc id="value" param1="url.id" /></td>
+            <td><vlc id="value" param1="url.url" /></td>
+            <td><vlc id="value" param1="url.mime" /></td>
+            <td><vlc id="value" param1="url.protected" /></td>
+            <td><vlc id="value" param1="url.used" /></td>
+            </tr>
+        <vlc id="end" />
+    <vlc id="end" />
+    </table>
+   </div>
+
+
+   <div class="sectitle">Stream list</div>
+   <div class="section">
+    <table border="1" cellspacing="0" >
+    <tr>
+        <th>Id</th><th>URL</th><th>Mime</th><th>Protected</th><th>Usage</th>
+    </tr>
+    <vlc id="foreach" param1="url" param2="urls" />
+        <vlc id="if" param1="url.stream" />
+            <tr>
+            <td><vlc id="value" param1="url.id" /></td>
+            <td><vlc id="value" param1="url.url" /></td>
+            <td><vlc id="value" param1="url.mime" /></td>
+            <td><vlc id="value" param1="url.protected" /></td>
+            <td><vlc id="value" param1="url.used" /></td>
+            </tr>
+        <vlc id="end" />
+    <vlc id="end" />
+    </table>
+   </div>
+
+   <div class="sectitle">Connections list</div>
+   <div class="section">
+    <table border="1" cellspacing="0" >
+    <tr>
+        <th>Id</th><th>ip</th><th>URL</th><th>Status</th><th>Actions</th>
+    </tr>
+    <vlc id="foreach" param1="con" param2="connections" />
+        <tr>
+        <td><vlc id="value" param1="con.id" /></td>
+        <td><vlc id="value" param1="con.ip" /></td>
+        <td><vlc id="value" param1="con.url" /></td>
+        <td><vlc id="value" param1="con.status" /></td>
+        <td>
+        <form method="get" action="">
+            <input type="hidden" name="id" value="<vlc id="value" param1="con.id" />"/>
+            <input type="submit" name="control" value="close" />
+        </form>
+
+        </td>
+        </tr>
+    <vlc id="end" />
+    </table>
+   </div>
+    <hr />
+    <p> <vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
+
diff --git a/share/http-lua/old/cone_minus.png b/share/http-lua/old/cone_minus.png
new file mode 100644 (file)
index 0000000..b7a75e7
Binary files /dev/null and b/share/http-lua/old/cone_minus.png differ
diff --git a/share/http-lua/old/cone_plus.png b/share/http-lua/old/cone_plus.png
new file mode 100644 (file)
index 0000000..d093904
Binary files /dev/null and b/share/http-lua/old/cone_plus.png differ
diff --git a/share/http-lua/old/index.html b/share/http-lua/old/index.html
new file mode 100644 (file)
index 0000000..6036377
--- /dev/null
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- $Id$-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+ <head>
+    <title>VLC media player</title>
+    <link href="style.css" title="Default" rel="stylesheet" type="text/css" />
+    <!-- Work around. should be done in the code -->
+    <vlc id="if" param1="url_param"/>
+        <meta http-equiv="Refresh" content="0;url=/old/" />
+    <vlc id="else" />
+        <meta http-equiv="Refresh" content="60;url=/old/">
+    <vlc id="end" />
+    
+    <vlc id="control" param1="stop,pause,previous,next,add,sout,play,delete,empty,seek,fullscreen,keep,volume,sort,move" />
+    <vlc id="set" param1="sout" param2="string" />
+<script type="text/javascript">
+
+function changeMe(item)
+{
+  if (item.parentNode.lastChild.style.display=="none")
+  {
+    item.parentNode.lastChild.style.display="block";
+    item.alt="[-]";
+    item.src="cone_minus.png";
+  }
+  else
+  {
+    item.parentNode.lastChild.style.display="none";
+    item.alt="[+]";
+    item.src="cone_plus.png";
+  }
+}
+</script>
+
+</head>
+
+
+ <body>
+
+    <!-- left menu -->
+    <div class="left">
+      <div class="sectitle">Playback control</div>
+      <div class="section-controls">
+        <p>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="control" value="stop" />
+          </form>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="control" value="pause" />
+          </form>
+        </p>
+        <p>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="control" value="previous" />
+          </form>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="control" value="next" />
+          </form>
+        </p>
+        <p>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="seek_value" value="-1min"/><input type="hidden" name="control" value="seek"/>
+          </form>
+          <form method="get" action="" style="display: inline">
+            <input type="submit" name="seek_value" value="+1min"/><input type="hidden" name="control" value="seek"/>
+          </form>
+        </p>
+        <p>
+          <form method="get" action="">
+            <input type="text" name="seek_value" size="14"/><input type="hidden" name="control" value="seek"/>
+            <input type="submit" value="Seek" />
+          </form>
+        </p>
+        <p>
+          <span class="small">( Seek Textbox: for example "+12min 42sec", "01:13:43", "-12%" etc... )</span>
+        </p>
+      </div> <!-- End section -->
+
+      <div class="sectitle">Misc controls</div>
+      <div class="section-controls">
+        <form method="get" action="">
+               <input type="hidden" name="control" value="volume" />
+          Vol: <input type="text" name="value" size="5"/>
+               <input type="submit" value="Set" /><br /> (0 - 1024)<br /><span class="small">(for example: "536", "-12", "+42", "36%")</span>
+        </form>
+        <br />
+        <form method="get" action="">
+          <input type="submit" name="control" value="fullscreen" />
+        </form>
+      </div>
+
+      <div class="sectitle">Status</div>
+      <div class="section">
+        State: <vlc id="value" param1="stream_state" /><br />
+        Length: <span id="length"><vlc id="value" param1="stream_length" /> s
+                </span><br />
+        Time: <span id="time"><vlc id="value" param1="stream_time" /> s</span><br />
+        Volume: <span id="volume"><vlc id="value" param1="volume" /></span>
+        <br /><a href="info.html">Information</a>  
+      </div>
+
+      <div class="section"><a href="admin/">Administration Page</a></div>
+
+    </div>
+    <!-- end left -->
+
+    <!-- main content -->
+    <div class ="right">
+      <h2 class="title"><a href="http://www.videolan.org/">VLC media player
+        <vlc id="value" param1="version" /></a> (http interface)
+      </h2>
+
+      <div class="sectitle">Add</div>
+      <div class="section">
+        <table class="add">
+          <tr>
+           <form method="get" action="?" enctype="text/plain" >
+              <td>Add a MRL (Media Resource Locator) to the playlist</td>
+              <td>
+               <input type="hidden" name="control" value="add" />
+              <input type="text" name="mrl" size="40" />
+              <input type="submit" value="Add" />
+             </td>
+             </form> 
+          </tr>
+         <tr>
+            <form method="get" action="" enctype="text/plain" >
+              <td>Stream Output:</td>
+              <td>
+              <input type="text" name="sout" size="40" value="<vlc id="get" param1="sout" param2="string" />" />
+              <input type="submit"  value="Sout" />
+             </td>
+             </form>
+           </tr>
+          </table>
+      </div>
+<!-- Playlist -->
+      <div class="section">
+       <form method="get" action="">
+         <ul id="playlist">
+           <vlc id="rpn" param1="first_item 0 store" />
+           <vlc id="rpn" param1="last_depth 0 store" />
+           <vlc id="foreach" param1="pl" param2="playlist" />
+                 <vlc id="if" param1="pl.depth value last_depth value <" />
+                     <vlc id="rpn" param1="pl.depth value ':' last_depth value 1 - ':' 1 strcat strcat strcat strcat" />
+                     <vlc id="foreach" param1="the_final_countdown" param2="integer" />
+                         </ul></li>
+                     <vlc id="end" />
+                 <vlc id="end" />
+
+               <vlc id="if" param1="pl.type value 'Node' strcmp" />
+                 <vlc id="rpn" param1="1 +" />
+                 <li>
+                   <input type="checkbox" name="item" value="<vlc id="value" param1="pl.index" />"/>
+                   <vlc id="if" param1="pl.current" />
+                     <strong>
+                   <vlc id="end" />
+                   <a href="?control=play&amp;item=<vlc id="value" param1="pl.index" />">
+                   <vlc id="value" param1="pl.name" /><vlc id="if" param1="pl.uri value pl.name value strcmp"/>  (<vlc id="value" param1="pl.uri" />)<vlc id="end"/></a>
+                   <vlc id="if" param1="pl.current" />
+                     </strong>
+                   <vlc id="end" />
+                 </li>
+               <vlc id="else" />
+                 <li>
+                   <vlc id="if" param1="first_item value 0 ="/>
+                   <img alt="Cone" src="cone_plus.png" />
+                     Playlist
+                     <vlc id="rpn" param1="first_item 1 store" />
+                   <vlc id="else"/>
+                   <img alt="[-]" src="cone_minus.png" onclick='changeMe(this)'/>
+                   <vlc id="if" param1="pl.depth value 0 >"/>
+                     <input type="checkbox" name="item" value="<vlc id="value" param1="pl.index" />"/>
+                    <a href="?control=play&amp;item=<vlc id="value" param1="pl.index" />">
+                   <vlc id="end"/>
+                  <vlc id="value" param1="pl.name" />
+                   <vlc id="if" param1="pl.depth value 0 >"/>
+                     </a>
+                   <vlc id="end"/>
+                  (<vlc id="value" param1="pl.i_children" />
+                   item<vlc id="if" param1="pl.i_children 1 >" />s<vlc id="end" />)
+                   <vlc id="end"/>
+
+                   <vlc id="if" param1="pl.i_children 0 !=" />
+                       <ul>
+                   <vlc id="else" />
+                       </li>
+                   <vlc id="end" />
+
+               <vlc id="end" />
+
+               <vlc id="rpn" param1="last_depth pl.depth value store" />
+
+           <vlc id="end" />
+     <vlc id="rpn" param1="0 ':' last_depth value 1 - ':' 1 strcat strcat strcat strcat" />
+     <vlc id="foreach" param1="the_final_countdown" param2="integer" />
+         </ul></li>
+     <vlc id="end" />
+
+         </ul>
+         <input type="submit" name="control" value="delete" />
+         <input type="submit" name="control" value="empty" />
+         <input type="submit" name="control" value="keep" />
+                     <input type="submit" name="control" value="sort" /> by
+                     <select name="type">
+                       <option value="title">title</option>
+                       <option value="shuffle">shuffle</option>
+                     </select> with
+                     <select name="order">
+                       <option value="0">normal order</option>
+                       <option value="1">reverse order</option>
+                     </select>
+        
+       </form>
+      </div>
+    </div>
+    <!-- end main content -->
+    
+    <p style="text-align:center;font-size:1.2em;"> <vlc id="value" param1="copyright" /> </p>
+
+    <script type="text/javascript">
+      got_time = <vlc id="value" param1="stream_time" />;
+      hours = Math.floor(got_time/ 3600);
+      minutes = Math.floor((got_time/60) % 60);
+      seconds = got_time % 60;
+      if ( hours < 10 ) hours = "0" + hours;
+      if ( minutes < 10 ) minutes = "0" + minutes;
+      if ( seconds < 10 ) seconds = "0" + seconds;
+      document.getElementById('time').innerHTML = hours+":"+minutes+":"+seconds;
+      got_length = <vlc id="value" param1="stream_length" />;
+      hours = Math.floor(got_length/ 3600);
+      minutes = Math.floor((got_length/60) % 60);
+      seconds = got_length % 60;
+      if ( hours < 10 ) hours = "0" + hours;
+      if ( minutes < 10 ) minutes = "0" + minutes;
+      if ( seconds < 10 ) seconds = "0" + seconds;
+      document.getElementById('length').innerHTML = hours+":"+minutes+":"+seconds;
+      got_volume = <vlc id="value" param1="volume" />;
+      document.getElementById( 'volume').innerHTML = Math.ceil(got_volume * 400/1024) + " %";
+    </script>
+</body>
+</html>
diff --git a/share/http-lua/old/info.html b/share/http-lua/old/info.html
new file mode 100644 (file)
index 0000000..12cbada
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+    <title>VLC media player - Information</title>
+</head>
+<body>
+    <h2><center><a href="/old/">VLC media player <vlc id="value" param1="version" /></a></center></h2>
+    <hr/>
+    <vlc id="foreach" param1="cat" param2="information" />
+        <p> <vlc id="value" param1="cat.name" />
+        <ul>
+        <vlc id="foreach" param1="info" param2="cat.info" />
+            <li> <vlc id="value" param1="info.name" />: <vlc id="value" param1="info.value" /> </li>
+        <vlc id="end" />
+        </ul>
+    <vlc id="end" />
+    <hr/>
+    <p><vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/style.css b/share/http-lua/old/style.css
new file mode 100644 (file)
index 0000000..6e56fb3
--- /dev/null
@@ -0,0 +1,98 @@
+div {
+    padding: 0px;
+    margin: 0px;
+    border-width: 0px;
+    border-style: none;
+}
+
+/* page body */
+body {
+    font-family: Verdana, Arial, sans-serif;
+    font-size: 10pt;
+    padding: 5pt;
+    margin: 5pt;
+}
+
+/* left column */
+div.left {
+    float: left;
+    width: 19%;
+}
+
+/* main content */
+div.right {
+    float: right;
+    width: 80%;
+}
+
+/* section bloc title */
+div.sectitle {
+    background-color: #5A5ABB;
+    color: #FFFFFF;
+    border: 1px black solid;
+    border-bottom: 0pt black none;
+    font-weight: bold;
+    padding: 0pt 5pt;
+}
+
+/* section bloc content */
+div.section {
+    background-color: #DDDDFF;
+    border: 1px black solid;
+    margin-bottom: 2em;
+    padding: 5pt;
+}
+
+/* section bloc controls */
+div.section-controls {
+    text-align: center;
+    background-color: #DDDDFF;
+    border: 1px black solid;
+    margin-bottom: 2em;
+    padding: 5pt;
+}
+
+/* page title */
+h2.title {
+    text-align: center;
+}
+
+h3 {
+    text-align: left;
+}
+
+table {
+    width: 100%;
+}
+
+table.add {
+    width: 100%;
+}
+
+/* playlist line */
+tr.line1 {
+    background-color: #EEEEFF;
+}
+
+/* playlist line */
+tr.line2 {
+    background-color: #CCCCFF;
+}
+
+/* help text */
+span.small {
+    font-size: 0.9em;
+}
+
+form {
+    margin: 0pt;
+    padding: 0pt;
+}
+
+input {
+    border: 1px solid black;
+}
+
+ul#playlist, ul#playlist ul{
+    list-style-type: none;
+}
diff --git a/share/http-lua/old/vlm/edit.html b/share/http-lua/old/vlm/edit.html
new file mode 100644 (file)
index 0000000..2b66a28
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+    <title>VLC media player</title>
+    <link href="../style.css" title="Default" rel="stylesheet" type="text/css" />
+
+    <vlc id="control" param1="vlm_setup,vlm_new,vlm_del,vlm_play,vlm_pause,vlm_stop,vlm_seek,vlm_save,vlm_load" />
+
+ </head>
+ <body>
+    <h2>
+     <a href="http://www.videolan.org/">VLC media player<vlc id="value" param1="version" /></a> (http interface)</h2>
+    <div class="sectitle">VLM - Edit <vlc id="value" param1="'name' url_extract"/></div>
+    <div class="section">
+
+<vlc id="foreach" param1="el" param2="vlm" />
+<vlc id="if" param1="'name' url_extract el.name value strcmp 0 =" />
+
+    <vlc id="if" param1="'type' url_extract 'broadcast' strcmp 0 =" />
+        <form method="get" action="/old/vlm/" />
+        <table>
+        <tr><td>Name : </td><td><vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: </td><td>Broadcast </td></tr>
+        <tr><td valign="top">Inputs: </td>
+            <td>
+            <vlc id="foreach" param1="in" param2="el.inputs" /><vlc id="value" param1="in" /><br/><vlc id="end" />
+            <input type="text" name="input" size="40" value=""/><br />
+            </td></tr>
+        <tr><td>Output: </td><td><input type="text" name="output" size="40" value="<vlc id="value" param1="el.output" />"/></td></tr>
+        <tr><td>Option: </td>
+             <td>
+             <vlc id="foreach" param1="op" param2="el.options" /><vlc id="value" param1="op" /><br /><vlc id="end" />
+             <input type="text" name="option" size="40" value=""/><br />
+             </td></tr>
+        </table>
+        <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+        <button name="control" value="vlm_setup">OK</button>
+        </form>
+    <vlc id="else" />
+    <vlc id="if" param1="'type' url_extract 'schedule' strcmp 0 =" />
+        <form method="get" action="/old/vlm/" />
+        <table>
+        <tr><td>Name : </td><td><vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: </td><td>Schedule </td></tr>
+        <tr><td valign="top">Commands: </td>
+            <td><vlc id="foreach" param1="in" param2="el.commands" /><vlc id="value" param1="in" /><br/><vlc id="end" />
+            <input type="text" name="append" size="40" value=""/><br/></td></tr>
+        <tr><td>Date: </td>
+            <td><input type="text" name="date" size="40" value="<vlc id="value" param1="el.date" />"/></td>
+        </tr>
+        <tr><td>Period: </td>
+            <td><input type="text" name="period" size="40" value="<vlc id="value" param1="el.period" />"/></td>
+        </tr>
+        <tr><td>Repeat: </td>
+            <td><input type="text" name="repeat" size="40" value="<vlc id="value" param1="el.repeat" />"/></td>
+        </table>
+        <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+        <button name="control" value="vlm_setup">OK</button>
+        </form>
+    <vlc id="end" />
+    <vlc id="end" />
+<vlc id="end" />
+<vlc id="end" />
+
+    </div>
+
+    <hr/>
+    <p> <vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/vlm/index.html b/share/http-lua/old/vlm/index.html
new file mode 100644 (file)
index 0000000..8330a91
--- /dev/null
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+    <title>VLC media player</title>
+    <link href="../style.css" title="Default" rel="stylesheet" type="text/css" />
+
+    <vlc id="if" param1="url_param"/>
+        <meta http-equiv="refresh" content="0;URL=/old/vlm/" />
+    <vlc id="end" />
+
+    <vlc id="control" param1="vlm_setup,vlm_new,vlm_del,vlm_play,vlm_pause,vlm_stop,vlm_seek,vlm_save,vlm_load" />
+ </head>
+ <body>
+    <h2>
+     <a href="http://www.videolan.org/">VLC media player <vlc id="value" param1="version" /></a> (http interface)</h2>
+     <h3>
+     The VLM http interface is currently brocken. You should use the telnet interface instead.
+     </h3>
+    <div class="sectitle">VLM - Configuration</div>
+    <div class="section">
+
+    <form method="get" action="" />
+    <input type="test" name="file" size="40"/>
+    <button name="control" value="vlm_load">Load</button>
+    <button name="control" value="vlm_save">Save</button>
+    </form>
+    </div>
+
+    <div class="sectitle">VLM - New</div>
+    <div class="section">
+
+    <form method="get" action="/old/vlm/new.html" />
+    <input type="test" name="name" size="40"/>
+    <input type="submit" name="type" value="broadcast"/>
+    </form>
+
+    <form method="get" action="/old/vlm/new.html" />
+    <input type="test" name="name" size="40"/>
+    <input type="submit" name="type" value="schedule"/>
+    </form>
+    </div>
+
+    <div class="sectitle">VLM - Media</div>
+    <div class="section">
+    <table border="1">
+     <tr class="ligne2">
+      <td>Media</td>
+      <td>State</td>
+      <td>Control</td>
+     </tr>
+<vlc id="foreach" param1="el" param2="vlm" />
+<vlc id="if" param1="el.type value 'broadcast' strcmp 0 = " />
+     <tr>
+      <td>
+       <table>
+        <tr>
+         <td width="30%">
+          <form method="get" action="" />
+           <button name="control" value="vlm_del">del</button>
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+          </form>
+         </td>
+         <td><a href="/old/vlm/show.html?name=<vlc id="value" param1="el.name" />&type=broadcast"><vlc id="value" param1="el.name" /></a></td>
+        </tr>
+       </table>
+      </td>
+      <td>
+<vlc id="if" param1="el.enabled value 'yes' strcmp 0 = " />
+       <table>
+        <tr>
+         <td>
+          <vlc id="foreach" param1="instance" param2="el.instances" />
+           <vlc id="value" param1="instance" />
+          <vlc id="end" />
+         </td>
+         <td align="right">
+          <form method="get" action="" />
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+           <input type="hidden" name="disabled" value="" />
+           <button name="control" value="vlm_setup">disable</button>
+          </form>
+         </td>
+        </tr>
+       </table>
+<vlc id="else" />
+       <table>
+        <tr>
+         <td>disabled</td>
+         <td align="right">
+          <form method="get" action="" />
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+           <input type="hidden" name="enabled" value="" />
+           <button name="control" value="vlm_setup">enable</button>
+          </form>
+         </td>
+        </tr>
+       </table>
+<vlc id="end" />
+      </td>
+      <td>
+<vlc id="if" param1="el.enabled value 'yes' strcmp 0 = " />
+       <form method="get" action="" />
+        <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+         <button name="control" value="vlm_stop">stop</button>
+         <button name="control" value="vlm_play">play</button>
+         <button name="control" value="vlm_pause">pause</button>
+        </form>
+<vlc id="end" />
+      </td>
+     </tr>
+<vlc id="end" />
+<vlc id="end" />
+    </table>
+    </div>
+
+    <div class="sectitle">VLM - Schedule</div>
+    <div class="section">
+    <table border="1">
+     <tr class="ligne2">
+      <td>Schedule</td>
+      <td>State</td>
+     </tr>
+<vlc id="foreach" param1="el" param2="vlm" />
+<vlc id="if" param1="el.type value 'schedule' strcmp 0 = " />
+     <tr>
+      <td>
+       <table>
+        <tr>
+         <td width="30%">
+          <form method="get" action="" />
+           <button name="control" value="vlm_del">del</button>
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+          </form>
+         </td>
+         <td><a href="/old/vlm/show.html?name=<vlc id="value" param1="el.name" />&type=schedule"><vlc id="value" param1="el.name" /></a></td>
+        </tr>
+       </table>
+      </td>
+      <td>
+<vlc id="if" param1="el.enabled value 'yes' strcmp 0 = " />
+       <table>
+        <tr>
+         <td>enabled</td>
+         <td align="right">
+          <form method="get" action="" />
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+           <input type="hidden" name="disabled" value="" />
+           <button name="control" value="vlm_setup">disable</button>
+          </form>
+         </td>
+        </tr>
+       </table>
+<vlc id="else" />
+       <table>
+        <tr>
+         <td>disabled</td>
+         <td align="right">
+          <form method="get" action="" />
+           <input type="hidden" name="name" value="<vlc id="value" param1="el.name" />" />
+           <input type="hidden" name="enabled" value="" />
+           <button name="control" value="vlm_setup">enable</button>
+          </form>
+         </td>
+        </tr>
+       </table>
+<vlc id="end" />
+      </td>
+     </tr>
+<vlc id="end" />
+<vlc id="end" />
+    </table>
+    </div>
+
+    <hr/>
+    <p> <vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/vlm/new.html b/share/http-lua/old/vlm/new.html
new file mode 100644 (file)
index 0000000..779b520
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+    <title>VLC media player</title>
+    <link href="../style.css" title="Default" rel="stylesheet" type="text/css" />
+
+    <vlc id="control" param1="vlm_setup,vlm_new,vlm_del,vlm_play,vlm_pause,vlm_stop,vlm_seek,vlm_save,vlm_load" />
+
+ </head>
+ <body>
+    <h2>
+     <a href="http://www.videolan.org/">VLC media player<vlc id="value" param1="version" /></a> (http interface)</h2>
+    <div class="sectitle">VLM - New <vlc id="value" param1="'name' url_extract"/></div>
+    <div class="section">
+
+    <vlc id="if" param1="'type' url_extract 'broadcast' strcmp 0 =" />
+        <form method="get" action="/old/vlm/" />
+        <table>
+        <tr><td>Name : <vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: Schedule </td></tr>
+        <tr><td>Input: <input type="text" name="input" size="40" value=""/></td></tr>
+        <tr><td>Output: <input type="text" name="output" size="40" value=""/></td></tr>
+        <tr><td>Option: <input type="text" name="option" size="40" value=""/></td></tr>
+        </table>
+        <input type="hidden" name="disabled" value=""/>
+        <input type="hidden" name="type" value="broadcast"/>
+        <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+        <input type="submit" name="control" value="vlm_new"/>
+        </form>
+    <vlc id="else" />
+    <vlc id="if" param1="'type' url_extract 'schedule' strcmp 0 =" />
+        <form method="get" action="/old/vlm/" />
+        <table>
+        <tr><td>Name : <vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: Schedule </td></tr>
+        <tr><td>Command: <input type="text" name="append" size="40" value=""/></td></tr>
+        <tr><td>Date: <input type="text" name="date" size="40" value=""/></td></tr>
+        <tr><td>Period: <input type="text" name="period" size="40" value=""/></td></tr>
+        <tr><td>Repeat: <input type="text" name="repeat" size="40" value=""/></td></tr>
+        </table>
+        <input type="hidden" name="disabled" value=""/>
+        <input type="hidden" name="type" value="schedule"/>
+        <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+        <input type="submit" name="control" value="vlm_new"/>
+        </form>
+    <vlc id="end" />
+    <vlc id="end" />
+
+    </div>
+    <hr/>
+    <p> <vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/vlm/show.html b/share/http-lua/old/vlm/show.html
new file mode 100644 (file)
index 0000000..27e99a7
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+    <title>VLC media player</title>
+    <link href="../style.css" title="Default" rel="stylesheet" type="text/css" />
+
+    <vlc id="control" param1="vlm_setup,vlm_new,vlm_del,vlm_play,vlm_pause,vlm_stop,vlm_seek,vlm_save,vlm_load" />
+
+ </head>
+ <body>
+    <h2>
+     <a href="http://www.videolan.org/">VLC media player<vlc id="value" param1="version" /></a> (http interface)</h2>
+    <div class="sectitle">VLM - Edit <vlc id="value" param1="'name' url_extract"/></div>
+    <div class="section">
+
+<vlc id="foreach" param1="el" param2="vlm" />
+<vlc id="if" param1="'name' url_extract el.name value strcmp 0 =" />
+
+    <vlc id="if" param1="'type' url_extract 'broadcast' strcmp 0 =" />
+        <table>
+        <tr><td>Name : </td><td><vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: </td><td>Broadcast </td></tr>
+        <tr><td valign="top">Inputs: </td>
+            <td>
+            <vlc id="foreach" param1="in" param2="el.inputs" /><vlc id="value" param1="in" /><br/><vlc id="end" />
+            </td></tr>
+        <tr><td>Output: </td><td><vlc id="value" param1="el.output" /></td></tr>
+        <tr><td>Option: </td>
+             <td>
+             <vlc id="foreach" param1="op" param2="el.options" /><vlc id="value" param1="op" /><br/><vlc id="end" />
+             </td></tr>
+        </table>
+        <form method="get" action="/old/vlm/edit.html" />
+         <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+         <input type="hidden" name="type" value="broadcast" />
+         <button name="control" value="vlm_setup">setup</button>
+        </form>
+    <vlc id="else" />
+    <vlc id="if" param1="'type' url_extract 'schedule' strcmp 0 =" />
+        <table>
+        <tr><td>Name : </td><td><vlc id="value" param1="'name' url_extract"/> </td> </tr>
+        <tr><td>Type: </td><td>Schedule </td></tr>
+        <tr><td valign="top">Commands: </td>
+            <td><vlc id="foreach" param1="in" param2="el.commands" /><vlc id="value" param1="in" /><br/><vlc id="end" />
+            </td></tr>
+        <tr><td>Date: </td>
+            <td><vlc id="value" param1="el.date" /></td>
+        </tr>
+<vlc id="if" param1="el.period value '0' strcmp" />
+        <tr>
+         <td>Period: </td>
+         <td><vlc id="value" param1="el.period" /></td>
+        </tr>
+        <tr>
+         <td>Repeat: </td>
+<vlc id="if" param1="el.repeat value "-1" strcmp" />
+         <td><vlc id="value" param1="el.repeat" /></td>
+<vlc id="else" />
+         Endless
+<vlc id="end" />
+        </tr>
+<vlc id="end" />
+        </table>
+        <form method="get" action="/old/vlm/edit.html" />
+         <input type="hidden" name="name" value="<vlc id="value" param1="'name' url_extract"/>" />
+         <input type="hidden" name="type" value="schedule" />
+         <button name="control" value="vlm_setup">setup</button>
+        </form>
+    <vlc id="end" />
+    <vlc id="end" />
+<vlc id="end" />
+<vlc id="end" />
+
+    </div>
+
+    <hr/>
+    <p> <vlc id="value" param1="copyright" /> </p>
+</body>
+</html>
diff --git a/share/http-lua/old/webcam.html b/share/http-lua/old/webcam.html
new file mode 100644 (file)
index 0000000..a94b0a7
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml10/DTD/xhtml10transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+       <head>
+               <title>VideoLAN browser output</title>
+               <link href="style.css" title="Default" rel="stylesheet" type="text/css" />
+       </head>
+<body>
+<p>
+This is an example webpage for viewing a Multipart MJPEG stream from any browser. You should edit it to point to the URL of your MPJEG stream that you are streaming with VLC or with a AXIS webcam for instance. For setting up such a stream, refer to the <a href="http://www.videolan.org/doc">VideoLAN HOWTO</a>.</p>
+<p>The page has two modes. A Netscape browser compatible mode which will directly show the videostream, and a mode in which it uses a Java Applet. This is because many browsers cannot handle live MJPEG streams. The Applet in use is the <a href="http://www.charliemouse.com/code/cambozola">Cambozola</a> plugin. You will need to download it from the Cambozola website and put it in the same directory as this webpage.</p>
+
+<h1>Netscape style</h1>
+<a href="http://vlc.server.org:8080/thestream">Click Here</a><br />
+
+<h1>Java applet style</h1>
+<applet code="com.charliemouse.cambozola.Viewer" archive="cambozola.jar" width="320" height="240">
+<param name="url" value="http://vlc.server.org:8080/thestream">
+<param name="properties" value="none">
+</applet>
+
+</body>
+</html>
diff --git a/share/http-lua/requests/browse.xml b/share/http-lua/requests/browse.xml
new file mode 100644 (file)
index 0000000..c252085
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?<?vlc print'>'?>
+<?vlc --[[
+vim:syntax=lua
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  status.xml: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+]] ?>
+
+<root>
+<?vlc
+local dir = _GET["dir"]
+if dir then
+  if dir == "~" then dir = vlc.homedir() end
+  dir = common.realpath(dir.."/")
+  local d = vlc.fd.opendir(dir)
+  table.sort(d)
+  for _,f in pairs(d) do
+    if f == ".." or not string.match(f,"^%.") then
+      local df = common.realpath(dir..f)
+      local s = vlc.fd.stat(df)
+      local path, name = vlc.convert_xml_special_chars( df, f )
+      print("<element type='"..s.type.."' size='"..s.size.."' path='"..path.."' name='"..name.."'/>\n")
+    end
+  end
+end
+?>
+</root>
diff --git a/share/http-lua/requests/playlist.xml b/share/http-lua/requests/playlist.xml
new file mode 100644 (file)
index 0000000..823bd2c
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?<?vlc print'>'?>
+<?vlc --[[
+vim:syntax=lua
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  playlist.xml: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+]] ?>
+
+<node id="0" name="Undefined" ro="ro">
+<?vlc
+local playlist = vlc.playlist.get()
+for i,item in ipairs(playlist) do
+  local name, path = vlc.convert_xml_special_chars(item.name,item.path)
+  print("<leaf id='"..tostring(i).."' uri='"..path.."' name='"..name.."' ro='ro' duration='"..tostring(item.duration).."'/>")
+end
+?>
+</node>
+
+<?vlc --[[
+<node id="9" name="Nevermind" ro="rw">
+<leaf id="10" current="current" uri="file:///mnt/stuff/media/Nirvana/Nevermind/01 - Smells Like Teen Spirit.mp3" name="Smells Like Teen Spirit" ro="rw" duration="-1"/>
+]]?>
diff --git a/share/http-lua/requests/readme b/share/http-lua/requests/readme
new file mode 100644 (file)
index 0000000..a4cfacb
--- /dev/null
@@ -0,0 +1,111 @@
+$Id$
+
+This file describes commands available through the requests/ file:
+
+Lines starting with < describe what the page sends back
+Lines starting with > describe what you can send to the page
+
+All parameters need to be URL encoded.
+Examples:
+ # -> %23
+ % -> %25
+ + -> %2B
+ space -> +
+ ...
+
+status.xml:
+===========
+< Get VLC status information, current item info and meta.
+
+> add <mrl> to playlist and start playback:
+  ?command=in_play&input=<mrl>
+
+> add <mrl> to playlist:
+  ?command=in_enqueue&input=<mrl>
+
+> play playlist item <id>:
+  ?command=pl_play&id=<id>
+
+> toggle pause. If current state was 'stop', play item <id>:
+  ?command=pl_pause&id=<id>
+
+> stop playback:
+  ?command=pl_stop
+
+> jump to next item:
+  ?command=pl_next
+
+> jump to previous item:
+  ?command=pl_previous
+
+> delete item <id> from playlist:
+  ?command=pl_delete&id=<id>
+
+> empty playlist:
+  ?command=pl_empty
+
+> sort playlist using sort mode <val> and order <id>:
+  ?command=pl_sort&id=<id>&val=<val>
+  If id=0 then items will be sorted in normal order, if id=1 they will be
+  sorted in reverse order
+  A non exhaustive list of sort modes:
+    0 Id
+    1 Name
+    3 Author
+    5 Random
+    7 Track number
+
+> toggle random playback:
+  ?command=pl_random
+
+> toggle loop:
+  ?command=pl_loop
+
+> toggle repeat:
+  ?command=pl_repeat
+
+> toggle enable service discovery module <val>:
+  ?command=pl_sd&val=<val>
+  Typical values are:
+    sap
+    shoutcast
+    podcast
+    hal
+
+> toggle fullscreen:
+  ?command=fullscreen
+
+> set volume level to <val> (can be absolute integer, percent or +/- relative value):
+  ?command=volume&val=<val>
+  Allowed values are of the form:
+    +<int>, -<int>, <int> or <int>%
+
+> seek to <val>:
+  ?command=seek&val=<val>
+  Allowed values are of the form:
+    [+ or -][<int><H or h>:][<int><M or m or '>:][<int><nothing or S or s or ">]
+    or [+ or -]<int>%
+    (value between [ ] are optional, value between < > are mandatory)
+  examples:
+    1000 -> seek to the 1000th second
+    +1H:2M -> seek 1 hour and 2 minutes forward
+    -10% -> seek 10% back
+
+playlist.xml:
+=============
+< get the full playlist tree
+
+browse.xml:
+===========
+< ?dir=<dir>
+> get <dir>'s filelist
+
+vlm.xml:
+========
+< get the full list of VLM elements
+
+vlm_cmd.xml:
+============
+< execute VLM command <cmd>
+  ?command=<cmd>
+> get the error message from <cmd>
diff --git a/share/http-lua/requests/status.xml b/share/http-lua/requests/status.xml
new file mode 100644 (file)
index 0000000..c126005
--- /dev/null
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?<?vlcprint'>'?>
+<?vlc --[[
+vim:syntax=lua
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  status.xml: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+]]?>
+<?vlc
+
+local input = _GET['input']
+local command = _GET['command']
+local id = tonumber(_GET['id'] or -1)
+local val = _GET['val']
+
+--vlc.msg.err("requests/status.xml got:","input: "..tostring(input),"command: "..tostring(command),"id: "..tostring(id),"val: "..tostring(val))
+
+local function stripslashes(s)
+  return string.gsub(s,"\\(%.)","%1")
+end
+
+local status = vlc.playlist.status()
+
+if command == "in_play" then
+  local options = {}
+  for o in string.gmatch(input," :[^ ]*") do -- FIXME: options should be in seperate variables, not in the same string as the input.
+    table.insert(options,string.sub(o,3))
+  end
+  vlc.playlist.add({{path=stripslashes(input),options=options}})
+elseif command == "in_enqueue" then
+  vlc.playlist.enqueue(stripslashes(input))
+elseif command == "pl_play" then
+  vlc.playlist.goto(id)
+elseif command == "pl_pause" then
+  vlc.msg.err("FIXME: pl_pause implementation is ugly")
+  common.hotkey("key-play-pause") -- gruik
+elseif command == "pl_stop" then
+  vlc.playlist.stop()
+elseif command == "pl_next" then
+  vlc.playlist.next()
+elseif command == "pl_previous" then
+  vlc.playlist.prev()
+elseif command == "pl_delete" then
+  vlc.msg.err("FIXME: pl_delete unimplemented")
+  --vlc.playlist.delete(id)
+elseif command == "pl_empty" then
+  vlc.playlist.clear()
+elseif command == "pl_sort" then
+  vlc.msg.err("FIXME: pl_sort unimplemented")
+elseif command == "pl_random" then
+  vlc.playlist.random()
+elseif command == "pl_loop" then
+  vlc.playlist.loop()
+elseif command == "pl_repeat" then
+  vlc.playlist.repeat_()
+elseif command == "pl_sd" then
+  vlc.msg.err("FIXME: pl_sd unimplemented")
+  --[[
+    <vlc id="if" param1="val value services_discovery_is_loaded" />
+      <vlc id="rpn" param1="val value services_discovery_remove" />
+    <vlc id="else" />
+      <vlc id="rpn" param1="val value services_discovery_add" />
+    <vlc id="end" />
+  ]]
+elseif command == "fullscreen" then
+  vlc.fullscreen()
+elseif command == "snapshot" then
+  common.snapshot()
+elseif command == "volume" then
+  vlc.volume.set(tonumber(val))
+elseif command == "seek" then
+  common.seek(val)
+elseif command == "key" then
+  common.hotkey("key-"..val)
+end
+
+local input = nil
+local command = nil
+local id = nil
+local val = nil
+
+local input = vlc.object.input()
+local playlist = vlc.object.playlist()
+local vout = input and vlc.object.find(input,'vout','child')
+?>
+<root>
+  <volume><?vlc print(vlc.volume.get()) ?></volume>
+  <length><?vlc if input then print(vlc.var.get(input,"length")) else print(0) end?></length>
+  <time><?vlc if input then print(vlc.var.get(input,"time")) else print(0) end?></time>
+  <state><?vlc print(status) ?></state>
+  <position><?vlc if input then print(vlc.var.get(input,"position")) else print(0) end?></position>
+  <fullscreen><?vlc if vout then vlc.var.get(vout,"fullscreen") else print(0) end?></fullscreen>
+  <random><?vlc print(vlc.var.get(playlist,"random")) ?></random>
+  <loop><?vlc print(vlc.var.get(playlist,"loop")) ?></loop>
+  <repeat><?vlc print(vlc.var.get(playlist,"repeat")) ?></repeat>
+  <information>
+  <?vlc
+    if input then
+      local info = vlc.input_info()
+      for k, v in pairs(info) do
+        print("<category name='"..k.."'>")
+          for k2, v2 in pairs(v) do
+            print("<info name='"..k2.."'>"..v2.."</info>")
+          end
+        print("</category>")
+      end
+    end
+  ?>
+  </information>
+  <stats>
+  <?vlc
+    if input then
+      local stats = vlc.playlist.stats()
+      for k,v in pairs(stats) do
+        local tag = string.gsub(k,"_","")
+        print("<"..tag..">"..tostring(v).."</"..tag..">\n")
+      end
+    end
+  ?>
+  </stats>
+</root>
diff --git a/share/http-lua/requests/vlm.xml b/share/http-lua/requests/vlm.xml
new file mode 100644 (file)
index 0000000..d26edea
--- /dev/null
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?<?vlc print '>'
+--[[
+vim:syntax=lua
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  vlm.xml: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+]]
+
+local function insert_children(c,t)
+  print(c.children)
+    if c.children then
+      for _, d in ipairs(c.children) do
+        table.insert(t,d.value or d.name)
+        if d.value then
+        print("V"..d.value.."|")
+        end
+        if d.name then
+        print("N"..d.name.."|")
+        end
+      end
+    end
+end
+local function print_table(name,t)
+  print("<"..name.."s>")
+  if #t ~= 0 then
+    for _,v in ipairs(t) do
+      print("<"..name..">")
+        print(v)
+      print("</"..name..">")
+    end
+  end
+  print("</"..name.."s>")
+end
+local function print_media(m)
+  local name = m.name
+  local type_, enabled, loop, output
+  local inputs = {}
+  local options = {}
+  local instances = {}
+  for _,c in ipairs(m.children) do
+    if c.name=="type" then
+      type_ = c.value
+    elseif c.name=="enabled" then
+      enabled = c.value
+    elseif c.name=="loop" then
+      loop = c.value
+    elseif c.name=="output" then
+      output = c.value
+    elseif c.name=="inputs" then
+      insert_children(c,inputs)
+    elseif c.name=="options" then
+      insert_children(c,options)
+    elseif c.name=="instances" then
+      if c.children then
+        for _, d in ipairs(c.children) do
+          local instance = "<instance "
+          for _,e in ipairs(d.children) do
+            instance = instance .. e.name .. "=\"" .. e.value .. "\" "
+          end
+          instance = instance .. "/>"
+          table.insert(instances,instance)
+        end
+      end
+    end
+  end
+  print("<"..type_.." name=\""..name.."\" enabled=\""..enabled.."\" loop=\""..loop.."\">\n")
+  print("<output>"..output.."</output>\n")
+  print_table("input",inputs)
+  print_table("option",options)
+  print "<instances>\n"
+  if #instances ~= 0 then
+    print(table.concat(instances))
+  end
+  print "</instances>\n"
+  print("</"..type_..">\n")
+end
+
+local function print_schedule(m)
+  local name = m.name
+  local enabled, date, period, repeat_ = "", "", "", ""
+  local commands = {}
+  for _,c in ipairs(m.children) do
+    if c.name=="enabled" then
+      enabled = c.value
+    elseif c.name=="date" then
+      date = c.value
+    elseif c.name=="period" then
+      period = c.value
+    elseif c.name=="repeat" then
+      repeat_ = c.value
+    elseif c.name=="commands" then
+      insert_children(c,commands)
+    end
+  end
+  print("<schedule name=\""..name.."\" enabled=\""..enabled.."\" period=\""..period.."\" repeat=\""..repeat_.."\">\n")
+  print_table("command",commands)
+  print("</schedule>\n")
+end
+
+local function print_xml(m)
+  print "<vlm>"
+  if m then
+    for _, c in ipairs(m.children) do
+      if c.name=="media" and c.children then
+        for _, d in ipairs(c.children) do
+          print_media(d)
+        end
+      elseif c.name=="schedule" and c.children then
+        for _, d in ipairs(c.children) do
+          print_schedule(d)
+        end
+      end
+    end
+  else
+    print "oops"
+  end
+  print "</vlm>"
+end
+
+local function print_msg(m)
+  if not m then return end
+  print("<"..m.name..">\n")
+  if m.children then
+    for _, child in ipairs(m.children) do
+      print_msg(child)
+    end
+  elseif m.value then
+    print(m.value)
+  end
+  print("</"..m.name..">\n")
+end
+
+local msg = vlc.vlm.execute_command(vlm,"show")
+print_xml(msg)
+--print_msg(msg)
+
+?>
diff --git a/share/http-lua/requests/vlm_cmd.xml b/share/http-lua/requests/vlm_cmd.xml
new file mode 100644 (file)
index 0000000..35b8516
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?<?vlc print '>'
+--[[
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  vlm_cmd.xml: VLC media player web interface
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+]]?>
+<vlm><error><?vlc
+if _GET["command"] then
+  local msg = vlc.vlm.execute_command(vlm,_GET["command"])
+  if msg.value then
+    print(msg.name,":",msg.value)
+  end
+else
+?>No command<?vlc
+end
+?></error>
+</vlm>
diff --git a/share/http-lua/style.css b/share/http-lua/style.css
new file mode 100644 (file)
index 0000000..c994787
--- /dev/null
@@ -0,0 +1,253 @@
+/*****************************************************************************
+ * style.css: VLC media player web interface
+ *****************************************************************************
+ * Copyright (C) 2005-2006 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+body {
+       background-color: #eee;
+       font-family: Arial, sans-serif;
+       font-size: 12pt;
+       text-align: center; /* Center on page - IE */
+       padding: 0px;
+       margin: 0px;
+}
+
+div {
+       padding: 0px;
+       margin: 0px;
+       text-align: left;
+}
+
+div.dialog {
+       width: 440pt;
+       background: #fff;
+       border: solid #000 1px;
+       margin: 10px auto; /* Center on page - Firefox */
+       padding: 0px;
+       overflow: hidden; /* so that the title bar doesn't overflow on
+                           * firefox but still takes all the div's width
+                           * in IE */
+}
+
+div#footer {
+       font-size: 8pt;
+       text-align: center;
+}
+
+.btn_text {
+       display: none;
+}
+
+form {
+       display: inline;
+}
+
+input, textarea {
+       border: solid #000 1px;
+       background-color: #fff;
+}
+
+div.helper {
+       margin: 10px;
+       padding: 10px 0px;
+       border: solid 1px #000;
+}
+div.helper hr {
+       border: solid 1px #000;
+}
+
+div.title {
+       width: 100%/*576px*/; /* see overflow:hidden several lines 
+                                * before for explanation */
+       background: #000 url('images/vlc16x16.png') no-repeat top left;
+       padding-left: 24px;
+       color: #fff;
+       font-weight: bold;
+}
+div.title button {
+       border: 1px none #000;
+       padding: 0px;
+       background-color: #000;
+       color: #fff;
+}
+
+div.controls {
+       width: 100%;
+       padding: 3px 5px;
+}
+div.controls button {
+       border: 1px solid #fff;
+       padding: 0px;
+       background-color: #fff;
+}
+
+div.list {
+       padding: 1em;
+}
+div.list_element {
+       padding-bottom: 0.3em;
+}
+div.list_element ul {
+       margin: 0px;
+}
+
+div#infotree ul {
+       padding: 0.4em;
+       margin: 0em;
+}
+div#infotree li {
+       font-weight: bold;
+       font-size: 0.8em;
+}
+div#infotree dl {
+       font-weight: normal;
+       padding: 0em 1em;
+}
+div#infotree dt {
+       text-decoration: underline;
+}
+
+div#playtree {
+       min-height: 150px;
+}
+div.pl_node {
+       padding-left: 20px;
+       font-style: italic;
+}
+a.pl_leaf {
+       font-style: normal;
+}
+a.pl_leaf:hover {
+       color: #f00;
+}
+img {
+       border: 0px none black;
+}
+
+div.popup {
+       background-color: #fff;
+       overflow: hidden;
+       border: solid #888 1px;
+       margin: 10px auto; /* Center on page - Firefox */
+       position: absolute;
+       z-index: 2;
+       font-size: 0.8em;
+}
+div#browse {
+       width: 70%;
+       left: 15%;
+}
+div#browse div.title {
+       background-color: #008;
+}
+
+div#browser {
+       padding: 20px;
+}
+
+div#mosaic_list {
+       width: 50%;
+       left: 25%;
+       background: url('images/white.png') repeat;
+       display: none;
+}
+
+.mosaic_bg {
+       background-color: #aaf;
+}
+.mosaic_tbl {
+       background-color: #faa;
+}
+.mosaic_itm {
+       background-color: #afa;
+}
+div#mosaic_layout {
+       border: 0px solid #000;
+       padding: 0px;
+       margin: 10px auto;
+}
+
+div#mosaic_dt {
+       border: 0px solid #000;
+       position: relative;
+}
+table#mosaic_table {
+       border-spacing: 0px 0px;
+       position: relative;
+}
+table#mosaic_table tr {
+       padding: 0px;
+       margin: 0px;
+}
+table#mosaic_table td {
+       border: 0px solid #000;
+       text-align: center;
+       padding: 0px;
+       margin: 0px;
+}
+table#mosaic_table input {
+       border: 0px;
+       background: transparent;
+       text-align: center;
+}
+textarea#mosaic_code {
+       padding: 0px;
+       display: block;
+       margin: 10px auto;
+}
+
+div.controls button.on {
+       background-color: #aaa;
+}
+
+div.controls button.off {
+       background-color: #fff;
+}
+
+div.menubtn {
+       display: inline;
+}
+
+div.menu {
+       position: absolute;
+       border: 1px solid #ccc;
+       padding: 5px;
+       margin-top: -5px;
+       background: url('images/white.png') repeat;
+       z-index: 2;
+       display: none;
+}
+
+div.menu button {
+       background: transparent;
+}
+div.menu button.menuout {
+       border: 1px solid transparent;
+}
+div.menu button.menuover {
+        border: 1px solid #000;
+}
+
+div.popup img.close {
+       position: absolute;
+       right: 2px;
+       top: 2px;
+}
diff --git a/share/http-lua/vlm.html b/share/http-lua/vlm.html
new file mode 100644 (file)
index 0000000..3e14bc2
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  vlm.html: VLC media player web interface - VLM
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
+<  Copyright (C) 2005-2006 the VideoLAN team
+<  $Id$
+< 
+<  Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+< 
+<  This program is free software; you can redistribute it and/or modify
+<  it under the terms of the GNU General Public License as published by
+<  the Free Software Foundation; either version 2 of the License, or
+<  (at your option) any later version.
+< 
+<  This program is distributed in the hope that it will be useful,
+<  but WITHOUT ANY WARRANTY; without even the implied warranty of
+<  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+<  GNU General Public License for more details.
+< 
+<  You should have received a copy of the GNU General Public License
+<  along with this program; if not, write to the Free Software
+<  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+
+  <title>VLC media player - Web Interface - VLM</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=<?vlc --[[FIXME charset]]?>" />
+  <link href="style.css" rel="stylesheet" type="text/css" />
+  <script type="text/javascript" src="js/functions.js"></script>
+  <script type="text/javascript" src="js/vlm.js"></script>
+
+</head>
+
+<body onload="vlm_get_elements();">
+
+<?vlc
+current_page = "vlm"
+
+dialogs("browse","input","sout","vlm","footer")
+?>
+
+</body>
+
+</html>
diff --git a/share/http-lua/vlm_export.html b/share/http-lua/vlm_export.html
new file mode 100644 (file)
index 0000000..b90e5b7
--- /dev/null
@@ -0,0 +1,12 @@
+## <pre>
+##
+## <a href="vlm.html">VLM HTTP interface</a>
+## This file can be loaded as is in VLM.
+## Comments starting with "##" were added by the HTTP interface.
+## You can remove them if you want to.
+##
+<?vlc print(vlc.vlm.execute_command(vlm,"export").value) ?>
+
+##
+## end of export
+## </pre>
diff --git a/share/luaintf/http.lua b/share/luaintf/http.lua
new file mode 100644 (file)
index 0000000..ee36df7
--- /dev/null
@@ -0,0 +1,272 @@
+--[==========================================================================[
+ http.lua: HTTP interface module for VLC
+--[==========================================================================[
+ Copyright (C) 2007 the VideoLAN team
+ $Id$
+
+ Authors: Antoine Cellerier <dionoea at videolan dot org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+--]==========================================================================]
+
+--[==========================================================================[
+Configuration options:
+ * no_error_detail: If set, do not print the Lua error message when generating
+                    a page fails.
+ * no_index: If set, don't build directory indexes
+--]==========================================================================]
+
+
+require "httpd"
+require "acl"
+require "common"
+
+vlc.msg.err("Lua HTTP interface")
+
+open_tag = "<?vlc"
+close_tag = "?>"
+
+function escape(s)
+    return (string.gsub(s,"([%^%$%%%.%[%]%*%+%-%?])","%%%1"))
+end
+
+function process_raw(filename)
+    local input = io.open(filename):read("*a")
+    -- find the longest [===[ or ]=====] type sequence and make sure that
+    -- we use one that's longer.
+    local str="X"
+    for str2 in string.gmatch(input,"[%[%]]=*[%[%]]") do
+        if #str < #str2 then str = str2 end
+    end
+    str=string.rep("=",#str-1)
+
+    --[[ FIXME:
+    <?xml version="1.0" encoding="charset" standalone="yes" ?> is still a problem. The closing '?>' needs to be printed using '?<?vlc print ">" ?>' to prevent a parse error.
+    --]]
+    local code0 = string.gsub(input,escape(close_tag)," print(["..str.."[")
+    local code1 = string.gsub(code0,escape(open_tag),"]"..str.."]) ")
+    local code = "print(["..str.."["..code1.."]"..str.."])"
+    --[[ Uncomment to debug
+    if string.match(filename,"vlm_cmd.xml$") then
+    io.write(code)
+    io.write("\n")
+    end
+    --]]
+    return assert(loadstring(code,filename))
+end
+function process(filename)
+    vlc.msg.dbg("Loading `"..filename.."'")
+    local mtime = 0 -- vlc.fd.stat(filename).modification_time
+    local func = false -- process_raw(filename)
+    return function(...)
+        local new_mtime = vlc.fd.stat(filename).modification_time
+        if new_mtime ~= mtime then
+            -- Re-read the file if it changed
+            vlc.msg.dbg("Reloading `"..filename.."'")
+            func = process_raw(filename)
+            mtime = new_mtime
+        end
+        return func(...)
+    end
+end
+
+
+function callback_error(path,url,msg)
+    local url = url or "&lt;page unknown&gt;"
+    return  [[<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Error loading ]]..url..[[</title>
+</head>
+<body>
+<h1>Error loading ]]..url..[[</h1><pre>]]..(config.no_error_detail and "Remove configuration option `no_error_detail' on the server to get more information." or tostring(msg))..[[</pre>
+<p>
+<a href="http://www.videolan.org/">VideoLAN</a><br/>
+<a href="http://www.lua.org/manual/5.1/">Lua 5.1 Reference Manual</a>
+</p>
+</body>
+</html>]]
+end
+
+function dirlisting(url,listing)
+    local list = {}
+    for _,f in ipairs(listing) do
+        if not string.match(f,"^%.") then
+            table.insert(list,"<li><a href='"..f.."'>"..f.."</a></li>")
+        end
+    end
+    list = table.concat(list)
+    local function callback()
+        return [[<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Directory listing ]]..url..[[</title>
+</head>
+<body>
+<h1>Directory listing ]]..url..[[</h1><ul>]]..list..[[</ul>
+</body>
+</html>]]
+    end
+    return h:file_new(url,"text/html",nil,nil,nil,callback,nil)
+end
+
+function file(h,path,url,acl_,mime)
+    local generate_page = process(path)
+    local callback = function(data,request)
+        -- FIXME: I'm sure that we could define a real sandbox
+        -- redefine print
+        local page = {}
+        local function pageprint(...)
+            for i=1,select("#",...) do
+                if i== 1 then
+                    table.insert(page,tostring(select(i,...)))
+                else
+                    table.insert(page," "..tostring(select(i,...)))
+                end
+            end
+        end
+        _G._GET = parse_url_request(request)
+        local oldprint = print
+        print = pageprint
+        local ok, msg = pcall(generate_page)
+        -- reset
+        print = oldprint
+        if not ok then
+            return callback_error(path,url,msg)
+        end
+        return table.concat(page)
+    end
+    return h:file_new(url or path,mime,nil,nil,acl_,callback,nil)
+end
+
+function rawfile(h,path,url,acl_)
+    local filename = path
+    vlc.msg.dbg("Loading `"..filename.."'")
+    local mtime = 0 -- vlc.fd.stat(filename).modification_time
+    local page = false -- io.open(filename):read("*a")
+    local callback = function(data,request)
+        local new_mtime = vlc.fd.stat(filename).modification_time
+        if mtime ~= new_mtime then
+            -- Re-read the file if it changed
+            vlc.msg.dbg("Reloading `"..filename.."'")
+            page = io.open(filename):read("*a")
+            mtime = new_mtime
+        end
+        return page
+    end
+    return h:file_new(url or path,nil,nil,nil,acl_,callback,nil)
+end
+
+function parse_url_request(request)
+    if not request then return {} end
+    t = {}
+    for k,v in string.gmatch(request,"([^=&]+)=?([^=&]*)") do
+        local k_ = vlc.decode_uri(k)
+        local v_ = vlc.decode_uri(v)
+        t[k_]=v_
+    end
+    return t
+end
+
+local function find_datadir(name)
+    local list = vlc.datadir_list(name)
+    for _, l in ipairs(list) do
+        local s = vlc.fd.stat(l)
+        if s then
+            return l
+        end
+    end
+    error("Unable to find the `"..name.."' directory.")
+end
+http_dir = find_datadir("http-lua")
+
+do
+    local oldpath = package.path
+    package.path = http_dir.."/?.lua"
+    local ok, err = pcall(require,"custom")
+    if not ok then
+        vlc.msg.warn("Couldn't load "..http_dir.."/custom.lua")
+    else
+        vlc.msg.dbg("Loaded "..http_dir.."/custom.lua")
+    end
+    package.path = oldpath
+end
+local files = {}
+local mimes = {
+    txt = "text/plain",
+    html = "text/html",
+    xml = "text/xml",
+    js = "text/javascript",
+    png = "image/png",
+    ico = "image/x-icon",
+}
+local function load_dir(dir,root,parent_acl)
+    local root = root or "/"
+    local has_index = false
+    if string.match(dir,"/old") then
+        return
+    end
+    local my_acl = parent_acl
+    do
+        local af = dir.."/.hosts"
+        local s = vlc.fd.stat(af)
+        if s and s.type == "file" then
+            -- We found an acl
+            my_acl = acl.new(false)
+            my_acl:load_file(af)
+        end
+    end
+    local d = vlc.fd.opendir(dir)
+    for _,f in ipairs(d) do
+        if not string.match(f,"^%.") then
+            local s = vlc.fd.stat(dir.."/"..f)
+            if s.type == "file" then
+                local url
+                if f == "index.html" then
+                    url = root
+                    has_index = true
+                else
+                    url = root..f
+                end
+                local ext = string.match(f,"%.([^%.]-)$")
+                local mime = mimes[ext]
+                -- print(url,mime)
+                if mime and string.match(mime,"^text/") then
+                    table.insert(files,file(h,dir.."/"..f,url,my_acl and my_acl.private,mime))
+                else
+                    table.insert(files,rawfile(h,dir.."/"..f,url,my_acl and my_acl.private))
+                end
+            elseif s.type == "dir" then
+                if f == "dialogs" then -- FIXME
+                else
+                    load_dir(dir.."/"..f,root..f.."/",my_acl)
+                end
+            end
+        end
+    end
+    if not has_index and not config.no_index then
+        -- print("Adding index for", root)
+        table.insert(files,dirlisting(root,d,my_acl and my_acl.private))
+    end
+end
+
+h = httpd.new("localhost",8080)
+load_dir( http_dir )
+
+while not die do die = vlc.lock_and_wait() end -- everything happens in callbacks
+
+-- FIXME: We shouldn't need to do this ourselves.
+for i=1,#files do
+    getmetatable(files[i]).__gc(files[i])
+    files[i] = nil
+end
diff --git a/share/luaintf/modules/acl.lua b/share/luaintf/modules/acl.lua
new file mode 100644 (file)
index 0000000..d93f546
--- /dev/null
@@ -0,0 +1,81 @@
+--[==========================================================================[
+ acl.lua: VLC Lua interface ACL object
+--[==========================================================================[
+ Copyright (C) 2007 the VideoLAN team
+ $Id$
+
+ Authors: Antoine Cellerier <dionoea at videolan dot org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+--]==========================================================================]
+
+--[==========================================================================[
+require "acl"
+local a = acl.new(true) -> new ACL with default set to allow
+a:check("10.0.0.1") -> 0 == allow, 1 == deny, -1 == error
+a("10.0.0.1") -> same as a:check("10.0.0.1")
+a:duplicate() -> duplicate ACL object
+a:add_host("10.0.0.1",true) -> allow 10.0.0.1
+a:add_net("10.0.0.0",24,true) -> allow 10.0.0.0/24 (not sure)
+a:load_file("/path/to/acl") -> load ACL from file
+--]==========================================================================]
+
+module("acl",package.seeall)
+
+methods = {
+    check = function(this,ip)
+        return vlc.acl.check(this.private,ip)
+    end,
+    duplicate = function(this)
+        return setmetatable({ private = vlc.acl.duplicate( rawget(this,"private") ) },metatable)
+    end,
+    add_host = function(this,ip,allow)
+        return vlc.acl.add_host(this.private,ip,allow)
+    end,
+    add_net = function(this,ip,len,allow)
+        return vlc.acl.add_net(this.private,ip,len,allow)
+    end,
+    load_file = function(this,path)
+        return vlc.acl.load_file(this.private,path)
+    end,
+}
+
+metatable = {
+    __index = function(this,key)
+        if methods[key] then
+            return methods[key]
+        elseif key == "private" then
+            error("Forbidden")
+        else
+            return rawget(this,key)
+        end
+    end,
+    __newindex = function(this,key,value)
+        if key == "private" or methods[key] then
+            error("Forbidden")
+        else
+            rawset(this,key,value)
+        end
+    end,
+    __call = methods.check,
+    __gc = function(this)
+        vlc.acl.delete(this.private)
+    end,
+    __metatable = "None of your business.",
+}
+
+function new( allow )
+    return setmetatable({ private = vlc.acl.create( allow ) },metatable)
+end
index a709180..f0a1aa2 100644 (file)
@@ -70,3 +70,18 @@ function durationtostring(duration)
                          math.floor(duration/60)%60,
                          math.floor(duration%60))
 end
+
+-- realpath
+function realpath(path)
+    return string.gsub(string.gsub(string.gsub(string.gsub(path,"/%.%./[^/]+","/"),"/[^/]+/%.%./","/"),"/%./","/"),"//","/")
+end
+
+-- seek
+function seek(value)
+    local input = vlc.object.input()
+    if string.sub(value,#value)=="%" then
+        vlc.var.set(input,"position",tonumber(string.sub(value,1,#value-1))/100.)
+    else
+        vlc.var.set(input,"time",tonumber(value))
+    end
+end
diff --git a/share/luaintf/modules/httpd.lua b/share/luaintf/modules/httpd.lua
new file mode 100644 (file)
index 0000000..ff0ecb4
--- /dev/null
@@ -0,0 +1,75 @@
+--[==========================================================================[
+ httpd.lua: VLC Lua interface HTTPd module
+--[==========================================================================[
+ Copyright (C) 2007 the VideoLAN team
+ $Id$
+
+ Authors: Antoine Cellerier <dionoea at videolan dot org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+--]==========================================================================]
+
+--[==========================================================================[
+--]==========================================================================]
+
+module("httpd",package.seeall)
+
+local function generic_metatable(methods,destructor)
+    return {
+        __index = function(this,key)
+            if methods and methods[key] then
+                return methods[key]
+            elseif key == "private" then
+                error("Forbidden")
+            else
+                return rawget(this,key)
+            end
+        end,
+        __newindex = function(this,key,value)
+            if key == "private" or (methods and methods[key]) then
+                error("Forbidden")
+            else
+                rawset(this,key,value)
+            end
+        end,
+        __gc = function(this)
+            if destructor then
+                destructor(rawget(this,"private"))
+            end
+        end,
+        --__metatable = "None of your business.",
+    }
+end
+
+local handler_metatable = generic_metatable({},vlc.httpd.handler_delete)
+local file_metatable = generic_metatable({},vlc.httpd.file_delete)
+local redirect_metatable = generic_metatable({},vlc.httpd.redirect_delete)
+
+local host_methods = {
+    handler_new = function(this,...)
+        return setmetatable({private=vlc.httpd.handler_new(rawget(this,"private"),...),parent=this},handler_metatable)
+    end,
+    file_new = function(this,...)
+        return setmetatable({private=vlc.httpd.file_new(rawget(this,"private"),...),parent=this},file_metatable)
+    end,
+    redirect_new = function(this,...)
+        return setmetatable({private=vlc.httpd.redirect_new(rawget(this,"private"),...),parent=this},redirect_metatable)
+    end,
+}
+local host_metatable = generic_metatable(host_methods,vlc.httpd.host_delete)
+
+function new( ... )
+    return setmetatable({private=vlc.httpd.host_new(...)},host_metatable)
+end
index b325489..d02fb8b 100644 (file)
@@ -286,12 +286,7 @@ function titlechap_offset(client,offset)
 end
 
 function seek(name,client,value)
-    local input = vlc.object.input()
-    if string.sub(value,#value)=="%" then
-        vlc.var.set(input,"position",tonumber(string.sub(value,1,#value-1))/100.)
-    else
-        vlc.var.set(input,"time",tonumber(value))
-    end
+    common.seek(value)
 end
 
 function volume(name,client,value)