/* Enqueue an item for preparsing, and play it, if needed */ static void GoAndPreparse( playlist_t *p_playlist, int i_mode, playlist_item_t *p_item ) { PL_ASSERT_LOCKED; if( (i_mode & PLAYLIST_GO ) ) { pl_priv(p_playlist)->request.b_request = true; pl_priv(p_playlist)->request.i_skip = 0; pl_priv(p_playlist)->request.p_item = p_item; if( pl_priv(p_playlist)->p_input ) input_Stop( pl_priv(p_playlist)->p_input, true ); pl_priv(p_playlist)->request.i_status = PLAYLIST_RUNNING; vlc_cond_signal( &pl_priv(p_playlist)->signal ); } /* Preparse if no artist/album info, and hasn't been preparsed allready and if user has some preparsing option (auto-preparse variable) enabled*/ char *psz_artist = input_item_GetArtist( p_item->p_input ); char *psz_album = input_item_GetAlbum( p_item->p_input ); if( pl_priv(p_playlist)->b_auto_preparse && input_item_IsPreparsed( p_item->p_input ) == false && ( EMPTY_STR( psz_artist ) || ( EMPTY_STR( psz_album ) ) ) ) libvlc_MetaRequest( p_playlist->p_libvlc, p_item->p_input ); free( psz_artist ); free( psz_album ); }
/* Enqueue an item for preparsing, and play it, if needed */ static void GoAndPreparse( playlist_t *p_playlist, int i_mode, playlist_item_t *p_item ) { playlist_private_t *sys = pl_priv(p_playlist); PL_ASSERT_LOCKED; if( (i_mode & PLAYLIST_GO ) ) { sys->request.b_request = true; sys->request.i_skip = 0; sys->request.p_item = p_item; if( sys->p_input != NULL ) input_Stop( sys->p_input ); vlc_cond_signal( &sys->signal ); } /* Preparse if no artist/album info, and hasn't been preparsed already and if user has some preparsing option (auto-preparse variable) enabled*/ char *psz_artist = input_item_GetArtist( p_item->p_input ); char *psz_album = input_item_GetAlbum( p_item->p_input ); if( sys->b_preparse && !input_item_IsPreparsed( p_item->p_input ) && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) ) libvlc_MetadataRequest( p_playlist->obj.libvlc, p_item->p_input, 0, -1, NULL ); free( psz_artist ); free( psz_album ); }
static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item ) { lua_State * L = luaL_newstate(); if( !L ) { msg_Err( p_this, "Could not create new Lua State" ); return NULL; } char *psz_meta; /* Load Lua libraries */ luaL_openlibs( L ); /* XXX: Don't open all the libs? */ luaL_register( L, "vlc", p_reg ); luaopen_msg( L ); luaopen_stream( L ); luaopen_strings( L ); luaopen_variables( L ); luaopen_object( L ); luaopen_misc( L ); lua_pushlightuserdata( L, p_this ); lua_setfield( L, -2, "private" ); psz_meta = input_item_GetName( p_item ); lua_pushstring( L, psz_meta ); lua_setfield( L, -2, "name" ); free( psz_meta ); psz_meta = input_item_GetArtist( p_item ); lua_pushstring( L, psz_meta ); lua_setfield( L, -2, "artist" ); free( psz_meta ); psz_meta = input_item_GetTitle( p_item ) ; lua_pushstring( L, psz_meta ); lua_setfield( L, -2, "title" ); free( psz_meta ); psz_meta = input_item_GetAlbum( p_item ); lua_pushstring( L, psz_meta ); lua_setfield( L, -2, "album" ); free( psz_meta ); psz_meta = input_item_GetArtURL( p_item ); lua_pushstring( L, psz_meta ); lua_setfield( L, -2, "arturl" ); free( psz_meta ); /* XXX: all should be passed ( could use macro ) */ return L; }
/** * Recursiveyy follow the playlist * @param p_playlist: the playlist * @param p_export: the export structure * @param p_root: the current node */ static void DoChildren( playlist_t *p_playlist, playlist_export_t *p_export, playlist_item_t *p_root ) { /* Go through the playlist and add items */ for( int i = 0; i < p_root->i_children ; i++) { playlist_item_t *p_current = p_root->pp_children[i]; assert( p_current ); if( p_current->i_flags & PLAYLIST_SAVE_FLAG ) continue; if( p_current->i_children >= 0 ) { DoChildren( p_playlist, p_export, p_current ); continue; } char* psz_name = NULL; char *psz_tmp = input_item_GetName( p_current->p_input ); if( psz_tmp ) psz_name = convert_xml_special_chars( psz_tmp ); free( psz_tmp ); if( psz_name ) { char* psz_artist = NULL; psz_tmp = input_item_GetArtist( p_current->p_input ); if( psz_tmp ) psz_artist = convert_xml_special_chars( psz_tmp ); free( psz_tmp ); mtime_t i_duration = input_item_GetDuration( p_current->p_input ); int min = ( i_duration / 1000000 ) / 60; int sec = ( i_duration / 1000000 ) - min * 60; // Print the artist if we have one if( psz_artist && *psz_artist ) fprintf( p_export->p_file, " <li>%s - %s (%02d:%02d)</li>\n", psz_artist, psz_name, min, sec ); else fprintf( p_export->p_file, " <li>%s (%2d:%2d)</li>\n", psz_name, min, sec ); free( psz_artist ); } free( psz_name ); } }
void InputManager::UpdateName() { /* Update text, name and nowplaying */ QString text; /* Try to get the Title, then the Name */ char *psz_name = input_item_GetTitleFbName( input_GetItem( p_input ) ); /* Try to get the nowplaying */ char *psz_nowplaying = input_item_GetNowPlaying( input_GetItem( p_input ) ); if( !EMPTY_STR( psz_nowplaying ) ) { text.sprintf( "%s - %s", psz_nowplaying, psz_name ); } else /* Do it ourself */ { char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) ); if( !EMPTY_STR( psz_artist ) ) text.sprintf( "%s - %s", psz_artist, psz_name ); else text.sprintf( "%s", psz_name ); free( psz_artist ); } /* Free everything */ free( psz_name ); free( psz_nowplaying ); /* If we have Nothing */ if( text.isEmpty() ) { psz_name = input_item_GetURI( input_GetItem( p_input ) ); text.sprintf( "%s", psz_name ); text = text.remove( 0, text.lastIndexOf( DIR_SEP ) + 1 ); free( psz_name ); } if( oldName != text ) { emit nameChanged( text ); oldName = text; } }
/** * Recursively follow the playlist * @param p_export: the export structure * @param p_root: the current node */ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root ) { /* Go through the playlist and add items */ for( int i = 0; i < p_root->i_children ; i++) { playlist_item_t *p_current = p_root->pp_children[i]; assert( p_current ); if( p_current->i_children >= 0 ) { DoChildren( p_export, p_current ); continue; } char* psz_name = NULL; char *psz_tmp = input_item_GetName( p_current->p_input ); if( psz_tmp ) psz_name = vlc_xml_encode( psz_tmp ); free( psz_tmp ); if( psz_name ) { char* psz_artist = NULL; psz_tmp = input_item_GetArtist( p_current->p_input ); if( psz_tmp ) psz_artist = vlc_xml_encode( psz_tmp ); free( psz_tmp ); vlc_tick_t i_duration = input_item_GetDuration( p_current->p_input ); int min = SEC_FROM_VLC_TICK( i_duration ) / 60; int sec = SEC_FROM_VLC_TICK( i_duration ) - min * 60; // Print the artist if we have one if( psz_artist && *psz_artist ) fprintf( p_export->p_file, " <li>%s - %s (%02d:%02d)</li>\n", psz_artist, psz_name, min, sec ); else fprintf( p_export->p_file, " <li>%s (%2d:%2d)</li>\n", psz_name, min, sec ); free( psz_artist ); } free( psz_name ); } }
static void DisplayVoutTitle( input_resource_t *p_resource, vout_thread_t *p_vout ) { if( p_resource->p_input == NULL ) return; /* TODO display the title only one time for the same input ? */ input_item_t *p_item = input_GetItem( p_resource->p_input ); char *psz_nowplaying = input_item_GetNowPlaying( p_item ); if( psz_nowplaying && *psz_nowplaying ) { vout_DisplayTitle( p_vout, psz_nowplaying ); } else { char *psz_artist = input_item_GetArtist( p_item ); char *psz_name = input_item_GetTitle( p_item ); if( !psz_name || *psz_name == '\0' ) { free( psz_name ); psz_name = input_item_GetName( p_item ); } if( psz_artist && *psz_artist ) { char *psz_string; if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 ) { vout_DisplayTitle( p_vout, psz_string ); free( psz_string ); } } else if( psz_name ) { vout_DisplayTitle( p_vout, psz_name ); } free( psz_name ); free( psz_artist ); } free( psz_nowplaying ); }
/***************************************************************************** * Export_M3U: main export function *****************************************************************************/ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root, int (*pf_fprintf) (FILE *, const char *, ...) ) { /* Write header */ fputs( "#EXTM3U\n", p_export->p_file ); /* Go through the playlist and add items */ for( int i = 0; i< p_root->i_children ; i++) { playlist_item_t *p_current = p_root->pp_children[i]; assert( p_current ); if( p_current->i_flags & PLAYLIST_SAVE_FLAG ) continue; if( p_current->i_children >= 0 ) { DoChildren( p_export, p_current, pf_fprintf ); continue; } /* General info */ char *psz_uri = input_item_GetURI( p_current->p_input ); assert( psz_uri ); char *psz_name = input_item_GetName( p_current->p_input ); if( psz_name && strcmp( psz_uri, psz_name ) ) { char *psz_artist = input_item_GetArtist( p_current->p_input ); if( psz_artist == NULL ) psz_artist = strdup( "" ); mtime_t i_duration = input_item_GetDuration( p_current->p_input ); if( psz_artist && *psz_artist ) { /* write EXTINF with artist */ pf_fprintf( p_export->p_file, "#EXTINF:%"PRIu64",%s - %s\n", i_duration / CLOCK_FREQ, psz_artist, psz_name); } else { /* write EXTINF without artist */ pf_fprintf( p_export->p_file, "#EXTINF:%"PRIu64",%s\n", i_duration / CLOCK_FREQ, psz_name); } free( psz_artist ); } free( psz_name ); /* VLC specific options */ vlc_mutex_lock( &p_current->p_input->lock ); for( int j = 0; j < p_current->p_input->i_options; j++ ) { pf_fprintf( p_export->p_file, "#EXTVLCOPT:%s\n", p_current->p_input->ppsz_options[j][0] == ':' ? p_current->p_input->ppsz_options[j] + 1 : p_current->p_input->ppsz_options[j] ); } vlc_mutex_unlock( &p_current->p_input->lock ); /* Stupid third party players don't understand file: URIs. */ char *psz_path = make_path( psz_uri ); if( psz_path != NULL ) { free( psz_uri ); psz_uri = psz_path; } fprintf( p_export->p_file, "%s\n", psz_uri ); free( psz_uri ); } }
/************************************************************************* * Playlist stuff *************************************************************************/ void PlaylistListNode( intf_thread_t *p_intf, playlist_t *p_pl, playlist_item_t *p_node, char *name, mvar_t *s, int i_depth ) { if( !p_node || !p_node->p_input ) return; if( p_node->i_children == -1 ) { char value[512]; char *psz; playlist_item_t * p_item = playlist_CurrentPlayingItem( p_pl ); if( !p_item || !p_item->p_input ) return; mvar_t *itm = mvar_New( name, "set" ); if( p_item->p_input == p_node->p_input ) mvar_AppendNewVar( itm, "current", "1" ); else mvar_AppendNewVar( itm, "current", "0" ); sprintf( value, "%d", p_node->i_id ); mvar_AppendNewVar( itm, "index", value ); psz = input_item_GetName( p_node->p_input ); mvar_AppendNewVar( itm, "name", psz ); free( psz ); psz = input_item_GetURI( p_node->p_input ); mvar_AppendNewVar( itm, "uri", psz ); free( psz ); mvar_AppendNewVar( itm, "type", "Item" ); sprintf( value, "%d", i_depth ); mvar_AppendNewVar( itm, "depth", value ); if( p_node->i_flags & PLAYLIST_RO_FLAG ) mvar_AppendNewVar( itm, "ro", "ro" ); else mvar_AppendNewVar( itm, "ro", "rw" ); sprintf( value, "%"PRId64, input_item_GetDuration( p_node->p_input ) ); mvar_AppendNewVar( itm, "duration", value ); //Adding extra meta-information to each playlist item psz = input_item_GetTitle( p_node->p_input ); mvar_AppendNewVar( itm, "title", psz ); free( psz ); psz = input_item_GetArtist( p_node->p_input ); mvar_AppendNewVar( itm, "artist", psz ); free( psz ); psz = input_item_GetGenre( p_node->p_input ); mvar_AppendNewVar( itm, "genre", psz ); free( psz ); psz = input_item_GetCopyright( p_node->p_input ); mvar_AppendNewVar( itm, "copyright", psz ); free( psz ); psz = input_item_GetAlbum( p_node->p_input ); mvar_AppendNewVar( itm, "album", psz ); free( psz ); psz = input_item_GetTrackNum( p_node->p_input ); mvar_AppendNewVar( itm, "track", psz ); free( psz ); psz = input_item_GetDescription( p_node->p_input ); mvar_AppendNewVar( itm, "description", psz ); free( psz ); psz = input_item_GetRating( p_node->p_input ); mvar_AppendNewVar( itm, "rating", psz ); free( psz ); psz = input_item_GetDate( p_node->p_input ); mvar_AppendNewVar( itm, "date", psz ); free( psz ); psz = input_item_GetURL( p_node->p_input ); mvar_AppendNewVar( itm, "url", psz ); free( psz ); psz = input_item_GetLanguage( p_node->p_input ); mvar_AppendNewVar( itm, "language", psz ); free( psz ); psz = input_item_GetNowPlaying( p_node->p_input ); mvar_AppendNewVar( itm, "now_playing", psz ); free( psz ); psz = input_item_GetPublisher( p_node->p_input ); mvar_AppendNewVar( itm, "publisher", psz ); free( psz ); psz = input_item_GetEncodedBy( p_node->p_input ); mvar_AppendNewVar( itm, "encoded_by", psz ); free( psz ); psz = input_item_GetArtURL( p_node->p_input ); mvar_AppendNewVar( itm, "art_url", psz ); free( psz ); psz = input_item_GetTrackID( p_node->p_input ); mvar_AppendNewVar( itm, "track_id", psz ); free( psz ); mvar_AppendVar( s, itm ); } else { char value[512]; int i_child; mvar_t *itm = mvar_New( name, "set" ); mvar_AppendNewVar( itm, "name", p_node->p_input->psz_name ); mvar_AppendNewVar( itm, "uri", p_node->p_input->psz_name ); mvar_AppendNewVar( itm, "type", "Node" ); sprintf( value, "%d", p_node->i_id ); mvar_AppendNewVar( itm, "index", value ); sprintf( value, "%d", p_node->i_children); mvar_AppendNewVar( itm, "i_children", value ); sprintf( value, "%d", i_depth ); mvar_AppendNewVar( itm, "depth", value ); if( p_node->i_flags & PLAYLIST_RO_FLAG ) mvar_AppendNewVar( itm, "ro", "ro" ); else mvar_AppendNewVar( itm, "ro", "rw" ); mvar_AppendVar( s, itm ); for( i_child = 0 ; i_child < p_node->i_children ; i_child++ ) PlaylistListNode( p_intf, p_pl, p_node->pp_children[i_child], name, s, i_depth + 1); } }
/***************************************************************************** * ItemChange: Playlist item change callback *****************************************************************************/ static int ItemChange( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *param ) { VLC_UNUSED(psz_var); VLC_UNUSED(oldval); VLC_UNUSED(newval); char psz_tmp[MAX_LENGTH]; char psz_notify[MAX_LENGTH]; char *psz_title; char *psz_artist; char *psz_album; char *psz_arturl; input_thread_t *p_input = playlist_CurrentInput( (playlist_t*)p_this ); intf_thread_t *p_intf = param; intf_sys_t *p_sys = p_intf->p_sys; if( !p_input ) return VLC_SUCCESS; if( p_input->b_dead ) { /* Not playing anything ... */ vlc_object_release( p_input ); return VLC_SUCCESS; } /* Wait a tad so the meta has been fetched * FIXME that's awfully wrong */ msleep( 10000 ); /* Playing something ... */ input_item_t *p_input_item = input_GetItem( p_input ); psz_title = input_item_GetTitleFbName( p_input_item ); /* We need at least a title */ if( EMPTY_STR( psz_title ) ) { free( psz_title ); vlc_object_release( p_input ); return VLC_SUCCESS; } psz_artist = input_item_GetArtist( p_input_item ); psz_album = input_item_GetAlbum( p_input_item ); if( !EMPTY_STR( psz_artist ) ) { if( !EMPTY_STR( psz_album ) ) snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s\n[%s]", psz_title, psz_artist, psz_album ); else snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s", psz_title, psz_artist ); } else snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>", psz_title ); free( psz_title ); free( psz_artist ); free( psz_album ); GdkPixbuf *pix = NULL; psz_arturl = input_item_GetArtURL( p_input_item ); vlc_object_release( p_input ); if( psz_arturl ) { char *psz = make_path( psz_arturl ); free( psz_arturl ); psz_arturl = psz; } if( psz_arturl ) { /* scale the art to show it in notify popup */ GError *p_error = NULL; pix = gdk_pixbuf_new_from_file_at_scale( psz_arturl, 72, 72, TRUE, &p_error ); } else /* else we show state-of-the art logo */ { /* First try to get an icon from the current theme. */ GtkIconTheme* p_theme = gtk_icon_theme_get_default(); pix = gtk_icon_theme_load_icon( p_theme, "vlc", 72, 0, NULL); if( !pix ) { /* Load icon from share/ */ GError *p_error = NULL; char *psz_pixbuf; char *psz_data = config_GetDataDir( p_this ); if( asprintf( &psz_pixbuf, "%s/icons/48x48/vlc.png", psz_data ) >= 0 ) { pix = gdk_pixbuf_new_from_file( psz_pixbuf, &p_error ); free( psz_pixbuf ); } free( psz_data ); } } free( psz_arturl ); /* we need to replace '&' with '&' because '&' is a keyword of * notification-daemon parser */ const int i_len = strlen( psz_tmp ); int i_notify = 0; for( int i = 0; i < i_len && i_notify < ( MAX_LENGTH - 5 ); i++ ) { /* we use MAX_LENGTH - 5 because if the last char of psz_tmp is '&' * we will need 5 more characters: 'amp;\0' . * however that's unlikely to happen because the last char is '\0' */ if( psz_tmp[i] != '&' ) { psz_notify[i_notify] = psz_tmp[i]; } else { strcpy( &psz_notify[i_notify], "&" ); i_notify += 4; } i_notify++; } psz_notify[i_notify] = '\0'; vlc_mutex_lock( &p_sys->lock ); Notify( p_this, psz_notify, pix, p_intf ); vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS; }
/***************************************************************************** * ItemChange: Playlist item change callback *****************************************************************************/ static int ItemChange( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *param ) { VLC_UNUSED(psz_var); VLC_UNUSED(oldval); VLC_UNUSED(newval); char psz_tmp[MAX_LENGTH]; char psz_notify[MAX_LENGTH]; char *psz_title; char *psz_artist; char *psz_album; char *psz_arturl; input_thread_t *p_input = newval.p_address; intf_thread_t *p_intf = param; intf_sys_t *p_sys = p_intf->p_sys; if( !p_input ) return VLC_SUCCESS; /* Playing something ... */ input_item_t *p_input_item = input_GetItem( p_input ); /* Checking for click on directories */ if(p_input_item->i_type == ITEM_TYPE_DIRECTORY || p_input_item->i_type == ITEM_TYPE_PLAYLIST || p_input_item->i_type == ITEM_TYPE_NODE || p_input_item->i_type== ITEM_TYPE_UNKNOWN || p_input_item->i_type == ITEM_TYPE_CARD){ return VLC_SUCCESS; } psz_title = input_item_GetTitleFbName( p_input_item ); /* We need at least a title */ if( EMPTY_STR( psz_title ) ) { free( psz_title ); return VLC_SUCCESS; } psz_artist = input_item_GetArtist( p_input_item ); psz_album = input_item_GetAlbum( p_input_item ); if( !EMPTY_STR( psz_artist ) ) { if( !EMPTY_STR( psz_album ) ) snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s\n[%s]", psz_title, psz_artist, psz_album ); else snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s", psz_title, psz_artist ); } else snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>", psz_title ); free( psz_title ); free( psz_artist ); free( psz_album ); GdkPixbuf *pix = NULL; psz_arturl = input_item_GetArtURL( p_input_item ); if( psz_arturl ) { char *psz = vlc_uri2path( psz_arturl ); free( psz_arturl ); psz_arturl = psz; } if( psz_arturl ) { /* scale the art to show it in notify popup */ GError *p_error = NULL; pix = gdk_pixbuf_new_from_file_at_scale( psz_arturl, 72, 72, TRUE, &p_error ); } else /* else we show state-of-the art logo */ { /* First try to get an icon from the current theme. */ GtkIconTheme* p_theme = gtk_icon_theme_get_default(); pix = gtk_icon_theme_load_icon( p_theme, "vlc", 72, 0, NULL); if( !pix ) { /* Load icon from share/ */ GError *p_error = NULL; char *psz_pixbuf = config_GetSysPath(VLC_SYSDATA_DIR, "icons/hicolor/48x48/"PACKAGE_NAME".png"); if (psz_pixbuf != NULL) { pix = gdk_pixbuf_new_from_file( psz_pixbuf, &p_error ); free( psz_pixbuf ); } } } free( psz_arturl ); /* we need to replace '&' with '&' because '&' is a keyword of * notification-daemon parser */ const int i_len = strlen( psz_tmp ); int i_notify = 0; for( int i = 0; i < i_len && i_notify < ( MAX_LENGTH - 5 ); i++ ) { /* we use MAX_LENGTH - 5 because if the last char of psz_tmp is '&' * we will need 5 more characters: 'amp;\0' . * however that's unlikely to happen because the last char is '\0' */ if( psz_tmp[i] != '&' ) { psz_notify[i_notify] = psz_tmp[i]; } else { strcpy( &psz_notify[i_notify], "&" ); i_notify += 4; } i_notify++; } psz_notify[i_notify] = '\0'; vlc_mutex_lock( &p_sys->lock ); Notify( p_this, psz_notify, pix, p_intf ); vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS; }
static void ProcessEntry( int *pi_n_entry, xml_reader_t *p_xml_reader, input_item_node_t *p_subitems, input_item_t *p_current_input, char *psz_prefix ) { const char *psz_node = NULL; const char *psz_txt = NULL; int i_type; char *psz_title = NULL; char *psz_artist = NULL; char *psz_copyright = NULL; char *psz_moreinfo = NULL; char *psz_description = NULL; char *psz_name = NULL; char *psz_mrl = NULL; char *psz_href = NULL; input_item_t *p_entry = NULL; int i_options; mtime_t i_start = 0; mtime_t i_duration = 0; char *ppsz_options[2]; do { i_type = xml_ReaderNextNode( p_xml_reader, &psz_node ); if( i_type == XML_READER_STARTELEM ) { /* Metadata Node */ if( !strncasecmp( psz_node, "TITLE", 5 ) ) ReadElement( p_xml_reader, &psz_title ); else if( !strncasecmp( psz_node, "AUTHOR", 6 ) ) ReadElement( p_xml_reader, &psz_artist ); else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) ) ReadElement( p_xml_reader, &psz_copyright ); else if( !strncasecmp( psz_node,"MOREINFO", 8 ) ) { do { psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while(psz_txt && strncasecmp( psz_txt, "HREF", 4 ) ); if( !psz_txt ) ReadElement( p_xml_reader, &psz_moreinfo ); else psz_moreinfo = strdup( psz_node ); resolve_xml_special_chars( psz_moreinfo ); } else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) ) ReadElement( p_xml_reader, &psz_description ); else if( !strncasecmp( psz_node, "DURATION", 8 ) ) i_duration = ParseTime( p_xml_reader ); else if( !strncasecmp( psz_node, "STARTTIME", 9 ) ) i_start = ParseTime( p_xml_reader ); else /* Reference Node */ /* All ref node will be converted into an entry */ if( !strncasecmp( psz_node, "REF", 3 ) ) { *pi_n_entry = *pi_n_entry + 1; if( !psz_title ) psz_title = input_item_GetTitle( p_current_input ); if( !psz_artist ) psz_artist = input_item_GetArtist( p_current_input ); if( !psz_copyright ) psz_copyright = input_item_GetCopyright( p_current_input ); if( !psz_description ) psz_description = input_item_GetDescription( p_current_input ); do { psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( strncasecmp( psz_txt, "HREF", 4) ); psz_href = strdup( psz_node ); if( asprintf( &psz_name, "%d. %s", *pi_n_entry, psz_title ) == -1) psz_name = strdup( psz_title ); resolve_xml_special_chars( psz_href ); psz_mrl = ProcessMRL( psz_href, psz_prefix ); /* Add Time information */ i_options = 0; if( i_start ) { if( asprintf( ppsz_options, ":start-time=%d" ,(int) i_start/1000000 ) != -1) i_options++; } if( i_duration) { if( asprintf( ppsz_options + i_options, ":stop-time=%d", (int) (i_start+i_duration)/1000000 ) != -1) i_options++; } /* Create the input item */ p_entry = input_item_NewExt( psz_mrl, psz_name, i_options, (const char* const*) ppsz_options, VLC_INPUT_OPTION_TRUSTED, i_duration ); input_item_CopyOptions( p_current_input, p_entry ); /* Add the metadata */ if( psz_name ) input_item_SetTitle( p_entry, psz_name ); if( psz_artist ) input_item_SetArtist( p_entry, psz_artist ); if( psz_copyright ) input_item_SetCopyright( p_entry, psz_copyright ); if( psz_moreinfo ) input_item_SetURL( p_entry, psz_moreinfo ); if( psz_description ) input_item_SetDescription( p_entry, psz_description ); if( i_duration > 0) input_item_SetDuration( p_entry, i_duration ); input_item_node_AppendItem( p_subitems, p_entry ); while( i_options ) free( ppsz_options[--i_options] ); free( psz_name ); free( psz_mrl ); } } } while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ENTRY", 5 ) ); free( psz_href ); free( psz_title ); free( psz_artist ); free( psz_copyright ); free( psz_moreinfo ); free( psz_description ); }
static LRESULT HandleCadMessage(intf_thread_t* p_intf, HWND hwnd, WPARAM wParam, LPARAM lParam) { intf_sys_t* const p_sys = p_intf->p_sys; switch (lParam) { case IPC_PLAY: { playlist_Play(pl_Get(p_intf->p_libvlc)); return 1; } case IPC_PLAYPAUSE: { playlist_t* p_playlist = pl_Get(p_intf->p_libvlc); const bool playing = playlist_Status(p_playlist) == PLAYLIST_RUNNING; playlist_Control(p_playlist, playing ? PLAYLIST_PAUSE : PLAYLIST_PLAY, pl_Unlocked); return 1; } case IPC_PAUSE: { playlist_Pause(pl_Get(p_intf->p_libvlc)); return 1; } case IPC_STOP: { playlist_Stop(pl_Get(p_intf->p_libvlc)); return 1; } case IPC_NEXT: { playlist_Next(pl_Get(p_intf->p_libvlc)); return 1; } case IPC_PREVIOUS: { playlist_Prev(pl_Get(p_intf->p_libvlc)); return 1; } case IPC_SET_VOLUME: { playlist_VolumeSet(pl_Get(p_intf->p_libvlc), (int)wParam / 100.0f); return 1; } case IPC_GET_VOLUME: { // VLC can return a volume larger than 100% so we need to cap it to 100 here. const float volume = playlist_VolumeGet(pl_Get(p_intf->p_libvlc)) * 100.0f; return (LRESULT)min(volume, 100.0f); } case IPC_GET_DURATION: { unsigned int duration = 0; if (p_sys->p_input) { input_item_t* const p_item = input_GetItem(p_sys->p_input); duration = (unsigned int)(input_item_GetDuration(p_item) / 1000000); } return duration; } case IPC_GET_POSITION: { int pos = 0; if (p_sys->p_input) { pos = (int)(var_GetTime(p_sys->p_input, "time") / CLOCK_FREQ); } return pos; } case IPC_SET_POSITION: { if (p_sys->p_input) { var_SetTime(p_sys->p_input, "time", (int64_t)wParam * CLOCK_FREQ); } return 0; } case IPC_GET_SHUFFLE: { return (int)var_GetBool(pl_Get(p_intf->p_libvlc), "random"); } case IPC_SET_SHUFFLE: { return (int)var_SetBool(pl_Get(p_intf->p_libvlc), "random", (bool)wParam); } case IPC_GET_REPEAT: { return (int)var_GetBool(pl_Get(p_intf->p_libvlc), "repeat"); } case IPC_SET_REPEAT: { return (int)var_SetBool(pl_Get(p_intf->p_libvlc), "repeat", (bool)wParam); } case IPC_SET_RATING: { // VLC does not support ratings so send back 0. PostMessage(p_sys->cad_window, WM_USER, 0, IPC_RATING_CHANGED_NOTIFICATION); return 0; } case IPC_SET_CALLBACK_HWND: { p_sys->cad_window = (HWND)wParam; return 1; } case IPC_SHOW_WINDOW: { // TODO. return 0; } case IPC_GET_STATE: { const int status = playlist_Status(pl_Get(p_intf->p_libvlc)); return status == PLAYLIST_RUNNING ? 1 : status == PLAYLIST_PAUSED ? 2 : 0; } case IPC_SHUTDOWN_NOTIFICATION: { p_sys->cad_window = NULL; return 1; } case IPC_CLOSE: { libvlc_Quit(p_intf->p_libvlc); return 1; } case IPC_GET_CURRENT_TRACK: { if (!p_sys->p_input) return 0; input_item_t* p_item = input_GetItem(p_sys->p_input); char buffer[DATA_MAX_LENGTH]; int buffer_len = 0; // If the i sstarts with file://, we assume that it is a local file and detailed // metadata is available. Otherwise, we assume it to be a network stream (i.e. radio) // with limited info (only a title). char* const file = decode_URI(input_item_GetURI(p_item)); if (strncmp(file, "file://", 7) == 0) { char* const title = input_item_GetTitleFbName(p_item); char* const artist = input_item_GetArtist(p_item); char* const album = input_item_GetAlbum(p_item); char* const cover = decode_URI(input_item_GetArtworkURL(p_item)); const unsigned int duration = input_item_GetDuration(p_item) / 1000000U; buffer_len = _snprintf( buffer, ARRAYSIZE(buffer), "%s\t%s\t%s\t\t\t\t\t%u\t%s\t\t%s\t\t\t\t\t\t\t", title ? title : "", artist ? artist : "", album ? album : "", duration, file ? &file[8] : "", cover ? &cover[8] : ""); // Skip the "file://" part. free(title); free(artist); free(album); free(cover); } else if (char* now_playing = input_item_GetNowPlaying(p_item)) { char* artist = NULL; char* title = now_playing; char* pos = strstr(now_playing, " - "); if (pos) { pos[0] = '\0'; artist = title; title = pos + 3; // Skip the " - " } buffer_len = _snprintf( buffer, ARRAYSIZE(buffer), "%s\t%s\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", title ? title : "", artist ? artist : ""); free(now_playing); } free(file); if (buffer_len) { wchar_t buffer_w[DATA_MAX_LENGTH]; const int buffer_w_len = MultiByteToWideChar( CP_UTF8, 0, buffer, buffer_len + 1, buffer_w, ARRAYSIZE(buffer_w)); COPYDATASTRUCT cds; cds.dwData = IPC_CURRENT_TRACK_NOTIFICATION; cds.lpData = &buffer_w; cds.cbData = buffer_w_len * sizeof(buffer_w[0]); SendMessage( p_sys->cad_window, WM_COPYDATA, IPC_CURRENT_TRACK_NOTIFICATION, (LPARAM)&cds); } return 1; } } return 0; }
/***************************************************************************** * ItemChange: Playlist item change callback *****************************************************************************/ static int ItemChange( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *param ) { VLC_UNUSED(psz_var); VLC_UNUSED(oldval); VLC_UNUSED(newval); char psz_tmp[MAX_LENGTH]; char psz_notify[MAX_LENGTH]; char *psz_title = NULL; char *psz_artist = NULL; char *psz_album = NULL; char *psz_arturl = NULL; input_thread_t *p_input = playlist_CurrentInput( (playlist_t*) p_this ); intf_thread_t *p_intf = param; intf_sys_t *p_sys = p_intf->p_sys; if( !p_input ) return VLC_SUCCESS; if( p_input->b_dead ) { /* Not playing anything ... */ vlc_object_release( p_input ); return VLC_SUCCESS; } /* Wait a tad so the meta has been fetched * FIXME that's awfully wrong */ msleep( 1000*4 ); /* Playing something ... */ input_item_t *p_input_item = input_GetItem( p_input ); psz_artist = input_item_GetArtist( p_input_item ); psz_album = input_item_GetAlbum( p_input_item ); psz_title = input_item_GetTitleFbName( p_input_item ); if( EMPTY_STR( psz_title ) ) { /* Not enough metadata ... */ free( psz_title ); free( psz_artist ); free( psz_album ); vlc_object_release( p_input ); return VLC_SUCCESS; } if( EMPTY_STR( psz_artist ) ) { free( psz_artist ); psz_artist = NULL; } if( EMPTY_STR( psz_album ) ) { free( psz_album ); psz_album = NULL; } if( psz_artist && psz_album ) snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s\n[%s]", psz_title, psz_artist, psz_album ); else if( psz_artist ) snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s", psz_title, psz_artist ); else snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>", psz_title ); free( psz_title ); free( psz_artist ); free( psz_album ); GdkPixbuf *pix = NULL; psz_arturl = input_item_GetArtURL( p_input_item ); vlc_object_release( p_input ); if( psz_arturl && !strncmp( psz_arturl, "file://", 7 ) && decode_URI( psz_arturl + 7 ) ) { /* scale the art to show it in notify popup */ GError *p_error = NULL; pix = gdk_pixbuf_new_from_file_at_scale( &psz_arturl[7], 72, 72, TRUE, &p_error ); } else /* else we show state-of-the art logo */ { GError *p_error = NULL; char *psz_pixbuf; if( asprintf( &psz_pixbuf, "%s/vlc48x48.png", config_GetDataDir() ) >= 0 ) { pix = gdk_pixbuf_new_from_file( psz_pixbuf, &p_error ); free( psz_pixbuf ); } } free( psz_arturl ); /* we need to replace '&' with '&' because '&' is a keyword of * notification-daemon parser */ const int i_len = strlen( psz_tmp ); int i_notify = 0; for( int i = 0; i < i_len && i_notify < ( MAX_LENGTH - 5 ); i++ ) { /* we use MAX_LENGTH - 5 because if the last char of psz_tmp is '&' * we will need 5 more characters: 'amp;\0' . * however that's unlikely to happen because the last char is '\0' */ if( psz_tmp[i] != '&' ) { psz_notify[i_notify] = psz_tmp[i]; } else { snprintf( &psz_notify[i_notify], 6, "&" ); i_notify += 4; } i_notify++; } psz_notify[i_notify] = '\0'; vlc_mutex_lock( &p_sys->lock ); Notify( p_this, psz_notify, pix, p_intf ); vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS; }
void EvaluateRPN( intf_thread_t *p_intf, mvar_t *vars, rpn_stack_t *st, char *exp ) { intf_sys_t *p_sys = p_intf->p_sys; while( exp != NULL && *exp != '\0' ) { char *p, *s; /* skip space */ while( *exp == ' ' ) { exp++; } if( *exp == '\'' ) { /* extract string */ p = FirstWord( exp, exp ); SSPush( st, exp ); exp = p; continue; } /* extract token */ p = FirstWord( exp, exp ); s = exp; if( p == NULL ) { exp += strlen( exp ); } else { exp = p; } if( *s == '\0' ) { break; } /* 1. Integer function */ if( !strcmp( s, "!" ) ) { SSPushN( st, ~SSPopN( st, vars ) ); } else if( !strcmp( s, "^" ) ) { SSPushN( st, SSPopN( st, vars ) ^ SSPopN( st, vars ) ); } else if( !strcmp( s, "&" ) ) { SSPushN( st, SSPopN( st, vars ) & SSPopN( st, vars ) ); } else if( !strcmp( s, "|" ) ) { SSPushN( st, SSPopN( st, vars ) | SSPopN( st, vars ) ); } else if( !strcmp( s, "+" ) ) { SSPushN( st, SSPopN( st, vars ) + SSPopN( st, vars ) ); } else if( !strcmp( s, "-" ) ) { int j = SSPopN( st, vars ); int i = SSPopN( st, vars ); SSPushN( st, i - j ); } else if( !strcmp( s, "*" ) ) { SSPushN( st, SSPopN( st, vars ) * SSPopN( st, vars ) ); } else if( !strcmp( s, "/" ) ) { int i, j; j = SSPopN( st, vars ); i = SSPopN( st, vars ); SSPushN( st, j != 0 ? i / j : 0 ); } else if( !strcmp( s, "%" ) ) { int i, j; j = SSPopN( st, vars ); i = SSPopN( st, vars ); SSPushN( st, j != 0 ? i % j : 0 ); } /* 2. integer tests */ else if( !strcmp( s, "=" ) ) { SSPushN( st, SSPopN( st, vars ) == SSPopN( st, vars ) ? -1 : 0 ); } else if( !strcmp( s, "!=" ) ) { SSPushN( st, SSPopN( st, vars ) != SSPopN( st, vars ) ? -1 : 0 ); } else if( !strcmp( s, "<" ) ) { int j = SSPopN( st, vars ); int i = SSPopN( st, vars ); SSPushN( st, i < j ? -1 : 0 ); } else if( !strcmp( s, ">" ) ) { int j = SSPopN( st, vars ); int i = SSPopN( st, vars ); SSPushN( st, i > j ? -1 : 0 ); } else if( !strcmp( s, "<=" ) ) { int j = SSPopN( st, vars ); int i = SSPopN( st, vars ); SSPushN( st, i <= j ? -1 : 0 ); } else if( !strcmp( s, ">=" ) ) { int j = SSPopN( st, vars ); int i = SSPopN( st, vars ); SSPushN( st, i >= j ? -1 : 0 ); } /* 3. string functions */ else if( !strcmp( s, "strcat" ) ) { char *s2 = SSPop( st ); char *s1 = SSPop( st ); char *str = malloc( strlen( s1 ) + strlen( s2 ) + 1 ); strcpy( str, s1 ); strcat( str, s2 ); SSPush( st, str ); free( s1 ); free( s2 ); free( str ); } else if( !strcmp( s, "strcmp" ) ) { char *s2 = SSPop( st ); char *s1 = SSPop( st ); SSPushN( st, strcmp( s1, s2 ) ); free( s1 ); free( s2 ); } else if( !strcmp( s, "strncmp" ) ) { int n = SSPopN( st, vars ); char *s2 = SSPop( st ); char *s1 = SSPop( st ); SSPushN( st, strncmp( s1, s2 , n ) ); free( s1 ); free( s2 ); } else if( !strcmp( s, "strsub" ) ) { int n = SSPopN( st, vars ); int m = SSPopN( st, vars ); int i_len; char *s = SSPop( st ); char *str; if( n >= m ) { i_len = n - m + 1; } else { i_len = 0; } str = malloc( i_len + 1 ); memcpy( str, s + m - 1, i_len ); str[ i_len ] = '\0'; SSPush( st, str ); free( s ); free( str ); } else if( !strcmp( s, "strlen" ) ) { char *str = SSPop( st ); SSPushN( st, strlen( str ) ); free( str ); } else if( !strcmp( s, "str_replace" ) ) { char *psz_to = SSPop( st ); char *psz_from = SSPop( st ); char *psz_in = SSPop( st ); char *psz_in_current = psz_in; char *psz_out = malloc( strlen(psz_in) * strlen(psz_to) + 1 ); char *psz_out_current = psz_out; while( (p = strstr( psz_in_current, psz_from )) != NULL ) { memcpy( psz_out_current, psz_in_current, p - psz_in_current ); psz_out_current += p - psz_in_current; strcpy( psz_out_current, psz_to ); psz_out_current += strlen(psz_to); psz_in_current = p + strlen(psz_from); } strcpy( psz_out_current, psz_in_current ); psz_out_current += strlen(psz_in_current); *psz_out_current = '\0'; SSPush( st, psz_out ); free( psz_to ); free( psz_from ); free( psz_in ); free( psz_out ); } else if( !strcmp( s, "url_extract" ) ) { const char *url = mvar_GetValue( vars, "url_value" ); char *name = SSPop( st ); char *value = ExtractURIString( url, name ); if( value != NULL ) { decode_URI( value ); SSPush( st, value ); free( value ); } else SSPush( st, "" ); free( name ); } else if( !strcmp( s, "url_encode" ) ) { char *url = SSPop( st ); char *value = vlc_UrlEncode( url ); free( url ); SSPush( st, value ); free( value ); } else if( !strcmp( s, "xml_encode" ) || !strcmp( s, "htmlspecialchars" ) ) { char *url = SSPop( st ); char *value = convert_xml_special_chars( url ); free( url ); SSPush( st, value ); free( value ); } else if( !strcmp( s, "addslashes" ) ) { char *psz_src = SSPop( st ); char *psz_dest; char *str = psz_src; p = psz_dest = malloc( strlen( str ) * 2 + 1 ); while( *str != '\0' ) { if( *str == '"' || *str == '\'' || *str == '\\' ) { *p++ = '\\'; } *p++ = *str; str++; } *p = '\0'; SSPush( st, psz_dest ); free( psz_src ); free( psz_dest ); } else if( !strcmp( s, "stripslashes" ) ) { char *psz_src = SSPop( st ); char *psz_dest; char *str = psz_src; p = psz_dest = strdup( psz_src ); while( *str ) { if( *str == '\\' && *(str + 1) ) { str++; } *p++ = *str++; } *p = '\0'; SSPush( st, psz_dest ); free( psz_src ); free( psz_dest ); } else if( !strcmp( s, "realpath" ) ) { char *psz_src = SSPop( st ); char *psz_dir = RealPath( psz_src ); SSPush( st, psz_dir ); free( psz_src ); free( psz_dir ); } /* 4. stack functions */ else if( !strcmp( s, "dup" ) ) { char *str = SSPop( st ); SSPush( st, str ); SSPush( st, str ); free( str ); } else if( !strcmp( s, "drop" ) ) { char *str = SSPop( st ); free( str ); } else if( !strcmp( s, "swap" ) ) { char *s1 = SSPop( st ); char *s2 = SSPop( st ); SSPush( st, s1 ); SSPush( st, s2 ); free( s1 ); free( s2 ); } else if( !strcmp( s, "flush" ) ) { SSClean( st ); SSInit( st ); } else if( !strcmp( s, "store" ) ) { char *value = SSPop( st ); char *name = SSPop( st ); mvar_PushNewVar( vars, name, value ); free( name ); free( value ); } else if( !strcmp( s, "value" ) ) { char *name = SSPop( st ); const char *value = mvar_GetValue( vars, name ); SSPush( st, value ); free( name ); } /* 5. player control */ else if( !strcmp( s, "vlc_play" ) ) { int i_id = SSPopN( st, vars ); int i_ret; playlist_Lock( p_sys->p_playlist ); i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, NULL, playlist_ItemGetById( p_sys->p_playlist, i_id ) ); playlist_Unlock( p_sys->p_playlist ); msg_Dbg( p_intf, "requested playlist item: %i", i_id ); SSPushN( st, i_ret ); } else if( !strcmp( s, "vlc_stop" ) ) { playlist_Control( p_sys->p_playlist, PLAYLIST_STOP, pl_Unlocked ); msg_Dbg( p_intf, "requested playlist stop" ); } else if( !strcmp( s, "vlc_pause" ) ) { playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE, pl_Unlocked ); msg_Dbg( p_intf, "requested playlist pause" ); } else if( !strcmp( s, "vlc_next" ) ) { playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, pl_Unlocked, 1 ); msg_Dbg( p_intf, "requested playlist next" ); } else if( !strcmp( s, "vlc_previous" ) ) { playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, pl_Unlocked, -1 ); msg_Dbg( p_intf, "requested playlist previous" ); } else if( !strcmp( s, "vlc_seek" ) ) { char *psz_value = SSPop( st ); HandleSeek( p_intf, psz_value ); msg_Dbg( p_intf, "requested playlist seek: %s", psz_value ); free( psz_value ); } else if( !strcmp( s, "vlc_var_type" ) || !strcmp( s, "vlc_config_type" ) ) { vlc_object_t *p_object; const char *psz_type = NULL; int i_type = 0; if( !strcmp( s, "vlc_var_type" ) ) { char *psz_object = SSPop( st ); char *psz_variable = SSPop( st ); bool b_need_release; p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); if( p_object != NULL ) i_type = var_Type( p_object, psz_variable ); free( psz_variable ); free( psz_object ); if( b_need_release && p_object != NULL ) vlc_object_release( p_object ); } else { char *psz_variable = SSPop( st ); p_object = VLC_OBJECT(p_intf); i_type = config_GetType( p_object, psz_variable ); free( psz_variable ); } if( p_object != NULL ) { switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: psz_type = "VLC_VAR_BOOL"; break; case VLC_VAR_INTEGER: psz_type = "VLC_VAR_INTEGER"; break; case VLC_VAR_HOTKEY: psz_type = "VLC_VAR_HOTKEY"; break; case VLC_VAR_STRING: psz_type = "VLC_VAR_STRING"; break; case VLC_VAR_MODULE: psz_type = "VLC_VAR_MODULE"; break; case VLC_VAR_FILE: psz_type = "VLC_VAR_FILE"; break; case VLC_VAR_DIRECTORY: psz_type = "VLC_VAR_DIRECTORY"; break; case VLC_VAR_VARIABLE: psz_type = "VLC_VAR_VARIABLE"; break; case VLC_VAR_FLOAT: psz_type = "VLC_VAR_FLOAT"; break; default: psz_type = "UNDEFINED"; } } else psz_type = "INVALID"; SSPush( st, psz_type ); } else if( !strcmp( s, "vlc_var_set" ) ) { char *psz_object = SSPop( st ); char *psz_variable = SSPop( st ); bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); if( p_object != NULL ) { bool b_error = false; char *psz_value = NULL; vlc_value_t val; int i_type; i_type = var_Type( p_object, psz_variable ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: val.b_bool = SSPopN( st, vars ); msg_Dbg( p_intf, "requested %s var change: %s->%d", psz_object, psz_variable, val.b_bool ); break; case VLC_VAR_INTEGER: case VLC_VAR_HOTKEY: val.i_int = SSPopN( st, vars ); msg_Dbg( p_intf, "requested %s var change: %s->%d", psz_object, psz_variable, val.i_int ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: case VLC_VAR_VARIABLE: val.psz_string = psz_value = SSPop( st ); msg_Dbg( p_intf, "requested %s var change: %s->%s", psz_object, psz_variable, psz_value ); break; case VLC_VAR_FLOAT: psz_value = SSPop( st ); val.f_float = atof( psz_value ); msg_Dbg( p_intf, "requested %s var change: %s->%f", psz_object, psz_variable, val.f_float ); break; default: SSPopN( st, vars ); msg_Warn( p_intf, "invalid %s variable type %d (%s)", psz_object, i_type & VLC_VAR_TYPE, psz_variable ); b_error = true; } if( !b_error ) var_Set( p_object, psz_variable, val ); if( psz_value != NULL ) free( psz_value ); } else msg_Warn( p_intf, "vlc_var_set called without an object" ); free( psz_variable ); free( psz_object ); if( b_need_release && p_object != NULL ) vlc_object_release( p_object ); } else if( !strcmp( s, "vlc_var_get" ) ) { char *psz_object = SSPop( st ); char *psz_variable = SSPop( st ); bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); if( p_object != NULL ) { vlc_value_t val; int i_type; i_type = var_Type( p_object, psz_variable ); var_Get( p_object, psz_variable, &val ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: SSPushN( st, val.b_bool ); break; case VLC_VAR_INTEGER: case VLC_VAR_HOTKEY: SSPushN( st, val.i_int ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: case VLC_VAR_VARIABLE: SSPush( st, val.psz_string ); free( val.psz_string ); break; case VLC_VAR_FLOAT: { char psz_value[20]; lldiv_t value = lldiv( val.f_float * 1000000, 1000000 ); snprintf( psz_value, sizeof(psz_value), "%lld.%06u", value.quot, (unsigned int)value.rem ); SSPush( st, psz_value ); break; } default: msg_Warn( p_intf, "invalid %s variable type %d (%s)", psz_object, i_type & VLC_VAR_TYPE, psz_variable ); SSPush( st, "" ); } } else { msg_Warn( p_intf, "vlc_var_get called without an object" ); SSPush( st, "" ); } free( psz_variable ); free( psz_object ); if( b_need_release && p_object != NULL ) vlc_object_release( p_object ); } else if( !strcmp( s, "vlc_object_exists" ) ) { char *psz_object = SSPop( st ); bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); if( b_need_release && p_object != NULL ) vlc_object_release( p_object ); if( p_object != NULL ) SSPush( st, "1" ); else SSPush( st, "0" ); } else if( !strcmp( s, "vlc_config_set" ) ) { char *psz_variable = SSPop( st ); int i_type = config_GetType( p_intf, psz_variable ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: case VLC_VAR_INTEGER: config_PutInt( p_intf, psz_variable, SSPopN( st, vars ) ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: { char *psz_string = SSPop( st ); config_PutPsz( p_intf, psz_variable, psz_string ); free( psz_string ); break; } case VLC_VAR_FLOAT: { char *psz_string = SSPop( st ); config_PutFloat( p_intf, psz_variable, atof(psz_string) ); free( psz_string ); break; } default: msg_Warn( p_intf, "vlc_config_set called on unknown var (%s)", psz_variable ); } free( psz_variable ); } else if( !strcmp( s, "vlc_config_get" ) ) { char *psz_variable = SSPop( st ); int i_type = config_GetType( p_intf, psz_variable ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: case VLC_VAR_INTEGER: SSPushN( st, config_GetInt( p_intf, psz_variable ) ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: { char *psz_string = config_GetPsz( p_intf, psz_variable ); SSPush( st, psz_string ); free( psz_string ); break; } case VLC_VAR_FLOAT: { char psz_string[20]; lldiv_t value = lldiv( config_GetFloat( p_intf, psz_variable ) * 1000000, 1000000 ); snprintf( psz_string, sizeof(psz_string), "%lld.%06u", value.quot, (unsigned int)value.rem ); SSPush( st, psz_string ); break; } default: msg_Warn( p_intf, "vlc_config_get called on unknown var (%s)", psz_variable ); SSPush( st, "" ); } free( psz_variable ); } else if( !strcmp( s, "vlc_config_save" ) ) { char *psz_module = SSPop( st ); int i_result; if( !*psz_module ) { free( psz_module ); psz_module = NULL; } i_result = config_SaveConfigFile( p_intf, psz_module ); if( psz_module != NULL ) free( psz_module ); SSPushN( st, i_result ); } else if( !strcmp( s, "vlc_config_reset" ) ) { config_ResetAll( p_intf ); } /* 6. playlist functions */ else if( !strcmp( s, "playlist_add" ) ) { char *psz_name = SSPop( st ); char *mrl = SSPop( st ); input_item_t *p_input; int i_ret; p_input = MRLParse( p_intf, mrl, psz_name ); char *psz_uri = input_item_GetURI( p_input ); if( !p_input || !psz_uri || !*psz_uri ) { i_ret = VLC_EGENERIC; msg_Dbg( p_intf, "invalid requested mrl: %s", mrl ); } else { i_ret = playlist_AddInput( p_sys->p_playlist, p_input, PLAYLIST_APPEND, PLAYLIST_END, true, pl_Unlocked ); if( i_ret == VLC_SUCCESS ) { playlist_item_t *p_item; msg_Dbg( p_intf, "requested mrl add: %s", mrl ); playlist_Lock( p_sys->p_playlist ); p_item = playlist_ItemGetByInput( p_sys->p_playlist, p_input ); if( p_item ) i_ret = p_item->i_id; playlist_Unlock( p_sys->p_playlist ); } else msg_Warn( p_intf, "adding mrl %s failed", mrl ); vlc_gc_decref( p_input ); } free( psz_uri ); SSPushN( st, i_ret ); free( mrl ); free( psz_name ); } else if( !strcmp( s, "playlist_empty" ) ) { playlist_Clear( p_sys->p_playlist, pl_Unlocked ); msg_Dbg( p_intf, "requested playlist empty" ); } else if( !strcmp( s, "playlist_delete" ) ) { int i_id = SSPopN( st, vars ); playlist_Lock( p_sys->p_playlist ); playlist_item_t *p_item = playlist_ItemGetById( p_sys->p_playlist, i_id ); if( p_item ) { playlist_DeleteFromInput( p_sys->p_playlist, p_item->p_input, pl_Locked ); msg_Dbg( p_intf, "requested playlist delete: %d", i_id ); } else { msg_Dbg( p_intf, "couldn't find playlist item to delete (%d)", i_id ); } playlist_Unlock( p_sys->p_playlist ); } else if( !strcmp( s, "playlist_move" ) ) { /*int i_newpos =*/ SSPopN( st, vars ); /*int i_pos =*/ SSPopN( st, vars ); /* FIXME FIXME TODO TODO XXX XXX do not release before fixing this if ( i_pos < i_newpos ) { playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 ); } else { playlist_Move( p_sys->p_playlist, i_pos, i_newpos ); } msg_Dbg( p_intf, "requested to move playlist item %d to %d", i_pos, i_newpos); FIXME FIXME TODO TODO XXX XXX */ msg_Err( p_intf, "moving using indexes is obsolete. We need to update this function" ); } else if( !strcmp( s, "playlist_sort" ) ) { int i_order = SSPopN( st, vars ); int i_sort = SSPopN( st, vars ); i_order = i_order % 2; i_sort = i_sort % 9; /* FIXME FIXME TODO TODO XXX XXX do not release before fixing this playlist_RecursiveNodeSort( p_sys->p_playlist, p_sys->p_playlist->p_general, i_sort, i_order ); msg_Dbg( p_intf, "requested sort playlist by : %d in order : %d", i_sort, i_order ); FIXME FIXME TODO TODO XXX XXX */ msg_Err( p_intf, "this needs to be fixed to use the new playlist framework" ); } else if( !strcmp( s, "services_discovery_add" ) ) { char *psz_sd = SSPop( st ); playlist_ServicesDiscoveryAdd( p_sys->p_playlist, psz_sd ); free( psz_sd ); } else if( !strcmp( s, "services_discovery_remove" ) ) { char *psz_sd = SSPop( st ); playlist_ServicesDiscoveryRemove( p_sys->p_playlist, psz_sd ); free( psz_sd ); } else if( !strcmp( s, "services_discovery_is_loaded" ) ) { char *psz_sd = SSPop( st ); SSPushN( st, playlist_IsServicesDiscoveryLoaded( p_sys->p_playlist, psz_sd ) ); free( psz_sd ); } else if( !strcmp( s, "vlc_volume_set" ) ) { char *psz_vol = SSPop( st ); int i_value; audio_volume_t i_volume; aout_VolumeGet( p_intf, &i_volume ); if( psz_vol[0] == '+' ) { i_value = atoi( psz_vol ); if( (i_volume + i_value) > AOUT_VOLUME_MAX ) aout_VolumeSet( p_intf, AOUT_VOLUME_MAX ); else aout_VolumeSet( p_intf, i_volume + i_value ); } else if( psz_vol[0] == '-' ) { i_value = atoi( psz_vol ); if( (i_volume + i_value) < AOUT_VOLUME_MIN ) aout_VolumeSet( p_intf, AOUT_VOLUME_MIN ); else aout_VolumeSet( p_intf, i_volume + i_value ); } else if( strstr( psz_vol, "%") != NULL ) { i_value = atoi( psz_vol ); if( i_value < 0 ) i_value = 0; if( i_value > 400 ) i_value = 400; aout_VolumeSet( p_intf, (i_value * (AOUT_VOLUME_MAX - AOUT_VOLUME_MIN))/400+AOUT_VOLUME_MIN); } else { i_value = atoi( psz_vol ); if( i_value > AOUT_VOLUME_MAX ) i_value = AOUT_VOLUME_MAX; if( i_value < AOUT_VOLUME_MIN ) i_value = AOUT_VOLUME_MIN; aout_VolumeSet( p_intf, i_value ); } aout_VolumeGet( p_intf, &i_volume ); free( psz_vol ); } else if( !strcmp( s, "vlc_get_meta" ) ) { char *psz_meta = SSPop( st ); char *psz_val = NULL; if( p_sys->p_input && input_GetItem(p_sys->p_input) ) { #define p_item input_GetItem( p_sys->p_input ) if( !strcmp( psz_meta, "ARTIST" ) ) { psz_val = input_item_GetArtist( p_item ); } else if( !strcmp( psz_meta, "TITLE" ) ) { psz_val = input_item_GetTitle( p_item ); if( !psz_val ) psz_val = input_item_GetName( p_item ); } else if( !strcmp( psz_meta, "ALBUM" ) ) { psz_val = input_item_GetAlbum( p_item ); } else if( !strcmp( psz_meta, "GENRE" ) ) { psz_val = input_item_GetGenre( p_item ); } else if( !strcmp( psz_meta, "COPYRIGHT" ) ) { psz_val = input_item_GetCopyright( p_item ); } else if( !strcmp( psz_meta, "TRACK_NUMBER" ) ) { psz_val = input_item_GetTrackNum( p_item ); } else if( !strcmp( psz_meta, "DESCRIPTION" ) ) { psz_val = input_item_GetDescription( p_item ); } else if( !strcmp( psz_meta, "RATING" ) ) { psz_val = input_item_GetRating( p_item ); } else if( !strcmp( psz_meta, "DATE" ) ) { psz_val = input_item_GetDate( p_item ); } else if( !strcmp( psz_meta, "URL" ) ) { psz_val = input_item_GetURL( p_item ); } else if( !strcmp( psz_meta, "LANGUAGE" ) ) { psz_val = input_item_GetLanguage( p_item ); } else if( !strcmp( psz_meta, "NOW_PLAYING" ) ) { psz_val = input_item_GetNowPlaying( p_item ); } else if( !strcmp( psz_meta, "PUBLISHER" ) ) { psz_val = input_item_GetPublisher( p_item ); } else if( !strcmp( psz_meta, "ENCODED_BY" ) ) { psz_val = input_item_GetEncodedBy( p_item ); } else if( !strcmp( psz_meta, "ART_URL" ) ) { psz_val = input_item_GetEncodedBy( p_item ); } else if( !strcmp( psz_meta, "TRACK_ID" ) ) { psz_val = input_item_GetTrackID( p_item ); } #undef p_item } if( psz_val == NULL ) psz_val = strdup( "" ); SSPush( st, psz_val ); free( psz_meta ); free( psz_val ); } #ifdef ENABLE_VLM else if( !strcmp( s, "vlm_command" ) || !strcmp( s, "vlm_cmd" ) ) { char *psz_elt; char *psz_cmd = strdup( "" ); char *psz_error; vlm_message_t *vlm_answer; /* make sure that we have a vlm object */ if( p_intf->p_sys->p_vlm == NULL ) p_intf->p_sys->p_vlm = vlm_New( p_intf ); /* vlm command uses the ';' delimiter * (else we can't know when to stop) */ while( strcmp( psz_elt = SSPop( st ), "" ) && strcmp( psz_elt, ";" ) ) { char* psz_buf; if( asprintf( &psz_buf, "%s %s", psz_cmd, psz_elt ) == -1 ) psz_buf = NULL; free( psz_cmd ); free( psz_elt ); psz_cmd = psz_buf; } msg_Dbg( p_intf, "executing vlm command: %s", psz_cmd ); vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz_cmd, &vlm_answer ); if( vlm_answer->psz_value == NULL ) { psz_error = strdup( "" ); } else { if( asprintf( &psz_error , "%s : %s" , vlm_answer->psz_name, vlm_answer->psz_value ) == -1 ) psz_error = NULL; } mvar_AppendNewVar( vars, "vlm_error", psz_error ); /* this is kind of a duplicate but we need to have the message * without the command name for the "export" command */ mvar_AppendNewVar( vars, "vlm_value", vlm_answer->psz_value ); vlm_MessageDelete( vlm_answer ); free( psz_cmd ); free( psz_error ); } #endif /* ENABLE_VLM */ else if( !strcmp( s, "snapshot" ) ) { if( p_sys->p_input ) { vout_thread_t *p_vout = input_GetVout( p_sys->p_input ); if( p_vout ) { var_TriggerCallback( p_vout, "video-snapshot" ); vlc_object_release( p_vout ); msg_Dbg( p_intf, "requested snapshot" ); } } break; } else { SSPush( st, s ); } } }