Logo Search packages:      
Sourcecode: pcmanfm version File versions  Download package

main.c

/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <glib.h>

#include <stdlib.h>

/* socket is used to keep single instance */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include "main-window.h"

#include "vfs-file-info.h"
#include "vfs-mime-type.h"
#include "vfs-app-desktop.h"

#include "vfs-file-monitor.h"
#include "vfs-volume.h"

#include "ptk-utils.h"
#include "app-chooser-dialog.h"

#include "glade-support.h"
#include "settings.h"

static char* init_path = NULL;

static int sock;
GIOChannel* io_channel = NULL;

static FMMainWindow* create_main_window();

static void open_file( const char* path );

static gboolean on_socket_event( GIOChannel* ioc,
                                 GIOCondition cond,
                                 gpointer data )
{
    int client, r;
    socklen_t addr_len = 0;
    struct sockaddr_un client_addr =
        {
            0
        };
    FMMainWindow* main_window;
    static char path[ PATH_MAX ];

    if ( cond & G_IO_IN )
    {
        client = accept( g_io_channel_unix_get_fd( ioc ), (struct sockaddr *)&client_addr, &addr_len );
        if ( client != -1 )
        {
            r = read( client, path, PATH_MAX );
            if ( r != -1 )
            {
                path[ r ] = '\0';
                GDK_THREADS_ENTER();
                if ( g_file_test( path, G_FILE_TEST_IS_DIR ) )
                {
                    main_window = create_main_window();
                    fm_main_window_add_new_tab( main_window, path,
                                                appSettings.showSidePane,
                                                appSettings.sidePaneMode );
                    gtk_window_present( GTK_WINDOW(main_window) );
                }
                else
                {
                    open_file( path );
                }
                GDK_THREADS_LEAVE();
            }
            shutdown( client, 2 );
            close( client );
        }
    }
    return TRUE;
}

static void get_socket_name( char* buf, int len )
{
    g_snprintf( buf, len, "/tmp/.pcmanfm-socket%s-%s", gdk_get_display(), g_get_user_name() );
}

static void single_instance_init()
{
    struct sockaddr_un addr;
    int addr_len;
    int ret;
    int reuse;

    if ( ( sock = socket( AF_UNIX, SOCK_STREAM, 0 ) ) == -1 )
    {
        ret = 1;
        goto _exit;
    }

    addr.sun_family = AF_UNIX;
    get_socket_name( addr.sun_path, sizeof( addr.sun_path ) );
#ifdef SUN_LEN

    addr_len = SUN_LEN( &addr );
#else

    addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
#endif

    if ( connect( sock, ( struct sockaddr* ) & addr, addr_len ) == 0 )
    {
        /* connected successfully */
        write( sock, init_path, strlen( init_path ) );
        shutdown( sock, 2 );
        close( sock );
        gdk_notify_startup_complete();

        ret = 0;
        goto _exit;
    }

    /* There is no existing server. So, we are in the first instance. */
    unlink( addr.sun_path ); /* delete old socket file if it exists. */
    reuse = 1;
    ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
    if ( bind( sock, ( struct sockaddr* ) & addr, addr_len ) == -1 )
    {
        ret = 1;
        goto _exit;
    }

    io_channel = g_io_channel_unix_new( sock );
    g_io_channel_set_encoding( io_channel, NULL, NULL );
    g_io_channel_set_buffered( io_channel, FALSE );

    g_io_add_watch( io_channel, G_IO_IN,
                    ( GIOFunc ) on_socket_event, NULL );

    if ( listen( sock, 5 ) == -1 )
    {
        ret = 1;
        goto _exit;
    }
    return ;

_exit:
    g_free( init_path );
    init_path = NULL;
    exit( ret );
}

static void single_instance_finalize()
{
    char lock_file[ 256 ];

    shutdown( sock, 2 );
    g_io_channel_unref( io_channel );
    close( sock );

    get_socket_name( lock_file, sizeof( lock_file ) );
    unlink( lock_file );
}

FMMainWindow* create_main_window()
{
    FMMainWindow * main_window = FM_MAIN_WINDOW(fm_main_window_new ());
    gtk_window_set_default_size( GTK_WINDOW( main_window ),
                                 appSettings.width, appSettings.height );
    gtk_widget_show ( GTK_WIDGET( main_window ) );
    return main_window;
}

static void check_icon_theme()
{
    GtkSettings * settings;
    char* theme;
    const char* title = N_( "GTK+ icon theme is not properly set" );
    const char* error_msg =
        N_( "<big><b>%s</b></big>\n\n"
            "This usually means you don't have an XSETTINGS manager running.  "
            "Desktop environment like GNOME or XFCE automatically execute their "
            "XSETTING managers like gnome-settings-daemon or xfce-mcs-manager.\n\n"
            "<b>If you don't use these desktop environments, "
            "you have two choices:\n"
            "1. run an XSETTINGS manager, or\n"
            "2. simply specify an icon theme in ~/.gtkrc-2.0.</b>\n"
            "For example to use the Tango icon theme add a line:\n"
            "<i><b>gtk-icon-theme-name=\"Tango\"</b></i> in your ~/.gtkrc-2.0. (create it if no such file)\n\n"
            "<b>NOTICE: The icon theme you choose should be compatible with GNOME, "
            "or the file icons cannot be displayed correctly.</b>  "
            "Due to the differences in icon naming of GNOME and KDE, KDE themes cannot be used.  "
            "Currently there is no standard for this, but it will be solved by freedesktop.org in the future." );
    settings = gtk_settings_get_default();
    g_object_get( settings, "gtk-icon-theme-name", &theme, NULL );

    /* No icon theme available */
    if ( !theme || !*theme || 0 == strcmp( theme, "hicolor" ) )
    {
        GtkWidget * dlg;
        dlg = gtk_message_dialog_new_with_markup( NULL,
                                                  GTK_DIALOG_MODAL,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_OK,
                                                  _( error_msg ), _( title ) );
        gtk_window_set_title( GTK_WINDOW( dlg ), _( title ) );
        gtk_dialog_run( GTK_DIALOG( dlg ) );
        gtk_widget_destroy( dlg );
    }
    g_free( theme );
}

