X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Frss.c;h=885bfc9154a9f7314484a60af6eea545981e97ef;hb=396236ce7c5034845c15559d420ca82c3f24d56f;hp=f00eed1e36c12a7883fcc5ab4c3dff35475f6d95;hpb=d466fd4185ffd791413658e948205e2676d2f470;p=vlc diff --git a/modules/video_filter/rss.c b/modules/video_filter/rss.c index f00eed1e36..885bfc9154 100644 --- a/modules/video_filter/rss.c +++ b/modules/video_filter/rss.c @@ -1,25 +1,25 @@ /***************************************************************************** * rss.c : rss/atom feed display video plugin for vlc ***************************************************************************** - * Copyright (C) 2003-2006 the VideoLAN team + * Copyright (C) 2003-2006 VLC authors and VideoLAN * $Id$ * * Authors: Antoine Cellerier * Rémi Duraffort * - * 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 + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser 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. + * You should have received a copy of the GNU Lesser 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. *****************************************************************************/ /***************************************************************************** @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -167,6 +166,8 @@ struct filter_sys_t #define TITLE_TEXT N_("Title display mode") #define TITLE_LONGTEXT N_("Title display mode. Default is 0 (hidden) if the feed has an image and feed images are enabled, 1 otherwise.") +#define RSS_HELP N_("Display a RSS or ATOM Feed on your video") + static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 }; static const char *const ppsz_pos_descriptions[] = { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"), @@ -188,45 +189,47 @@ static const char *const ppsz_title_modes[] = * Module descriptor *****************************************************************************/ vlc_module_begin () - set_capability( "sub filter", 1 ) - set_shortname( "RSS / Atom" ) + set_capability( "sub source", 1 ) + set_shortname( N_("RSS / Atom") ) + set_help(RSS_HELP) set_callbacks( CreateFilter, DestroyFilter ) set_category( CAT_VIDEO ) set_subcategory( SUBCAT_VIDEO_SUBPIC ) - add_string( CFG_PREFIX "urls", NULL, NULL, MSG_TEXT, MSG_LONGTEXT, false ) + add_string( CFG_PREFIX "urls", NULL, MSG_TEXT, MSG_LONGTEXT, false ) set_section( N_("Position"), NULL ) - add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true ) - add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true ) - add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false ) - change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL ) + add_integer( CFG_PREFIX "x", 0, POSX_TEXT, POSX_LONGTEXT, true ) + add_integer( CFG_PREFIX "y", 0, POSY_TEXT, POSY_LONGTEXT, true ) + add_integer( CFG_PREFIX "position", -1, POS_TEXT, POS_LONGTEXT, false ) + change_integer_list( pi_pos_values, ppsz_pos_descriptions ) set_section( N_("Font"), NULL ) /* 5 sets the default to top [1] left [4] */ - add_integer_with_range( CFG_PREFIX "opacity", 255, 0, 255, NULL, + add_integer_with_range( CFG_PREFIX "opacity", 255, 0, 255, OPACITY_TEXT, OPACITY_LONGTEXT, false ) - add_integer( CFG_PREFIX "color", 0xFFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT, + add_rgb( CFG_PREFIX "color", 0xFFFFFF, COLOR_TEXT, COLOR_LONGTEXT, false ) - change_integer_list( pi_color_values, ppsz_color_descriptions, NULL ) - add_integer( CFG_PREFIX "size", -1, NULL, SIZE_TEXT, SIZE_LONGTEXT, false ) + change_integer_list( pi_color_values, ppsz_color_descriptions ) + add_integer( CFG_PREFIX "size", -1, SIZE_TEXT, SIZE_LONGTEXT, false ) + change_integer_range( -1, 4096) set_section( N_("Misc"), NULL ) - add_integer( CFG_PREFIX "speed", 100000, NULL, SPEED_TEXT, SPEED_LONGTEXT, + add_integer( CFG_PREFIX "speed", 100000, SPEED_TEXT, SPEED_LONGTEXT, + false ) + add_integer( CFG_PREFIX "length", 60, LENGTH_TEXT, LENGTH_LONGTEXT, false ) - add_integer( CFG_PREFIX "length", 60, NULL, LENGTH_TEXT, LENGTH_LONGTEXT, + add_integer( CFG_PREFIX "ttl", 1800, TTL_TEXT, TTL_LONGTEXT, false ) + add_bool( CFG_PREFIX "images", true, IMAGE_TEXT, IMAGE_LONGTEXT, false ) + add_integer( CFG_PREFIX "title", default_title, TITLE_TEXT, TITLE_LONGTEXT, false ) - add_integer( CFG_PREFIX "ttl", 1800, NULL, TTL_TEXT, TTL_LONGTEXT, false ) - add_bool( CFG_PREFIX "images", true, NULL, IMAGE_TEXT, IMAGE_LONGTEXT, false ) - add_integer( CFG_PREFIX "title", default_title, NULL, TITLE_TEXT, TITLE_LONGTEXT, false ) - change_integer_list( pi_title_modes, ppsz_title_modes, NULL ) + change_integer_list( pi_title_modes, ppsz_title_modes ) set_description( N_("RSS and Atom feed display") ) - add_shortcut( "rss" ) - add_shortcut( "atom" ) + add_shortcut( "rss", "atom" ) vlc_module_end () static const char *const ppsz_filter_options[] = { - "urls", "x", "y", "position", "color", "size", "speed", "length", + "urls", "x", "y", "position", "opacity", "color", "size", "speed", "length", "ttl", "images", "title", NULL }; @@ -286,13 +289,14 @@ static int CreateFilter( vlc_object_t *p_this ) p_sys->i_xoff = var_CreateGetInteger( p_filter, CFG_PREFIX "x" ); p_sys->i_yoff = var_CreateGetInteger( p_filter, CFG_PREFIX "y" ); p_sys->i_pos = var_CreateGetInteger( p_filter, CFG_PREFIX "position" ); - p_sys->p_style->i_font_alpha = 255 - var_CreateGetInteger( p_filter, CFG_PREFIX "opacity" ); + p_sys->p_style->i_font_alpha = var_CreateGetInteger( p_filter, CFG_PREFIX "opacity" ); p_sys->p_style->i_font_color = var_CreateGetInteger( p_filter, CFG_PREFIX "color" ); p_sys->p_style->i_font_size = var_CreateGetInteger( p_filter, CFG_PREFIX "size" ); if( p_sys->b_images && p_sys->p_style->i_font_size == -1 ) { - msg_Warn( p_filter, "rss-size wasn't specified. Feed images will thus be displayed without being resized" ); + msg_Warn( p_filter, "rss-size wasn't specified. Feed images will thus " + "be displayed without being resized" ); } /* Parse the urls */ @@ -301,7 +305,7 @@ static int CreateFilter( vlc_object_t *p_this ) /* Misc init */ vlc_mutex_init( &p_sys->lock ); - p_filter->pf_sub_filter = Filter; + p_filter->pf_sub_source = Filter; p_sys->last_date = (mtime_t)0; p_sys->b_fetched = false; @@ -370,7 +374,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) } if( p_sys->last_date - + ( p_sys->i_cur_char == 0 && p_sys->i_cur_item == ( p_sys->i_title == scroll_title ? -1 : 0 ) ? 5 : 1 ) + + ( p_sys->i_cur_char == 0 && + p_sys->i_cur_item == ( p_sys->i_title == scroll_title ? -1 : 0 ) ? 5 : 1 ) /* ( ... ? 5 : 1 ) means "wait 5 times more for the 1st char" */ * p_sys->i_speed > date ) { @@ -380,7 +385,10 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) p_sys->last_date = date; p_sys->i_cur_char++; - if( p_sys->i_cur_item == -1 ? p_sys->p_feeds[p_sys->i_cur_feed].psz_title[p_sys->i_cur_char] == 0 : p_sys->p_feeds[p_sys->i_cur_feed].p_items[p_sys->i_cur_item].psz_title[p_sys->i_cur_char] == 0 ) + + if( p_sys->i_cur_item == -1 ? + p_sys->p_feeds[p_sys->i_cur_feed].psz_title[p_sys->i_cur_char] == 0 : + p_sys->p_feeds[p_sys->i_cur_feed].p_items[p_sys->i_cur_item].psz_title[p_sys->i_cur_char] == 0 ) { p_sys->i_cur_char = 0; p_sys->i_cur_item++; @@ -406,7 +414,7 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) p_spu->p_region = subpicture_region_New( &fmt ); if( !p_spu->p_region ) { - p_filter->pf_sub_buffer_del( p_filter, p_spu ); + subpicture_Delete( p_spu ); vlc_mutex_unlock( &p_sys->lock ); return NULL; } @@ -481,7 +489,7 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) /* where to locate the string: */ if( p_sys->i_pos < 0 ) { /* set to an absolute xy */ - p_spu->p_region->i_align = OSD_ALIGN_LEFT | OSD_ALIGN_TOP; + p_spu->p_region->i_align = SUBPICTURE_ALIGN_LEFT | SUBPICTURE_ALIGN_TOP; p_spu->b_absolute = true; } else @@ -489,6 +497,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) p_spu->p_region->i_align = p_sys->i_pos; p_spu->b_absolute = false; } + p_spu->p_region->i_x = p_sys->i_xoff; + p_spu->p_region->i_y = p_sys->i_yoff; p_spu->p_region->p_style = text_style_Duplicate( p_sys->p_style ); @@ -514,15 +524,15 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) } else { - p_region->i_x = p_sys->i_xoff; - p_region->i_y = p_sys->i_yoff; + p_region->i_x = p_spu->p_region->i_x; + p_region->i_y = p_spu->p_region->i_y; /* FIXME the copy is probably not needed anymore */ picture_Copy( p_region->p_picture, p_pic ); p_spu->p_region->p_next = p_region; - } - /* Offset text to display right next to the image */ - p_spu->p_region->i_x = p_pic->p[Y_PLANE].i_visible_pitch; + /* Offset text to display right next to the image */ + p_spu->p_region->i_x += fmt_out.i_visible_width; + } } vlc_mutex_unlock( &p_sys->lock ); @@ -676,32 +686,29 @@ static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader, rss_feed_t *p_feed ) { VLC_UNUSED(p_filter); + const char *node; char *psz_eltname = NULL; bool b_is_item = false; bool b_is_image = false; int i_item = 0; + int type; - while( xml_ReaderRead( p_xml_reader ) == 1 ) + while( (type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 ) { - switch( xml_ReaderNodeType( p_xml_reader ) ) + switch( type ) { - // Error - case -1: - goto end; - case XML_READER_STARTELEM: - free( psz_eltname ); - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - goto end; - #ifdef RSS_DEBUG - msg_Dbg( p_filter, "element name: %s", psz_eltname ); + msg_Dbg( p_filter, "element <%s>", node ); #endif + psz_eltname = strdup( node ); + if( unlikely(!psz_eltname) ) + goto end; + /* rss or atom */ - if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) ) + if( !strcmp( node, "item" ) || !strcmp( node, "entry" ) ) { b_is_item = true; p_feed->i_items++; @@ -712,34 +719,29 @@ static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader, p_feed->p_items[p_feed->i_items-1].psz_link = NULL; } /* rss */ - else if( !strcmp( psz_eltname, "image" ) ) + else if( !strcmp( node, "image" ) ) { b_is_image = true; } /* atom */ - else if( !strcmp( psz_eltname, "link" ) ) + else if( !strcmp( node, "link" ) ) { + const char *name, *value; char *psz_href = NULL; char *psz_rel = NULL; - while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) + + while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) != NULL ) { - char *psz_name = xml_ReaderName( p_xml_reader ); - char *psz_value = xml_ReaderValue( p_xml_reader ); - if( !strcmp( psz_name, "rel" ) ) + if( !strcmp( name, "rel" ) ) { free( psz_rel ); - psz_rel = psz_value; + psz_rel = strdup( value ); } - else if( !strcmp( psz_name, "href" ) ) + else if( !strcmp( name, "href" ) ) { free( psz_href ); - psz_href = psz_value; - } - else - { - free( psz_value ); + psz_href = strdup( value ); } - free( psz_name ); } /* "rel" and "href" must be defined */ @@ -772,42 +774,32 @@ static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader, break; case XML_READER_ENDELEM: - free( psz_eltname ); - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - goto end; - + FREENULL( psz_eltname ); #ifdef RSS_DEBUG - msg_Dbg( p_filter, "element end : %s", psz_eltname ); + msg_Dbg( p_filter, "element end ", node ); #endif /* rss or atom */ - if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) ) + if( !strcmp( node, "item" ) || !strcmp( node, "entry" ) ) { b_is_item = false; i_item++; } /* rss */ - else if( !strcmp( psz_eltname, "image" ) ) + else if( !strcmp( node, "image" ) ) { b_is_image = false; } - FREENULL( psz_eltname ); break; case XML_READER_TEXT: { if( !psz_eltname ) break; - char *psz_eltvalue = xml_ReaderValue( p_xml_reader ); - if( !psz_eltvalue ) - goto end; - char *psz_clean = removeWhiteChars( psz_eltvalue ); - free( psz_eltvalue ); - psz_eltvalue = psz_clean; + char *psz_eltvalue = removeWhiteChars( node ); #ifdef RSS_DEBUG - msg_Dbg( p_filter, " text : <%s>", psz_eltvalue ); + msg_Dbg( p_filter, " text : \"%s\"", psz_eltvalue ); #endif /* Is it an item ? */ if( b_is_item ) @@ -883,7 +875,6 @@ static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader, return true; end: - free( psz_eltname ); return false; } @@ -964,7 +955,7 @@ static rss_feed_t* FetchRSS( filter_t *p_filter ) } msg_Dbg( p_filter, "done with %s RSS/Atom feed", p_feed->psz_url ); - xml_ReaderDelete( p_xml, p_xml_reader ); + xml_ReaderDelete( p_xml_reader ); stream_Delete( p_stream ); } @@ -974,7 +965,7 @@ static rss_feed_t* FetchRSS( filter_t *p_filter ) error: FreeRSS( p_feeds, i_feed + 1 ); if( p_xml_reader ) - xml_ReaderDelete( p_xml, p_xml_reader ); + xml_ReaderDelete( p_xml_reader ); if( p_stream ) stream_Delete( p_stream ); if( p_xml )