From: Antoine Cellerier Date: Thu, 2 Feb 2006 17:29:06 +0000 (+0000) Subject: src/*, include/* : update core functions. (Should make it relatively easy X-Git-Tag: 0.9.0-test0~12514 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=bcf427725c9ac014faf5a637feb01bd4c38a4f21;p=vlc src/*, include/* : update core functions. (Should make it relatively easy to use in interfaces) The downloadable plugins part still needs some work. modules/control/rc.c : add function to query updates (mainly used for testing) modules/gui/wxwidgets/* : update pannel. --- diff --git a/Makefile.am b/Makefile.am index 6306d66040..0c36d11056 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,6 +131,7 @@ HEADERS_include = \ include/vlc_symbols.h \ include/vlc_threads_funcs.h \ include/vlc_threads.h \ + include/vlc_update.h \ include/vlc_video.h \ include/vlc_vlm.h \ include/vlc_vod.h \ @@ -466,6 +467,7 @@ SOURCES_libvlc_common = \ src/misc/objects.c \ src/misc/variables.c \ src/misc/error.c \ + src/misc/update.c \ src/misc/vlm.c \ src/misc/xml.c \ src/misc/version.c \ diff --git a/include/vlc_common.h b/include/vlc_common.h index 77670e2ddb..3f16671f93 100644 --- a/include/vlc_common.h +++ b/include/vlc_common.h @@ -416,12 +416,16 @@ typedef struct vlm_schedule_t vlm_schedule_t; /* divers */ typedef struct vlc_meta_t vlc_meta_t; +/* Stats */ typedef struct counter_t counter_t; typedef struct counter_sample_t counter_sample_t; typedef struct stats_handler_t stats_handler_t; typedef struct input_stats_t input_stats_t; typedef struct global_stats_t global_stats_t; +/* Update */ +typedef struct update_t update_t; +typedef struct update_iterator_t update_iterator_t; /***************************************************************************** * Variable callbacks diff --git a/include/vlc_symbols.h b/include/vlc_symbols.h index 804f536ff3..190850f47e 100644 --- a/include/vlc_symbols.h +++ b/include/vlc_symbols.h @@ -84,6 +84,7 @@ void __intf_UserHide (vlc_object_t *, int); int __config_LoadConfigFile (vlc_object_t *, const char *); int vlc_asprintf (char **, const char *, ...); int __var_Change (vlc_object_t *, const char *, int, vlc_value_t *, vlc_value_t *); +update_iterator_t * update_iterator_New (update_t *); int playlist_Disable (playlist_t *, playlist_item_t *); char * vlc_input_item_GetInfo (input_item_t *p_i, const char *psz_cat,const char *psz_name); int vout_VarCallback (vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void *); @@ -91,6 +92,7 @@ session_descriptor_t* sout_AnnounceSessionCreate (void); void __osd_Volume (vlc_object_t *); int vlc_vasprintf (char **, const char *, va_list); int playlist_Sort (playlist_t *, int, int); +void update_Check (update_t *, vlc_bool_t); int aout_DecDelete (aout_instance_t *, aout_input_t *); int vlc_strcasecmp (const char *s1, const char *s2); sout_packetizer_input_t * sout_InputNew (sout_instance_t *, es_format_t *); @@ -136,6 +138,7 @@ stream_t * __stream_UrlNew (vlc_object_t *p_this, const char *psz_url); sout_mux_t * sout_MuxNew (sout_instance_t*, char *, sout_access_out_t *); stream_t * __stream_DemuxNew (vlc_object_t *p_obj, char *psz_demux, es_out_t *out); int vout_ShowTextRelative (vout_thread_t *, int, char *, text_style_t *, int, int, int, mtime_t); +unsigned int update_iterator_Action (update_iterator_t *, int); void __stats_TimerDump (vlc_object_t*, const char *); int block_FifoPut (block_fifo_t *, block_t *); int playlist_ItemAddParent (playlist_item_t *, int,playlist_item_t *); @@ -161,6 +164,7 @@ int httpd_UrlCatch (httpd_url_t *, int i_msg, httpd_callback_t, httpd_callback_s void __vlc_object_yield (vlc_object_t *); const char * VLC_CompileBy (void); playlist_item_t * playlist_LockItemGetByPos (playlist_t *, int); +void update_Delete (update_t *); input_thread_t * __input_CreateThread (vlc_object_t *, input_item_t *); const char * DecodeLanguage (uint16_t); int __aout_VolumeSet (vlc_object_t *, audio_volume_t); @@ -220,6 +224,7 @@ void __stats_ComputeGlobalStats (vlc_object_t*,global_stats_t*); char * vlc_strndup (const char *s, size_t n); void vout_PlacePicture (vout_thread_t *, unsigned int, unsigned int, unsigned int *, unsigned int *, unsigned int *, unsigned int *); float __config_GetFloat (vlc_object_t *, const char *); +void update_iterator_Delete (update_iterator_t *); playlist_item_t * playlist_ItemGetById (playlist_t *, int); const char * vlc_gai_strerror (int); void net_ListenClose (int *fd); @@ -345,6 +350,7 @@ int playlist_PreparseEnqueue (playlist_t *, input_item_t *); aout_buffer_t * aout_FifoPop (aout_instance_t * p_aout, aout_fifo_t * p_fifo); int __vout_InitPicture (vlc_object_t *p_this, picture_t *p_pic, uint32_t i_chroma, int i_width, int i_height, int i_aspect); int playlist_LockClear (playlist_t *); +unsigned int update_iterator_ChooseMirrorAndFile (update_iterator_t *, int, int, int); void intf_InteractionManage (playlist_t *); char * mstrtime (char *psz_buffer, mtime_t date); void aout_FormatPrepare (audio_sample_format_t * p_format); @@ -356,6 +362,7 @@ xml_t * __xml_Create (vlc_object_t *); msg_subscription_t* __msg_Subscribe (vlc_object_t *, int); const char * VLC_Version (void); session_descriptor_t* sout_AnnounceRegisterSDP (sout_instance_t *,const char *, const char *, announce_method_t*); +update_t * __update_New (vlc_object_t *); char * stream_ReadLine (stream_t *); int playlist_PreparseEnqueueItem (playlist_t *, playlist_item_t *); void __osd_MenuPrev (vlc_object_t *); @@ -364,6 +371,7 @@ module_t * config_FindModule (vlc_object_t *, const char *); void aout_VolumeSoftInit (aout_instance_t *); void block_FifoRelease (block_fifo_t *); void block_FifoEmpty (block_fifo_t *); +void update_download (update_iterator_t *, char *); int playlist_ItemAddOption (playlist_item_t *, const char *); void aout_VolumeNoneInit (aout_instance_t *); void aout_DateInit (audio_date_t *, uint32_t); @@ -903,6 +911,14 @@ struct module_symbols_t void (*__stats_ComputeGlobalStats_inner) (vlc_object_t*,global_stats_t*); void (*__stats_TimerStop_inner) (vlc_object_t*, const char *); void (*__stats_TimersDumpAll_inner) (vlc_object_t*); + update_iterator_t * (*update_iterator_New_inner) (update_t *); + void (*update_Check_inner) (update_t *, vlc_bool_t); + unsigned int (*update_iterator_Action_inner) (update_iterator_t *, int); + void (*update_Delete_inner) (update_t *); + void (*update_iterator_Delete_inner) (update_iterator_t *); + unsigned int (*update_iterator_ChooseMirrorAndFile_inner) (update_iterator_t *, int, int, int); + update_t * (*__update_New_inner) (vlc_object_t *); + void (*update_download_inner) (update_iterator_t *, char *); }; # if defined (__PLUGIN__) # define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner @@ -1339,6 +1355,14 @@ struct module_symbols_t # define __stats_ComputeGlobalStats (p_symbols)->__stats_ComputeGlobalStats_inner # define __stats_TimerStop (p_symbols)->__stats_TimerStop_inner # define __stats_TimersDumpAll (p_symbols)->__stats_TimersDumpAll_inner +# define update_iterator_New (p_symbols)->update_iterator_New_inner +# define update_Check (p_symbols)->update_Check_inner +# define update_iterator_Action (p_symbols)->update_iterator_Action_inner +# define update_Delete (p_symbols)->update_Delete_inner +# define update_iterator_Delete (p_symbols)->update_iterator_Delete_inner +# define update_iterator_ChooseMirrorAndFile (p_symbols)->update_iterator_ChooseMirrorAndFile_inner +# define __update_New (p_symbols)->__update_New_inner +# define update_download (p_symbols)->update_download_inner # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__) /****************************************************************** * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access. @@ -1778,6 +1802,14 @@ struct module_symbols_t ((p_symbols)->__stats_ComputeGlobalStats_inner) = __stats_ComputeGlobalStats; \ ((p_symbols)->__stats_TimerStop_inner) = __stats_TimerStop; \ ((p_symbols)->__stats_TimersDumpAll_inner) = __stats_TimersDumpAll; \ + ((p_symbols)->update_iterator_New_inner) = update_iterator_New; \ + ((p_symbols)->update_Check_inner) = update_Check; \ + ((p_symbols)->update_iterator_Action_inner) = update_iterator_Action; \ + ((p_symbols)->update_Delete_inner) = update_Delete; \ + ((p_symbols)->update_iterator_Delete_inner) = update_iterator_Delete; \ + ((p_symbols)->update_iterator_ChooseMirrorAndFile_inner) = update_iterator_ChooseMirrorAndFile; \ + ((p_symbols)->__update_New_inner) = __update_New; \ + ((p_symbols)->update_download_inner) = update_download; \ (p_symbols)->net_ConvertIPv4_deprecated = NULL; \ (p_symbols)->__stats_CounterGet_deprecated = NULL; \ (p_symbols)->__stats_TimerDumpAll_deprecated = NULL; \ diff --git a/include/vlc_update.h b/include/vlc_update.h new file mode 100644 index 0000000000..d4ecbdcd15 --- /dev/null +++ b/include/vlc_update.h @@ -0,0 +1,171 @@ +/***************************************************************************** + * vlc_update.h: VLC update and plugins download + ***************************************************************************** + * Copyright (C) 2005 the VideoLAN team + * $Id: $ + * + * Authors: Antoine Cellerier + * + * 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 release 2 of the License, or + * (at your option) any later release. + * + * 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. + *****************************************************************************/ + +#ifndef _VLC_UPDATE_H +#define _VLC_UPDATE_H + +#include + +#define UPDATE_FILE_TYPE_ALL (~0) +#define UPDATE_FILE_TYPE_NONE 0 + +#define UPDATE_FILE_TYPE_UNDEF 1 +#define UPDATE_FILE_TYPE_INFO 2 +#define UPDATE_FILE_TYPE_SOURCE 4 +#define UPDATE_FILE_TYPE_BINARY 8 +#define UPDATE_FILE_TYPE_PLUGIN 16 + +#define UPDATE_RELEASE_STATUS_ALL (~0) +#define UPDATE_RELEASE_STATUS_NONE 0 + +#define UPDATE_RELEASE_STATUS_OLDER 1 +#define UPDATE_RELEASE_STATUS_EQUAL 2 +#define UPDATE_RELEASE_STATUS_NEWER 4 + +#define UPDATE_RELEASE_TYPE_STABLE 1 +#define UPDATE_RELEASE_TYPE_TESTING 2 +#define UPDATE_RELEASE_TYPE_UNSTABLE 4 + +#define UPDATE_FAIL 0 +#define UPDATE_SUCCESS 1 +#define UPDATE_NEXT 0 +#define UPDATE_PREV 2 +#define UPDATE_MIRROR 4 +#define UPDATE_RELEASE 8 +#define UPDATE_FILE 16 +#define UPDATE_RESET 32 + +/** + * Describes an update file + */ +struct update_file_t +{ + int i_type; //< File type + char* psz_md5; //< MD5 hash + long int l_size; //< File size in bytes + char* psz_url; //< Relative (to a mirror) or absolute url + char* psz_description; //< Plain text description +}; + +/** + * Describes an update VLC release number + */ +struct update_release_t +{ + char* psz_major; //< Version major string + char* psz_minor; //< Version minor string + char* psz_revision; //< Version revision string + char* psz_extra; //< Version extra string + + char* psz_svn_revision; //< SVN revision + + int i_type; //< Release type + + int i_status; //< Release status compared to current VLC version + + struct update_file_t* p_files; //< Files list + int i_files; //< Number of files in the files list +}; + +/** + * Describes a mirror + */ +struct update_mirror_t +{ + char *psz_name; //< Mirror name + char *psz_location; //< Mirror geographical location + char *psz_type; //< Mirror type (FTP, HTTP, ...) + + char *psz_base_url; //< Mirror base url + +}; + +/** + * The update object. Stores (and caches) all information relative to updates + */ +struct update_t +{ + vlc_t *p_vlc; + + vlc_mutex_t lock; + + struct update_release_t *p_releases; //< Releases (version) list + int i_releases; //< Number of releases + vlc_bool_t b_releases; //< True if we have a releases list + + struct update_mirror_t *p_mirrors; //< Mirrors list + int i_mirrors; //< Number of mirrors + vlc_bool_t b_mirrors; //< True if we have a mirrors list +}; + +/** + * The update iterator structure. Usefull to browse the update object seamlessly + */ +struct update_iterator_t +{ + update_t *p_u; //< Pointer to VLC update object + + int i_r; //< Position in the releases list + int i_f; //< Position in the release's files list + int i_m; //< Position in the mirrors list + + int i_t; //< File type bitmask + int i_rs; //< Release status bitmask + int i_rt; //< Release type bitmask + + struct + { + int i_type; //< Type + char* psz_md5; //< MD5 hash + long int l_size; //< Size in bytes + char* psz_url; //< Absolute URL + char* psz_description; //< Description + } file; //< Local 'copy' of the current file's information + struct + { + char *psz_version; //< Version string + char *psz_svn_revision; //< SVN revision + int i_status; //< Status + int i_type; //< Type + } release; //< Local 'copy' of the current release's information + struct + { + char *psz_name; //< Name + char *psz_location; //< Geographical location + char *psz_type; //< Type (HTTP, FTP, ...) + } mirror; //< Local 'copy' of the current mirror's information +}; + +#define update_New( a ) __update_New( VLC_OBJECT( a ) ) + +VLC_EXPORT( update_t *, __update_New, ( vlc_object_t * ) ); +VLC_EXPORT( void, update_Delete, (update_t * ) ); +VLC_EXPORT( void, update_Check, ( update_t *, vlc_bool_t ) ); + +VLC_EXPORT( update_iterator_t *, update_iterator_New, ( update_t * ) ); +VLC_EXPORT( void, update_iterator_Delete, ( update_iterator_t * ) ); +VLC_EXPORT( unsigned int, update_iterator_Action, ( update_iterator_t *, int ) ); +VLC_EXPORT( unsigned int, update_iterator_ChooseMirrorAndFile, ( update_iterator_t *, int, int, int ) ); +VLC_EXPORT( void, update_download, ( update_iterator_t *, char * ) ); + +#endif diff --git a/modules/control/rc.c b/modules/control/rc.c index 2d4d4bf005..5d366c58e7 100644 --- a/modules/control/rc.c +++ b/modules/control/rc.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H # include @@ -95,6 +96,7 @@ static int AudioConfig ( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); static int Menu ( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); +static void checkUpdates( intf_thread_t *p_intf, char *psz_arg ); /* Status Callbacks */ static int TimeOffsetChanged( vlc_object_t *, char const *, @@ -350,7 +352,7 @@ static void Deactivate( vlc_object_t *p_this ) #endif free( p_intf->p_sys->psz_unix_path ); } - vlc_mutex_destroy( &p_intf->p_sys->status_lock ); + vlc_mutex_destroy( &p_intf->p_sys->status_lock ); free( p_intf->p_sys ); } @@ -459,7 +461,7 @@ static void RegisterCallbacks( intf_thread_t *p_intf ) /* OSD menu commands */ var_Create( p_intf, "menu", VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); - var_AddCallback( p_intf, "menu", Menu, NULL ); + var_AddCallback( p_intf, "menu", Menu, NULL ); /* DVD commands */ var_Create( p_intf, "pause", VLC_VAR_VOID | VLC_VAR_ISCOMMAND ); @@ -793,6 +795,10 @@ static void Run( intf_thread_t *p_intf ) Help( p_intf, b_longhelp ); } + else if( !strcmp( psz_cmd, "check-updates" ) ) + { + checkUpdates( p_intf, psz_arg ); + } else switch( psz_cmd[0] ) { case 'f': @@ -944,6 +950,9 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp) msg_rc(_("| mosaic-cols #. . . . . . . . . . .number of cols")); msg_rc(_("| mosaic-keep-aspect-ratio {0,1} . . .aspect ratio")); msg_rc( "| "); + msg_rc(_("| check-updates [newer] [equal] [older]\n" + "| [undef] [info] [source] [binary] [plugin]")); + msg_rc( "| "); } msg_rc(_("| help . . . . . . . . . . . . . this help message")); msg_rc(_("| longhelp . . . . . . . . . a longer help message")); @@ -1245,7 +1254,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd, if( p_playlist->p_input ) { vlc_value_t val; - + var_Get( p_playlist->p_input, "rate", &val ); if( val.i_int != INPUT_RATE_DEFAULT ) { @@ -1260,10 +1269,10 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd, } else if (!strcmp( psz_cmd, "goto" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); - playlist_Goto( p_playlist, val.i_int); + playlist_Goto( p_playlist, val.i_int); } } else if( !strcmp( psz_cmd, "stop" ) ) @@ -1387,7 +1396,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, val.psz_string = newval.psz_string; var_Set( p_input->p_libvlc, "marq-marquee", val ); } - else + else { val.psz_string = ""; var_Set( p_input->p_libvlc, "marq-marquee", val); @@ -1395,7 +1404,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-x" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "marq-x", val ); @@ -1403,7 +1412,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-y" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "marq-y", val ); @@ -1411,7 +1420,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-position" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "marq-position", val ); @@ -1419,7 +1428,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-color" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = strtol( newval.psz_string, NULL, 0 ); var_Set( p_input->p_libvlc, "marq-color", val ); @@ -1427,7 +1436,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-opacity" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = strtol( newval.psz_string, NULL, 0 ); var_Set( p_input->p_libvlc, "marq-opacity", val ); @@ -1435,7 +1444,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-size" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "marq-size", val ); @@ -1443,7 +1452,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "marq-timeout" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input, "marq-timeout", val ); @@ -1552,7 +1561,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, val.psz_string = newval.psz_string; var_Set( p_input->p_libvlc, "time-format", val ); } - else + else { val.psz_string = ""; var_Set( p_input->p_libvlc, "time-format", val); @@ -1560,7 +1569,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-x" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "time-x", val ); @@ -1568,7 +1577,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-y" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "time-y", val ); @@ -1576,7 +1585,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-position" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "time-position", val ); @@ -1584,7 +1593,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-color" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = strtol( newval.psz_string, NULL, 0 ); var_Set( p_input->p_libvlc, "time-color", val ); @@ -1592,7 +1601,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-opacity" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = strtol( newval.psz_string, NULL, 0 ); var_Set( p_input->p_libvlc, "time-opacity", val ); @@ -1600,7 +1609,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "time-size" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "time-size", val ); @@ -1616,7 +1625,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "logo-x" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "logo-x", val ); @@ -1624,7 +1633,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "logo-y" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "logo-y", val ); @@ -1632,7 +1641,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "logo-position" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = atoi( newval.psz_string ); var_Set( p_input->p_libvlc, "logo-position", val ); @@ -1640,7 +1649,7 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd, } else if( !strcmp( psz_cmd, "logo-transparency" ) ) { - if( strlen( newval.psz_string ) > 0) + if( strlen( newval.psz_string ) > 0) { val.i_int = strtol( newval.psz_string, NULL, 0 ); var_Set( p_input->p_libvlc, "logo-transparency", val ); @@ -2150,3 +2159,120 @@ static playlist_item_t *parse_MRL( intf_thread_t *p_intf, char *psz_mrl ) return p_item; } + +/***************************************************************************** + * checkUpdates : check for updates + ****************************************************************************/ +static void checkUpdates( intf_thread_t *p_intf, char *psz_arg ) +{ + update_iterator_t *p_uit; + update_t *p_u = update_New( p_intf ); + if( p_u == NULL ) return; + p_uit = update_iterator_New( p_u ); + if( p_uit ) + { + int s = 0, t = 0; + + if( strstr( psz_arg, "newer" ) ) + s |= UPDATE_RELEASE_STATUS_NEWER; + if( strstr( psz_arg, "equal" ) ) + s |= UPDATE_RELEASE_STATUS_EQUAL; + if( strstr( psz_arg, "older" ) ) + s |= UPDATE_RELEASE_STATUS_OLDER; + if( s ) p_uit->i_rs = s; + else p_uit->i_rs = UPDATE_RELEASE_STATUS_NEWER; + + if( strstr( psz_arg, "undef" ) ) + t |= UPDATE_FILE_TYPE_UNDEF; + if( strstr( psz_arg, "info" ) ) + t |= UPDATE_FILE_TYPE_INFO; + if( strstr( psz_arg, "source" ) ) + t |= UPDATE_FILE_TYPE_SOURCE; + if( strstr( psz_arg, "binary" ) ) + t |= UPDATE_FILE_TYPE_BINARY; + if( strstr( psz_arg, "plugin" ) ) + t |= UPDATE_FILE_TYPE_PLUGIN; + if( t ) p_uit->i_t = t; + + update_Check( p_u, VLC_FALSE ); + update_iterator_Action( p_uit, UPDATE_MIRROR ); + msg_rc( "\nUsing mirror: %s (%s) [%s]", + p_uit->mirror.psz_name, + p_uit->mirror.psz_location, + p_uit->mirror.psz_type ); + while( (s = update_iterator_Action( p_uit, UPDATE_FILE )) != UPDATE_FAIL ) + { + char *psz_tmp; + if( s & UPDATE_RELEASE ) + { + switch( p_uit->release.i_status ) + { + case UPDATE_RELEASE_STATUS_OLDER: + psz_tmp = strdup( "older" ); + break; + case UPDATE_RELEASE_STATUS_EQUAL: + psz_tmp = strdup( "equal" ); + break; + case UPDATE_RELEASE_STATUS_NEWER: + psz_tmp = strdup( "newer" ); + break; + default: + psz_tmp = strdup( "?!?" ); + break; + } + msg_rc( "\n+----[ VLC %s %s (%s) ] ", + p_uit->release.psz_version, + p_uit->release.psz_svn_revision, + psz_tmp ); + free( psz_tmp ); + } + switch( p_uit->file.i_type ) + { + case UPDATE_FILE_TYPE_UNDEF: + psz_tmp = strdup( "undef" ); + break; + case UPDATE_FILE_TYPE_INFO: + psz_tmp = strdup( "info" ); + break; + case UPDATE_FILE_TYPE_SOURCE: + psz_tmp = strdup( "source" ); + break; + case UPDATE_FILE_TYPE_BINARY: + psz_tmp = strdup( "binary" ); + break; + case UPDATE_FILE_TYPE_PLUGIN: + psz_tmp = strdup( "plugin" ); + break; + default: + psz_tmp = strdup( "?!?" ); + break; + } + msg_rc( "| %s (%s)", p_uit->file.psz_description, psz_tmp ); + free( psz_tmp ); + if( p_uit->file.l_size ) + { + if( p_uit->file.l_size > 1024 * 1024 * 1024 ) + asprintf( &psz_tmp, "(%ld GB)", + p_uit->file.l_size / (1024*1024*1024) ); + if( p_uit->file.l_size > 1024 * 1024 ) + asprintf( &psz_tmp, "(%ld MB)", + p_uit->file.l_size / (1024*1024) ); + else if( p_uit->file.l_size > 1024 ) + asprintf( &psz_tmp, "(%ld kB)", + p_uit->file.l_size / 1024 ); + else + asprintf( &psz_tmp, "(%ld B)", p_uit->file.l_size ); + } + else + { + psz_tmp = strdup( "" ); + } + msg_rc( "| %s %s", p_uit->file.psz_url, psz_tmp ); + msg_rc( "+----" ); + free( psz_tmp ); + } + msg_rc( "" ); + update_iterator_Delete( p_uit ); + } + update_Delete( p_u ); +} diff --git a/modules/gui/wxwidgets/bitmaps/update_ascii.xpm b/modules/gui/wxwidgets/bitmaps/update_ascii.xpm new file mode 100644 index 0000000000..5eef12358e --- /dev/null +++ b/modules/gui/wxwidgets/bitmaps/update_ascii.xpm @@ -0,0 +1,133 @@ +/* XPM */ +static char * update_ascii_xpm[] = { +"34 34 96 2", +" c None", +". c #BCBCBC", +"+ c #F7F7F7", +"@ c #F3F3F3", +"# c #F1F1F1", +"$ c #EFEFEF", +"% c #ECECEC", +"& c #EAEAEA", +"* c #E9E9E9", +"= c #C2C2C2", +"- c #808080", +"; c #FFFFFF", +"> c #FEFEFE", +", c #FBFBFB", +"' c #F2F2F2", +") c #EEEEEE", +"! c #E3E3E3", +"~ c #BDBDBD", +"{ c #C0C0C0", +"] c #BBBBBB", +"^ c #B6B6B6", +"/ c #AFAFAF", +"( c #A2A2A2", +"_ c #8E8E8E", +": c #828282", +"< c #FCFCFC", +"[ c #F8F8F8", +"} c #AEAEAE", +"| c #A9A9A9", +"1 c #9E9E9E", +"2 c #C4C4C4", +"3 c #BABABA", +"4 c #CACACA", +"5 c #C9C9C9", +"6 c #B5B5B5", +"7 c #F9F9F9", +"8 c #E0E0E0", +"9 c #CCCCCC", +"0 c #BEBEBE", +"a c #FDFDFD", +"b c #FAFAFA", +"c c #F5F5F5", +"d c #BFBFBF", +"e c #A0A0A0", +"f c #D5D5D5", +"g c #C6C6C6", +"h c #F4F4F4", +"i c #C1C1C1", +"j c #E1E1E1", +"k c #DBDBDB", +"l c #CECECE", +"m c #F6F6F6", +"n c #D4D4D4", +"o c #E4E4E4", +"p c #DEDEDE", +"q c #D1D1D1", +"r c #EBEBEB", +"s c #B8B8B8", +"t c #B7B7B7", +"u c #DCDCDC", +"v c #D3D3D3", +"w c #F0F0F0", +"x c #E8E8E8", +"y c #868686", +"z c #DADADA", +"A c #D2D2D2", +"B c #E7E7E7", +"C c #878787", +"D c #888888", +"E c #E5E5E5", +"F c #E2E2E2", +"G c #D7D7D7", +"H c #DFDFDF", +"I c #D0D0D0", +"J c #E6E6E6", +"K c #DDDDDD", +"L c #767676", +"M c #777777", +"N c #CDCDCD", +"O c #EDEDED", +"P c #D8D8D8", +"Q c #B9B9B9", +"R c #D6D6D6", +"S c #B3B3B3", +"T c #CBCBCB", +"U c #CFCFCF", +"V c #787878", +"W c #ACACAC", +"X c #A6A6A6", +"Y c #9D9D9D", +"Z c #9A9A9A", +"` c #969696", +" . c #919191", +".. c #8C8C8C", +"+. c #848484", +"@. c #818181", +" ", +" . . . . . . . . . . . . . . . . ", +" . + + + + + + + + @ # $ % & * = - ", +" . + ; ; ; ; ; ; ; ; > ; , ' ) = ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; , ' = ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; , = ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; ~ { ] ^ / ( _ : - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; < [ # } | 1 2 / - ", +" . + ; ; ; ; ; ; ; ; ; ; ; ; ; ; , ' ] 3 4 5 6 - ", +" . + ; ; ; ; ; ; ; ; ; ; ; ; < 7 + $ ~ 1 8 9 0 - ", +" . + ; ; ; ; ; ; ; ; ; ; a b + c # $ d e 8 f g - ", +" . + ; ; ; ; ; ; ; ; ; b [ + h # $ ) i ( j k l - ", +" . + ; ; ; ; ; ; ; < 7 + m @ ' $ $ & n o ! p q - ", +" . + ; ; ; ; ; ; , 7 [ c c ' $ $ r * s t n u v - ", +" . + ; ; ; ; ; , b [ m c ' w $ % * x 3 y 8 z A - ", +" . + ; ; ; ; < < [ [ m @ # $ % * x B ] C 8 u q - ", +" . + ; ; ; ; , b + m @ # $ % * x B o . D 8 z A - ", +" . + ; ; ; , b + c h # $ % * * E o F n 8 8 G q - ", +" . + ; ; , 7 [ c @ # ) % & x E o j H ^ 6 u f I - ", +" . + ; , 7 + c ' w ) % & B J ! j H K t L 8 n l - ", +" . + ; 7 m h ' w ) r * x o ! j p K k t M 8 n N - ", +" . + b m h ' w O r * x o F j p K k P Q M 8 q l - ", +" Q + [ h # $ O r * B J F j p u k P R n 8 8 N N - ", +" 6 + c # $ O r * B J F 8 p u k G R v Q s H 4 9 - ", +" S + @ $ O r * B o ! 8 p u z G f v q Q M 8 4 T - ", +" / + # O r * B o F 8 K u z G f v I U s V 8 4 5 - ", +" W + ) r * B o ! F 8 u k P n n q q N Q V 8 4 5 - ", +" | + x J ! j H u z P R n n A I U l N n ! 8 5 5 - ", +" | X ( Y Z ` ...D +.@.- - - - - - - - - - - - - ", +" ", +" "}; diff --git a/modules/gui/wxwidgets/bitmaps/update_binary.xpm b/modules/gui/wxwidgets/bitmaps/update_binary.xpm new file mode 100644 index 0000000000..3ace9ae6b0 --- /dev/null +++ b/modules/gui/wxwidgets/bitmaps/update_binary.xpm @@ -0,0 +1,329 @@ +/* XPM */ +static char * update_binary_xpm[] = { +"34 34 292 2", +" c None", +". c #BCBCBC", +"+ c #F7F7F7", +"@ c #F3F3F3", +"# c #F1F1F1", +"$ c #EFEFEF", +"% c #ECECEC", +"& c #EAEAEA", +"* c #E9E9E9", +"= c #C2C2C2", +"- c #808080", +"; c #FFFFFF", +"> c #FEFEFE", +", c #FBFBFB", +"' c #F2F2F2", +") c #EEEEEE", +"! c #E3E3E3", +"~ c #647EAA", +"{ c #5B77A6", +"] c #6584AD", +"^ c #718DB3", +"/ c #5F7FAA", +"( c #6080AB", +"_ c #5C7AA7", +": c #6684AC", +"< c #5D7EAA", +"[ c #6E97BD", +"} c #6F98BE", +"| c #6082AD", +"1 c #F6F6F8", +"2 c #FDFDFD", +"3 c #BDBDBD", +"4 c #C0C0C0", +"5 c #BBBBBB", +"6 c #B6B6B6", +"7 c #AFAFAF", +"8 c #A2A2A2", +"9 c #8E8E8E", +"0 c #828282", +"a c #FBFCFD", +"b c #5A79A7", +"c c #6081AB", +"d c #6385AE", +"e c #688CB1", +"f c #7CA1C3", +"g c #799FC2", +"h c #D8E2ED", +"i c #F5F6F7", +"j c #F9F9F9", +"k c #F8F8F8", +"l c #DBDBDB", +"m c #D0D0D0", +"n c #C4C4C4", +"o c #5975A4", +"p c #607BA8", +"q c #5C78A7", +"r c #6587AE", +"s c #7298BF", +"t c #7CA2C5", +"u c #84A7C7", +"v c #8AABC9", +"w c #D7E2EC", +"x c #5D7BA8", +"y c #E8E8E8", +"z c #E2E2E2", +"A c #D8D8D8", +"B c #C9C9C9", +"C c #B5B5B5", +"D c #5D7DA8", +"E c #C3D4E4", +"F c #E3EBF2", +"G c #DCE6EF", +"H c #B7CBDE", +"I c #80A4C5", +"J c #96B4CF", +"K c #9CB8D3", +"L c #ABC2D8", +"M c #E1E2E5", +"N c #EEEFF0", +"O c #EBEBEB", +"P c #E4E4E4", +"Q c #DADADA", +"R c #CCCCCC", +"S c #BEBEBE", +"T c #A9C1D8", +"U c #E6EDF3", +"V c #B0C5DB", +"W c #91B1CE", +"X c #A0BAD3", +"Y c #98B6D1", +"Z c #9EB9D3", +"` c #A6BFD7", +" . c #ADC4DA", +".. c #C1D2E2", +"+. c #DDE7F0", +"@. c #7F9AB8", +"#. c #E0E1E3", +"$. c #EBEBEC", +"%. c #D5D5D5", +"&. c #C6C6C6", +"*. c #B9CDE0", +"=. c #D4E0EB", +"-. c #97B5D0", +";. c #749CC1", +">. c #6386AE", +",. c #5771A2", +"'. c #A7C0D8", +"). c #B1C6DC", +"!. c #BBCEE0", +"~. c #CBDAE8", +"{. c #D1DEEA", +"]. c #718DB1", +"^. c #E5E5E6", +"/. c #E7E7E7", +"(. c #DEDEDE", +"_. c #CECECE", +":. c #E0E8F1", +"<. c #5976A6", +"[. c #6279A5", +"}. c #B7BBC4", +"|. c #B9BDC5", +"1. c #B2C8DD", +"2. c #C9D8E6", +"3. c #DFE8F0", +"4. c #6082AB", +"5. c #D5D6D9", +"6. c #E1E1E2", +"7. c #E0E0E0", +"8. c #D1D1D1", +"9. c #D9E4EE", +"0. c #A4BED7", +"a. c #BABEC7", +"b. c #BFC3CB", +"c. c #C2C5CC", +"d. c #6182AE", +"e. c #D0DEE9", +"f. c #C6D5E5", +"g. c #8DAECC", +"h. c #5A76A5", +"i. c #D5D6D8", +"j. c #E5E5E5", +"k. c #DCDCDC", +"l. c #D3D3D3", +"m. c #668AAF", +"n. c #86A9C9", +"o. c #B5BAC3", +"p. c #BEC2CA", +"q. c #C9CCD2", +"r. c #D1D3D8", +"s. c #D9DBDF", +"t. c #94B3CF", +"u. c #5A78A5", +"v. c #C9CACE", +"w. c #D2D2D2", +"x. c #C4D5E5", +"y. c #B8BCC5", +"z. c #CED1D7", +"A. c #DEDFE3", +"B. c #EAEBED", +"C. c #7AA0C3", +"D. c #6589AE", +"E. c #BEC0C6", +"F. c #DFDFDF", +"G. c #5F80AA", +"H. c #6D94BC", +"I. c #698EB4", +"J. c #CEDCE9", +"K. c #678BB0", +"L. c #BDC1C9", +"M. c #E4E6E9", +"N. c #EFF0F1", +"O. c #DBE5EE", +"P. c #E6ECF3", +"Q. c #5972A1", +"R. c #A8ACB4", +"S. c #B8BBC1", +"T. c #81A5C6", +"U. c #A3BCD4", +"V. c #637AA6", +"W. c #C6C9D0", +"X. c #DEE0E4", +"Y. c #EEEFF1", +"Z. c #F5F7FA", +"`. c #6177A3", +" + c #A5A9B2", +".+ c #ABAFB7", +"++ c #BBBEC3", +"@+ c #DDDDDD", +"#+ c #D7D7D7", +"$+ c #9AB6D1", +"%+ c #6382AB", +"&+ c #CBCED4", +"*+ c #D6E1EB", +"=+ c #EBF1F6", +"-+ c #CCDAE9", +";+ c #ABAEB6", +">+ c #B7BABF", +",+ c #C7C9CC", +"'+ c #A3BDD6", +")+ c #AEC5DB", +"!+ c #EFF2F6", +"~+ c #F6F9FB", +"{+ c #A4A8B1", +"]+ c #B8BBC0", +"^+ c #D2D3D4", +"/+ c #D4D4D4", +"(+ c #5E7EA9", +"_+ c #B4C9DD", +":+ c #BECFE1", +"<+ c #EAF0F5", +"[+ c #F9FBFC", +"}+ c #FCFDFD", +"|+ c #657EA7", +"1+ c #B3B6BC", +"2+ c #C6C7CB", +"3+ c #D6D6D6", +"4+ c #CDCDCD", +"5+ c #C2D3E3", +"6+ c #D1DFEA", +"7+ c #E4ECF3", +"8+ c #ACC3D9", +"9+ c #E9EEF4", +"0+ c #85A8C8", +"a+ c #BBBDC2", +"b+ c #CDCED0", +"c+ c #D4D5D5", +"d+ c #9BB7D2", +"e+ c #B6B9BE", +"f+ c #CACBCD", +"g+ c #D3D3D4", +"h+ c #F2F6F9", +"i+ c #6079A4", +"j+ c #A3A7AF", +"k+ c #B0B3B8", +"l+ c #C6C7C9", +"m+ c #CFD0D0", +"n+ c #CACACA", +"o+ c #B4B8C0", +"p+ c #93B2CE", +"q+ c #A3A7B0", +"r+ c #A1A5AE", +"s+ c #A1A5AD", +"t+ c #A5A8B0", +"u+ c #B3B5BA", +"v+ c #C5C6C8", +"w+ c #CECECF", +"x+ c #CBCBCB", +"y+ c #909398", +"z+ c #BFC2C9", +"A+ c #B8BBC3", +"B+ c #82A6C7", +"C+ c #5771A1", +"D+ c #ADB1B7", +"E+ c #B0B3B9", +"F+ c #AFB2B8", +"G+ c #AEB0B6", +"H+ c #BFC1C4", +"I+ c #C9CACB", +"J+ c #9D9EA1", +"K+ c #D6D8DC", +"L+ c #C9CCD1", +"M+ c #BDBFC6", +"N+ c #A5A9B1", +"O+ c #B7BAC0", +"P+ c #C2C3C7", +"Q+ c #C7C9CB", +"R+ c #C6C7CA", +"S+ c #C3C4C7", +"T+ c #CACACB", +"U+ c #CFCFCF", +"V+ c #A4A5A5", +"W+ c #EBEBED", +"X+ c #DADBDD", +"Y+ c #CDCFD2", +"Z+ c #BABCC2", +"`+ c #A7ABB2", +" @ c #B3B6BB", +".@ c #C2C4C7", +"+@ c #CDCDCF", +"@@ c #D0D1D1", +"#@ c #CECFCF", +"$@ c #CDCDCE", +"%@ c #A8A8A8", +"&@ c #A4A4A5", +"*@ c #9F9FA0", +"=@ c #969798", +"-@ c #8B8D90", +";@ c #7E8086", +">@ c #777A7F", +",@ c #76797E", +"'@ c #7B7C80", +")@ c #7F7F81", +" ", +" . . . . . . . . . . . . . . . . ", +" . + + + + + + + + @ # $ % & * = - ", +" . + ; ; ; ; ; ; ; ; > ; , ' ) = ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; , ' = ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; , = ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ! ; ; - ", +" . + ; ; ; ~ { ; ; ; ] ^ ; ; ; = ! ! ! ! ; ; - ", +" . + ; ; { / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 - ", +" . + a b ( c | d e } f g h | i j k # * l m n 7 - ", +" o p q < / ( c r s t u v w u x i j ' y z A B C - ", +" o D / x r E F G H I u J K L v { M N ) O P Q R S - ", +" { / _ T U V W I I X Y Z ` ...+.@.#.$.O ! l %.&.- ", +" _ D *.=.-.;.>.( { ,.*.'.).!.E ~.{.].^.& /.(.l _.- ", +" _ ( } :.J [ c <.[.}.|.| 1.!.E 2.3.w 4.5.6./.7.(.8.- ", +" _ c ( 9.0.s c o }.a.b.c.d.!.E e.+.G f.g.h.i.j.z k.l.- ", +"_ c | m.G n.d.o o.p.q.r.s.>.f.{.+.2.'.t.u u.v.z 7.Q w.- ", +"_ d.d g.x.} _ y.b.z.A.B.r f.{.+.f.Z C.D.c o E.F.F.k.8.- ", +"G.d.H.I.J.K.o L.z.M.N.r f.=.O.P.'.g | x Q.R.S.k.k.Q w.- ", +" / ;.T.U.I.V.W.X.Y.r 2.w 9.F Z.K D.D `. +.+++@+#+#+8.- ", +" ( u W $+` %+&+>.D.J.*+O.F =+; -+c ,. +;+>+,+l %.%.m - ", +" ( W $+'+)+..>.E J.w :.U !+~+; h ( {+;+]+,+^+A #+/+_.- ", +"(+t.Y '+V _+:+x.{.9.U <+[+}+; x.T -.|+1+2+^+3+3+/+/+4+- ", +" c x.J...5+2.6+O.7+f.8+` 9+e.'.0+m._ a+b+c+3+l.w.8._.- ", +" d.J g.*+6+9.<+E d+C.K.r t.t.D./ ,.e+f+g+l.w.m 4+4+- ", +" < _ W F h+:.0.f | D ,.i+b _ ,.j+k+l+m+8.m R n+R - ", +" ,.o+[ e.5+p+r D `.q+q+j+r+s+t+u+v+w+m x+x+n+x+- ", +" y+z+A+( v B+( C+{+R.D+E+F+G+u+H+I+_.x+x+x+n+B - ", +" J+K+L+M+o u.o N+.+O+P+Q+R+S+l+T+U+4+R n+n+n+B - ", +" V+W+X+Y+Z+;+N+`+ @.@+@m @@#@$@_._.4+R x+B B B - ", +" %@&@*@=@-@;@>@,@'@)@- - - - - - - - - - - - - - ", +" ", +" "}; diff --git a/modules/gui/wxwidgets/bitmaps/update_document.xpm b/modules/gui/wxwidgets/bitmaps/update_document.xpm new file mode 100644 index 0000000000..5c193965dc --- /dev/null +++ b/modules/gui/wxwidgets/bitmaps/update_document.xpm @@ -0,0 +1,139 @@ +/* XPM */ +static char * update_document_xpm[] = { +"34 34 102 2", +" c None", +". c #BCBCBC", +"+ c #F7F7F7", +"@ c #F3F3F3", +"# c #F1F1F1", +"$ c #EFEFEF", +"% c #ECECEC", +"& c #EAEAEA", +"* c #E9E9E9", +"= c #C2C2C2", +"- c #808080", +"; c #FFFFFF", +"> c #FEFEFE", +", c #FBFBFB", +"' c #F2F2F2", +") c #EEEEEE", +"! c #B2B2B2", +"~ c #E3E3E3", +"{ c #B1B1B1", +"] c #BDBDBD", +"^ c #C0C0C0", +"/ c #B6B6B6", +"( c #AFAFAF", +"_ c #A2A2A2", +": c #8E8E8E", +"< c #828282", +"[ c #EDEDED", +"} c #E2E2E2", +"| c #DBDBDB", +"1 c #D0D0D0", +"2 c #C4C4C4", +"3 c #FAFAFA", +"4 c #F4F4F4", +"5 c #D8D8D8", +"6 c #C9C9C9", +"7 c #B5B5B5", +"8 c #E6E6E6", +"9 c #DCDCDC", +"0 c #DADADA", +"a c #CCCCCC", +"b c #BEBEBE", +"c c #ADADAD", +"d c #A8A8A8", +"e c #EBEBEB", +"f c #DFDFDF", +"g c #D7D7D7", +"h c #D5D5D5", +"i c #C6C6C6", +"j c #F9F9F9", +"k c #F6F6F6", +"l c #E7E7E7", +"m c #CECECE", +"n c #AEAEAE", +"o c #ABABAB", +"p c #AAAAAA", +"q c #A4A4A4", +"r c #9F9F9F", +"s c #D1D1D1", +"t c #F8F8F8", +"u c #E0E0E0", +"v c #DEDEDE", +"w c #D3D3D3", +"x c #A6A6A6", +"y c #A5A5A5", +"z c #D2D2D2", +"A c #F5F5F5", +"B c #A1A1A1", +"C c #CBCBCB", +"D c #C8C8C8", +"E c #9D9D9D", +"F c #ACACAC", +"G c #E5E5E5", +"H c #E4E4E4", +"I c #9C9C9C", +"J c #DDDDDD", +"K c #A3A3A3", +"L c #E1E1E1", +"M c #9A9A9A", +"N c #A7A7A7", +"O c #A0A0A0", +"P c #9E9E9E", +"Q c #9B9B9B", +"R c #989898", +"S c #D4D4D4", +"T c #CDCDCD", +"U c #F0F0F0", +"V c #E8E8E8", +"W c #D6D6D6", +"X c #B9B9B9", +"Y c #969696", +"Z c #959595", +"` c #939393", +" . c #B3B3B3", +".. c #999999", +"+. c #919191", +"@. c #CACACA", +"#. c #CFCFCF", +"$. c #A9A9A9", +"%. c #8C8C8C", +"&. c #888888", +"*. c #848484", +"=. c #818181", +" . . . . . . . . . . . . . . . . ", +" . + + + + + + + + @ # $ % & * = - ", +" . + ; ; ; ; ; ; ; ; > ; , ' ) = ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; , ' = ; ; - ", +" . + ; ! ! ! ; ; ; ; > ; ; ; , = ~ ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ~ ~ ; ; - ", +" . + ; ! ! ! ! ! ! ! { ! ! ; ; = ~ ~ ~ ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ~ ~ ~ ~ ; ; - ", +" . + ; ! ! ! ! ! ! ! { ! ! ; ; ] ^ . / ( _ : < - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; , [ } * | 1 2 ( - ", +" . + ; ! ! ! ! ! ! ! ! ! ! ; ; ; 3 4 ~ ~ 5 6 7 - ", +" . + ; ; ; ; ; ; ; ; ; ; ; ; ; 3 3 ' 8 9 0 a b - ", +" . + ; ! ! ! ! ! ! ! ! ! ! ! ( c d d e f g h i - ", +" . + ; ; ; ; ; ; ; ; ; ; ; , j k $ $ [ l | 0 m - ", +" . + ; ! ! ! ! ! ! ! ! ! n c o p d q q r } 5 s - ", +" . + ; ; ; ; ; ; ; ; ; 3 t k 4 # $ * * l u v w - ", +" . + ; ! ! ! ! ! ! ! n c o p d x y q r r } 9 z - ", +" . + ; ; ; ; ; ; > 3 t A @ ' $ [ e * } } u 0 s - ", +" . + ; ! ! ! ! { c c o @ d x y q _ B r f f 9 z - ", +" . + ; ; ; ; , 3 + k @ # x C C 6 D i E 9 9 0 s - ", +" . + ; ! ! ( n F o p d $ q e * G H } I J g g 1 - ", +" . + ; ; , j t A @ # ) % K * G H L f M | h h m - ", +" . + ; ( c F o d N x q & B O P E Q M R 5 g S T - ", +" . + ; j k 4 ' U ) e * V H ~ L v J | 5 W S S m - ", +" X + 3 o p d N y q _ B r E E M M R Y Z ` z s T - ", +" 7 + t 4 # $ [ e * l 8 } L v 9 | 5 W w z 1 T a - ", +" .+ A d x y q _ B O E I M ..R Y Z ` +.+.a @.C - ", +" ( + @ $ [ e * l H ~ u v 9 0 g h w s 1 C C @.6 - ", +" F + # y e _ B H } u J 9 0 g h w 1 #.C C C @.6 - ", +" F + ) e * l H ~ } u 9 | 5 S S s s T a @.@.@.6 - ", +" $.+ V 8 ~ L f 9 0 5 W S S z 1 #.m T a C 6 6 6 - ", +" $.x _ E M Y +.%.&.*.=.- - - - - - - - - - - - - ", +" ", +" "}; diff --git a/modules/gui/wxwidgets/bitmaps/update_info.xpm b/modules/gui/wxwidgets/bitmaps/update_info.xpm new file mode 100644 index 0000000000..3f99ce86d2 --- /dev/null +++ b/modules/gui/wxwidgets/bitmaps/update_info.xpm @@ -0,0 +1,308 @@ +/* XPM */ +static char * update_info_xpm[] = { +"34 34 271 2", +" c None", +". c #BCBCBC", +"+ c #F7F7F7", +"@ c #F3F3F3", +"# c #F1F1F1", +"$ c #EFEFEF", +"% c #ECECEC", +"& c #EAEAEA", +"* c #E9E9E9", +"= c #C2C2C2", +"- c #808080", +"; c #FFFFFF", +"> c #FEFEFE", +", c #FBFBFB", +"' c #F2F2F2", +") c #EEEEEE", +"! c #E3E3E3", +"~ c #BDBDBD", +"{ c #C0C0C0", +"] c #BBBBBB", +"^ c #B6B6B6", +"/ c #AFAFAF", +"( c #A2A2A2", +"_ c #8E8E8E", +": c #828282", +"< c #FCFCFC", +"[ c #F8F8F8", +"} c #DBDBDB", +"| c #D0D0D0", +"1 c #C4C4C4", +"2 c #F0F1F4", +"3 c #D5DAE9", +"4 c #B2BFD9", +"5 c #9DACCF", +"6 c #E8E8E8", +"7 c #E2E2E2", +"8 c #D8D8D8", +"9 c #C9C9C9", +"0 c #B5B5B5", +"a c #F7F8FA", +"b c #C8D0E2", +"c c #8FA9DA", +"d c #789ED7", +"e c #87AFDF", +"f c #98BCE4", +"g c #8CA7D8", +"h c #C2CBDC", +"i c #E7E8EA", +"j c #EBEBEB", +"k c #E4E4E4", +"l c #DADADA", +"m c #CCCCCC", +"n c #BEBEBE", +"o c #ADBFE1", +"p c #85A9DB", +"q c #97BBE4", +"r c #AFC6E8", +"s c #B0C7E9", +"t c #AEC5E7", +"u c #A8C2E5", +"v c #92B0E1", +"w c #7F9DD7", +"x c #A5B4D4", +"y c #DDDFE1", +"z c #D5D5D5", +"A c #C6C6C6", +"B c #F7F8FB", +"C c #AFC0E3", +"D c #87ABDC", +"E c #A2BCE3", +"F c #A5BEE4", +"G c #9EBDE3", +"H c #9AB8E1", +"I c #99B9E0", +"J c #92B3E1", +"K c #91B1E0", +"L c #78A2D6", +"M c #A2B6D6", +"N c #E0E1E3", +"O c #DEDEDE", +"P c #CECECE", +"Q c #CAD6EA", +"R c #89ADDB", +"S c #87AADE", +"T c #79A2DA", +"U c #6C9CD7", +"V c #678FD2", +"W c #5F8CD0", +"X c #5886D3", +"Y c #618CD2", +"Z c #6890D3", +"` c #76A1D7", +" . c #7196D2", +".. c #B7C0D4", +"+. c #D1D1D1", +"@. c #F1F3F7", +"#. c #93B0DE", +"$. c #6C93D6", +"%. c #638ED4", +"&. c #5381CE", +"*. c #4472C5", +"=. c #3868C1", +"-. c #3262BB", +";. c #FDFDFD", +">. c #2047A9", +",. c #325CB3", +"'. c #3666BD", +"). c #386DC5", +"!. c #4678CB", +"~. c #4A7ACC", +"{. c #7998C9", +"]. c #D5D7DA", +"^. c #DCDCDC", +"/. c #D3D3D3", +"(. c #D4DCEC", +"_. c #6187CC", +":. c #4674C9", +"<. c #3867BD", +"[. c #2F56AE", +"}. c #2951A2", +"|. c #274996", +"1. c #264895", +"2. c #183289", +"3. c #254492", +"4. c #254897", +"5. c #2A509D", +"6. c #2D55A6", +"7. c #4B6CB6", +"8. c #B9BFCF", +"9. c #D2D2D2", +"0. c #A9B7D5", +"a. c #3A62B5", +"b. c #2A57AB", +"c. c #264F9B", +"d. c #26448F", +"e. c #223D83", +"f. c #203A7D", +"g. c #1E3879", +"h. c #1F3974", +"i. c #122871", +"j. c #1F3A7E", +"k. c #214388", +"l. c #2E4E98", +"m. c #949EB9", +"n. c #95A4C8", +"o. c #203E83", +"p. c #11276E", +"q. c #1B346E", +"r. c #1A336D", +"s. c #1C376F", +"t. c #1F3D7F", +"u. c #808CAC", +"v. c #8E9AB4", +"w. c #2F55AC", +"x. c #2D53A2", +"y. c #183593", +"z. c #1C3473", +"A. c #79839D", +"B. c #D7D7D7", +"C. c #9CA7C0", +"D. c #274286", +"E. c #3261B7", +"F. c #3464BB", +"G. c #244376", +"H. c #838EA3", +"I. c #C4CAD8", +"J. c #38538D", +"K. c #4C7FCB", +"L. c #4A78CB", +"M. c #406FC5", +"N. c #2654BB", +"O. c #284AB7", +"P. c #34497F", +"Q. c #A9AFBB", +"R. c #D4D4D4", +"S. c #E5E7ED", +"T. c #697C9F", +"U. c #8CAEE1", +"V. c #7CA5DD", +"W. c #739BD8", +"X. c #3C61C1", +"Y. c #4275C9", +"Z. c #596990", +"`. c #C3C5CA", +" + c #CDCDCD", +".+ c #FAFAFA", +"++ c #B4BDCE", +"@+ c #4C6DB8", +"#+ c #D3DCF0", +"$+ c #CDDAEE", +"%+ c #C4D6EF", +"&+ c #BBD3EC", +"*+ c #8FA3D6", +"=+ c #859DD4", +"-+ c #7C97CF", +";+ c #6F8BD0", +">+ c #7DA8DE", +",+ c #3D5591", +"'+ c #9CA4B5", +")+ c #B9B9B9", +"!+ c #F4F4F4", +"~+ c #E7E9ED", +"{+ c #919EB6", +"]+ c #4772BF", +"^+ c #CDDAEF", +"/+ c #EDF3F8", +"(+ c #EAF2F9", +"_+ c #E7EEF8", +":+ c #E5EBF6", +"<+ c #E0E9F5", +"[+ c #DBE6F4", +"}+ c #D6E1F1", +"|+ c #92B3E0", +"1+ c #39589E", +"2+ c #818DA6", +"3+ c #CACBCF", +"4+ c #F5F5F5", +"5+ c #DADDE5", +"6+ c #8F9CB7", +"7+ c #618BCF", +"8+ c #B4C8E8", +"9+ c #F7F8FC", +"0+ c #F1F4FA", +"a+ c #F1F2FA", +"b+ c #F2F6FB", +"c+ c #DFE8F4", +"d+ c #9EBDE2", +"e+ c #4D75BF", +"f+ c #8290A9", +"g+ c #C1C4CB", +"h+ c #CACACA", +"i+ c #B3B3B3", +"j+ c #EDEDED", +"k+ c #E0E2E6", +"l+ c #ACB4C8", +"m+ c #6A85BA", +"n+ c #658ED2", +"o+ c #7BA5D9", +"p+ c #A5C0E6", +"q+ c #729FD7", +"r+ c #628BCF", +"s+ c #647CB2", +"t+ c #9EA6BA", +"u+ c #C9CBCF", +"v+ c #CBCBCB", +"w+ c #E7E7E7", +"x+ c #D0D3D9", +"y+ c #B3BCCE", +"z+ c #8E9EC1", +"A+ c #7F8BAD", +"B+ c #7E8AAC", +"C+ c #8A9BBD", +"D+ c #ABB3C6", +"E+ c #C2C6CC", +"F+ c #CFCFCF", +"G+ c #ACACAC", +"H+ c #E0E0E0", +"I+ c #A9A9A9", +"J+ c #E6E6E6", +"K+ c #E1E1E1", +"L+ c #DFDFDF", +"M+ c #D6D6D6", +"N+ c #A6A6A6", +"O+ c #9D9D9D", +"P+ c #9A9A9A", +"Q+ c #969696", +"R+ c #919191", +"S+ c #8C8C8C", +"T+ c #888888", +"U+ c #848484", +"V+ c #818181", +" ", +" . . . . . . . . . . . . . . . . ", +" . + + + + + + + + @ # $ % & * = - ", +" . + ; ; ; ; ; ; ; ; > ; , ' ) = ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; , ' = ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; , = ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; = ! ! ! ! ; ; - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; ~ { ] ^ / ( _ : - ", +" . + ; ; ; ; ; ; ; ; > ; ; ; ; < [ # * } | 1 / - ", +" . + ; ; ; ; ; < 2 3 4 5 5 4 3 2 [ ' 6 7 8 9 0 - ", +" . + ; ; ; ; a b c d e f f e d g h i j k l m n - ", +" . + ; ; ; 2 o p q r s s r t u v w x y ! } z A - ", +" . + ; ; B C D E F G H I J K J I J L M N O } P - ", +" . + ; < Q R K S T U V W X X Y Z U ` ...O O +.- ", +" . + ; @.#.$.%.&.*.=.-.;.;.>.,.'.).!.~.{.].^./.- ", +" . + ; (._.:.<.[.}.|.1.;.;.2.3.4.5.6.,.7.8.l 9.- ", +" . + ; 0.a.b.c.d.e.f.g.h.i.i.h.g.j.k.3.l.m.^.+.- ", +" . + ; n.c.c.d.k.o.f.;.;.;.p.q.r.s.h.f.t.u.l 9.- ", +" . + ; v.k.w.b.x.}.}.5.;.< y.4.4.1.3.d.z.A.B.+.- ", +" . + ; C.D.E.F.F.-.E.,.< < >.[.b.6.6.}.G.H.z | - ", +" . + ; I.J.=.K.L.:.*.M.< < N.O.=.<.'.6.P.Q.R.P - ", +" . + ; S.T.*.K U.V.W.< < < < X.K.L.Y.}.Z.`.R. +- ", +" . + .+@ ++@+u #+$+%+&+*+=+-+;+>+W.*.,+'+| +.P - ", +" )++ [ !+~+{+]+^+/+(+_+:+<+[+}+$+|+1+2+3+| + +- ", +" 0 + 4+# $ 5+6+7+8+_+9+0+a+b+c+d+e+f+g+| m h+m - ", +" i++ @ $ j+j k+l+m+n+o+p+p+q+r+s+t+u+| v+v+h+v+- ", +" / + # j+j * w+7 x+y+z+A+B+C+D+E+P F+v+v+v+h+9 - ", +" G++ ) j * w+k ! 7 H+^.} 8 R.R.+.+. +m h+h+h+9 - ", +" I++ 6 J+! K+L+^.l 8 M+R.R.9.| F+P +m v+9 9 9 - ", +" I+N+( O+P+Q+R+S+T+U+V+- - - - - - - - - - - - - ", +" ", +" "}; diff --git a/modules/gui/wxwidgets/bitmaps/update_source.xpm b/modules/gui/wxwidgets/bitmaps/update_source.xpm new file mode 100644 index 0000000000..7b7552bbd7 --- /dev/null +++ b/modules/gui/wxwidgets/bitmaps/update_source.xpm @@ -0,0 +1,180 @@ +/* XPM */ +static char * update_source_xpm[] = { +"34 34 143 2", +" c None", +". c #BCBCBC", +"+ c #F7F7F7", +"@ c #F3F3F3", +"# c #F1F1F1", +"$ c #EFEFEF", +"% c #ECECEC", +"& c #EAEAEA", +"* c #E9E9E9", +"= c #C2C2C2", +"- c #808080", +"; c #FFFFFF", +"> c #003377", +", c #CEDBEB", +"' c #FBFBFB", +") c #F2F2F2", +"! c #EEEEEE", +"~ c #BFD0E5", +"{ c #E3E3E3", +"] c #FEFEFE", +"^ c #004F33", +"/ c #BDCEE4", +"( c #C2E1CF", +"_ c #CCE6D7", +": c #B6DBC5", +"< c #BDBDBD", +"[ c #C0C0C0", +"} c #B6B6B6", +"| c #AFAFAF", +"1 c #A2A2A2", +"2 c #8E8E8E", +"3 c #828282", +"4 c #008437", +"5 c #EDEDED", +"6 c #E2E2E2", +"7 c #DBDBDB", +"8 c #D0D0D0", +"9 c #C4C4C4", +"0 c #BCDDCA", +"a c #B9DBC7", +"b c #CEE4D7", +"c c #FAFAFA", +"d c #F4F4F4", +"e c #D8D8D8", +"f c #C9C9C9", +"g c #B5B5B5", +"h c #C5E0D0", +"i c #B7D8C5", +"j c #E6E6E6", +"k c #DCDCDC", +"l c #DADADA", +"m c #CCCCCC", +"n c #BEBEBE", +"o c #BCDDC9", +"p c #C6E0D1", +"q c #F9F9F9", +"r c #EBEBEB", +"s c #DFDFDF", +"t c #D7D7D7", +"u c #D5D5D5", +"v c #C6C6C6", +"w c #F6F6F6", +"x c #E7E7E7", +"y c #CECECE", +"z c #767676", +"A c #8B8B8B", +"B c #9F9F9F", +"C c #B3B3B3", +"D c #C7C7C7", +"E c #9E9E9E", +"F c #898989", +"G c #616161", +"H c #4C4C4C", +"I c #383838", +"J c #E4E4E4", +"K c #D1D1D1", +"L c #8D8D8D", +"M c #9A9A9A", +"N c #ACACAC", +"O c #888888", +"P c #777777", +"Q c #676767", +"R c #585858", +"S c #A5A5A5", +"T c #E0E0E0", +"U c #DEDEDE", +"V c #D3D3D3", +"W c #E5E5E5", +"X c #D2D2D2", +"Y c #000000", +"Z c #8C8C8C", +"` c #BFBFBF", +" . c #D6D6D6", +".. c #565656", +"+. c #454545", +"@. c #989898", +"#. c #737373", +"$. c #9B9B9B", +"%. c #656565", +"&. c #4B4B4B", +"*. c #848484", +"=. c #DDDDDD", +"-. c #F8F8F8", +";. c #F5F5F5", +">. c #E1E1E1", +",. c #F0F0F0", +"'. c #080808", +"). c #D4D4D4", +"!. c #CDCDCD", +"~. c #272727", +"{. c #1E1E1E", +"]. c #2D2D2D", +"^. c #232323", +"/. c #D9D9D9", +"(. c #343434", +"_. c #B9B9B9", +":. c #555555", +"<. c #E8E8E8", +"[. c #444444", +"}. c #535353", +"|. c #7A7A7A", +"1. c #6E6E6E", +"2. c #626262", +"3. c #6A6A6A", +"4. c #606060", +"5. c #595959", +"6. c #636363", +"7. c #CACACA", +"8. c #CBCBCB", +"9. c #747474", +"0. c #727272", +"a. c #707070", +"b. c #6B6B6B", +"c. c #686868", +"d. c #7B7B7B", +"e. c #CFCFCF", +"f. c #929292", +"g. c #A9A9A9", +"h. c #A6A6A6", +"i. c #9D9D9D", +"j. c #969696", +"k. c #919191", +"l. c #818181", +" . . . . . . . . . . . . . . . . ", +" . + + + + + + + + @ # $ % & * = - ", +" . + ; ; ; ; ; ; ; > , ; ' ) ! = ; - ", +" . + ; ; ; ; ; ; ; > ~ ; ; ' ) = ; ; - ", +" . + ; ; ; ; ; ; ; > ~ ; ; ; ' = { ; ; - ", +" . + ; ; ; ; ; ; ; ; ] ; ; ; ; = { { ; ; - ", +" . + ; ; ; ^ ^ ; ; > / ; ; ; ; = { { { ; ; - ", +" . + ; ; ^ ( _ ^ ; ; ] ; ; ; ; = { { { { ; ; - ", +" . + ; ; : ; ; ^ ; ; ] ; ; ; ; < [ . } | 1 2 3 - ", +" . + ; ; ; ; ^ : ; ; 4 4 ; ; ; ' 5 6 * 7 8 9 | - ", +" . + ; ; ; ; 0 ; ; 4 a b 4 ; 4 ; c d { { e f g - ", +" . + ; ; ; ^ ; ; ; 4 ; ; h ; i c c ) j k l m n - ", +" . + ; ; ; o ; ; ; p 4 ; ; ; ' q ) ) r s t u v - ", +" . + ; ; ; ; ; ; ; ; ; ; ; ' q w $ $ 5 x 7 l y - ", +" . + z A B C D k D C E F z G H I ) r r J 6 e K - ", +" . + ; f L M N < N M O P Q R S # $ * * x T U V - ", +" . + z F E C D k D C E F z G H I 5 r W W 6 k X - ", +" . + z F E C Y Z S ` .; z G H I r * 6 6 T l K - ", +" . + z F E C D Y ` .; F z G H I * x J s s k X - ", +" . + V P O M N < Y ; O P Q ..+.@.x J 6 k k l K - ", +" . + ; g #.- 2 $.2 - #.%.R &.*.W J 6 T =.t t 8 - ", +" . + ; ; ' q -.;.@ # ! % & * W J >.s =.7 u u y - ", +" . + ; ' q Y Y Y ,.'.% Y Y Y { >.s =.7 e t ).!.- ", +" . + ; q w ~.j {.! ].* ^./.(.>.U =.7 e .).).y - ", +" _.+ c w d :.7 +.r +.<.[.8 }.U =.7 e .V X K !.- ", +" g + -.d # |.1.2.* 3.j 4.5.6.k 7 e .V X 8 !.m - ", +" C + ;.# $ 5 r * x j 6 T U k 7 t .V K 8 m 7.8.- ", +" | + @ $ 5 9.* 0.a.1.T b.k c.t u V K 8 8.8.7.f - ", +" N + # 5 r A x O ).*.=.- l d.u V 8 e.8.8.8.7.f - ", +" N + ! r * 1 J $.8 @.k f.e L ).K K !.m 7.7.7.f - ", +" g.+ <.j { >.s k l e .).).X 8 e.y !.m 8.f f f - ", +" g.h.1 i.M j.k.Z O *.l.- - - - - - - - - - - - - ", +" ", +" "}; diff --git a/modules/gui/wxwidgets/dialogs/updatevlc.cpp b/modules/gui/wxwidgets/dialogs/updatevlc.cpp index e0988db28b..790b6fa7dc 100644 --- a/modules/gui/wxwidgets/dialogs/updatevlc.cpp +++ b/modules/gui/wxwidgets/dialogs/updatevlc.cpp @@ -25,46 +25,21 @@ * Preamble *****************************************************************************/ #include "updatevlc.hpp" -#include -#include +#include +#include +#include + +#include "bitmaps/update_ascii.xpm" +#include "bitmaps/update_binary.xpm" +#include "bitmaps/update_document.xpm" +#include "bitmaps/update_info.xpm" +#include "bitmaps/update_source.xpm" #include "vlc_block.h" #include "vlc_stream.h" -#include "vlc_xml.h" - -/* define UPDATE_VLC_OS and UPDATE_VLC_ARCH */ -/* todo : move this somewhere else (isn't wx specific) */ - -#ifdef WIN32 -# define UPDATE_VLC_OS "windows" -# define UPDATE_VLC_ARCH "i386" -#else -#ifdef __APPLE__ -# define UPDATE_VLC_OS "macosx" -# define UPDATE_VLC_ARCH "ppc" -#else -# define UPDATE_VLC_OS "*" -# define UPDATE_VLC_ARCH "*" -#endif -#endif - -/* arch == "*" and os == "*" concern non OS or arch specific stuff */ - -#define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status" -#define UPDATE_VLC_MIRRORS_URL "http://update.videolan.org/mirrors" #define UPDATE_VLC_DOWNLOAD_BUFFER_SIZE 2048 -class UpdatesTreeItem : public wxTreeItemData -{ - public: - UpdatesTreeItem( wxString _url ):wxTreeItemData() - { - url = _url; - } - wxString url; -}; - /***************************************************************************** * Event Table. *****************************************************************************/ @@ -74,8 +49,7 @@ enum { Close_Event, CheckForUpdate_Event, - MirrorChoice_Event, - UpdatesTreeActivate_Event + ChooseItem_Event }; BEGIN_EVENT_TABLE(UpdateVLC, wxFrame) @@ -83,11 +57,8 @@ BEGIN_EVENT_TABLE(UpdateVLC, wxFrame) EVT_BUTTON(wxID_OK, UpdateVLC::OnButtonClose) EVT_BUTTON(CheckForUpdate_Event, UpdateVLC::OnCheckForUpdate) - /* Choice events */ - EVT_CHOICE(MirrorChoice_Event, UpdateVLC::OnMirrorChoice) - - /* Tree events */ - EVT_TREE_ITEM_ACTIVATED(UpdatesTreeActivate_Event, UpdateVLC::OnUpdatesTreeActivate) + /* CtrlList events */ + EVT_LIST_ITEM_ACTIVATED( ChooseItem_Event, UpdateVLC::OnChooseItem ) /* Hide the window when the user closes the window */ EVT_CLOSE(UpdateVLC::OnClose) @@ -98,515 +69,31 @@ END_EVENT_TABLE() * Constructor. *****************************************************************************/ UpdateVLC::UpdateVLC( intf_thread_t *_p_intf, wxWindow *p_parent ): - wxFrame( p_parent, -1, wxU(_("Check for updates ...")), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_FRAME_STYLE ) + wxFrame( p_parent, -1, wxU(_("VLC media player - Updates")), + wxDefaultPosition, wxDefaultSize, + wxSYSTEM_MENU|wxCLOSE_BOX|wxFRAME_FLOAT_ON_PARENT|wxFRAME_TOOL_WINDOW) { /* Initializations */ p_intf = _p_intf; - release_type = wxT( "testing" ); SetIcon( *p_intf->p_sys->p_icon ); SetAutoLayout( TRUE ); - /* Create a panel to put everything in */ - wxPanel *panel = new wxPanel( this, -1 ); - panel->SetAutoLayout( TRUE ); - - updates_tree = - new wxTreeCtrl( panel, UpdatesTreeActivate_Event, wxDefaultPosition, - wxSize( 400, 200 ), - wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT | wxSUNKEN_BORDER ); - updates_tree->AddRoot( wxU(_("root" )), -1, -1, NULL ); - - /* Place everything in sizers */ wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer *subpanel_sizer = new wxBoxSizer( wxHORIZONTAL ); - panel_sizer->Add( updates_tree, 1, wxGROW | wxALL, 5 ); wxButton *update_button = - new wxButton( panel, CheckForUpdate_Event, + new wxButton( this, CheckForUpdate_Event, wxU(_("Check for updates now !")) ); - subpanel_sizer->Add( update_button, 0, wxALL, 5 ); -//wxChoice constructor prototype changes with 2.5 -#if wxCHECK_VERSION(2,5,0) - wxArrayString *choices_array = new wxArrayString(); - choices_array->Add( wxT("") ); - mirrors_choice = - new wxChoice( panel, MirrorChoice_Event, wxDefaultPosition, - wxSize( 200, -1 ), *choices_array ); -#else - wxString choices_array = wxT(""); - mirrors_choice = - new wxChoice( panel, -1, wxDefaultPosition, - wxSize( 200, -1 ),1, *choices_array ); -#endif - subpanel_sizer->Add( mirrors_choice, 0, wxALL, 5 ); - subpanel_sizer->Layout(); - panel_sizer->Add( subpanel_sizer, 0, wxALL , 0 ); - panel_sizer->Layout(); - panel->SetSizerAndFit( panel_sizer ); - main_sizer->Add( panel, 1, wxALL | wxGROW, 0 ); - main_sizer->Layout(); + main_sizer->Add( update_button ); SetSizerAndFit( main_sizer ); - UpdateMirrorsChoice(); - UpdateUpdatesTree(); + p_u = update_New( p_intf ); } UpdateVLC::~UpdateVLC() { - fprintf( stderr, "Fooing\n"); -} - -/* this function gets all the info from the xml files hosted on -http://update.videolan.org/ and stores it in appropriate lists */ -void UpdateVLC::GetData() -{ - stream_t *p_stream = NULL; - char *psz_eltname = NULL; - char *psz_name = NULL; - char *psz_value = NULL; - char *psz_eltvalue = NULL; - xml_t *p_xml = NULL; - xml_reader_t *p_xml_reader = NULL; - bool b_os = false; - bool b_arch = false; - - struct update_file_t tmp_file; - struct update_version_t tmp_version; - std::list::iterator it; - std::list::iterator it_files; - - struct update_mirror_t tmp_mirror; - - p_xml = xml_Create( p_intf ); - if( !p_xml ) - { - msg_Err( p_intf, "Failed to open XML parser" ); - // FIXME : display error message in dialog - return; - } - - p_stream = stream_UrlNew( p_intf, UPDATE_VLC_STATUS_URL ); - if( !p_stream ) - { - msg_Err( p_intf, "Failed to open %s for reading", - UPDATE_VLC_STATUS_URL ); - // FIXME : display error message in dialog - return; - } - - p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); - - if( !p_xml_reader ) - { - msg_Err( p_intf, "Failed to open %s for parsing", - UPDATE_VLC_STATUS_URL ); - // FIXME : display error message in dialog - return; - } - - /* empty tree */ - m_versions.clear(); - - /* build tree */ - while( xml_ReaderRead( p_xml_reader ) == 1 ) - { - switch( xml_ReaderNodeType( p_xml_reader ) ) - { - // Error - case -1: - // TODO : print message - return; - - case XML_READER_STARTELEM: - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - { - // TODO : print message - return; - } - msg_Dbg( p_intf, "element name : %s", psz_eltname ); - while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) - { - psz_name = xml_ReaderName( p_xml_reader ); - psz_value = xml_ReaderValue( p_xml_reader ); - if( !psz_name || !psz_value ) - { - // TODO : print message - free( psz_eltname ); - return; - } - msg_Dbg( p_intf, " attribute %s = %s", - psz_name, psz_value ); - if( b_os && b_arch ) - { - if( strcmp( psz_eltname, "version" ) == 0 ) - { - if( !strcmp( psz_name, "type" ) ) - tmp_version.type = wxU( psz_value ); - if( !strcmp( psz_name, "major" ) ) - tmp_version.major = wxU( psz_value ); - if( !strcmp( psz_name, "minor" ) ) - tmp_version.minor = wxU( psz_value ); - if( !strcmp( psz_name, "revision" ) ) - tmp_version.revision = wxU( psz_value ); - if( !strcmp( psz_name, "extra" ) ) - tmp_version.extra = wxU( psz_value ); - } - if( !strcmp( psz_eltname, "file" ) ) - { - if( !strcmp( psz_name, "type" ) ) - tmp_file.type = wxU( psz_value ); - if( !strcmp( psz_name, "md5" ) ) - tmp_file.md5 = wxU( psz_value ); - if( !strcmp( psz_name, "size" ) ) - tmp_file.size = wxU( psz_value ); - if( !strcmp( psz_name, "url" ) ) - tmp_file.url = wxU( psz_value ); - } - } - if( !strcmp( psz_name, "name" ) - && ( !strcmp( psz_value, UPDATE_VLC_OS ) - || !strcmp( psz_value, "*" ) ) - && !strcmp( psz_eltname, "os" ) ) - { - b_os = true; - } - if( b_os && !strcmp( psz_name, "name" ) - && ( !strcmp( psz_value, UPDATE_VLC_ARCH ) - || !strcmp( psz_value, "*" ) ) - && !strcmp( psz_eltname, "arch" ) ) - { - b_arch = true; - } - free( psz_name ); - free( psz_value ); - } - if( ( b_os && b_arch && strcmp( psz_eltname, "arch" ) ) ) - { - if( !strcmp( psz_eltname, "version" ) ) - { - it = m_versions.begin(); - while( it != m_versions.end() ) - { - if( it->type == tmp_version.type - && it->major == tmp_version.major - && it->minor == tmp_version.minor - && it->revision == tmp_version.revision - && it->extra == tmp_version.extra ) - { - break; - } - it++; - } - if( it == m_versions.end() ) - { - m_versions.push_back( tmp_version ); - it = m_versions.begin(); - while( it != m_versions.end() ) - { - if( it->type == tmp_version.type - && it->major == tmp_version.major - && it->minor == tmp_version.minor - && it->revision == tmp_version.revision - && it->extra == tmp_version.extra ) - { - break; - } - it++; - } - } - tmp_version.type = wxT( "" ); - tmp_version.major = wxT( "" ); - tmp_version.minor = wxT( "" ); - tmp_version.revision = wxT( "" ); - tmp_version.extra = wxT( "" ); - } - if( !strcmp( psz_eltname, "file" ) ) - { - it->m_files.push_back( tmp_file ); - tmp_file.type = wxT( "" ); - tmp_file.md5 = wxT( "" ); - tmp_file.size = wxT( "" ); - tmp_file.url = wxT( "" ); - tmp_file.description = wxT( "" ); - } - } - free( psz_eltname ); - break; - - case XML_READER_ENDELEM: - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - { - // TODO : print message - return; - } - msg_Dbg( p_intf, "element end : %s", psz_eltname ); - if( !strcmp( psz_eltname, "os" ) ) - b_os = false; - if( !strcmp( psz_eltname, "arch" ) ) - b_arch = false; - free( psz_eltname ); - break; - - case XML_READER_TEXT: - psz_eltvalue = xml_ReaderValue( p_xml_reader ); - msg_Dbg( p_intf, " text : %s", psz_eltvalue ); - /* This doesn't look safe ... but it works */ - if( !m_versions.empty() ) - if( !it->m_files.empty() ) - it->m_files.back().description = wxU( psz_eltvalue ); - free( psz_eltvalue ); - break; - } - } - - if( p_xml_reader && p_xml ) xml_ReaderDelete( p_xml, p_xml_reader ); - if( p_stream ) stream_Delete( p_stream ); - - p_stream = stream_UrlNew( p_intf, UPDATE_VLC_MIRRORS_URL ); - if( !p_stream ) - { - msg_Err( p_intf, "Failed to open %s for reading", - UPDATE_VLC_MIRRORS_URL ); - // FIXME : display error message in dialog - return; - } - - p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); - - if( !p_xml_reader ) - { - msg_Err( p_intf, "Failed to open %s for parsing", - UPDATE_VLC_MIRRORS_URL ); - // FIXME : display error message in dialog - return; - } - /* empty list */ - m_mirrors.clear(); - - /* build list */ - while( xml_ReaderRead( p_xml_reader ) == 1 ) - { - switch( xml_ReaderNodeType( p_xml_reader ) ) - { - // Error - case -1: - // TODO : print message - return; - - case XML_READER_STARTELEM: - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - { - // TODO : print message - return; - } - msg_Dbg( p_intf, "element name : %s", psz_eltname ); - while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) - { - psz_name = xml_ReaderName( p_xml_reader ); - psz_value = xml_ReaderValue( p_xml_reader ); - if( !psz_name || !psz_value ) - { - // TODO : print message - free( psz_eltname ); - return; - } - msg_Dbg( p_intf, " attribute %s = %s", - psz_name, psz_value ); - if( !strcmp( psz_eltname, "mirror" ) ) - { - if( !strcmp( psz_name, "name" ) ) - tmp_mirror.name = wxU( psz_value ); - if( !strcmp( psz_name, "location" ) ) - tmp_mirror.location = wxU( psz_value ); - } - if( !strcmp( psz_eltname, "url" ) ) - { - if( !strcmp( psz_name, "type" ) ) - tmp_mirror.type = wxU( psz_value ); - if( !strcmp( psz_name, "base" ) ) - tmp_mirror.base_url = wxU( psz_value ); - } - free( psz_name ); - free( psz_value ); - } - if( !strcmp( psz_eltname, "url" ) ) - { - m_mirrors.push_back( tmp_mirror ); - tmp_mirror.type = wxT( "" ); - tmp_mirror.base_url = wxT( "" ); - } - free( psz_eltname ); - break; - - case XML_READER_ENDELEM: - psz_eltname = xml_ReaderName( p_xml_reader ); - if( !psz_eltname ) - { - // TODO : print message - return; - } - msg_Dbg( p_intf, "element end : %s", psz_eltname ); - if( !strcmp( psz_eltname, "mirror" ) ) - { - tmp_mirror.name = wxT( "" ); - tmp_mirror.location = wxT( "" ); - } - free( psz_eltname ); - break; - - case XML_READER_TEXT: - psz_eltvalue = xml_ReaderValue( p_xml_reader ); - msg_Dbg( p_intf, " text : %s", psz_eltvalue ); - free( psz_eltvalue ); - break; - } - } - - - if( p_xml_reader && p_xml ) xml_ReaderDelete( p_xml, p_xml_reader ); - if( p_stream ) stream_Delete( p_stream ); - if( p_xml ) xml_Delete( p_xml ); -} - -void UpdateVLC::UpdateUpdatesTree() -{ - wxTreeItemId parent; - std::list::iterator it; - std::list::iterator it_files; - std::list::iterator it_mirrors; - - int selection = mirrors_choice->GetSelection(); - wxString base_url = wxT( "" ); - - if( selection-- ) - { - it_mirrors = m_mirrors.begin(); - while( it_mirrors != m_mirrors.end() && selection ) - { - it_mirrors++; - selection--; - } - if( it_mirrors != m_mirrors.end() ) base_url = it_mirrors->base_url; - } - - /* empty tree */ - updates_tree->DeleteAllItems(); - - /* build tree */ - parent=updates_tree->AddRoot( wxU(_("root" )), -1, -1, NULL ); - updates_tree->AppendItem( parent, - wxT( "Current version : VLC media player "PACKAGE_VERSION_MAJOR"."PACKAGE_VERSION_MINOR"."PACKAGE_VERSION_REVISION"-"PACKAGE_VERSION_EXTRA ), - -1, -1, new UpdatesTreeItem( wxT( "" ) )); - it = m_versions.begin(); - while( it != m_versions.end() ) - { - if( it->type != release_type ) - { - it++; - continue; - } - - if( release_type != wxT( "stable" ) && it->type == wxT( "stable" ) ) - { - it++; - continue; - } - - if( release_type != wxT( "stable" ) && release_type != wxT( "testing" ) - && it->type == wxT( "testing" ) ) - { - it++; - continue; - } - - if( release_type != wxT( "stable" ) && release_type != wxT( "testing" ) - && release_type != wxT( "nightly" ) ) - { - it++; - continue; - } - - if( atoi((const char *)it->major.mb_str()) < - atoi(PACKAGE_VERSION_MAJOR) - || ( atoi((const char *)it->major.mb_str()) == - atoi(PACKAGE_VERSION_MAJOR) - && ( atoi((const char *)it->minor.mb_str()) < - atoi(PACKAGE_VERSION_MINOR) - || ( atoi((const char *)it->minor.mb_str()) == - atoi(PACKAGE_VERSION_MINOR) - && ( atoi((const char *)it->revision.mb_str()) < - atoi(PACKAGE_VERSION_REVISION) - || ( atoi((const char *)it->revision.mb_str()) == - atoi(PACKAGE_VERSION_REVISION) ) ) ) ) ) ) - { - /* version is older or equal tu current version. - FIXME : how do we handle the extra version number ? */ - it++; - continue; - } - wxTreeItemId cat = updates_tree->AppendItem( parent, - wxT("New Version : VLC media player ") - + it->major + wxT(".") - + it->minor + wxT(".") + it->revision + wxT("-") - + it->extra + wxT(" (") + it->type + wxT(")"), - -1, -1, new UpdatesTreeItem( wxT( "" ) )); - it_files = it->m_files.begin(); - while( it_files != it->m_files.end() ) - { - wxString url = (it_files->url[0]=='/' ? base_url : wxT( "" ) ) - + it_files->url; - wxTreeItemId file = - updates_tree->AppendItem( cat, it_files->description, - -1, -1, new UpdatesTreeItem( url ) ); - updates_tree->AppendItem( file, - wxU(_("type : ")) + it_files->type, - -1, -1, new UpdatesTreeItem( url )); - updates_tree->AppendItem( file, wxU(_("URL : ")) + url, - -1, -1, new UpdatesTreeItem( url )); - if( it_files->size != wxT( "" ) ) - updates_tree->AppendItem( file, - wxU(_("file size : ")) + it_files->size, - -1, -1, new UpdatesTreeItem( url )); - if( it_files->md5 != wxT( "" ) ) - updates_tree->AppendItem( file, - wxU(_("file md5 hash : ")) + it_files->md5, - -1, -1, new UpdatesTreeItem( url )); - it_files ++; - } - it ++; - updates_tree->Expand( cat ); - updates_tree->Expand( parent ); - } + update_Delete( p_u ); } -void UpdateVLC::UpdateMirrorsChoice() -{ - std::list::iterator it_mirrors; - - mirrors_choice->Clear(); - mirrors_choice->Append( wxU(_("Choose a mirror")) ); - it_mirrors = m_mirrors.begin(); - while( it_mirrors != m_mirrors.end() ) - { - mirrors_choice->Append( it_mirrors->name + wxT(" (") - + it_mirrors->location + wxT(") [") - + it_mirrors->type + wxT("]") ); - it_mirrors++; - } - mirrors_choice->SetSelection( 0 ); -} - -/*void UpdateVLC::UpdateUpdateVLC() -{ - UpdateUpdatesTree(); - UpdateMirrorsChoice(); -}*/ - void UpdateVLC::OnButtonClose( wxCommandEvent& event ) { wxCloseEvent cevent; @@ -620,83 +107,121 @@ void UpdateVLC::OnClose( wxCloseEvent& WXUNUSED(event) ) void UpdateVLC::OnCheckForUpdate( wxCommandEvent& event ) { - GetData(); - UpdateMirrorsChoice(); - UpdateUpdatesTree(); -} - -void UpdateVLC::OnMirrorChoice( wxCommandEvent& event ) -{ - UpdateUpdatesTree(); -} - -void UpdateVLC::OnUpdatesTreeActivate( wxTreeEvent& event ) -{ - wxString url = - ((UpdatesTreeItem *)(updates_tree->GetItemData(event.GetItem())))->url; - if( url != wxT( "" ) ? url[0] != '/' : false ) + update_Check( p_u, VLC_FALSE ); + update_iterator_t *p_uit = update_iterator_New( p_u ); + if( p_uit ) { - wxFileDialog *filedialog = - new wxFileDialog( updates_tree, wxU(_("Save file ...")), - wxT(""), url.AfterLast( '/' ), wxT("*.*"), - wxSAVE | wxOVERWRITE_PROMPT ); - if( filedialog->ShowModal() == wxID_OK ) + wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL ); + + p_uit->i_rs = UPDATE_RELEASE_STATUS_NEWER; + p_uit->i_t = UPDATE_FILE_TYPE_ALL; + update_iterator_Action( p_uit, UPDATE_MIRROR ); + + DestroyChildren(); + + wxListCtrl *list = + new wxListCtrl( this, ChooseItem_Event, + wxDefaultPosition, wxSize( 400, 300 ), + wxLC_AUTOARRANGE|wxLC_SINGLE_SEL ); + wxImageList *images = new wxImageList( 32, 32, TRUE ); + images->Add( wxIcon( update_ascii_xpm ) ); + images->Add( wxIcon( update_info_xpm ) ); + images->Add( wxIcon( update_source_xpm ) ); + images->Add( wxIcon( update_binary_xpm ) ); + images->Add( wxIcon( update_document_xpm ) ); + list->AssignImageList( images, wxIMAGE_LIST_SMALL ); + while( update_iterator_Action( p_uit, UPDATE_FILE ) != UPDATE_FAIL ) { - DownloadFile( url, filedialog->GetPath() ); + /*wxButton *update_button = + new wxButton( this, Download_Event, + wxU(p_uit->file.psz_description) ); + main_sizer->Add( update_button, 0, wxALIGN_CENTER );*/ + int i_image; + switch( p_uit->file.i_type ) + { + case UPDATE_FILE_TYPE_INFO: + i_image = 1; + break; + case UPDATE_FILE_TYPE_SOURCE: + i_image = 2; + break; + case UPDATE_FILE_TYPE_BINARY: + i_image = 3; + break; + case UPDATE_FILE_TYPE_PLUGIN: + i_image = 4; + break; + default: + i_image = 0; + } + list->InsertItem( list->GetItemCount(), + wxU(p_uit->file.psz_description)+wxU("\n") + + wxU(p_uit->release.psz_version)+wxU(" (") + + wxU(p_uit->release.psz_svn_revision)+wxU(")"), + i_image ); } + + main_sizer->Add( new wxStaticText( this, -1, wxU( _("\nAvailable updates and related downloads:\n(Double click on a file to download it)\n" ) ) ) ); + main_sizer->Add( list/*, 0, wxEXPAND */); + SetSizerAndFit( main_sizer ); + Layout(); + update_iterator_Delete( p_uit ); } } -void UpdateVLC::DownloadFile( wxString url, wxString dst ) +class DownloadThread : public wxThread { - char *psz_local = ToLocale( dst.mb_str() ); - msg_Dbg( p_intf, "Downloading %s to %s", - (const char *)url.mb_str(), psz_local ); - - stream_t *p_stream = NULL; - p_stream = stream_UrlNew( p_intf, (const char *)url.mb_str() ); - if( !p_stream ) + public: + DownloadThread( update_iterator_t *p_uit, char *psz_dest ) + :p_uit( p_uit ),psz_dest( psz_dest ) { - msg_Err( p_intf, "Failed to open %s for reading", (const char *)url.mb_str() ); - // FIXME : display error message in dialog - return; + Create(); + Run(); } + ExitCode Entry() + { + update_download( p_uit, psz_dest ); + update_iterator_Delete( p_uit ); + LocaleFree( psz_dest ); + return 0; + }; + update_iterator_t *p_uit; + char *psz_dest; +}; - FILE *p_file = NULL; - p_file = fopen( psz_local, "w" ); - if( !p_file ) +void UpdateVLC::OnChooseItem( wxListEvent& event ) +{ + update_iterator_t *p_uit = update_iterator_New( p_u ); + if( p_uit ) { - msg_Err( p_intf, "Failed to open %s for writing", psz_local ); - // FIXME : display error message in dialog - return; - } - LocaleFree( psz_local ); + p_uit->i_rs = UPDATE_RELEASE_STATUS_NEWER; + p_uit->i_t = UPDATE_FILE_TYPE_ALL; + update_iterator_Action( p_uit, UPDATE_MIRROR ); - int i_progress = 0; - wxProgressDialog *progressdialog = - new wxProgressDialog( wxU(_("Downloading...")), - wxU(wxT("Src: ") +url + wxT("\nDst: ") +dst ), - (int)(stream_Size(p_stream)/UPDATE_VLC_DOWNLOAD_BUFFER_SIZE), NULL, - wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME | wxPD_AUTO_HIDE - | wxPD_CAN_ABORT ); + int i_count = 0; + while( update_iterator_Action( p_uit, UPDATE_FILE ) != UPDATE_FAIL ) + { + if( i_count == event.GetIndex() ) + break; + i_count++; + } + wxString url = wxU( p_uit->file.psz_url ); + wxFileDialog *filedialog = + new wxFileDialog( this, wxU(_("Save file ...")), + wxT(""), url.AfterLast( '/' ), wxT("*.*"), + wxSAVE | wxOVERWRITE_PROMPT ); + if( filedialog->ShowModal() == wxID_OK ) + { + char *psz_dest = ToLocale( filedialog->GetPath().mb_str() ); - void *buffer = (void *)malloc( UPDATE_VLC_DOWNLOAD_BUFFER_SIZE ); - while( stream_Read( p_stream, buffer, UPDATE_VLC_DOWNLOAD_BUFFER_SIZE ) ) - { - fwrite( buffer, UPDATE_VLC_DOWNLOAD_BUFFER_SIZE, 1, p_file); - if( !progressdialog->Update(++i_progress) ) + /* Launch the download process in a new thread so it doesn't + * block the interface */ + new DownloadThread( p_uit, psz_dest ); + } + else { - free( buffer ); - fclose( p_file ); - if( p_stream ) stream_Delete( p_stream ); - progressdialog->Destroy(); - msg_Warn( p_intf, "User aborted download" ); - return; + update_iterator_Delete( p_uit ); } + delete filedialog; } - progressdialog->Destroy(); - msg_Dbg( p_intf, "Download finished" ); - free( buffer ); - fclose( p_file ); - if( p_stream ) stream_Delete( p_stream ); } diff --git a/modules/gui/wxwidgets/dialogs/updatevlc.hpp b/modules/gui/wxwidgets/dialogs/updatevlc.hpp index 3d4e0fc910..70262b87f5 100644 --- a/modules/gui/wxwidgets/dialogs/updatevlc.hpp +++ b/modules/gui/wxwidgets/dialogs/updatevlc.hpp @@ -24,9 +24,10 @@ #ifndef _WXVLC_UPDATEVLC_H_ #define _WXVLC_UPDATEVLC_H_ +#include + #include "wxwidgets.hpp" #include -#include class wxTreeCtrl; @@ -35,60 +36,19 @@ namespace wxvlc class UpdateVLC: public wxFrame { public: - /** Constructor */ UpdateVLC( intf_thread_t *p_intf, wxWindow *p_parent ); virtual ~UpdateVLC(); private: void OnButtonClose( wxCommandEvent& event ); void OnClose( wxCloseEvent& WXUNUSED(event) ); - void GetData(); void OnCheckForUpdate( wxCommandEvent& event ); - void OnMirrorChoice( wxCommandEvent& event ); - void UpdateUpdatesTree(); - void UpdateMirrorsChoice(); - void OnUpdatesTreeActivate( wxTreeEvent& event ); - void DownloadFile( wxString url, wxString dst ); + void OnChooseItem( wxListEvent& event ); DECLARE_EVENT_TABLE(); intf_thread_t *p_intf; - wxTreeCtrl *updates_tree; - - wxChoice *mirrors_choice; - - wxString release_type; /* could be "stable", "test", "nightly" ... */ - - struct update_file_t - { - wxString type; - wxString md5; - wxString size; - wxString url; - wxString description; - }; - - struct update_version_t - { - wxString type; - wxString major; - wxString minor; - wxString revision; - wxString extra; - std::list m_files; - }; - - std::list m_versions; - - struct update_mirror_t - { - wxString name; - wxString location; - wxString type; - wxString base_url; - }; - - std::list m_mirrors; + update_t *p_u; }; }; diff --git a/src/misc/modules.c b/src/misc/modules.c index 743ac51963..b11815cf04 100644 --- a/src/misc/modules.c +++ b/src/misc/modules.c @@ -109,6 +109,8 @@ #include "vlc_image.h" #include "vlc_osd.h" +#include "vlc_update.h" + #if defined( _MSC_VER ) && defined( UNDER_CE ) # include "modules_builtin_evc.h" #elif defined( _MSC_VER ) diff --git a/src/misc/update.c b/src/misc/update.c new file mode 100644 index 0000000000..fb185d38cf --- /dev/null +++ b/src/misc/update.c @@ -0,0 +1,1257 @@ +/***************************************************************************** + * update.c: VLC update and plugins download + ***************************************************************************** + * Copyright (C) 2005 the VideoLAN team + * $Id: $ + * + * Authors: Antoine Cellerier + * + * 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 release 2 of the License, or + * (at your option) any later release. + * + * 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. + *****************************************************************************/ + +/* TODO + * --> check release types. + * --> make sure that the version comparision method is ok. + */ + +/** + * \file + * This file contains functions related to VLC and plugins update management + */ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include /* malloc(), free() */ +#include /* tolower() */ +#include + +#include + +#include "vlc_update.h" + +#include "vlc_block.h" +#include "vlc_stream.h" +#include "vlc_xml.h" +#include "vlc_interaction.h" + +/***************************************************************************** + * Misc defines + *****************************************************************************/ + +/* All release notes and source packages should match on "*" + * Only binary installers are OS specific ( we only provide these + * for Win32, Mac OS X, WincCE, beos(?) ) */ +#if defined( UNDER_CE ) +# define UPDATE_VLC_OS "*" +# define UPDATE_VLC_ARCH "*" +#elif defined( WIN32 ) +# define UPDATE_VLC_OS "windows" +# define UPDATE_VLC_ARCH "i386" +#elif defined( __APPLE__ ) +# define UPDATE_VLC_OS "macosx" +# if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ ) +# define UPDATE_VLC_ARCH "ppc" +# else +# define UPDATE_VLC_ARCH "x86" +# endif +#elif defined( SYS_BEOS ) +# define UPDATE_VLC_OS "beos" +# define UPDATE_VLC_ARCH "i386" +#else +# define UPDATE_VLC_OS "*" +# define UPDATE_VLC_ARCH "*" +#endif + +#define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status.xml" +#define UPDATE_VLC_MIRRORS_URL "http://update.videolan.org/mirrors.xml" + +#define FREE( a ) free(a);a=NULL; +#define STRDUP( a ) ( a ? strdup( a ) : NULL ) + +/***************************************************************************** + * Local Prototypes + *****************************************************************************/ + +void FreeMirrorsList( update_t * ); +void FreeReleasesList( update_t * ); +void GetMirrorsList( update_t *, vlc_bool_t ); +void GetFilesList( update_t *, vlc_bool_t ); + +int CompareReleases( struct update_release_t *, struct update_release_t * ); +int CompareReleaseToCurrent( struct update_release_t * ); + +unsigned int update_iterator_Reset( update_iterator_t * ); +unsigned int update_iterator_NextFile( update_iterator_t * ); +unsigned int update_iterator_PrevFile( update_iterator_t * ); +unsigned int update_iterator_NextMirror( update_iterator_t * ); +unsigned int update_iterator_PrevMirror( update_iterator_t * ); + +void update_iterator_GetData( update_iterator_t * ); +void update_iterator_ClearData( update_iterator_t * ); + +/***************************************************************************** + * Update_t functions + *****************************************************************************/ + +/** + * Create a new update VLC struct + * + * \param p_this the calling vlc_object + * \return pointer to new update_t or NULL + */ +update_t *__update_New( vlc_object_t *p_this ) +{ + update_t *p_update; + + if( p_this == NULL ) return NULL; + + p_update = (update_t *)malloc( sizeof( update_t ) ); + + vlc_mutex_init( p_this, &p_update->lock ); + + p_update->p_vlc = p_this->p_vlc; + + p_update->p_releases = NULL; + p_update->i_releases = 0; + p_update->b_releases = VLC_FALSE; + + p_update->p_mirrors = NULL; + p_update->i_mirrors = 0; + p_update->b_mirrors = VLC_FALSE; + + return p_update; +} + +/** + * Delete an update_t struct + * + * \param p_update update_t* pointer + * \return nothing + */ +void update_Delete( update_t *p_update ) +{ + vlc_mutex_destroy( &p_update->lock ); + FreeMirrorsList( p_update ); + FreeReleasesList( p_update ); + free( p_update ); +} + +/** + * Empty the mirrors list + * *p_update should be locked before using this function + * + * \param p_update pointer to the update struct + * \return nothing + */ +void FreeMirrorsList( update_t *p_update ) +{ + int i; + + for( i = 0; i < p_update->i_mirrors; i++ ) + { + free( p_update->p_mirrors[i].psz_name ); + free( p_update->p_mirrors[i].psz_location ); + free( p_update->p_mirrors[i].psz_type ); + free( p_update->p_mirrors[i].psz_base_url ); + } + FREE( p_update->p_mirrors ); + p_update->i_mirrors = 0; + p_update->b_mirrors = VLC_FALSE; +} + +/** + * Empty the releases list + * *p_update should be locked before calling this function + * + * \param p_update pointer to the update struct + * \return nothing + */ +void FreeReleasesList( update_t *p_update ) +{ + int i; + + for( i = 0; i < p_update->i_releases; i++ ) + { + int j; + struct update_release_t *p_release = (p_update->p_releases + i); + for( j = 0; j < p_release->i_files; j++ ) + { + free( p_release->p_files[j].psz_md5 ); + free( p_release->p_files[j].psz_url ); + free( p_release->p_files[j].psz_description ); + } + free( p_release->psz_major ); + free( p_release->psz_minor ); + free( p_release->psz_revision ); + free( p_release->psz_extra ); + free( p_release->psz_svn_revision ); + free( p_release->p_files ); + } + FREE( p_update->p_releases ); + p_update->i_releases = 0; + p_update->b_releases = VLC_FALSE; +} + +/** + * Get the mirrors list XML file and parse it + * *p_update has to be unlocked when calling this function + * + * \param p_update pointer to the update struct + * \param b_force set to VLC_TRUE if you want to force the mirrors list update + * \return nothing + */ +void GetMirrorsList( update_t *p_update, vlc_bool_t b_force ) +{ + stream_t *p_stream = NULL; + + xml_t *p_xml = NULL; + xml_reader_t *p_xml_reader = NULL; + + char *psz_eltname = NULL; + //char *psz_eltvalue = NULL; + char *psz_name = NULL; + char *psz_value = NULL; + + struct update_mirror_t tmp_mirror = {0}; + + vlc_mutex_lock( &p_update->lock ); + + if( p_update->b_mirrors && b_force == VLC_FALSE ) + { + vlc_mutex_unlock( &p_update->lock ); + return; + } + + p_xml = xml_Create( p_update->p_vlc ); + if( !p_xml ) + { + msg_Err( p_update->p_vlc, "Failed to open XML parser" ); + goto error; + } + + p_stream = stream_UrlNew( p_update->p_vlc, UPDATE_VLC_MIRRORS_URL ); + if( !p_stream ) + { + msg_Err( p_update->p_vlc, "Failed to open %s for reading", + UPDATE_VLC_MIRRORS_URL ); + goto error; + } + + p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); + + if( !p_xml_reader ) + { + msg_Err( p_update->p_vlc, "Failed to open %s for parsing", + UPDATE_VLC_MIRRORS_URL ); + goto error; + } + + if( p_update->p_mirrors ) + { + FreeMirrorsList( p_update ); + } + + while( xml_ReaderRead( p_xml_reader ) == 1 ) + { + switch( xml_ReaderNodeType( p_xml_reader ) ) + { + case -1: + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_MIRRORS_URL ); + goto error; + + case XML_READER_STARTELEM: + psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_MIRRORS_URL ); + goto error; + } + + while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) + { + psz_name = xml_ReaderName( p_xml_reader ); + psz_value = xml_ReaderValue( p_xml_reader ); + + if( !psz_name || !psz_value ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_MIRRORS_URL ); + goto error; + } + + if( !strcmp( psz_eltname, "mirror" ) ) + { + if( !strcmp( psz_name, "name" ) ) + tmp_mirror.psz_name = STRDUP( psz_value ); + else if( !strcmp( psz_name, "location" ) ) + tmp_mirror.psz_location = STRDUP( psz_value ); + } + else if( !strcmp( psz_eltname, "url" ) ) + { + if( !strcmp( psz_name, "type" ) ) + tmp_mirror.psz_type = STRDUP( psz_value ); + else if( !strcmp( psz_name, "base" ) ) + tmp_mirror.psz_base_url = STRDUP( psz_value ); + } + FREE( psz_name ); + FREE( psz_value ); + } + if( !strcmp( psz_eltname, "url" ) ) + { + /* append to mirrors list */ + p_update->p_mirrors = + (struct update_mirror_t *)realloc( p_update->p_mirrors, + (++(p_update->i_mirrors)) + *sizeof( struct update_mirror_t ) ); + p_update->p_mirrors[ p_update->i_mirrors - 1 ] = + tmp_mirror; + tmp_mirror.psz_name = STRDUP( tmp_mirror.psz_name ); + tmp_mirror.psz_location = STRDUP( tmp_mirror.psz_location ); + tmp_mirror.psz_type = NULL; + tmp_mirror.psz_base_url = NULL; + } + FREE( psz_eltname ); + break; + + case XML_READER_ENDELEM: + psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_MIRRORS_URL ); + goto error; + } + + if( !strcmp( psz_eltname, "mirror" ) ) + { + FREE( tmp_mirror.psz_name ); + FREE( tmp_mirror.psz_location ); + } + + FREE( psz_eltname ); + break; + + /*case XML_READER_TEXT: + psz_eltvalue = xml_ReaderValue( p_xml_reader ); + FREE( psz_eltvalue ); + break;*/ + } + } + + p_update->b_mirrors = VLC_TRUE; + + error: + vlc_mutex_unlock( &p_update->lock ); + + free( psz_eltname ); + //free( psz_eltvalue ); + free( psz_name ); + free( psz_value ); + + free( tmp_mirror.psz_name ); + free( tmp_mirror.psz_location ); + free( tmp_mirror.psz_type ); + free( tmp_mirror.psz_base_url ); + + if( p_xml_reader && p_xml ) + xml_ReaderDelete( p_xml, p_xml_reader ); + if( p_stream ) + stream_Delete( p_stream ); + if( p_xml ) + xml_Delete( p_xml ); +} + +/** + * Get the files list XML file and parse it + * *p_update has to be unlocked when calling this function + * + * \param p_update pointer to update struct + * \param b_force set to VLC_TRUE if you want to force the files list update + * \return nothing + */ +void GetFilesList( update_t *p_update, vlc_bool_t b_force ) +{ + stream_t *p_stream = NULL; + + xml_t *p_xml = NULL; + xml_reader_t *p_xml_reader = NULL; + + char *psz_eltname = NULL; + char *psz_eltvalue = NULL; + char *psz_name = NULL; + char *psz_value = NULL; + + struct update_release_t *p_release = NULL; + struct update_release_t tmp_release = {0}; + struct update_file_t tmp_file = {0}; + tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; + + vlc_bool_t b_os = VLC_FALSE, b_arch = VLC_FALSE; + + vlc_mutex_lock( &p_update->lock ); + + if( p_update->b_releases && b_force == VLC_FALSE ) + { + vlc_mutex_unlock( &p_update->lock ); + return; + } + + p_xml = xml_Create( p_update->p_vlc ); + if( !p_xml ) + { + msg_Err( p_update->p_vlc, "Failed to open XML parser" ); + goto error; + } + + p_stream = stream_UrlNew( p_update->p_vlc, UPDATE_VLC_STATUS_URL ); + if( !p_stream ) + { + msg_Err( p_update->p_vlc, "Failed to open %s for reading", + UPDATE_VLC_STATUS_URL ); + goto error; + } + + p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); + + if( !p_xml_reader ) + { + msg_Err( p_update->p_vlc, "Failed to open %s for parsing", + UPDATE_VLC_STATUS_URL ); + goto error; + } + + if( p_update->p_releases ) + { + FreeReleasesList( p_update ); + } + + while( xml_ReaderRead( p_xml_reader ) == 1 ) + { + switch( xml_ReaderNodeType( p_xml_reader ) ) + { + case -1: + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_STATUS_URL ); + goto error; + + case XML_READER_STARTELEM: + psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_STATUS_URL ); + goto error; + } + + while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) + { + psz_name = xml_ReaderName( p_xml_reader ); + psz_value = xml_ReaderValue( p_xml_reader ); + + if( !psz_name || !psz_value ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_STATUS_URL ); + goto error; + } + + if( b_os && b_arch ) + { + if( strcmp( psz_eltname, "version" ) == 0 ) + { + if( !strcmp( psz_name, "major" ) ) + tmp_release.psz_major = STRDUP( psz_value ); + else if( !strcmp( psz_name, "minor" ) ) + tmp_release.psz_minor = STRDUP( psz_value ); + else if( !strcmp( psz_name, "revision" ) ) + tmp_release.psz_revision = STRDUP( psz_value ); + else if( !strcmp( psz_name, "extra" ) ) + tmp_release.psz_extra = STRDUP( psz_value ); + else if( !strcmp( psz_name, "svn" ) ) + tmp_release.psz_svn_revision = + STRDUP( psz_value ); + else if( !strcmp( psz_name, "version" ) ) + { + if( !strcmp( psz_value, "unstable" ) ) + tmp_release.i_type = + UPDATE_RELEASE_TYPE_UNSTABLE; + else if( !strcmp( psz_value, "testing" ) ) + tmp_release.i_type = + UPDATE_RELEASE_TYPE_TESTING; + else + tmp_release.i_type = + UPDATE_RELEASE_TYPE_STABLE; + } + } + else if( !strcmp( psz_eltname, "file" ) ) + { + if( !strcmp( psz_name, "type" ) ) + { + if( !strcmp( psz_value, "info" ) ) + tmp_file.i_type = UPDATE_FILE_TYPE_INFO; + else if( !strcmp( psz_value, "source" ) ) + tmp_file.i_type = UPDATE_FILE_TYPE_SOURCE; + else if( !strcmp( psz_value, "binary" ) ) + tmp_file.i_type = UPDATE_FILE_TYPE_BINARY; + else if( !strcmp( psz_value, "plugin" ) ) + tmp_file.i_type = UPDATE_FILE_TYPE_PLUGIN; + else + tmp_file.i_type = UPDATE_FILE_TYPE_UNDEF; + } + else if( !strcmp( psz_name, "md5" ) ) + tmp_file.psz_md5 = STRDUP( psz_value ); + else if( !strcmp( psz_name, "size" ) ) + tmp_file.l_size = atol( psz_value ); + else if( !strcmp( psz_name, "url" ) ) + tmp_file.psz_url = STRDUP( psz_value ); + } + } + if( !strcmp( psz_name, "name" ) + && ( !strcmp( psz_value, UPDATE_VLC_OS ) + || !strcmp( psz_value, "*" ) ) + && !strcmp( psz_eltname, "os" ) ) + { + b_os = VLC_TRUE; + } + if( b_os && !strcmp( psz_name, "name" ) + && ( !strcmp( psz_value, UPDATE_VLC_ARCH ) + || !strcmp( psz_value, "*" ) ) + && !strcmp( psz_eltname, "arch" ) ) + { + b_arch = VLC_TRUE; + } + FREE( psz_name ); + FREE( psz_value ); + } + if( ( b_os && b_arch && strcmp( psz_eltname, "arch" ) ) ) + { + if( !strcmp( psz_eltname, "version" ) ) + { + int i; + /* look for a previous occurence of this release */ + for( i = 0; i < p_update->i_releases; i++ ) + { + p_release = p_update->p_releases + i; + if( CompareReleases( p_release, &tmp_release ) + == UPDATE_RELEASE_STATUS_EQUAL ) + { + break; + } + } + /* if this is the first time that we see this release, + * append it to the list of releases */ + if( i == p_update->i_releases ) + { + tmp_release.i_status = + CompareReleaseToCurrent( &tmp_release ); + p_update->p_releases = + (struct update_release_t *)realloc( p_update->p_releases, + (++(p_update->i_releases))*sizeof( struct update_release_t ) ); + p_update->p_releases[ p_update->i_releases - 1 ] = + tmp_release; + p_release = + p_update->p_releases + p_update->i_releases - 1; + tmp_release.psz_major = NULL; + tmp_release.psz_minor = NULL; + tmp_release.psz_revision = NULL; + tmp_release.psz_extra = NULL; + tmp_release.psz_svn_revision = NULL; + tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; + tmp_release.i_status = 0; + tmp_release.p_files = NULL; + tmp_release.i_files = 0; + } + else + { + FREE( tmp_release.psz_major ); + FREE( tmp_release.psz_minor ); + FREE( tmp_release.psz_revision ); + FREE( tmp_release.psz_extra ); + FREE( tmp_release.psz_svn_revision ); + tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; + FREE( tmp_release.p_files ); + tmp_release.i_files = 0; + } + } + else if( !strcmp( psz_eltname, "file" ) ) + { + /* append file to p_release's file list */ + if( p_release == NULL ) + { + goto error; + } + p_release->p_files = + (struct update_file_t *)realloc( p_release->p_files, + (++(p_release->i_files))*sizeof( struct update_file_t ) ); + p_release->p_files[ p_release->i_files - 1 ] = tmp_file; + tmp_file.i_type = UPDATE_FILE_TYPE_UNDEF; + tmp_file.psz_md5 = NULL; + tmp_file.l_size = 0; + tmp_file.psz_url = NULL; + tmp_file.psz_description = NULL; + } + } + FREE( psz_eltname ); + break; + + case XML_READER_ENDELEM: + psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + { + msg_Err( p_update->p_vlc, "Error while parsing %s", + UPDATE_VLC_STATUS_URL ); + goto error; + } + + if( !strcmp( psz_eltname, "os" ) ) + b_os = VLC_FALSE; + else if( !strcmp( psz_eltname, "arch" ) ) + b_arch = VLC_FALSE; + FREE( psz_eltname ); + break; + + case XML_READER_TEXT: + psz_eltvalue = xml_ReaderValue( p_xml_reader ); + if( p_release && p_release->i_files ) + p_release->p_files[ p_release->i_files - 1 ] + .psz_description = STRDUP( psz_eltvalue ); + FREE( psz_eltvalue ); + break; + } + } + + p_update->b_releases = VLC_TRUE; + + error: + vlc_mutex_unlock( &p_update->lock ); + + free( psz_eltname ); + free( psz_eltvalue ); + free( psz_name ); + free( psz_value ); + + free( tmp_release.psz_major ); + free( tmp_release.psz_minor ); + free( tmp_release.psz_revision ); + free( tmp_release.psz_extra ); + free( tmp_release.psz_svn_revision ); + + free( tmp_file.psz_md5 ); + free( tmp_file.psz_url ); + free( tmp_file.psz_description ); + + if( p_xml_reader && p_xml ) + xml_ReaderDelete( p_xml, p_xml_reader ); + if( p_stream ) + stream_Delete( p_stream ); + if( p_xml ) + xml_Delete( p_xml ); +} + +/** + * Check for updates + * + * \param p_update pointer to update struct + * \param b_force set to VLC_TRUE if you want to force the update + * \returns nothing + */ +void update_Check( update_t *p_update, vlc_bool_t b_force ) +{ + if( p_update == NULL ) return; + GetMirrorsList( p_update, b_force ); + GetFilesList( p_update, b_force ); +} + +/** + * Compare two release numbers + * The comparision algorith basically performs an alphabetical order (strcmp) + * comparision of each of the version number elements until it finds two + * different ones. This is the tricky function. + * + * \param p1 first release + * \param p2 second release + * \return like strcmp + */ +int CompareReleases( struct update_release_t *p1, struct update_release_t *p2 ) +{ + int d; + if( ( d = strcmp( p1->psz_major, p2->psz_major ) ) ) ; + else if( ( d = strcmp( p1->psz_minor, p2->psz_minor ) ) ) ; + else if( ( d = strcmp( p1->psz_revision, p2->psz_revision ) ) ) ; + else + { + d = strcmp( p1->psz_extra, p2->psz_extra ); + if( d<0 ) + { + /* FIXME: + * not num < NULL < num + * -test and -svn releases are thus always considered older than + * -'' or -0 releases, which is the best i could come up with */ + char *psz_end1; + char *psz_end2; + strtol( p1->psz_extra, &psz_end1, 10 ); + strtol( p2->psz_extra, &psz_end2, 10 ); + if( psz_end2 == p2->psz_extra + && ( psz_end1 != p1->psz_extra || *p1->psz_extra == '\0' ) ) + d = 1; + } + } + if( d < 0 ) + return UPDATE_RELEASE_STATUS_OLDER; + else if( d == 0 ) + return UPDATE_RELEASE_STATUS_EQUAL; + else + return UPDATE_RELEASE_STATUS_NEWER; +} + +/** + * Compare a given release's version number to the current VLC's one + * + * \param p a release + * \return >0 if newer, 0 if equal and <0 if older + */ +int CompareReleaseToCurrent( struct update_release_t *p ) +{ + struct update_release_t c = {0}; + int r; + c.psz_major = STRDUP( PACKAGE_VERSION_MAJOR ); + c.psz_minor = STRDUP( PACKAGE_VERSION_MINOR ); + c.psz_revision = STRDUP( PACKAGE_VERSION_REVISION ); + c.psz_extra = STRDUP( PACKAGE_VERSION_EXTRA ); + r = CompareReleases( p, &c ); + free( c.psz_major ); + free( c.psz_minor ); + free( c.psz_revision ); + free( c.psz_extra ); + return r; +} + +/***************************************************************************** + * Updatei_iterator_t functions + *****************************************************************************/ + +/** + * Create a new update iterator structure. This structure can then be used to + * describe a position and move through the update and mirror trees/lists. + * This will use an existing update struct or create a new one if none is + * found + * + * \param p_u the calling update_t + * \return a pointer to an update iterator + */ +update_iterator_t *update_iterator_New( update_t *p_u ) +{ + update_iterator_t *p_uit = NULL; + + if( p_u == NULL ) + return NULL; + + p_uit = (update_iterator_t *)malloc( sizeof( update_iterator_t ) ); + if( p_uit == NULL ) return NULL; + + p_uit->p_u = p_u; + + p_uit->i_m = -1; + p_uit->i_r = -1; + p_uit->i_f = -1; + + p_uit->i_t = UPDATE_FILE_TYPE_ALL; + p_uit->i_rs = UPDATE_RELEASE_STATUS_ALL; + p_uit->i_rt = UPDATE_RELEASE_TYPE_STABLE; + + p_uit->file.i_type = UPDATE_FILE_TYPE_NONE; + p_uit->file.psz_md5 = NULL; + p_uit->file.psz_url = NULL; + p_uit->file.l_size = 0; + p_uit->file.psz_description = NULL; + + p_uit->release.psz_version = NULL; + p_uit->release.psz_svn_revision = NULL; + p_uit->release.i_type = UPDATE_RELEASE_TYPE_UNSTABLE; + p_uit->release.i_status = UPDATE_RELEASE_STATUS_NONE; + + p_uit->mirror.psz_name = NULL; + p_uit->mirror.psz_location = NULL; + p_uit->mirror.psz_type = NULL; + + return p_uit; +} + +/** + * Delete an update iterator structure (duh!) + * + * \param p_uit pointer to an update iterator + * \return nothing + */ +void update_iterator_Delete( update_iterator_t *p_uit ) +{ + if( !p_uit ) return; + update_iterator_ClearData( p_uit ); + free( p_uit ); +} + +/** + * Reset an update_iterator_t structure + * + * \param p_uit pointer to an update iterator + * \return UPDATE_FAIL upon error, UPDATE_SUCCESS otherwise + */ +unsigned int update_iterator_Reset( update_iterator_t *p_uit ) +{ + if( !p_uit ) return UPDATE_FAIL; + + p_uit->i_r = -1; + p_uit->i_f = -1; + p_uit->i_m = -1; + + update_iterator_ClearData( p_uit ); + return UPDATE_SUCCESS; +} + +/** + * Finds the next file in the update tree that matches status and type + * requirements set in the update_iterator + * + * \param p_uit update iterator + * \return UPDATE_FAIL if we can't find the next file, UPDATE_SUCCESS|UPDATE_FILE if we stay in the same release, UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE if we change the release index + */ +unsigned int update_iterator_NextFile( update_iterator_t *p_uit ) +{ + int r,f=-1,old_r; + + if( !p_uit ) return UPDATE_FAIL; + + old_r=p_uit->i_r; + + /* if the update iterator was already in a "no match" state, start over */ + if( p_uit->i_r == -1 ) p_uit->i_r = 0; + //if( p_uit->i_f == -1 ) p_uit->i_f = 0; + + vlc_mutex_lock( &p_uit->p_u->lock ); + + for( r = p_uit->i_r; r < p_uit->p_u->i_releases; r++ ) + { + if( !( p_uit->p_u->p_releases[r].i_status & p_uit->i_rs ) ) continue; + for( f = ( r == p_uit->i_r ? p_uit->i_f + 1 : 0 ); + f < p_uit->p_u->p_releases[r].i_files; f++ ) + { + if( p_uit->p_u->p_releases[r].p_files[f].i_type & p_uit->i_t ) + { + goto done;/* "double break" */ + } + } + } + done: + p_uit->i_r = r; + p_uit->i_f = f; + + r = p_uit->p_u->i_releases; + + if( old_r == p_uit->i_r ) + { + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_SUCCESS|UPDATE_FILE; + } + else if( p_uit->i_r == r ) + { + p_uit->i_r = -1; + p_uit->i_f = -1; + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_FAIL; + } + else + { + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE; + } +} + +/** + * Finds the previous file in the update tree that matches status and type + * requirements set in the update_iterator + * + * \param p_uit update iterator + * \return UPDATE_FAIL if we can't find the previous file, UPDATE_SUCCESS|UPDATE_FILE if we stay in the same release, UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE if we change the release index + */ +//TODO: test +unsigned int update_iterator_PrevFile( update_iterator_t *p_uit ) +{ + int r,f=-1,old_r; + + if( !p_uit ) return UPDATE_FAIL; + + old_r=p_uit->i_r; + + /* if the update iterator was already in a "no match" state, start over + * (begin at the end of the list) */ + if( p_uit->i_r == -1 ) p_uit->i_r = p_uit->p_u->i_releases - 1; + p_uit->i_f = p_uit->p_u->p_releases[p_uit->i_r].i_files + 1; + + vlc_mutex_lock( &p_uit->p_u->lock ); + + for( r = p_uit->i_r; r >= 0; r-- ) + { + if( !( p_uit->p_u->p_releases[r].i_status & p_uit->i_rs ) ) continue; + for( f =( r==p_uit->i_r ? p_uit->i_f - 1 : p_uit->p_u->p_releases[r].i_files ); + f >= 0; f-- ) + { + if( p_uit->p_u->p_releases[r].p_files[f].i_type & p_uit->i_t ) + { + goto done;/* "double break" */ + } + } + } + done: + p_uit->i_r = r; + p_uit->i_f = f; + + r = p_uit->p_u->i_releases; + + if( old_r == p_uit->i_r ) + { + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_SUCCESS|UPDATE_FILE; + } + else if( p_uit->i_r == -1 ) + { + p_uit->i_r = -1; + p_uit->i_f = -1; + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_FAIL; + } + else + { + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE; + } +} + +/** + * Finds the next mirror in the update tree + * + * \param update iterator + * \return UPDATE_FAIL if we can't find the next mirror, UPDATE_SUCCESS|UPDATE_MIRROR otherwise + */ +unsigned int update_iterator_NextMirror( update_iterator_t *p_uit ) +{ + if( !p_uit ) return UPDATE_FAIL; + vlc_mutex_lock( &p_uit->p_u->lock ); + p_uit->i_m++; + if( p_uit->i_m >= p_uit->p_u->i_mirrors ) p_uit->i_m = -1; + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return p_uit->i_m == -1 ? UPDATE_FAIL : UPDATE_SUCCESS|UPDATE_MIRROR; +} + +/** + * Finds the previous mirror in the update tree + * + * \param update iterator + * \return UPDATE_FAIL if we can't find a previous mirror, UPDATE_SUCCESS|UPDATE_MIRROR otherwise + */ +unsigned int update_iterator_PrevMirror( update_iterator_t *p_uit ) +{ + if( !p_uit ) return UPDATE_FAIL; + vlc_mutex_lock( &p_uit->p_u->lock ); + p_uit->i_m--; + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + return p_uit->i_m == -1 ? UPDATE_FAIL : UPDATE_SUCCESS|UPDATE_MIRROR; +} + +/** + * Change the update iterator's position in the file and mirrors tree + * If position is negative, don't change it + * + * \param i_m position in mirrors list + * \param i_r position in releases list + * \param i_f position in release's files list + * \return UPDATE_FAIL when changing position fails or position wasn't changed, a combination of UPDATE_MIRROR, UPDATE_RELEASE and UPDATE_FILE otherwise + */ +unsigned int update_iterator_ChooseMirrorAndFile( update_iterator_t *p_uit, + int i_m, int i_r, int i_f ) +{ + unsigned int i_val = 0; + + if( !p_uit ) return 0; + vlc_mutex_lock( &p_uit->p_u->lock ); + + if( i_m >= 0 ) + { + if( i_m < p_uit->p_u->i_mirrors ) + { + if( i_m != p_uit->i_m ) + i_val |= UPDATE_MIRROR; + p_uit->i_m = i_m; + } + else i_m = -1; + } + + if( i_r >= 0 ) + { + if( i_r < p_uit->p_u->i_releases ) + { + if( i_r != p_uit->i_r ) + i_val |= UPDATE_FILE; + p_uit->i_r = i_r; + } + else i_r = -1; + } + + if( i_f >= 0 ) + { + if( i_r >= 0 && i_r < p_uit->p_u->i_releases + && i_f < p_uit->p_u->p_releases[p_uit->i_r].i_files ) + { + if( i_f != p_uit->i_f ) + i_val |= UPDATE_FILE; + p_uit->i_f = i_f; + } + else i_f = -1; + } + + update_iterator_GetData( p_uit ); + vlc_mutex_unlock( &p_uit->p_u->lock ); + + if( ( i_m < 0 || p_uit->i_m >= 0 ) + && ( i_r < 0 || p_uit->i_r >= 0 ) + && ( i_f < 0 || p_uit->i_f >= 0 ) ) + { + /* Everything worked */ + return UPDATE_SUCCESS|i_val; + } + else + { + /* Something failed */ + return UPDATE_FAIL; + } +} + +/** + * Fills the iterator data (file, release and mirror structs) + * The update struct should be locked before calling this function. + * + * \param p_uit update iterator + * \return nothing + */ +void update_iterator_GetData( update_iterator_t *p_uit ) +{ + struct update_release_t *p_r = NULL; + struct update_file_t *p_f = NULL; + struct update_mirror_t *p_m = NULL; + + update_iterator_ClearData( p_uit ); + + if( p_uit->i_m >= 0 ) + { + p_m = p_uit->p_u->p_mirrors + p_uit->i_m; + p_uit->mirror.psz_name = STRDUP( p_m->psz_name ); + p_uit->mirror.psz_location = STRDUP( p_m->psz_location ); + p_uit->mirror.psz_type = STRDUP( p_m->psz_type ); + } + + if( p_uit->i_r >= 0 ) + { + p_r = p_uit->p_u->p_releases + p_uit->i_r; + asprintf( &p_uit->release.psz_version, "%s.%s.%s-%s", + p_r->psz_major, + p_r->psz_minor, + p_r->psz_revision, + p_r->psz_extra ); + p_uit->release.psz_svn_revision = STRDUP( p_r->psz_svn_revision ); + p_uit->release.i_type = p_r->i_type; + p_uit->release.i_status = p_r->i_status; + if( p_uit->i_f >= 0 ) + { + p_f = p_r->p_files + p_uit->i_f; + p_uit->file.i_type = p_f->i_type; + p_uit->file.psz_md5 = STRDUP( p_f->psz_md5 ); + p_uit->file.l_size = p_f->l_size; + p_uit->file.psz_description = STRDUP( p_f->psz_description); + if( p_f->psz_url[0] == '/' ) + { + if( p_m ) + { + asprintf( &p_uit->file.psz_url, "%s%s", + p_m->psz_base_url, p_f->psz_url ); + } + } + else + { + p_uit->file.psz_url = STRDUP( p_f->psz_url ); + } + } + } +} + +/** + * Clears the iterator data (file, release and mirror structs) + * + * \param p_uit update iterator + * \return nothing + */ +void update_iterator_ClearData( update_iterator_t *p_uit ) +{ + p_uit->file.i_type = UPDATE_FILE_TYPE_NONE; + FREE( p_uit->file.psz_md5 ); + p_uit->file.l_size = 0; + FREE( p_uit->file.psz_description ); + FREE( p_uit->file.psz_url ); + FREE( p_uit->release.psz_version ); + FREE( p_uit->release.psz_svn_revision ); + p_uit->release.i_type = UPDATE_RELEASE_TYPE_UNSTABLE; + p_uit->release.i_status = UPDATE_RELEASE_STATUS_NONE; + FREE( p_uit->mirror.psz_name ); + FREE( p_uit->mirror.psz_location ); + FREE( p_uit->mirror.psz_type ); +} + +/** + * Perform an action on the update iterator + * Only the first matching action is performed. + * + * \param p_uit update iterator + * \param i_action update action bitmask. can be a combination of UPDATE_NEXT, UPDATE_PREV, UPDATE_MIRROR, UPDATE_RELEASE, UPDATE_FILE, UPDATE_RESET + * \return UPDATE_FAIL if action fails, UPDATE_SUCCESS|(combination of UPDATE_MIRROR, UPDATE_RELEASE and UPDATE_FILE if these changed) otherwise + */ +unsigned int update_iterator_Action( update_iterator_t *p_uit, int i_action ) +{ + if( i_action & UPDATE_RESET ) + { + return update_iterator_Reset( p_uit ); + } + else + if( i_action & UPDATE_MIRROR ) + { + if( i_action & UPDATE_PREV ) + { + return update_iterator_PrevMirror( p_uit ); + } + else + { + return update_iterator_NextMirror( p_uit ); + } + } + /*else if( i_action & UPDATE_RELEASE ) + { + if( i_action & UPDATE_PREV ) + { + return update_iterator_PrevRelease( p_uit ); + } + else + { + return update_iterator_NextRelease( p_uit ); + } + }*/ + else if( i_action & UPDATE_FILE ) + { + if( i_action & UPDATE_PREV ) + { + return update_iterator_PrevFile( p_uit ); + } + else + { + return update_iterator_NextFile( p_uit ); + } + } + else + { + return UPDATE_SUCCESS; + } +} + +/** + * Download the file selected by the update iterator + * + * \param p_uit update iterator + * \param psz_dest destination file path + * \return nothing + */ +void update_download( update_iterator_t *p_uit, char *psz_dest ) +{ + char *psz_src = p_uit->file.psz_url; + stream_t *p_stream; + vlc_t *p_vlc = p_uit->p_u->p_vlc; + + FILE *p_file = NULL; + void *p_buffer; + + char *psz_status; + + int i_progress; + int i_size; + int i_done = 0; + + p_stream = stream_UrlNew( p_vlc, psz_src ); + if( !p_stream ) + { + msg_Err( p_vlc, "Failed to open %s for reading", psz_src ); + return; + } + + p_file = fopen( psz_dest, "w" ); + if( !p_file ) + { + msg_Err( p_vlc, "Failed to open %s for writing", psz_dest ); + return; + } + + i_size = (int)(stream_Size(p_stream)/(1<<10)); + p_buffer = (void *)malloc( 1<<10 ); + + asprintf( &psz_status, + "%s - %s (%s)\n" + "Source: %s\n" + "Destination: %s\n" + "Downloading... %.1f%% done", + p_uit->file.psz_description, p_uit->release.psz_version, + p_uit->release.psz_svn_revision, p_uit->file.psz_url, + psz_dest, 0.0 ); + i_progress = intf_UserProgress( p_vlc, "Downloading...", psz_status, 0.0 ); + + while( stream_Read( p_stream, p_buffer, 1<<10 ) ) + { + float f_progress; + + fwrite( p_buffer, 1<<10, 1, p_file ); + + i_done++; + free( psz_status ); + f_progress = 100.0*(float)i_done/(float)i_size; + asprintf( &psz_status, + "%s - %s (%s)\n" + "Source: %s\n" + "Destination: %s\n" + "Downloading... %.1f%% done", + p_uit->file.psz_description, p_uit->release.psz_version, + p_uit->release.psz_svn_revision, p_uit->file.psz_url, + psz_dest, f_progress ); + intf_UserProgressUpdate( p_vlc, i_progress, psz_status, f_progress ); + } + + free( p_buffer ); + free( psz_status ); + fclose( p_file ); + stream_Delete( p_stream ); +}