⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfs-mime-type.c

📁 台湾人开发的Linux下的文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/**  C Implementation: vfs-mime_type-type** Description:*** Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006** Copyright: See COPYING file that comes with this distribution**/#include "vfs-mime-type.h"#include "vfs-file-monitor.h"#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <gtk/gtk.h>#include "glib-mem.h"static GHashTable *mime_hash = NULL;static guint reload_callback_id = 0;static int big_icon_size = 32, small_icon_size = 16;const char mime_actions_group[] = "MIME Cache";static GKeyFile *mime_actions = NULL;static GKeyFile *user_actions = NULL;VFSFileMonitor* mime_actions_monitor = NULL;static guint theme_change_notify = 0;static void on_icon_theme_changed( GtkIconTheme *icon_theme,                                   gpointer user_data );#if 0/* FIXME: Don't cache mime actions since they change often */static void free_old_actions( gpointer key,                              gpointer value,                              gpointer user_data ){    VFSMimeType * mime_type = ( VFSMimeType* ) value;    g_strfreev( mime_type->actions );    mime_type->actions = NULL;}#endifstatic void reload_mime_actions( VFSFileMonitor* fm,                                 VFSFileMonitorEvent event,                                 const char* file_name,                                 gpointer user_data ){#if 0    /* unload all old cached data */    /* FIXME: Why sometimes this callback gets called twice? */    g_hash_table_foreach( mime_hash, free_old_actions, NULL );#endif    GDK_THREADS_ENTER();    if ( mime_actions )    {        g_key_file_free( mime_actions );        /* reload data */        mime_actions = g_key_file_new();        g_key_file_load_from_file( mime_actions,                                   fm->path,                                   G_KEY_FILE_NONE, NULL );    }    GDK_THREADS_LEAVE();}static void init_mime_actions(){    /* FIXME: Paths of directories shouldn't be hardcoded */    gchar * full_path = g_build_filename( "/usr/share",                                          "applications/mimeinfo.cache",                                          NULL );    mime_actions = g_key_file_new();    g_key_file_load_from_file( mime_actions,                               full_path,                               G_KEY_FILE_NONE, NULL );    /* FIXME: using file monitors for this purpose is a waste and should be changed */    mime_actions_monitor = vfs_file_monitor_add( full_path,                                                 reload_mime_actions,                                                 mime_hash );    g_free( full_path );    full_path = g_build_filename( g_get_home_dir(),                                  ".pcmanfm/mime_info",                                  NULL );    user_actions = g_key_file_new();    g_key_file_load_from_file( user_actions,                               full_path,                               G_KEY_FILE_NONE, NULL );    g_free( full_path );}/* Final clean up */void finalize_mime_actions(){    if ( mime_actions )        g_key_file_free( mime_actions );    if ( user_actions )        g_key_file_free( user_actions );    if ( mime_actions_monitor )        vfs_file_monitor_remove( mime_actions_monitor,                                 reload_mime_actions, mime_hash );}/* Save user profile */static void save_mime_actions(){    gchar * full_path;    gchar* data;    gsize len;    int file;    if ( ! mime_actions && ! user_actions )        init_mime_actions();    if ( user_actions )    {        if ( (data = g_key_file_to_data ( user_actions, &len, NULL )) )        {            full_path = g_build_filename( g_get_home_dir(),                                          ".pcmanfm/mime_info",                                          NULL );            file = creat( full_path, S_IWUSR | S_IRUSR | S_IRGRP );            g_free( full_path );            if ( file != -1 )            {                write( file, data, len );                close( file );            }            else            {                g_warning( "Cannot save mime actions\n" );            }            g_free( data );        }    }}static void vfs_mime_type_reload( void* user_data ){    /* FIXME: process mime database reloading properly. */    /* Remove all items in the hash table */    GDK_THREADS_ENTER();    g_hash_table_foreach_remove ( mime_hash, ( GHRFunc ) gtk_true, NULL );    GDK_THREADS_LEAVE();}void vfs_mime_type_init(){    GtkIconTheme * theme;    xdg_mime_init();    reload_callback_id = xdg_mime_register_reload_callback( vfs_mime_type_reload,                                                            NULL, NULL );    mime_hash = g_hash_table_new_full( g_str_hash, g_str_equal,                                       NULL, vfs_mime_type_unref );    theme = gtk_icon_theme_get_default();    theme_change_notify = g_signal_connect( theme, "changed",                                            G_CALLBACK( on_icon_theme_changed ),                                            NULL );}void vfs_mime_type_clean(){    GtkIconTheme * theme;    theme = gtk_icon_theme_get_default();    g_signal_handler_disconnect( theme, theme_change_notify );    xdg_mime_remove_callback( reload_callback_id );    xdg_mime_shutdown();    g_hash_table_destroy( mime_hash );    if ( mime_actions || user_actions )        finalize_mime_actions();}VFSMimeType* vfs_mime_type_get_from_file_name( const char* ufile_name ){    const char * type;    type = xdg_mime_get_mime_type_from_file_name( ufile_name );    return vfs_mime_type_get_from_type( type );}VFSMimeType* vfs_mime_type_get_from_file( const char* file_path,                                          const char* base_name,                                          struct stat* pstat ){    struct stat file_stat;    const char* type;    /* We have to get the mime-type of target path       when the file itself is a symlink */    if ( !pstat || S_ISLNK( pstat->st_mode ) )    {        /* FIXME: If the file doesn't exist, should we return NULL? */        if ( stat( file_path, &file_stat ) == 0 )            pstat = &file_stat;    }    if ( S_ISDIR( pstat->st_mode ) )    {        type = XDG_MIME_TYPE_DIRECTORY;    }    else    {        if ( !base_name )        {            base_name = strrchr( file_path, '/' );            if ( base_name )            {                ++base_name;            }            else            {                base_name = file_path;            }        }        type = xdg_mime_get_mime_type_for_file( file_path, base_name, pstat );    }    return vfs_mime_type_get_from_type( type );}VFSMimeType* vfs_mime_type_get_from_type( const char* type ){    VFSMimeType * mime_type;    mime_type = g_hash_table_lookup( mime_hash, type );    if ( !mime_type )    {        mime_type = vfs_mime_type_new( type );        g_hash_table_insert( mime_hash, mime_type->type, mime_type );    }    vfs_mime_type_ref( mime_type );    return mime_type;}VFSMimeType* vfs_mime_type_new( const char* type_name ){    VFSMimeType * mime_type = g_slice_new0( VFSMimeType );    mime_type->type = g_strdup( type_name );    mime_type->n_ref = 1;    return mime_type;}void vfs_mime_type_ref( VFSMimeType* mime_type ){    ++mime_type->n_ref;}void vfs_mime_type_unref( gpointer mime_type_ ){    VFSMimeType* mime_type = (VFSMimeType*)mime_type_;    --mime_type->n_ref;    if ( mime_type->n_ref == 0 )    {        g_free( mime_type->type );        if ( mime_type->big_icon )            gdk_pixbuf_unref( mime_type->big_icon );        if ( mime_type->small_icon )            gdk_pixbuf_unref( mime_type->small_icon );        /* g_strfreev( mime_type->actions ); */        g_slice_free( VFSMimeType, mime_type );    }}GdkPixbuf* vfs_mime_type_get_icon( VFSMimeType* mime_type, gboolean big ){    GdkPixbuf * icon = NULL;    const char* sep;    char icon_name[ 100 ];    GtkIconTheme *icon_theme;    int size;    if ( big )    {        if ( G_LIKELY( mime_type->big_icon ) )     /* big icon */            return gdk_pixbuf_ref( mime_type->big_icon );        size = big_icon_size;    }    else    /* small icon */    {        if ( G_LIKELY( mime_type->small_icon ) )            return gdk_pixbuf_ref( mime_type->small_icon );        size = small_icon_size;    }    icon_theme = gtk_icon_theme_get_default ();    if ( G_UNLIKELY( 0 == strcmp( mime_type->type, XDG_MIME_TYPE_DIRECTORY ) ) )    {        icon = gtk_icon_theme_load_icon ( icon_theme, "gnome-fs-directory",                                          size, 0, NULL );        if ( big )            mime_type->big_icon = icon;        else            mime_type->small_icon = icon;        return icon ? gdk_pixbuf_ref( icon ) : NULL;    }    sep = strchr( mime_type->type, '/' );    if ( !sep )        return NULL;    strcpy( icon_name, "gnome-mime-" );    strncat( icon_name, mime_type->type, ( sep - mime_type->type ) );    strcat( icon_name, "-" );    strcat( icon_name, sep + 1 );    icon = gtk_icon_theme_load_icon ( icon_theme, icon_name,                                      size, 0, NULL );    if ( ! icon )    {        icon_name[ 11 ] = 0;        strncat( icon_name, mime_type->type, ( sep - mime_type->type ) );        icon = gtk_icon_theme_load_icon ( icon_theme, icon_name,                                          size, 0, NULL );    }    if( G_UNLIKELY( !icon ) )    {        /* prevent endless recursion of XDG_MIME_TYPE_UNKNOWN */        if( G_LIKELY( strcmp(mime_type->type, XDG_MIME_TYPE_UNKNOWN) ) )        {            /* FIXME: fallback to icon of parent mime-type */            VFSMimeType* unknown;            unknown = vfs_mime_type_get_from_type( XDG_MIME_TYPE_UNKNOWN );            icon = vfs_mime_type_get_icon( unknown, big );            vfs_mime_type_unref( unknown );        }        else /* unknown */        {            icon = gtk_icon_theme_load_icon ( icon_theme, "unknown",                                              size, 0, NULL );        }    }    if ( big )        mime_type->big_icon = icon;    else        mime_type->small_icon = icon;    return icon ? gdk_pixbuf_ref( icon ) : NULL;}static void free_cached_icons ( gpointer key,                                gpointer value,                                gpointer user_data ){    VFSMimeType * mime_type = ( VFSMimeType* ) value;    gboolean big = ( gboolean ) user_data;    if ( big )    {        if ( mime_type->big_icon )        {            gdk_pixbuf_unref( mime_type->big_icon );            mime_type->big_icon = NULL;        }    }    else    {        if ( mime_type->small_icon )        {            gdk_pixbuf_unref( mime_type->small_icon );            mime_type->small_icon = NULL;        }    }}void vfs_mime_type_set_icon_size( int big, int small ){    if ( big != big_icon_size )    {        big_icon_size = big;        /* Unload old cached icons */        g_hash_table_foreach( mime_hash,                              free_cached_icons,                              ( gpointer ) TRUE );    }    if ( small != small_icon_size )    {        small_icon_size = small;        /* Unload old cached icons */        g_hash_table_foreach( mime_hash,                              free_cached_icons,                              ( gpointer ) FALSE );    }}void vfs_mime_type_get_icon_size( int* big, int* small ){    if ( big )        * big = big_icon_size;    if ( small )        * small = small_icon_size;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -