gpointer thumbnail_loader_thread( VFSAsyncTask* task, VFSThumbnailLoader* loader ) { ThumbnailRequest* req; int i; gboolean load_big, need_update; while( G_LIKELY( ! vfs_async_task_is_cancelled(task) )) { vfs_async_task_lock( task ); req = (ThumbnailRequest*)g_queue_pop_head( loader->queue ); vfs_async_task_unlock( task ); if( G_UNLIKELY( ! req ) ) break; /* g_debug("pop: %s", req->file->name); */ /* Only we have the reference. That means, no body is using the file */ if( req->file->n_ref == 1 ) { thumbnail_request_free( req ); continue; } need_update = FALSE; for ( i = 0; i < 2; ++i ) { if ( 0 == req->n_requests[ i ] ) continue; load_big = ( i == LOAD_BIG_THUMBNAIL ); if ( ! vfs_file_info_is_thumbnail_loaded( req->file, load_big ) ) { char* full_path; full_path = g_build_filename( loader->dir->path, vfs_file_info_get_name( req->file ), NULL ); vfs_file_info_load_thumbnail( req->file, full_path, load_big ); g_free( full_path ); /* Slow down for displaying. */ g_usleep(G_USEC_PER_SEC/1000); /* g_debug( "thumbnail loaded: %s", req->file ); */ } need_update = TRUE; } if( ! vfs_async_task_is_cancelled(task) && need_update ) { vfs_async_task_lock( task ); g_queue_push_tail( loader->update_queue, vfs_file_info_ref(req->file) ); if( 0 == loader->idle_handler) loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL ); vfs_async_task_unlock( task ); } /* g_debug( "NEED_UPDATE: %d", need_update ); */ thumbnail_request_free( req ); } if( vfs_async_task_is_cancelled(task) ) { /* g_debug( "THREAD CANCELLED!!!" ); */ vfs_async_task_lock( task ); if( loader->idle_handler) { g_source_remove( loader->idle_handler ); loader->idle_handler = 0; } vfs_async_task_unlock( task ); } else { if( 0 == loader->idle_handler) { /* g_debug( "ADD IDLE HANDLER BEFORE THREAD ENDING" ); */ loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL ); } } /* g_debug("THREAD ENDED!"); */ return NULL; }
gpointer vfs_dir_load_thread( VFSAsyncTask* task, VFSDir* dir ) { const gchar * file_name; char* full_path; GDir* dir_content; VFSFileInfo* file; char* hidden = NULL; //MOD added dir->file_listed = 0; dir->load_complete = 0; dir->xhidden_count = 0; //MOD if ( dir->path ) { /* Install file alteration monitor */ dir->monitor = vfs_file_monitor_add_dir( dir->path, vfs_dir_monitor_callback, dir ); dir_content = g_dir_open( dir->path, 0, NULL ); if ( dir_content ) { GKeyFile* kf; if( G_UNLIKELY(dir->is_trash) ) kf = g_key_file_new(); // MOD dir contains .hidden file? hidden = gethidden( dir->path ); while ( ! vfs_async_task_is_cancelled( dir->task ) && ( file_name = g_dir_read_name( dir_content ) ) ) { full_path = g_build_filename( dir->path, file_name, NULL ); if ( !full_path ) continue; //MOD ignore if in .hidden if ( hidden && ishidden( hidden, file_name ) ) { dir->xhidden_count++; continue; } /* FIXME: Is locking GDK needed here? */ /* GDK_THREADS_ENTER(); */ file = vfs_file_info_new(); if ( G_LIKELY( vfs_file_info_get( file, full_path, file_name ) ) ) { g_mutex_lock( dir->mutex ); /* Special processing for desktop folder */ vfs_file_info_load_special_info( file, full_path ); /* FIXME: load info, too when new file is added to trash dir */ if( G_UNLIKELY( dir->is_trash ) ) /* load info of trashed files */ { gboolean info_loaded; char* info = g_strconcat( home_trash_dir, "/info/", file_name, ".trashinfo", NULL ); info_loaded = g_key_file_load_from_file( kf, info, 0, NULL ); g_free( info ); if( info_loaded ) { char* ori_path = g_key_file_get_string( kf, "Trash Info", "Path", NULL ); if( ori_path ) { /* Thanks to the stupid freedesktop.org spec, the filename is encoded * like a URL, which is insane. This add nothing more than overhead. */ char* fake_uri = g_strconcat( "file://", ori_path, NULL ); g_free( ori_path ); ori_path = g_filename_from_uri( fake_uri, NULL, NULL ); /* g_debug( ori_path ); */ if( file->disp_name && file->disp_name != file->name ) g_free( file->disp_name ); file->disp_name = g_filename_display_basename( ori_path ); g_free( ori_path ); } } } dir->file_list = g_list_prepend( dir->file_list, file ); g_mutex_unlock( dir->mutex ); ++dir->n_files; } else { vfs_file_info_unref( file ); } /* GDK_THREADS_LEAVE(); */ g_free( full_path ); } g_dir_close( dir_content ); if ( hidden ) g_free( hidden ); if( G_UNLIKELY(dir->is_trash) ) g_key_file_free( kf ); } } return NULL; }