X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fncurses.c;h=101d4cf01c5974086afa85cb95da51036fcc98ff;hb=9e11182b0b6accaaed446c064836d37e7249f8b1;hp=ff6a29e29917531a74cd0ffa51ead1bb0ca6ae25;hpb=49a88c0e0f1e634f278fb14068853b313d849900;p=vlc diff --git a/modules/gui/ncurses.c b/modules/gui/ncurses.c index ff6a29e299..101d4cf01c 100644 --- a/modules/gui/ncurses.c +++ b/modules/gui/ncurses.c @@ -1,7 +1,7 @@ /***************************************************************************** * ncurses.c : NCurses plugin for vlc ***************************************************************************** - * Copyright (C) 2001-2004 VideoLAN + * Copyright (C) 2001-2006 the VideoLAN team * $Id$ * * Authors: Sam Hocevar @@ -21,7 +21,7 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -39,6 +39,7 @@ #include #include #include +#include "charset.h" #ifdef HAVE_SYS_STAT_H # include @@ -75,14 +76,19 @@ static void Eject ( intf_thread_t * ); static int HandleKey ( intf_thread_t *, int ); static void Redraw ( intf_thread_t *, time_t * ); + +static playlist_item_t *PlaylistGetRoot( intf_thread_t * ); static void PlaylistRebuild( intf_thread_t * ); static void PlaylistAddNode( intf_thread_t *, playlist_item_t *, int, char *); static void PlaylistDestroy( intf_thread_t * ); static int PlaylistChanged( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); +static inline vlc_bool_t PlaylistIsPlaying( intf_thread_t *, + playlist_item_t * ); static void FindIndex ( intf_thread_t * ); static void SearchPlaylist ( intf_thread_t *, char * ); static int SubSearchPlaylist( intf_thread_t *, char *, int, int ); + static void ManageSlider ( intf_thread_t * ); static void ReadDir ( intf_thread_t * ); @@ -100,7 +106,7 @@ vlc_module_begin(); set_description( _("Ncurses interface") ); set_capability( "interface", 10 ); set_category( CAT_INTERFACE ); - set_subcategory( SUBCAT_INTERFACE_GENERAL ); + set_subcategory( SUBCAT_INTERFACE_MAIN ); set_callbacks( Open, Close ); add_shortcut( "curses" ); add_directory( "browse-dir", NULL, NULL, BROWSE_TEXT, BROWSE_LONGTEXT, VLC_FALSE ); @@ -120,6 +126,11 @@ enum BOX_OPEN, BOX_BROWSE }; +enum +{ + VIEW_CATEGORY, + VIEW_ONELEVEL +}; struct dir_entry_t { vlc_bool_t b_file; @@ -160,10 +171,12 @@ struct intf_sys_t int i_before_search; char *psz_open_chain; + char psz_partial_keys[7]; char *psz_current_dir; int i_dir_entries; struct dir_entry_t **pp_dir_entries; + vlc_bool_t b_show_hidden_files; int i_current_view; /* playlist view */ struct pl_item_t **pp_plist; @@ -171,7 +184,7 @@ struct intf_sys_t vlc_bool_t b_need_update; /* for playlist view */ }; -static void DrawBox( WINDOW *win, int y, int x, int h, int w, char *title ); +static void DrawBox( WINDOW *win, int y, int x, int h, int w, const char *title ); static void DrawLine( WINDOW *win, int y, int x, int w ); static void DrawEmptyLine( WINDOW *win, int y, int x, int w ); @@ -199,7 +212,8 @@ static int Open( vlc_object_t *p_this ) p_sys->i_box_plidx = 0; p_sys->p_plnode = NULL; p_sys->i_box_bidx = 0; - p_sys->p_sub = msg_Subscribe( p_intf ); + p_sys->p_sub = msg_Subscribe( p_intf, MSG_QUEUE_NORMAL ); + memset( p_sys->psz_partial_keys, 0, sizeof( p_sys->psz_partial_keys ) ); /* Initialize the curses library */ p_sys->w = initscr(); @@ -243,7 +257,7 @@ static int Open( vlc_object_t *p_this ) if( val.psz_string && *val.psz_string ) { - p_sys->psz_current_dir = strdup( val.psz_string); + p_sys->psz_current_dir = strdup( val.psz_string ); free( val.psz_string ); } else @@ -253,6 +267,7 @@ static int Open( vlc_object_t *p_this ) p_sys->i_dir_entries = 0; p_sys->pp_dir_entries = NULL; + p_sys->b_show_hidden_files = VLC_FALSE; ReadDir( p_intf ); return VLC_SUCCESS; @@ -362,12 +377,12 @@ static void Run( intf_thread_t *p_intf ) vlc_mutex_unlock( &p_sys->p_playlist->object_lock ); } - if( p_sys->b_box_plidx_follow && p_sys->p_playlist->i_index >= 0 ) + if( p_sys->b_box_plidx_follow && p_sys->p_playlist->status.p_item ) { FindIndex( p_intf ); } - while( ( i_key = getch()) != -1 ) + while( ( i_key = getch() ) != -1 ) { /* * HandleKey returns 1 if the screen needs to be redrawn @@ -398,6 +413,52 @@ static void Run( intf_thread_t *p_intf ) /* following functions are local */ +static char *KeyToUTF8( int i_key, char *psz_part ) +{ + char *psz_utf8, *psz; + int len = strlen( psz_part ); + if( len == 6 ) + { + /* overflow error - should not happen */ + memset( psz_part, 0, 6 ); + return NULL; + } + + psz_part[len] = (char)i_key; + + psz_utf8 = FromLocaleDup( psz_part ); + + /* Ugly check for incomplete bytes sequences + * (in case of non-UTF8 multibyte local encoding) */ + for( psz = psz_utf8; *psz; psz++ ) + if( ( *psz == '?' ) && ( *psz_utf8 != '?' ) ) + { + /* incomplete bytes sequence detected + * (VLC core inserted dummy question marks) */ + free( psz_utf8 ); + return NULL; + } + + /* Check for incomplete UTF8 bytes sequence */ + if( EnsureUTF8( psz_utf8 ) == NULL ) + { + free( psz_utf8 ); + return NULL; + } + + memset( psz_part, 0, 6 ); + return psz_utf8; +} + +static inline int RemoveLastUTF8Entity( char *psz, int len ) +{ + while( len && ( (psz[--len] & 0xc0) == 0x80 ) ); + /* UTF8 continuation byte */ + + psz[len] = '\0'; + return len; +} + static int HandleKey( intf_thread_t *p_intf, int i_key ) { intf_sys_t *p_sys = p_intf->p_sys; @@ -406,6 +467,7 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) if( p_sys->i_box_type == BOX_PLAYLIST && p_sys->p_playlist ) { int b_ret = VLC_TRUE; + vlc_bool_t b_box_plidx_follow = VLC_FALSE; switch( i_key ) { @@ -429,10 +491,16 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) /* Playlist sort */ case 'o': - playlist_Sort( p_sys->p_playlist, SORT_TITLE, ORDER_NORMAL ); + playlist_RecursiveNodeSort( p_sys->p_playlist, + PlaylistGetRoot( p_intf ), + SORT_TITLE_NODES_FIRST, ORDER_NORMAL ); + p_sys->b_need_update = VLC_TRUE; return 1; case 'O': - playlist_Sort( p_sys->p_playlist, SORT_TITLE, ORDER_REVERSE ); + playlist_RecursiveNodeSort( p_sys->p_playlist, + PlaylistGetRoot( p_intf ), + SORT_TITLE_NODES_FIRST, ORDER_REVERSE ); + p_sys->b_need_update = VLC_TRUE; return 1; /* Playlist view */ @@ -440,13 +508,13 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) switch( p_sys->i_current_view ) { case VIEW_CATEGORY: - p_sys->i_current_view = VIEW_ALL; + p_sys->i_current_view = VIEW_ONELEVEL; break; default: p_sys->i_current_view = VIEW_CATEGORY; } + //p_sys->b_need_update = VLC_TRUE; PlaylistRebuild( p_intf ); - FindIndex( p_intf ); return 1; /* Playlist navigation */ @@ -472,40 +540,42 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) case KEY_BACKSPACE: case KEY_DC: { - int i_item = p_sys->p_playlist->i_index; + playlist_t *p_playlist = p_sys->p_playlist; + playlist_item_t *p_item; - playlist_LockDelete( p_sys->p_playlist, p_sys->i_box_plidx ); - if( i_item < p_sys->p_playlist->i_size && - i_item != p_sys->p_playlist->i_index ) + vlc_mutex_lock( &p_playlist->object_lock ); + p_item = p_sys->pp_plist[p_sys->i_box_plidx]->p_item; + if( p_item->i_children == -1 ) { - playlist_Goto( p_sys->p_playlist, i_item ); + playlist_DeleteFromItemId( p_playlist, p_item->i_id ); } + else + { + playlist_NodeDelete( p_playlist, p_item, + VLC_TRUE , VLC_FALSE ); + } + vlc_mutex_unlock( &p_playlist->object_lock ); + p_sys->b_need_update = VLC_TRUE; + break; } case KEY_ENTER: case 0x0d: - if( p_sys->i_current_view == VIEW_ALL ) + if( p_sys->pp_plist[p_sys->i_box_plidx]->p_item->i_children + == -1 ) { - playlist_Goto( p_sys->p_playlist, p_sys->i_box_plidx ); + playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY, + NULL, + p_sys->pp_plist[p_sys->i_box_plidx]->p_item ); } else { - if( p_sys->pp_plist[p_sys->i_box_plidx]->p_item->i_children - == -1 ) - { - playlist_Control( p_sys->p_playlist, PLAYLIST_ITEMPLAY, - p_sys->pp_plist[p_sys->i_box_plidx]->p_item ); - } - else - { - playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY, - p_sys->i_current_view, - p_sys->pp_plist[p_sys->i_box_plidx]->p_item, - NULL ); - } + playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY, + p_sys->pp_plist[p_sys->i_box_plidx]->p_item, + NULL ); } - p_sys->b_box_plidx_follow = VLC_TRUE; + b_box_plidx_follow = VLC_TRUE; break; default: b_ret = VLC_FALSE; @@ -515,25 +585,12 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) if( b_ret ) { int i_max = p_sys->i_plist_entries; - if( p_sys->i_current_view == VIEW_ALL ) - i_max = p_sys->p_playlist->i_size; if( p_sys->i_box_plidx >= i_max ) p_sys->i_box_plidx = i_max - 1; if( p_sys->i_box_plidx < 0 ) p_sys->i_box_plidx = 0; - if( p_sys->i_current_view == VIEW_ALL ) - { - if( p_sys->i_box_plidx == p_sys->p_playlist->i_index ) - p_sys->b_box_plidx_follow = VLC_TRUE; - else - p_sys->b_box_plidx_follow = VLC_FALSE; - } - else - { - if( p_sys->pp_plist[p_sys->i_box_plidx]->p_item == - p_sys->p_playlist->status.p_item ) - p_sys->b_box_plidx_follow = VLC_TRUE; - else - p_sys->b_box_plidx_follow = VLC_FALSE; - } + if( PlaylistIsPlaying( p_intf, + p_sys->pp_plist[p_sys->i_box_plidx]->p_item ) ) + b_box_plidx_follow = VLC_TRUE; + p_sys->b_box_plidx_follow = b_box_plidx_follow; return 1; } } @@ -561,19 +618,27 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) case KEY_NPAGE: p_sys->i_box_bidx += p_sys->i_box_lines; break; + case '.': /* Toggle show hidden files */ + p_sys->b_show_hidden_files = ( p_sys->b_show_hidden_files == + VLC_TRUE ? VLC_FALSE : VLC_TRUE ); + ReadDir( p_intf ); + break; case KEY_ENTER: case 0x0d: - if( p_sys->pp_dir_entries[p_sys->i_box_bidx]->b_file ) + case ' ': + if( p_sys->pp_dir_entries[p_sys->i_box_bidx]->b_file || i_key == ' ' ) { int i_size_entry = strlen( p_sys->psz_current_dir ) + strlen( p_sys->pp_dir_entries[p_sys->i_box_bidx]->psz_path ) + 2; char *psz_uri = (char *)malloc( sizeof(char)*i_size_entry); sprintf( psz_uri, "%s/%s", p_sys->psz_current_dir, p_sys->pp_dir_entries[p_sys->i_box_bidx]->psz_path ); + /* XXX playlist_Add( p_sys->p_playlist, psz_uri, psz_uri, PLAYLIST_APPEND, PLAYLIST_END ); + */ p_sys->i_box_type = BOX_PLAYLIST; free( psz_uri ); } @@ -688,18 +753,23 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) p_sys->i_box_type = BOX_PLAYLIST; return 1; case KEY_BACKSPACE: - if( i_chain_len > 0 ) - { - p_sys->psz_search_chain[ i_chain_len - 1 ] = '\0'; - } + RemoveLastUTF8Entity( p_sys->psz_search_chain, i_chain_len ); break; default: - if( i_chain_len < SEARCH_CHAIN_SIZE ) + { + char *psz_utf8 = KeyToUTF8( i_key, p_sys->psz_partial_keys ); + + if( psz_utf8 != NULL ) { - p_sys->psz_search_chain[ i_chain_len++ ] = i_key; - p_sys->psz_search_chain[ i_chain_len ] = 0; + if( i_chain_len + strlen( psz_utf8 ) < SEARCH_CHAIN_SIZE ) + { + strcpy( p_sys->psz_search_chain + i_chain_len, + psz_utf8 ); + } + free( psz_utf8 ); } break; + } } if( p_sys->psz_old_search ) { @@ -723,9 +793,11 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) case 0x0d: if( p_playlist && i_chain_len > 0 ) { + /* playlist_Add( p_playlist, p_sys->psz_open_chain, p_sys->psz_open_chain, PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END ); + */ p_sys->b_box_plidx_follow = VLC_TRUE; } p_sys->i_box_type = BOX_PLAYLIST; @@ -734,18 +806,23 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) p_sys->i_box_type = BOX_PLAYLIST; return 1; case KEY_BACKSPACE: - if( i_chain_len > 0 ) - { - p_sys->psz_open_chain[ i_chain_len - 1 ] = '\0'; - } + RemoveLastUTF8Entity( p_sys->psz_open_chain, i_chain_len ); break; default: - if( i_chain_len < OPEN_CHAIN_SIZE ) + { + char *psz_utf8 = KeyToUTF8( i_key, p_sys->psz_partial_keys ); + + if( psz_utf8 != NULL ) { - p_sys->psz_open_chain[ i_chain_len++ ] = i_key; - p_sys->psz_open_chain[ i_chain_len ] = 0; + if( i_chain_len + strlen( psz_utf8 ) < OPEN_CHAIN_SIZE ) + { + strcpy( p_sys->psz_open_chain + i_chain_len, + psz_utf8 ); + } + free( psz_utf8 ); } break; + } } return 1; } @@ -835,16 +912,31 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) /* Common control */ case 'f': { - vout_thread_t *p_vout; if( p_intf->p_sys->p_input ) { + vout_thread_t *p_vout; p_vout = vlc_object_find( p_intf->p_sys->p_input, VLC_OBJECT_VOUT, FIND_CHILD ); if( p_vout ) { - p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE; + var_Get( p_vout, "fullscreen", &val ); + val.b_bool = !val.b_bool; + var_Set( p_vout, "fullscreen", val ); vlc_object_release( p_vout ); } + else + { + playlist_t *p_playlist; + p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist ) + { + var_Get( p_playlist, "fullscreen", &val ); + val.b_bool = !val.b_bool; + var_Set( p_playlist, "fullscreen", val ); + vlc_object_release( p_playlist ); + } + } } return 0; } @@ -971,7 +1063,6 @@ static void SearchPlaylist( intf_thread_t *p_intf, char *psz_searchstring ) int i_first = 0 ; int i_item = -1; intf_sys_t *p_sys = p_intf->p_sys; - playlist_t *p_playlist = p_sys->p_playlist; if( p_sys->i_before_search >= 0 ) { @@ -984,8 +1075,7 @@ static void SearchPlaylist( intf_thread_t *p_intf, char *psz_searchstring ) return; } - i_max = p_sys->i_current_view == VIEW_ALL ? - p_playlist->i_size : p_sys->i_plist_entries; + i_max = p_sys->i_plist_entries; i_item = SubSearchPlaylist( p_intf, psz_searchstring, i_first + 1, i_max ); if( i_item < 0 ) @@ -1002,33 +1092,15 @@ static int SubSearchPlaylist( intf_thread_t *p_intf, char *psz_searchstring, int i_start, int i_stop ) { intf_sys_t *p_sys = p_intf->p_sys; - playlist_t *p_playlist = p_sys->p_playlist; int i, i_item = -1; - if( p_sys->i_current_view == VIEW_ALL ) - { - for( i = i_start + 1; i < i_stop; i++ ) - { - if( strcasestr( p_playlist->pp_items[i]->input.psz_name, - psz_searchstring ) != NULL - || strcasestr( p_playlist->pp_items[i]->input.psz_uri, - psz_searchstring ) != NULL ) - { - i_item = i; - break; - } - } - } - else + for( i = i_start + 1; i < i_stop; i++ ) { - for( i = i_start + 1; i < i_stop; i++ ) + if( strcasestr( p_sys->pp_plist[i]->psz_display, + psz_searchstring ) != NULL ) { - if( strcasestr( p_sys->pp_plist[i]->psz_display, - psz_searchstring ) != NULL ) - { - i_item = i; - break; - } + i_item = i; + break; } } @@ -1054,6 +1126,7 @@ static void mvnprintw( int y, int x, int w, const char *p_fmt, ... ) { if( ( i_len = strlen( p_buf ) ) > w ) { + char *psz_local; int i_cut = i_len - w; int x1 = i_len/2 - i_cut/2; int x2 = x1 + i_cut; @@ -1069,11 +1142,15 @@ static void mvnprintw( int y, int x, int w, const char *p_fmt, ... ) p_buf[w/2 ] = '.'; p_buf[w/2+1] = '.'; } - mvprintw( y, x, "%s", p_buf ); + psz_local = ToLocale( p_buf ); + mvprintw( y, x, "%s", psz_local ); + LocaleFree( p_buf ); } else { - mvprintw( y, x, "%s", p_buf ); + char *psz_local = ToLocale( p_buf ); + mvprintw( y, x, "%s", psz_local ); + LocaleFree( p_buf ); mvhline( y, x + i_len, ' ', w - i_len ); } } @@ -1110,7 +1187,7 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) int h; int y_end; - //clear(); + clear(); /* Title */ attrset( A_REVERSE ); @@ -1247,6 +1324,12 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) MainBoxWrite( p_intf, l++, 1, " Delete an entry" ); MainBoxWrite( p_intf, l++, 1, "" ); + MainBoxWrite( p_intf, l++, 1, "[Filebrowser]" ); + MainBoxWrite( p_intf, l++, 1, " Add the selected file to the playlist" ); + MainBoxWrite( p_intf, l++, 1, " Add the selected directory to the playlist" ); + MainBoxWrite( p_intf, l++, 1, " . Show/Hide hidden files" ); + MainBoxWrite( p_intf, l++, 1, "" ); + MainBoxWrite( p_intf, l++, 1, "[Boxes]" ); MainBoxWrite( p_intf, l++, 1, " , Navigate through the box line by line" ); MainBoxWrite( p_intf, l++, 1, " , Navigate through the box page by page" ); @@ -1398,7 +1481,7 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) { attrset( A_REVERSE ); } - mvnprintw( y++, 1, COLS - 2, "%c %s", p_sys->pp_dir_entries[i_item]->b_file == VLC_TRUE ? '-' : '+', + mvnprintw( y++, 1, COLS - 2, " %c %s", p_sys->pp_dir_entries[i_item]->b_file == VLC_TRUE ? ' ' : '+', p_sys->pp_dir_entries[i_item]->psz_path ); if( b_selected ) { @@ -1412,16 +1495,14 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) p_sys->i_box_type == BOX_OPEN ) && p_sys->p_playlist ) { /* Playlist box */ - playlist_t *p_playlist = p_sys->p_playlist; int i_start, i_stop, i_max = p_sys->i_plist_entries; int i_item; char *psz_title; switch( p_sys->i_current_view ) { - case VIEW_ALL: - psz_title = strdup( " Playlist (All, unsorted) " ); - i_max = p_playlist->i_size; + case VIEW_ONELEVEL: + psz_title = strdup( " Playlist (All, one level) " ); break; case VIEW_CATEGORY: psz_title = strdup( " Playlist (By category) " ); @@ -1432,8 +1513,7 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) DrawBox( p_sys->w, y++, 0, h, COLS, psz_title ); - if( p_sys->i_current_view != VIEW_ALL && - ( p_sys->b_need_update || p_sys->pp_plist == NULL ) ) + if( p_sys->b_need_update || p_sys->pp_plist == NULL ) { PlaylistRebuild( p_intf ); } @@ -1443,6 +1523,8 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) } if( p_sys->i_box_plidx < 0 ) p_sys->i_box_plidx = 0; + if( p_sys->i_box_plidx < 0 ) p_sys->i_box_plidx = 0; + if( p_sys->i_box_plidx >= i_max ) p_sys->i_box_plidx = i_max - 1; if( p_sys->i_box_plidx < (h - 2)/2 ) { @@ -1468,50 +1550,11 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) i_stop = i_max; } - if( p_sys->i_current_view == VIEW_ALL ) - { - - for( i_item = i_start; i_item < i_stop; i_item++ ) - { - vlc_bool_t b_selected = ( p_sys->i_box_plidx == i_item ); - int c = p_playlist->i_index == i_item ? '>' : ' '; - - if( y >= y_end ) break; - if( b_selected ) - { - attrset( A_REVERSE ); - } - if( !strcmp( p_playlist->pp_items[i_item]->input.psz_name, - p_playlist->pp_items[i_item]->input.psz_uri ) ) - { - mvnprintw( y++, 1, COLS - 2, "%c %d - '%s'", - c, - i_item, - p_playlist->pp_items[i_item]->input.psz_uri ); - } - else - { - mvnprintw( y++, 1, COLS - 2, "%c %d - '%s' (%s)", - c, - i_item, - p_playlist->pp_items[i_item]->input.psz_uri, - p_playlist->pp_items[i_item]->input.psz_name ); - } - if( b_selected ) - { - attroff( A_REVERSE ); - } - } - - } - else - { - for( i_item = i_start; i_item < i_stop; i_item++ ) { vlc_bool_t b_selected = ( p_sys->i_box_plidx == i_item ); - int c = ( p_playlist->status.p_item == - p_sys->pp_plist[i_item]->p_item ) ? '>' : ' '; + int c = ( PlaylistIsPlaying( p_intf, + p_sys->pp_plist[i_item]->p_item ) ) ? '>' : ' '; if( y >= y_end ) break; if( b_selected ) @@ -1526,7 +1569,6 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) } } - } } else { @@ -1568,10 +1610,28 @@ static void Redraw( intf_thread_t *p_intf, time_t *t_last_refresh ) *t_last_refresh = time( 0 ); } +static playlist_item_t *PlaylistGetRoot( intf_thread_t *p_intf ) +{ + intf_sys_t *p_sys = p_intf->p_sys; + playlist_t *p_playlist = p_sys->p_playlist; + + if( p_playlist == NULL ) + { + return NULL; + } + + switch( p_sys->i_current_view ) + { + case VIEW_CATEGORY: + return p_playlist->p_root_category; + default: + return p_playlist->p_root_onelevel; + } +} + static void PlaylistRebuild( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; - playlist_view_t *p_view; playlist_t *p_playlist = p_sys->p_playlist; if( p_playlist == NULL ) @@ -1581,13 +1641,11 @@ static void PlaylistRebuild( intf_thread_t *p_intf ) vlc_mutex_lock( &p_playlist->object_lock ); - p_view = playlist_ViewFind( p_playlist, p_intf->p_sys->i_current_view ); - /* First clear the old one */ PlaylistDestroy( p_intf ); /* Build the new one */ - PlaylistAddNode( p_intf, p_view->p_root, 0, "" ); + PlaylistAddNode( p_intf, PlaylistGetRoot( p_intf ), 0, "" ); p_sys->b_need_update = VLC_FALSE; @@ -1611,19 +1669,19 @@ static void PlaylistAddNode( intf_thread_t *p_intf, playlist_item_t *p_node, int i_size; p_child = p_node->pp_children[k]; - i_size = strlen( c ) + strlen( p_child->input.psz_name ) + 4; + i_size = strlen( c ) + strlen( p_child->p_input->psz_name ) + 4; buff = (char *)malloc( sizeof( char ) * i_size ); p_pl_item = (struct pl_item_t *)malloc( sizeof( struct pl_item_t ) ); - if( p_pl_item == NULL || buff == NULL ) return; + if( p_pl_item == NULL || buff == NULL ) return; if( strlen( c ) ) { sprintf( buff, "%s%c-%s", c, k == p_node->i_children - 1 ? - '`' : '|', p_child->input.psz_name ); + '`' : '|', p_child->p_input->psz_name ); } else { - sprintf( buff, " %s", p_child->input.psz_name ); + sprintf( buff, " %s", p_child->p_input->psz_name ); } p_pl_item->psz_display = strdup( buff ); p_pl_item->p_item = p_child; @@ -1651,27 +1709,35 @@ static int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable, return VLC_SUCCESS; } +/* Playlist suxx */ +static inline vlc_bool_t PlaylistIsPlaying( intf_thread_t *p_intf, + playlist_item_t *p_item ) +{ + playlist_item_t *p_played_item = p_intf->p_sys->p_playlist->status.p_item; + return( p_item != NULL && p_played_item != NULL && + p_item->p_input != NULL && p_played_item->p_input != NULL && + p_item->p_input->i_id == p_played_item->p_input->i_id ); +} + static void FindIndex( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; int i; - if( p_sys->i_current_view == VIEW_ALL ) + if( p_sys->i_box_plidx < p_sys->i_plist_entries && + p_sys->i_box_plidx >= 0 && + PlaylistIsPlaying( p_intf, + p_sys->pp_plist[p_sys->i_box_plidx]->p_item ) ) { - p_sys->i_box_plidx = p_sys->p_playlist->i_index; + return; } - else if( ( p_sys->i_box_plidx < p_sys->i_plist_entries && - p_sys->pp_plist[p_sys->i_box_plidx]->p_item != - p_sys->p_playlist->status.p_item ) ) + + for( i = 0; i < p_sys->i_plist_entries; i++ ) { - for( i = 0; i < p_sys->i_plist_entries; i++ ) + if( PlaylistIsPlaying( p_intf, p_sys->pp_plist[i]->p_item ) ) { - if( p_sys->pp_plist[i]->p_item == - p_sys->p_playlist->status.p_item ) - { - p_sys->i_box_plidx = i; - break; - } + p_sys->i_box_plidx = i; + break; } } } @@ -1712,14 +1778,14 @@ static void Eject( intf_thread_t *p_intf ) vlc_mutex_lock( &p_playlist->object_lock ); - if( p_playlist->i_index < 0 ) + if( p_playlist->status.p_item == NULL ) { vlc_mutex_unlock( &p_playlist->object_lock ); vlc_object_release( p_playlist ); return; } - psz_name = p_playlist->pp_items[ p_playlist->i_index ]->input.psz_name; + psz_name = p_playlist->status.p_item->p_input->psz_name; if( psz_name ) { @@ -1802,17 +1868,32 @@ static void Eject( intf_thread_t *p_intf ) return; } +static int comp_dir_entries( const void *pp_dir_entry1, + const void *pp_dir_entry2 ) +{ + struct dir_entry_t *p_dir_entry1 = *(struct dir_entry_t**)pp_dir_entry1; + struct dir_entry_t *p_dir_entry2 = *(struct dir_entry_t**)pp_dir_entry2; + if ( p_dir_entry1->b_file == p_dir_entry2->b_file ) { + return strcasecmp( p_dir_entry1->psz_path, p_dir_entry2->psz_path ); + } + else + { + return ( p_dir_entry1->b_file ? 1 : -1 ); + } +} + static void ReadDir( intf_thread_t *p_intf ) { - intf_sys_t *p_sys = p_intf->p_sys; - DIR * p_current_dir; - struct dirent * p_dir_content; + intf_sys_t *p_sys = p_intf->p_sys; + DIR *p_current_dir; int i; if( p_sys->psz_current_dir && *p_sys->psz_current_dir ) { + const char *psz_entry; + /* Open the dir */ - p_current_dir = opendir( p_sys->psz_current_dir ); + p_current_dir = utf8_opendir( p_sys->psz_current_dir ); if( p_current_dir == NULL ) { @@ -1838,21 +1919,30 @@ static void ReadDir( intf_thread_t *p_intf ) p_sys->i_dir_entries = 0; /* get the first directory entry */ - p_dir_content = readdir( p_current_dir ); + psz_entry = utf8_readdir( p_current_dir ); /* while we still have entries in the directory */ - while( p_dir_content != NULL ) + while( psz_entry != NULL ) { #if defined( S_ISDIR ) struct stat stat_data; #endif struct dir_entry_t *p_dir_entry; int i_size_entry = strlen( p_sys->psz_current_dir ) + - strlen( p_dir_content->d_name ) + 2; - char *psz_uri = (char *)malloc( sizeof(char)*i_size_entry); + strlen( psz_entry ) + 2; + char *psz_uri; + + if( p_sys->b_show_hidden_files == VLC_FALSE && + ( strlen( psz_entry ) && psz_entry[0] == '.' ) && + strcmp( psz_entry, ".." ) ) + { + LocaleFree( psz_entry ); + psz_entry = utf8_readdir( p_current_dir ); + continue; + } - sprintf( psz_uri, "%s/%s", p_sys->psz_current_dir, - p_dir_content->d_name ); + psz_uri = (char *)malloc( sizeof(char)*i_size_entry); + sprintf( psz_uri, "%s/%s", p_sys->psz_current_dir, psz_entry ); if( !( p_dir_entry = malloc( sizeof( struct dir_entry_t) ) ) ) { @@ -1861,31 +1951,37 @@ static void ReadDir( intf_thread_t *p_intf ) } #if defined( S_ISDIR ) - stat( psz_uri, &stat_data ); + utf8_stat( psz_uri, &stat_data ); if( S_ISDIR(stat_data.st_mode) ) -#elif defined( DT_DIR ) - if( p_dir_content->d_type & DT_DIR ) +/*#elif defined( DT_DIR ) + if( p_dir_content->d_type & DT_DIR )*/ #else if( 0 ) #endif { - p_dir_entry->psz_path = strdup( p_dir_content->d_name ); + p_dir_entry->psz_path = strdup( psz_entry ); p_dir_entry->b_file = VLC_FALSE; INSERT_ELEM( p_sys->pp_dir_entries, p_sys->i_dir_entries, p_sys->i_dir_entries, p_dir_entry ); } else { - p_dir_entry->psz_path = strdup( p_dir_content->d_name ); + p_dir_entry->psz_path = strdup( psz_entry ); p_dir_entry->b_file = VLC_TRUE; INSERT_ELEM( p_sys->pp_dir_entries, p_sys->i_dir_entries, p_sys->i_dir_entries, p_dir_entry ); } free( psz_uri ); + LocaleFree( psz_entry ); /* Read next entry */ - p_dir_content = readdir( p_current_dir ); + psz_entry = utf8_readdir( p_current_dir ); } + + /* Sort */ + qsort( p_sys->pp_dir_entries, p_sys->i_dir_entries, + sizeof(struct dir_entry_t*), &comp_dir_entries ); + closedir( p_current_dir ); return; } @@ -1923,7 +2019,7 @@ static void PlayPause( intf_thread_t *p_intf ) /**************************************************************************** * ****************************************************************************/ -static void DrawBox( WINDOW *win, int y, int x, int h, int w, char *title ) +static void DrawBox( WINDOW *win, int y, int x, int h, int w, const char *title ) { int i; int i_len;