static int vlclua_msg_warn( lua_State *L ) { int i_top = lua_gettop( L ); vlc_object_t *p_this = vlclua_get_this( L ); int i; for( i = 1; i <= i_top; i++ ) msg_Warn( p_this, "%s", luaL_checkstring( L, i ) ); return 0; }
/** Gets the OS file descriptor mapped to a VLC Lua file descriptor */ static int vlclua_fd_get( lua_State *L, unsigned idx ) { intf_thread_t *intf = (intf_thread_t *)vlclua_get_this( L ); intf_sys_t *sys = intf->p_sys; if( idx < 3u ) return idx; idx -= 3; return (idx < sys->fdc) ? sys->fdv[idx] : -1; }
static int vlclua_playlist_enqueue( lua_State *L ) { int i_count; vlc_object_t *p_this = vlclua_get_this( L ); playlist_t *p_playlist = vlclua_get_playlist_internal( L ); i_count = vlclua_playlist_add_internal( p_this, L, p_playlist, NULL, false ); lua_pushinteger( L, i_count ); return 1; }
static int vlclua_demux_read( lua_State *L ) { demux_t *p_demux = (demux_t *)vlclua_get_this( L ); const uint8_t *p_read; int n = luaL_checkint( L, 1 ); int i_read = stream_Peek( p_demux->s, &p_read, n ); lua_pushlstring( L, (const char *)p_read, i_read ); int i_seek = stream_Read( p_demux->s, NULL, i_read ); assert(i_read==i_seek); return 1; }
/* Takes a { fd : events } table as first arg and modifies it to { fd : revents } */ static int vlclua_net_poll( lua_State *L ) { intf_thread_t *intf = (intf_thread_t *)vlclua_get_this( L ); intf_sys_t *sys = intf->p_sys; luaL_checktype( L, 1, LUA_TTABLE ); int i_fds = 1; lua_pushnil( L ); while( lua_next( L, 1 ) ) { i_fds++; lua_pop( L, 1 ); } struct pollfd *p_fds = xmalloc( i_fds * sizeof( *p_fds ) ); int *luafds = xmalloc( i_fds * sizeof( *luafds ) ); lua_pushnil( L ); int i = 1; p_fds[0].fd = sys->fd[0]; p_fds[0].events = POLLIN; while( lua_next( L, 1 ) ) { luafds[i] = luaL_checkinteger( L, -2 ); p_fds[i].fd = vlclua_fd_get( L, luafds[i] ); p_fds[i].events = luaL_checkinteger( L, -1 ); p_fds[i].events &= POLLIN | POLLOUT | POLLPRI; lua_pop( L, 1 ); i++; } int i_ret; do i_ret = poll( p_fds, i_fds, -1 ); while( i_ret == -1 && errno == EINTR ); for( i = 1; i < i_fds; i++ ) { lua_pushinteger( L, luafds[i] ); lua_pushinteger( L, p_fds[i].revents ); lua_settable( L, 1 ); } lua_pushinteger( L, i_ret ); if( p_fds[0].revents ) i_ret = luaL_error( L, "Interrupted." ); else i_ret = 1; free( luafds ); free( p_fds ); return i_ret; }
/** Gets the VLC Lua file descriptor mapped from an OS file descriptor */ static int vlclua_fd_get_lua( lua_State *L, int fd ) { intf_thread_t *intf = (intf_thread_t *)vlclua_get_this( L ); intf_sys_t *sys = intf->p_sys; if( (unsigned)fd < 3u ) return fd; for( unsigned i = 0; i < sys->fdc; i++ ) if( sys->fdv[i] == fd ) return 3 + i; return -1; }
static int vlclua_sd_add_item( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "path" ); if( lua_isstring( L, -1 ) ) { char **ppsz_options = NULL; int i_options = 0; const char *psz_path = lua_tostring( L, -1 ); vlclua_read_options( p_sd, L, &i_options, &ppsz_options ); input_item_t *p_input = input_item_NewExt( p_sd, psz_path, psz_path, i_options, (const char **)ppsz_options, VLC_INPUT_OPTION_TRUSTED, -1 ); lua_pop( L, 1 ); if( p_input ) { vlclua_read_meta_data( p_sd, L, p_input ); /* This one is to be tested... */ vlclua_read_custom_meta_data( p_sd, L, p_input ); /* The duration is given in seconds, convert to microseconds */ lua_getfield( L, -1, "duration" ); if( lua_isnumber( L, -1 ) ) input_item_SetDuration( p_input, (lua_tonumber( L, -1 )*1e6) ); else if( !lua_isnil( L, -1 ) ) msg_Warn( p_sd, "Item duration should be a number (in seconds)." ); lua_pop( L, 1 ); services_discovery_AddItem( p_sd, p_input, NULL ); input_item_t **udata = (input_item_t **) lua_newuserdata( L, sizeof( input_item_t * ) ); *udata = p_input; if( luaL_newmetatable( L, "input_item_t" ) ) { lua_pushliteral( L, "none of your business" ); lua_setfield( L, -2, "__metatable" ); } lua_setmetatable( L, -2 ); vlc_gc_decref( p_input ); } while( i_options > 0 ) free( ppsz_options[--i_options] ); free( ppsz_options ); } else msg_Err( p_sd, "vlc.sd.add_item: the \"path\" parameter can't be empty" ); } else msg_Err( p_sd, "Error parsing add_item arguments" ); return 1; }
static int vlclua_node_add_node( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" ); if( *pp_node ) { if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "title" ); if( lua_isstring( L, -1 ) ) { const char *psz_name = lua_tostring( L, -1 ); input_item_node_t *p_input_node = input_item_node_Create( *pp_node ); input_item_t *p_input = input_item_NewWithType( VLC_OBJECT( p_sd ), "vlc://nop", psz_name, 0, NULL, 0, -1, ITEM_TYPE_NODE ); lua_pop( L, 1 ); if( p_input ) { lua_getfield( L, -1, "arturl" ); if( lua_isstring( L, -1 ) && strcmp( lua_tostring( L, -1 ), "" ) ) { char *psz_value = strdup( lua_tostring( L, -1 ) ); EnsureUTF8( psz_value ); msg_Dbg( p_sd, "ArtURL: %s", psz_value ); input_item_SetArtURL( p_input, psz_value ); free( psz_value ); } input_item_node_AppendItem( p_input_node, p_input ); input_item_node_PostAndDelete( p_input_node ); input_item_t **udata = (input_item_t **) lua_newuserdata( L, sizeof( input_item_t * ) ); *udata = p_input; if( luaL_newmetatable( L, "node" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_node_reg ); lua_setfield( L, -2, "__index" ); } lua_setmetatable( L, -2 ); } } else msg_Err( p_sd, "node:add_node: the \"title\" parameter can't be empty" ); } else msg_Err( p_sd, "Error parsing add_node arguments" ); } return 1; }
static int vlclua_demux_peek( lua_State *L ) { stream_t *s = (stream_t *)vlclua_get_this(L); int n = luaL_checkinteger( L, 1 ); const uint8_t *p_peek; ssize_t val = vlc_stream_Peek(s->s, &p_peek, n); if (val > 0) lua_pushlstring(L, (const char *)p_peek, val); else lua_pushnil( L ); return 1; }
static int vlclua_sd_remove_item( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); if( !lua_isnil( L, 1 ) ) { input_item_t **pp_input = luaL_checkudata( L, 1, "input_item_t" ); if( *pp_input ) services_discovery_RemoveItem( p_sd, *pp_input ); /* Make sure we won't try to remove it again */ *pp_input = NULL; } return 1; }
static int vlclua_demux_peek( lua_State *L ) { demux_t *p_demux = (demux_t *)vlclua_get_this( L ); int n = (int)luaL_checkinteger( L, 1 ); const uint8_t *p_peek; int i_peek = vlc_stream_Peek( p_demux->s, &p_peek, n ); if( i_peek > 0 ) lua_pushlstring( L, (const char *)p_peek, i_peek ); else lua_pushnil( L ); return 1; }
static int vlclua_sd_add_node( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "title" ); if( lua_isstring( L, -1 ) ) { const char *psz_name = lua_tostring( L, -1 ); input_item_t *p_input = input_item_NewWithType( "vlc://nop", psz_name, 0, NULL, 0, -1, ITEM_TYPE_NODE ); lua_pop( L, 1 ); if( p_input ) { lua_getfield( L, -1, "arturl" ); if( lua_isstring( L, -1 ) && strcmp( lua_tostring( L, -1 ), "" ) ) { char *psz_value = strdup( lua_tostring( L, -1 ) ); EnsureUTF8( psz_value ); msg_Dbg( p_sd, "ArtURL: %s", psz_value ); /** @todo Ask for art download if not local file */ input_item_SetArtURL( p_input, psz_value ); free( psz_value ); } lua_pop( L, 1 ); lua_getfield( L, -1, "category" ); if( lua_isstring( L, -1 ) ) services_discovery_AddItem( p_sd, p_input, luaL_checkstring( L, -1 ) ); else services_discovery_AddItem( p_sd, p_input, NULL ); input_item_t **udata = (input_item_t **) lua_newuserdata( L, sizeof( input_item_t * ) ); *udata = p_input; if( luaL_newmetatable( L, "node" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_node_reg ); lua_setfield( L, -2, "__index" ); } lua_setmetatable( L, -2 ); } } else msg_Err( p_sd, "vlc.sd.add_node: the \"title\" parameter can't be empty" ); } else msg_Err( p_sd, "Error parsing add_node arguments" ); return 1; }
static int vlclua_stream_add_filter( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); /* Make sure that we have 1 argument (+ 1 object) */ lua_settop( L, 2 ); stream_t **pp_stream = (stream_t **)luaL_checkudata( L, 1, "stream" ); if( !*pp_stream ) return vlclua_error( L ); const char *psz_filter = NULL; if( lua_isstring( L, 2 ) ) psz_filter = lua_tostring( L, 2 ); if( !psz_filter || !*psz_filter ) { msg_Dbg( p_this, "adding all automatic stream filters" ); while( true ) { /* Add next automatic stream */ stream_t *p_filtered = vlc_stream_FilterNew( *pp_stream, NULL ); if( !p_filtered ) break; else { msg_Dbg( p_this, "inserted an automatic stream filter" ); *pp_stream = p_filtered; } } luaL_getmetatable( L, "stream" ); lua_setmetatable( L, 1 ); } else { /* Add a named filter */ stream_t *p_filter = vlc_stream_FilterNew( *pp_stream, psz_filter ); if( !p_filter ) msg_Dbg( p_this, "Unable to open requested stream filter '%s'", psz_filter ); else { *pp_stream = p_filter; luaL_getmetatable( L, "stream" ); lua_setmetatable( L, 1 ); } } return 1; }
static int vlclua_demux_readline( lua_State *L ) { stream_t *s = (stream_t *)vlclua_get_this(L); char *line = vlc_stream_ReadLine(s->s); if (line != NULL) { lua_pushstring(L, line); free(line); } else lua_pushnil( L ); return 1; }
static int vlclua_demux_readline( lua_State *L ) { demux_t *p_demux = (demux_t *)vlclua_get_this( L ); char *psz_line = stream_ReadLine( p_demux->s ); if( psz_line ) { lua_pushstring( L, psz_line ); free( psz_line ); } else { lua_pushnil( L ); } return 1; }
static int vlclua_stream_new( lua_State *L ) { vlc_object_t * p_this = vlclua_get_this( L ); const char * psz_url = luaL_checkstring( L, 1 ); stream_t *p_stream = vlc_stream_NewURL( p_this, psz_url ); /* XXX: For hysterical raisins, append one inflate decompression stream * filter automatically (if applicable). */ if( p_stream != NULL ) { stream_t *inflated = vlc_stream_FilterNew( p_stream, "inflate" ); if( inflated != NULL ) p_stream = inflated; } return vlclua_stream_new_inner( L, p_stream ); }
static int vlclua_demux_read( lua_State *L ) { demux_t *p_demux = (demux_t *)vlclua_get_this( L ); const uint8_t *p_read; int n = (int)luaL_checkinteger( L, 1 ); int i_read = vlc_stream_Peek( p_demux->s, &p_read, n ); if( i_read > 0 ) { lua_pushlstring( L, (const char *)p_read, i_read ); int i_seek = vlc_stream_Read( p_demux->s, NULL, i_read ); assert( i_read == i_seek ); } else lua_pushnil( L ); return 1; }
static int vlclua_libvlc_command( lua_State *L ) { vlc_object_t * p_this = vlclua_get_this( L ); const char *psz_cmd; vlc_value_t val_arg; psz_cmd = luaL_checkstring( L, 1 ); val_arg.psz_string = strdup( luaL_optstring( L, 2, "" ) ); lua_pop( L, 2 ); int i_type = var_Type( p_this->p_libvlc, psz_cmd ); if( ! (i_type & VLC_VAR_ISCOMMAND) ) { free( val_arg.psz_string ); return luaL_error( L, "libvlc's \"%s\" is not a command", psz_cmd ); } return vlclua_push_ret( L, var_Set( p_this->p_libvlc, psz_cmd, val_arg ) ); }
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 ) { VLC_UNUSED(p_handler); 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 running 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; }
static int vlclua_var_inherit( lua_State *L ) { vlc_value_t val; vlc_object_t *p_obj; if( lua_type( L, 1 ) == LUA_TNIL ) p_obj = vlclua_get_this( L ); else { vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); p_obj = *pp_obj; } const char *psz_var = luaL_checkstring( L, 2 ); int i_type = config_GetType( p_obj, psz_var ); if( var_Inherit( p_obj, psz_var, i_type, &val ) != VLC_SUCCESS ) return 0; lua_pop( L, 2 ); return vlclua_pushvalue( L, i_type, val, true ); }
static int vlclua_demux_read( lua_State *L ) { stream_t *s = (stream_t *)vlclua_get_this(L); int n = luaL_checkinteger( L, 1 ); char *buf = malloc(n); if (buf != NULL) { ssize_t val = vlc_stream_Read(s->s, buf, n); if (val > 0) lua_pushlstring(L, buf, val); else lua_pushnil( L ); free(buf); } else lua_pushnil( L ); return 1; }
static int vlclua_vlm_new( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); vlm_t *p_vlm = vlm_New( p_this ); if( !p_vlm ) return luaL_error( L, "Cannot start VLM." ); vlm_t **pp_vlm = lua_newuserdata( L, sizeof( vlm_t * ) ); *pp_vlm = p_vlm; if( luaL_newmetatable( L, "vlm" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_vlm_reg ); lua_setfield( L, -2, "__index" ); lua_pushcfunction( L, vlclua_vlm_delete ); lua_setfield( L, -2, "__gc" ); } lua_setmetatable( L, -2 ); return 1; }
static int vlclua_command( lua_State *L ) { vlc_object_t * p_this = vlclua_get_this( L ); char *psz_msg; const char *psz_name = luaL_checkstring( L, 1 ); const char *psz_cmd = luaL_checkstring( L, 2 ); const char *psz_arg = luaL_checkstring( L, 3 ); int ret = var_Command( p_this, psz_name, psz_cmd, psz_arg, &psz_msg ); lua_pop( L, 3 ); if( psz_msg ) { lua_pushstring( L, psz_msg ); free( psz_msg ); } else { lua_pushliteral( L, "" ); } return vlclua_push_ret( L, ret ) + 1; }
/** Unmaps an OS file descriptor from VLC Lua */ static void vlclua_fd_unmap( lua_State *L, unsigned idx ) { intf_thread_t *intf = (intf_thread_t *)vlclua_get_this( L ); intf_sys_t *sys = intf->p_sys; int fd = -1; if( idx < 3u ) return; /* Never close stdin/stdout/stderr. */ idx -= 3; if( idx >= sys->fdc ) return; fd = sys->fdv[idx]; sys->fdc--; memmove( sys->fdv + idx, sys->fdv + idx + 1, (sys->fdc - idx) * sizeof (sys->fdv[0]) ); /* realloc() not really needed */ #ifndef NDEBUG for( unsigned i = 0; i < sys->fdc; i++ ) assert( sys->fdv[i] != fd ); #endif }
static int vlclua_xml_create_reader( lua_State *L ) { vlc_object_t *obj = vlclua_get_this( L ); stream_t *p_stream = *(stream_t **)luaL_checkudata( L, 2, "stream" ); xml_reader_t *p_reader = xml_ReaderCreate( obj, p_stream ); if( !p_reader ) return luaL_error( L, "XML reader creation failed." ); xml_reader_t **pp_reader = lua_newuserdata( L, sizeof( xml_reader_t * ) ); *pp_reader = p_reader; if( luaL_newmetatable( L, "xml_reader" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_xml_reader_reg ); lua_setfield( L, -2, "__index" ); lua_pushcfunction( L, vlclua_xml_reader_delete ); lua_setfield( L, -2, "__gc" ); } lua_setmetatable( L, -2 ); return 1; }
static int vlclua_get_libvlc( lua_State *L ) { vlclua_push_vlc_object( L, vlclua_get_this( L )->p_libvlc, NULL ); return 1; }
static int vlclua_menu_prev( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); osd_MenuPrev( p_this ); return 0; }
static int vlclua_menu_activate( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); osd_MenuActivate( p_this ); return 0; }
static int vlclua_menu_down( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); osd_MenuDown( p_this ); return 0; }
static int vlclua_menu_next( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); osd_MenuNext( p_this ); return 0; }