int
main ( int argc, char *argv[] )
{
    FMMainWindow * main_window;
    GtkSettings *settings;
    gboolean is_init_path_dir;

    load_settings();

    /* Use multithreading */
    g_thread_init( NULL );
    gdk_threads_init ();

    gtk_init ( &argc, &argv );

    /* FIXME: Support opening mutiple dirs|files from command line */

    /* FIXME: support command line options */
    --argc;
    /* Add check for -- to skip unknown options */
    if ( argc > 0 && *argv[ argc ] && strncmp( argv[ argc ], "--", 2 ) )
    {
        /* If this is a URI */
        if ( 0 == g_ascii_strncasecmp( argv[ argc ], "file:", 5 ) )
            init_path = g_filename_from_uri( argv[ argc ], NULL, NULL );
        else
            init_path = vfs_file_resolve_path( NULL, argv[ argc ] );
        is_init_path_dir = g_file_test( init_path, G_FILE_TEST_IS_DIR );
    }
    else
    {
        init_path = g_strdup( g_get_home_dir() );
        is_init_path_dir = TRUE;
    }

    /* if ( appSettings.singleInstance ) */
    single_instance_init();

#ifdef ENABLE_NLS
    bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
    bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
    textdomain ( GETTEXT_PACKAGE );
#endif

    vfs_file_info_set_utf8_filename( g_get_filename_charsets( NULL ) );
    vfs_mime_type_init();

    if ( ! is_init_path_dir )
    {
        open_file( init_path );
        g_free( init_path );
        return 0;
    }

    vfs_volume_init();

    vfs_mime_type_set_icon_size( appSettings.bigIconSize,
                                 appSettings.smallIconSize );
    vfs_file_info_set_thumbnail_size( appSettings.bigIconSize,
                                      appSettings.smallIconSize );

    check_icon_theme();

    if( appSettings.showDesktop )
        fm_desktop_init();
    else
    {
        main_window = create_main_window();
        fm_main_window_add_new_tab( main_window, init_path,
                                    appSettings.showSidePane,
                                    appSettings.sidePaneMode );
    }
    g_free( init_path );
    init_path = NULL;

    gtk_main ();

    /* if ( appSettings.singleInstance ) */
    single_instance_finalize();

    save_settings();
    free_settings();

    vfs_volume_clean();
    vfs_mime_type_clean();
    vfs_file_monitor_clean();

    if( appSettings.showDesktop )
        fm_desktop_cleanup();

    return 0;
}

void open_file( const char* path )
{
    GError * err;
    char *msg, *error_msg;
    VFSFileInfo* file;
    VFSMimeType* mime_type;
    gboolean opened;
    char* app_name;

    if ( ! g_file_test( path, G_FILE_TEST_EXISTS ) )
    {
        ptk_show_error( NULL, _( "File doesn't exist" ) );
        return ;
    }

    file = vfs_file_info_new();
    vfs_file_info_get( file, path, NULL );
    mime_type = vfs_file_info_get_mime_type( file );
    opened = FALSE;
    err = NULL;

    app_name = vfs_mime_type_get_default_action( mime_type );
    if ( app_name )
    {
        opened = vfs_file_info_open_file( file, path, &err );
        g_free( app_name );
    }
    else
    {
        VFSAppDesktop* app;
        GList* files;

        app_name = ptk_choose_app_for_mime_type( NULL, mime_type );
        if ( app_name )
        {
            app = vfs_app_desktop_new( app_name );
            if ( ! vfs_app_desktop_get_exec( app ) )
                app->exec = g_strdup( app_name ); /* This is a command line */
            files = g_list_prepend( NULL, path );
            opened = vfs_app_desktop_open_files( gdk_screen_get_default(),
                                                 NULL, app, files, &err );
            g_free( files->data );
            g_list_free( files );
            vfs_app_desktop_unref( app );
            g_free( app_name );
        }
        else
            opened = TRUE;
    }

    if ( !opened )
    {
        char * disp_path;
        if ( err && err->message )
        {
            error_msg = err->message;
        }
        else
            error_msg = _( "Don't know how to open the file" );
        disp_path = g_filename_display_name( path );
        msg = g_strdup_printf( _( "Unable to open file:\n\"%s\"\n%s" ), disp_path, error_msg );
        g_free( disp_path );
        ptk_show_error( NULL, msg );
        g_free( msg );
        if ( err )
            g_error_free( err );
    }
    vfs_mime_type_unref( mime_type );
    vfs_file_info_unref( file );
}

Generated by  Doxygen 1.6.0   Back to index