Changeset 12656


Ignore:
Timestamp:
Aug 9, 2011, 2:30:31 AM (10 years ago)
Author:
jordan
Message:

(trunk gtk) first cut at using GApplication. This lets glib replace hundreds of lines of homegrown code. Whee!

Location:
trunk/gtk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/conf.c

    r12652 r12656  
    4545
    4646static char * gl_confdir = NULL;
    47 static char * gl_lockpath = NULL;
    48 
    49 /* errstr may be NULL, this might be called before GTK is initialized */
    50 gboolean
    51 cf_init( const char * configDir, char ** errstr )
    52 {
    53     if( errstr != NULL )
    54         *errstr = NULL;
    55 
    56     gl_confdir = g_strdup( configDir );
    57 
    58     if( g_file_test( gl_confdir, G_FILE_TEST_IS_DIR ) )
    59         return true;
    60 
    61     if( g_mkdir_with_parents( gl_confdir, 0755 ) )
    62         return true;
    63 
    64     if( errstr != NULL )
    65         *errstr = g_strdup_printf( _( "Couldn't create \"%1$s\": %2$s" ),
    66                                   gl_confdir, g_strerror( errno ) );
    67 
    68     return FALSE;
    69 }
    70 
    71 /***
    72 ****
    73 ****  Lockfile
    74 ****
    75 ***/
    76 
    77 /* errstr may be NULL, this might be called before GTK is initialized */
    78 static gboolean
    79 lockfile( const char * filename, gtr_lockfile_state_t * tr_state, char ** errstr )
    80 {
    81     const gtr_lockfile_state_t state = gtr_lockfile( filename );
    82     const gboolean success = state == GTR_LOCKFILE_SUCCESS;
    83 
    84     if( errstr ) switch( state )
    85         {
    86             case GTR_LOCKFILE_EOPEN:
    87                 *errstr =
    88                     g_strdup_printf( _( "Couldn't open \"%1$s\": %2$s" ),
    89                                     filename, g_strerror( errno ) );
    90                 break;
    91 
    92             case GTR_LOCKFILE_ELOCK:
    93                 *errstr = g_strdup_printf( _( "%s is already running." ),
    94                                           g_get_application_name( ) );
    95                 break;
    96 
    97             case GTR_LOCKFILE_SUCCESS:
    98                 *errstr = NULL;
    99                 break;
    100         }
    101 
    102     if( tr_state != NULL )
    103         *tr_state = state;
    104 
    105     return success;
    106 }
    107 
    108 static char*
    109 getLockFilename( void )
    110 {
    111     g_assert( gl_confdir != NULL );
    112     return g_build_filename( gl_confdir, "lock", NULL );
    113 }
    114 
    115 static void
    116 cf_removelocks( void )
    117 {
    118     if( gl_lockpath )
    119     {
    120         g_unlink( gl_lockpath );
    121         g_free( gl_lockpath );
    122     }
    123 }
    124 
    125 /* errstr may be NULL, this might be called before GTK is initialized */
    126 gboolean
    127 cf_lock( gtr_lockfile_state_t * tr_state, char ** errstr )
    128 {
    129     char *         path = getLockFilename( );
    130     const gboolean didLock = lockfile( path, tr_state, errstr );
    131 
    132     if( didLock )
    133         gl_lockpath = g_strdup( path );
    134     g_atexit( cf_removelocks );
    135     g_free( path );
    136     return didLock;
     47
     48void
     49gtr_pref_init( const char * config_dir )
     50{
     51    gl_confdir = g_strdup( config_dir );
    13752}
    13853
  • trunk/gtk/conf.h

    r11709 r12656  
    2727
    2828#include <inttypes.h>
    29 #include <libtransmission/transmission.h>
    30 #include "util.h" /* gtr_lockfile */
     29#include <libtransmission/transmission.h> /* tr_benc, tr_session */
     30
     31void             gtr_pref_init              ( const char * config_dir );
    3132
    3233int64_t          gtr_pref_int_get           ( const char * key );
     
    4546struct tr_benc*  gtr_pref_get_all           ( void );
    4647
    47 /**
    48 ***
    49 **/
    50 
    51 gboolean cf_init( const char *confdir, char ** errstr );
    52 
    53 gboolean cf_lock( gtr_lockfile_state_t * tr_state, char ** errstr );
    54 
    5548#endif /* GTR_CONFIG_H */
  • trunk/gtk/main.c

    r12655 r12656  
    7474struct cbdata
    7575{
     76    char                      * config_dir;
     77    gboolean                    start_paused;
    7678    gboolean                    is_iconified;
     79
    7780    guint                       timer;
    7881    guint                       update_model_soon_tag;
     
    349352***/
    350353
    351 static void app_setup( TrWindow       * wind,
    352                        GSList         * torrent_files,
    353                        struct cbdata  * cbdata,
    354                        gboolean         paused,
    355                        gboolean         minimized );
     354static void app_setup( TrWindow * wind, struct cbdata  * cbdata );
    356355
    357356static void main_window_setup( struct cbdata * cbdata, TrWindow * wind );
     
    561560}
    562561
    563 static void
    564 setupsighandlers( void )
    565 {
    566     signal( SIGINT, signal_handler );
    567     signal( SIGKILL, signal_handler );
    568 }
    569 
    570 /***
    571 ****
    572 ***/
    573 
    574 static GSList *
    575 checkfilenames( int argc, char **argv )
    576 {
    577     int i;
    578     GSList * ret = NULL;
    579     char * pwd = g_get_current_dir( );
    580 
    581     for( i=0; i<argc; ++i )
    582     {
    583         const char * arg = argv[i];
    584 
    585         if( gtr_is_supported_url( arg ) || gtr_is_magnet_link( arg ) )
    586         {
    587             ret = g_slist_prepend( ret, g_strdup( arg ) );
    588         }
    589         else /* local file */
    590         {
    591             char * filename;
    592 
    593             if( g_path_is_absolute( arg ) )
    594                 filename = g_strdup( arg );
    595             else {
    596                 filename = g_filename_from_uri( arg, NULL, NULL );
    597 
    598                 if( filename == NULL )
    599                     filename = g_build_filename( pwd, arg, NULL );
    600             }
    601 
    602             if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
    603                 ret = g_slist_prepend( ret, filename );
    604             else {
    605                 if( gtr_is_hex_hashcode( argv[i] ) )
    606                     ret = g_slist_prepend( ret, g_strdup_printf( "magnet:?xt=urn:btih:%s", argv[i] ) );
    607                 g_free( filename );
    608             }
    609         }
    610     }
    611 
    612     g_free( pwd );
    613     return g_slist_reverse( ret );
    614 }
    615 
    616562/****
    617563*****
     
    619565****/
    620566
     567static void
     568on_startup( GApplication * application, gpointer user_data )
     569{
     570    const char * str;
     571    GtkWindow * win;
     572    GtkUIManager * ui_manager;
     573    tr_session * session;
     574    struct cbdata * cbdata = user_data;
     575
     576    signal( SIGINT, signal_handler );
     577    signal( SIGKILL, signal_handler );
     578
     579    sighandler_cbdata = cbdata;
     580
     581    /* ensure the directories are created */
     582    if(( str = gtr_pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR )))
     583        g_mkdir_with_parents( str, 0777 );
     584    if(( str = gtr_pref_string_get( TR_PREFS_KEY_INCOMPLETE_DIR )))
     585        g_mkdir_with_parents( str, 0777 );
     586
     587    /* initialize the libtransmission session */
     588    session = tr_sessionInit( "gtk", cbdata->config_dir, TRUE, gtr_pref_get_all( ) );
     589
     590    gtr_pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) );
     591    gtr_pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) );
     592    cbdata->core = gtr_core_new( session );
     593
     594    /* init the ui manager */
     595    ui_manager = gtk_ui_manager_new ( );
     596    gtr_actions_init ( ui_manager, cbdata );
     597    gtk_ui_manager_add_ui_from_string ( ui_manager, fallback_ui_file, -1, NULL );
     598    gtk_ui_manager_ensure_update ( ui_manager );
     599
     600    /* create main window now to be a parent to any error dialogs */
     601    win = GTK_WINDOW( gtr_window_new( ui_manager, cbdata->core ) );
     602    g_signal_connect( win, "size-allocate", G_CALLBACK( on_main_window_size_allocated ), cbdata );
     603    g_application_hold( application );
     604    g_object_weak_ref( G_OBJECT( win ), (GWeakNotify)g_application_release, application );
     605    app_setup( win, cbdata );
     606    tr_sessionSetRPCCallback( session, on_rpc_changed, cbdata );
     607
     608    /* check & see if it's time to update the blocklist */
     609    if( gtr_pref_flag_get( TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) {
     610        if( gtr_pref_flag_get( PREF_KEY_BLOCKLIST_UPDATES_ENABLED ) ) {
     611            const int64_t last_time = gtr_pref_int_get( "blocklist-date" );
     612            const int SECONDS_IN_A_WEEK = 7 * 24 * 60 * 60;
     613            const time_t now = time( NULL );
     614        if( last_time + SECONDS_IN_A_WEEK < now )
     615            gtr_core_blocklist_update( cbdata->core );
     616        }
     617    }
     618
     619    /* if there's no magnet link handler registered, register us */
     620    register_magnet_link_handler( );
     621}
     622
     623static void
     624on_activate( GApplication * app UNUSED, gpointer unused UNUSED )
     625{
     626    gtr_action_activate( "present-main-window" );
     627}
     628
     629static void
     630open_files( GSList * files, gpointer gdata )
     631{
     632    struct cbdata * cbdata = gdata;
     633    const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START ) && !cbdata->start_paused;
     634    const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
     635    const gboolean do_notify = TRUE;
     636
     637    gtr_core_add_files( cbdata->core, files, do_start, do_prompt, do_notify );
     638}
     639
     640static void
     641on_open (GApplication  * application UNUSED,
     642         GFile        ** f,
     643         gint            file_count,
     644         gchar         * hint UNUSED,
     645         gpointer        gdata )
     646{
     647    int i;
     648    GSList * files = NULL;
     649
     650    for( i=0; i<file_count; ++i )
     651        files = g_slist_append( files, f[i] );
     652
     653    open_files( files, gdata );
     654
     655    g_slist_free( files );
     656}
     657
     658/***
     659****
     660***/
     661
    621662int
    622663main( int argc, char ** argv )
    623664{
    624     char * err = NULL;
    625     GSList * argfiles;
    626     GError * gerr;
    627     gboolean didinit = FALSE;
    628     gboolean didlock = FALSE;
    629     gboolean showversion = FALSE;
    630     gboolean startpaused = FALSE;
    631     gboolean startminimized = FALSE;
    632     const char * domain = MY_READABLE_NAME;
    633     char * configDir = NULL;
    634     gtr_lockfile_state_t tr_state;
    635 
    636     GOptionEntry entries[] = {
    637         { "paused",     'p', 0, G_OPTION_ARG_NONE,
    638           &startpaused, _( "Start with all torrents paused" ), NULL },
    639         { "version",    '\0', 0, G_OPTION_ARG_NONE,
    640           &showversion, _( "Show version number and exit" ), NULL },
    641         { "minimized",  'm', 0, G_OPTION_ARG_NONE,
    642           &startminimized,
    643           _( "Start minimized in notification area" ), NULL },
    644         { "config-dir", 'g', 0, G_OPTION_ARG_FILENAME, &configDir,
    645           _( "Where to look for configuration files" ), NULL },
     665    int ret;
     666    struct stat sb;
     667    char * application_id;
     668    GApplication * app;
     669    GOptionContext * option_context;
     670    bool show_version = false;
     671    GError * error = NULL;
     672    struct cbdata cbdata;
     673
     674    GOptionEntry option_entries[] = {
     675        { "config-dir", 'g', 0, G_OPTION_ARG_FILENAME, &cbdata.config_dir, _( "Where to look for configuration files" ), NULL },
     676        { "paused",     'p', 0, G_OPTION_ARG_NONE, &cbdata.start_paused, _( "Start with all torrents paused" ), NULL },
     677        { "minimized",  'm', 0, G_OPTION_ARG_NONE, &cbdata.is_iconified, _( "Start minimized in notification area" ), NULL },
     678        { "version",    'v', 0, G_OPTION_ARG_NONE, &show_version, _( "Show version number and exit" ), NULL },
    646679        { NULL, 0,   0, 0, NULL, NULL, NULL }
    647680    };
    648681
    649     /* bind the gettext domain */
     682    /* default settings */
     683    memset( &cbdata, 0, sizeof( struct cbdata ) );
     684    cbdata.config_dir = (char*) tr_getDefaultConfigDir( MY_CONFIG_NAME );
     685
     686    /* init i18n */
    650687    setlocale( LC_ALL, "" );
    651     bindtextdomain( domain, TRANSMISSIONLOCALEDIR );
    652     bind_textdomain_codeset( domain, "UTF-8" );
    653     textdomain( domain );
    654     g_set_application_name( _( "Transmission" ) );
     688    bindtextdomain( MY_READABLE_NAME, TRANSMISSIONLOCALEDIR );
     689    bind_textdomain_codeset( MY_READABLE_NAME, "UTF-8" );
     690    textdomain( MY_READABLE_NAME );
     691
     692    /* init glib/gtk */
     693    g_thread_init (NULL);
     694    g_type_init ();
     695    gtk_init (&argc, &argv);
     696    g_set_application_name (_( "Transmission" ));
     697    gtk_window_set_default_icon_name (MY_CONFIG_NAME);
     698
     699
     700    /* parse the command line */
     701    option_context = g_option_context_new( _( "[torrent files or urls]" ) );
     702    g_option_context_add_main_entries( option_context, option_entries, GETTEXT_PACKAGE );
     703    g_option_context_set_translation_domain( option_context, GETTEXT_PACKAGE );
     704    if( !g_option_context_parse( option_context, &argc, &argv, &error ) ) {
     705        g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"), error->message, argv[0]);
     706        g_error_free (error);
     707        g_option_context_free (option_context);
     708        return 1;
     709    }
     710    g_option_context_free (option_context);
     711
     712    /* handle the trivial "version" option */
     713    if( show_version ) {
     714        fprintf( stderr, "%s %s\n", MY_READABLE_NAME, LONG_VERSION_STRING );
     715        return 0;
     716    }
     717
     718    /* init the unit formatters */
    655719    tr_formatter_mem_init( mem_K, _(mem_K_str), _(mem_M_str), _(mem_G_str), _(mem_T_str) );
    656720    tr_formatter_size_init( disk_K, _(disk_K_str), _(disk_M_str), _(disk_G_str), _(disk_T_str) );
    657721    tr_formatter_speed_init( speed_K, _(speed_K_str), _(speed_M_str), _(speed_G_str), _(speed_T_str) );
    658722
    659     /* initialize gtk */
    660     if( !g_thread_supported( ) )
    661         g_thread_init( NULL );
    662 
    663     gerr = NULL;
    664     if( !gtk_init_with_args( &argc, &argv, (char*)_( "[torrent files or urls]" ), entries,
    665                              (char*)domain, &gerr ) )
    666     {
    667         fprintf( stderr, "%s\n", gerr->message );
    668         g_clear_error( &gerr );
    669         return 0;
    670     }
    671 
    672     if( showversion )
    673     {
    674         fprintf( stderr, "%s %s\n", MY_READABLE_NAME, LONG_VERSION_STRING );
    675         return 0;
    676     }
    677 
    678     if( configDir == NULL )
    679         configDir = (char*) tr_getDefaultConfigDir( MY_CONFIG_NAME );
    680 
    681     didinit = cf_init( configDir, NULL ); /* must come before actions_init */
    682 
    683     setupsighandlers( ); /* set up handlers for fatal signals */
    684 
    685     didlock = cf_lock( &tr_state, &err );
    686     argfiles = checkfilenames( argc - 1, argv + 1 );
    687 
    688     if( !didlock && argfiles )
    689     {
    690         /* We have torrents to add but there's another copy of Transmsision
    691          * running... chances are we've been invoked from a browser, etc.
    692          * So send the files over to the "real" copy of Transmission, and
    693          * if that goes well, then our work is done. */
    694         GSList * l;
    695         gboolean delegated = FALSE;
    696         const gboolean trash_originals = gtr_pref_flag_get( TR_PREFS_KEY_TRASH_ORIGINAL );
    697 
    698         for( l=argfiles; l!=NULL; l=l->next )
    699         {
    700             const char * filename = l->data;
    701             const gboolean added = gtr_dbus_add_torrent( filename );
    702 
    703             if( added && trash_originals )
    704                 gtr_file_trash_or_remove( filename );
    705 
    706             delegated |= added;
    707         }
    708 
    709         if( delegated ) {
    710             g_slist_foreach( argfiles, (GFunc)g_free, NULL );
    711             g_slist_free( argfiles );
    712             argfiles = NULL;
    713 
    714             if( err ) {
    715                 g_free( err );
    716                 err = NULL;
    717             }
    718         }
    719     }
    720     else if( ( !didlock ) && ( tr_state == GTR_LOCKFILE_ELOCK ) )
    721     {
    722         /* There's already another copy of Transmission running,
    723          * so tell it to present its window to the user */
    724         err = NULL;
    725         if( !gtr_dbus_present_window( ) )
    726             err = g_strdup( _( "Transmission is already running, but is not responding. To start a new session, you must first close the existing Transmission process." ) );
    727     }
    728 
    729     if( didlock && ( didinit || cf_init( configDir, &err ) ) )
    730     {
    731         /* No other copy of Transmission running...
    732          * so we're going to be the primary. */
    733 
    734         const char * str;
    735         GtkWindow * win;
    736         GtkUIManager * myUIManager;
    737         tr_session * session;
    738         struct cbdata * cbdata = g_new0( struct cbdata, 1 );
    739 
    740         sighandler_cbdata = cbdata;
    741 
    742         /* ensure the directories are created */
    743         if(( str = gtr_pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR )))
    744             g_mkdir_with_parents( str, 0777 );
    745         if(( str = gtr_pref_string_get( TR_PREFS_KEY_INCOMPLETE_DIR )))
    746             g_mkdir_with_parents( str, 0777 );
    747 
    748         /* initialize the libtransmission session */
    749         session = tr_sessionInit( "gtk", configDir, TRUE, gtr_pref_get_all( ) );
    750 
    751         gtr_pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) );
    752         gtr_pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) );
    753         cbdata->core = gtr_core_new( session );
    754 
    755         /* init the ui manager */
    756         myUIManager = gtk_ui_manager_new ( );
    757         gtr_actions_init ( myUIManager, cbdata );
    758         gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL );
    759         gtk_ui_manager_ensure_update ( myUIManager );
    760         gtk_window_set_default_icon_name ( MY_CONFIG_NAME );
    761 
    762         /* create main window now to be a parent to any error dialogs */
    763         win = GTK_WINDOW( gtr_window_new( myUIManager, cbdata->core ) );
    764         g_signal_connect( win, "size-allocate", G_CALLBACK( on_main_window_size_allocated ), cbdata );
    765 
    766         app_setup( win, argfiles, cbdata, startpaused, startminimized );
    767         tr_sessionSetRPCCallback( session, on_rpc_changed, cbdata );
    768 
    769         /* on startup, check & see if it's time to update the blocklist */
    770         if( gtr_pref_flag_get( TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) {
    771             if( gtr_pref_flag_get( PREF_KEY_BLOCKLIST_UPDATES_ENABLED ) ) {
    772                 const int64_t last_time = gtr_pref_int_get( "blocklist-date" );
    773                 const int SECONDS_IN_A_WEEK = 7 * 24 * 60 * 60;
    774                 const time_t now = time( NULL );
    775                 if( last_time + SECONDS_IN_A_WEEK < now )
    776                     gtr_core_blocklist_update( cbdata->core );
    777             }
    778         }
    779 
    780         /* if there's no magnet link handler registered, register us */
    781         register_magnet_link_handler( );
    782 
    783         gtk_main( );
    784     }
    785     else if( err )
    786     {
    787         const char * primary_text = _( "Transmission cannot be started." );
    788         GtkWidget * w = gtk_message_dialog_new( NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, primary_text, NULL );
    789         gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( w ), "%s", err );
    790         g_signal_connect( w, "response", G_CALLBACK(gtk_main_quit), NULL );
    791         gtk_widget_show( w );
    792         g_free( err );
    793         gtk_main( );
    794     }
    795 
    796     return 0;
     723    /* set up the config dir */
     724    gtr_pref_init( cbdata.config_dir );
     725    g_mkdir_with_parents( cbdata.config_dir, 0755 );
     726
     727    /* init the application for the specified config dir */
     728    stat( cbdata.config_dir, &sb );
     729    application_id = g_strdup_printf( "com.transmissionbt.transmission_%lu_%lu", (unsigned long)sb.st_dev, (unsigned long)sb.st_ino );
     730    app = g_application_new( application_id, G_APPLICATION_HANDLES_OPEN );
     731    g_signal_connect( app, "open", G_CALLBACK(on_open), &cbdata );
     732    g_signal_connect( app, "startup", G_CALLBACK(on_startup), &cbdata );
     733    g_signal_connect( app, "activate", G_CALLBACK(on_activate), &cbdata );
     734    ret = g_application_run (app, argc, argv);
     735    g_object_unref( app );
     736    return ret;
    797737}
    798738
     
    804744
    805745static void
    806 app_setup( TrWindow      * wind,
    807            GSList        * files,
    808            struct cbdata * cbdata,
    809            gboolean        pause_all,
    810            gboolean        is_iconified )
    811 {
    812     const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START ) && !pause_all;
    813     const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
    814     const gboolean do_notify = TRUE;
    815 
    816     cbdata->is_iconified = is_iconified;
    817 
    818     if( is_iconified )
     746app_setup( TrWindow * wind, struct cbdata * cbdata )
     747{
     748    if( cbdata->is_iconified )
    819749        gtr_pref_flag_set( PREF_KEY_SHOW_TRAY_ICON, TRUE );
    820750
     
    828758
    829759    /* add torrents from command-line and saved state */
    830     gtr_core_load( cbdata->core, pause_all );
    831     gtr_core_add_list( cbdata->core, files, do_start, do_prompt, do_notify );
    832     files = NULL;
     760    gtr_core_load( cbdata->core, cbdata->start_paused );
    833761    gtr_core_torrents_added( cbdata->core );
    834762
     
    844772
    845773    /* either show the window or iconify it */
    846     if( !is_iconified )
     774    if( !cbdata->is_iconified )
    847775        gtk_widget_show( GTK_WIDGET( wind ) );
    848776    else
     
    955883                       gpointer            gdata )
    956884{
    957     int i;
    958     gboolean success = FALSE;
     885    guint i;
     886    char ** uris = gtk_selection_data_get_uris( selection_data );
     887    const guint file_count = g_strv_length( uris );
    959888    GSList * files = NULL;
    960     struct cbdata * data = gdata;
    961     char ** uris = gtk_selection_data_get_uris( selection_data );
    962 
    963     /* try to add the filename URIs... */
    964     for( i=0; uris && uris[i]; ++i )
    965     {
    966         const char * uri = uris[i];
    967         char * filename = g_filename_from_uri( uri, NULL, NULL );
    968 
    969         if( filename && g_file_test( filename, G_FILE_TEST_EXISTS ) )
    970         {
    971             files = g_slist_append( files, g_strdup( filename ) );
    972             success = TRUE;
    973         }
    974         else if( tr_urlIsValid( uri, -1 ) || gtr_is_magnet_link( uri ) )
    975         {
    976             gtr_core_add_from_url( data->core, uri );
    977             success = TRUE;
    978         }
    979 
    980         g_free( filename );
    981     }
    982 
    983     if( files )
    984         gtr_core_add_list_defaults( data->core, g_slist_reverse( files ), TRUE );
    985 
    986     gtr_core_torrents_added( data->core );
    987     gtk_drag_finish( drag_context, success, FALSE, time_ );
     889
     890    for( i=0; i<file_count; ++i )
     891        files = g_slist_append( files, g_file_new_for_uri( uris[i] ) );
     892
     893    open_files( files, gdata );
    988894
    989895    /* cleanup */
     896    g_slist_foreach( files, (GFunc)g_object_unref, NULL );
     897    g_slist_free( files );
    990898    g_strfreev( uris );
     899
     900    gtk_drag_finish( drag_context, true, FALSE, time_ );
    991901}
    992902
     
    1038948    g_slist_foreach( cbdata->duplicates_list, (GFunc)g_free, NULL );
    1039949    g_slist_free( cbdata->duplicates_list );
    1040     g_free( cbdata );
    1041 
    1042     gtk_main_quit( );
    1043950
    1044951    return FALSE;
  • trunk/gtk/open-dialog.c

    r12639 r12656  
    2424#include "open-dialog.h"
    2525#include "tr-prefs.h"
     26#include "util.h" /* gtr_priority_combo_get_value() */
    2627
    2728/****
     
    404405        GtkWidget       * w = gtk_file_chooser_get_extra_widget( chooser );
    405406        GtkToggleButton * tb = GTK_TOGGLE_BUTTON( w );
    406         const gboolean    doStart = gtr_pref_flag_get( TR_PREFS_KEY_START );
    407         const gboolean    doPrompt = gtk_toggle_button_get_active( tb );
    408         const gboolean    doNotify = FALSE;
    409         GSList * l = gtk_file_chooser_get_filenames( chooser );
    410 
    411         gtr_core_add_list( core, l, doStart, doPrompt, doNotify );
     407        const gboolean    do_start = gtr_pref_flag_get( TR_PREFS_KEY_START );
     408        const gboolean    do_prompt = gtk_toggle_button_get_active( tb );
     409        const gboolean    do_notify = FALSE;
     410        GSList * files = gtk_file_chooser_get_files( chooser );
     411
     412        gtr_core_add_files( core, files, do_start, do_prompt, do_notify );
     413        g_slist_foreach( files, (GFunc)g_object_unref, NULL );
     414        g_slist_free( files );
    412415    }
    413416
     
    454457onOpenURLResponse( GtkDialog * dialog, int response, gpointer user_data )
    455458{
    456     gboolean destroy = TRUE;
     459    bool handled = false;
    457460
    458461    if( response == GTK_RESPONSE_ACCEPT )
     
    462465        g_strstrip( url );
    463466
    464         if( url && *url )
    465         {
    466             TrCore * core = user_data;
    467 
    468             if( gtr_is_supported_url( url ) || gtr_is_magnet_link( url )
    469                                             || gtr_is_hex_hashcode( url ) )
    470             {
    471                 gtr_core_add_from_url( core, url );
    472             }
    473             else
    474             {
     467        if( url ) {
     468            handled = gtr_core_add_from_url( user_data, url );
     469            if( !handled )
    475470                gtr_unrecognized_url_dialog( GTK_WIDGET( dialog ), url );
    476                 destroy = FALSE;
    477             }
     471            g_free( url );
    478472        }
    479 
    480         g_free( url );
    481     }
    482 
    483     if( destroy )
     473    }
     474
     475    if( handled )
    484476        gtk_widget_destroy( GTK_WIDGET( dialog ) );
    485477}
  • trunk/gtk/tr-core.c

    r12655 r12656  
    7979    gboolean       dbus_error;
    8080    guint          inhibit_cookie;
    81     guint          dbus_session_owner_id;
    82     guint          dbus_display_owner_id;
    8381    gint           busy_count;
    8482    GtkTreeModel * raw_model;
     
    191189        G_TYPE_NONE,
    192190        1, G_TYPE_STRING );
    193 }
    194 
    195 static void
    196 handle_dbus_method( GDBusConnection       * connection UNUSED,
    197                     const gchar           * sender UNUSED,
    198                     const gchar           * object_path,
    199                     const gchar           * interface_name,
    200                     const gchar           * method_name,
    201                     GVariant              * parameters,
    202                     GDBusMethodInvocation * invocation,
    203                     gpointer                core )
    204 {
    205     gboolean handled = false;
    206 
    207     if( !g_strcmp0( interface_name, TR_DBUS_SESSION_INTERFACE ) )
    208     {
    209         if( !g_strcmp0( method_name, "TorrentAdd" ) )
    210         {
    211             GVariant * args = g_variant_get_child_value( parameters, 0 );
    212             GVariant * filename_variant = g_variant_lookup_value ( args, "filename", G_VARIANT_TYPE_STRING );
    213             char * filename = g_variant_dup_string( filename_variant, NULL );
    214             GSList * files = g_slist_append( NULL, filename );
    215             gtr_core_add_list_defaults( TR_CORE( core ), files, TRUE );
    216             g_dbus_method_invocation_return_value( invocation, g_variant_new( "(b)", true ) );
    217             handled = true;
    218         }
    219     }
    220     else if( !g_strcmp0( interface_name, TR_DBUS_DISPLAY_INTERFACE ) )
    221     {
    222         if( !g_strcmp0( method_name, "PresentWindow" ) )
    223         {
    224             gtr_action_activate( "present-main-window" );
    225             g_dbus_method_invocation_return_value( invocation, NULL );
    226             handled = true;
    227         }
    228     }
    229 
    230     if( !handled )
    231         g_warning( "Unhandled method call:\n\tObject Path: %s\n\tInterface Name: %s\n\tMethod Name: %s",
    232                    object_path, interface_name, method_name );
    233 };
    234 
    235 static void
    236 on_session_registered_in_dbus( GDBusConnection *connection, const gchar *name UNUSED, gpointer core )
    237 {
    238     GError * err = NULL;
    239     GDBusNodeInfo * node_info;
    240     GDBusInterfaceVTable vtable;
    241     const char * interface_xml = "<node>"
    242                                  "  <interface name='" TR_DBUS_SESSION_INTERFACE "'>"
    243                                  "    <method name='TorrentAdd'>"
    244                                  "      <arg type='a{sv}' name='args' direction='in'/>"
    245                                  "      <arg type='b' name='response' direction='out'/>"
    246                                  "    </method>"
    247                                  "  </interface>"
    248                                  "</node>";
    249 
    250     node_info = g_dbus_node_info_new_for_xml( interface_xml, &err );
    251 
    252     vtable.method_call = handle_dbus_method;
    253     vtable.get_property = NULL;
    254     vtable.set_property = NULL;
    255 
    256     g_dbus_connection_register_object ( connection,
    257                                         TR_DBUS_SESSION_OBJECT_PATH,
    258                                         node_info->interfaces[0],
    259                                         &vtable,
    260                                         core,
    261                                         NULL,
    262                                         &err );
    263 
    264     if( err != NULL ) {
    265         g_warning( "%s:%d Error registering object: %s", __FILE__, __LINE__, err->message );
    266         g_error_free( err );
    267     }
    268 }
    269 
    270 static void
    271 on_display_registered_in_dbus( GDBusConnection *connection, const gchar *name UNUSED, gpointer core )
    272 {
    273     GError * err = NULL;
    274     const char * interface_xml = "<node>"
    275                                  "  <interface name='" TR_DBUS_DISPLAY_INTERFACE "'>"
    276                                  "    <method name='PresentWindow'>"
    277                                  "    </method>"
    278                                  "  </interface>"
    279                                  "</node>";
    280     GDBusInterfaceVTable vtable = { .method_call=handle_dbus_method };
    281     GDBusNodeInfo * node_info = g_dbus_node_info_new_for_xml( interface_xml, &err );
    282 
    283     g_dbus_connection_register_object ( connection,
    284                                         TR_DBUS_DISPLAY_OBJECT_PATH,
    285                                         node_info->interfaces[0],
    286                                         &vtable,
    287                                         core,
    288                                         NULL,
    289                                         &err );
    290 
    291     if( err != NULL ) {
    292         g_warning( "%s:%d Error registering object: %s", __FILE__, __LINE__, err->message );
    293         g_error_free( err );
    294     }
    295191}
    296192
     
    331227    p->string_chunk = g_string_chunk_new( 2048 );
    332228    g_object_unref( p->raw_model );
    333 
    334     p->dbus_session_owner_id = g_bus_own_name( G_BUS_TYPE_SESSION,
    335                                                TR_DBUS_SESSION_SERVICE_NAME,
    336                                                G_BUS_NAME_OWNER_FLAGS_NONE,
    337                                                NULL,
    338                                                on_session_registered_in_dbus,
    339                                                NULL,
    340                                                self,
    341                                                NULL );
    342 
    343     p->dbus_display_owner_id = g_bus_own_name( G_BUS_TYPE_SESSION,
    344                                                TR_DBUS_DISPLAY_SERVICE_NAME,
    345                                                G_BUS_NAME_OWNER_FLAGS_NONE,
    346                                                NULL,
    347                                                on_display_registered_in_dbus,
    348                                                NULL,
    349                                                self,
    350                                                NULL );
    351229}
    352230
     
    756634    const time_t now = tr_time( );
    757635    struct TrCorePrivate * p = core->priv;
     636    const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START );
     637    const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
    758638
    759639    /* of the monitor_files, make a list of those that haven't
     
    765645            monitor_files = g_slist_prepend( monitor_files, f );
    766646        else {
    767             addme = g_slist_prepend( addme, g_strdup( f->filename ) );
     647            addme = g_slist_prepend( addme, g_file_new_for_commandline_arg( f->filename ) );
    768648            watchdir_file_free( f );
    769649        }
     
    772652    /* add the torrents from that list */
    773653    core->priv->adding_from_watch_dir = TRUE;
    774     gtr_core_add_list_defaults( core, addme, TRUE );
     654    gtr_core_add_files( core, addme, do_start, do_prompt, TRUE );
     655    g_slist_foreach( addme, (GFunc)g_object_unref, NULL );
     656    g_slist_free( addme );
    775657    core->priv->adding_from_watch_dir = FALSE;
    776658
     
    942824        tr_sessionClose( session );
    943825    }
    944 
    945     g_bus_unown_name( core->priv->dbus_display_owner_id );
    946     g_bus_unown_name( core->priv->dbus_session_owner_id );
    947826}
    948827
     
    12221101***/
    12231102
    1224 struct url_dialog_data
     1103struct add_from_url_data
    12251104{
    12261105    TrCore * core;
    12271106    tr_ctor * ctor;
    1228     char * url;
    1229 
    1230     bool did_connect;
    1231     bool did_timeout;
    1232     long response_code;
     1107    bool do_prompt;
     1108    bool do_notify;
    12331109};
    12341110
    1235 static gboolean
    1236 on_url_done_idle( gpointer vdata )
    1237 {
    1238     struct url_dialog_data * data = vdata;
    1239 
    1240     if( data->response_code != 200 )
    1241     {
    1242         gtr_http_failure_dialog( NULL, data->url, data->response_code );
     1111static void
     1112add_file_async_callback( GObject * file, GAsyncResult * result, gpointer gdata )
     1113{
     1114    gsize length;
     1115    char * contents;
     1116    GError * error = NULL;
     1117    struct add_from_url_data * data = gdata;
     1118
     1119    if( !g_file_load_contents_finish( G_FILE( file ), result, &contents, &length, NULL, &error ) )
     1120    {
     1121        g_message( _( "Couldn't read \"%s\": %s" ), g_file_get_parse_name( G_FILE( file ) ), error->message );
     1122        g_error_free( error );
     1123    }
     1124    else if( !tr_ctorSetMetainfo( data->ctor, (const uint8_t*)contents, length ) )
     1125    {
     1126        core_add_ctor( data->core, data->ctor, data->do_prompt, data->do_notify );
    12431127    }
    12441128    else
    12451129    {
    1246         const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
    1247         const gboolean do_notify = FALSE;
    1248         const int err = core_add_ctor( data->core, data->ctor, do_prompt, do_notify );
    1249 
    1250         if( err == TR_PARSE_ERR )
    1251             core_emit_err( data->core, TR_PARSE_ERR, data->url );
    1252 
    1253         gtr_core_torrents_added( data->core );
    1254     }
    1255 
    1256     /* cleanup */
     1130        tr_ctorFree( data->ctor );
     1131    }
     1132
    12571133    core_dec_busy( data->core );
    1258     g_free( data->url );
    12591134    g_free( data );
    1260     return FALSE;
    1261 }
    1262 
    1263 static void
    1264 on_url_done( tr_session   * session,
    1265              bool           did_connect,
    1266              bool           did_timeout,
    1267              long           response_code,
    1268              const void   * response,
    1269              size_t         response_byte_count,
    1270              void         * vdata )
    1271 {
    1272     struct url_dialog_data * data = vdata;
    1273 
    1274     data->did_connect = did_connect;
    1275     data->did_timeout = did_timeout;
    1276     data->response_code = response_code;
    1277     data->ctor = tr_ctorNew( session );
    1278     core_apply_defaults( data->ctor );
    1279     tr_ctorSetMetainfo( data->ctor, response, response_byte_count );
    1280 
    1281     gdk_threads_add_idle( on_url_done_idle, data );
    1282 }
    1283 
    1284 void
    1285 gtr_core_add_from_url( TrCore * core, const char * url )
    1286 {
     1135}
     1136
     1137static bool
     1138add_file( TrCore      * core,
     1139          GFile       * file,
     1140          gboolean      do_start,
     1141          gboolean      do_prompt,
     1142          gboolean      do_notify )
     1143{
     1144    bool handled = false;
    12871145    tr_session * session = gtr_core_session( core );
    1288     const gboolean is_magnet_link = gtr_is_magnet_link( url );
    1289 
    1290     if( is_magnet_link || gtr_is_hex_hashcode( url ) )
    1291     {
    1292         int err;
    1293         char * tmp = NULL;
    1294         tr_ctor * ctor = tr_ctorNew( session );
    1295 
    1296         if( gtr_is_hex_hashcode( url ) )
    1297             url = tmp = g_strdup_printf( "magnet:?xt=urn:btih:%s", url );
    1298 
    1299         err = tr_ctorSetMetainfoFromMagnetLink( ctor, url );
    1300 
    1301         if( !err )
    1302             gtr_core_add_ctor( core, ctor );
    1303         else {
    1304             gtr_unrecognized_url_dialog( NULL, url );
    1305             tr_ctorFree( ctor );
    1306         }
    1307 
    1308         g_free( tmp );
    1309     }
    1310     else
    1311     {
    1312         struct url_dialog_data * data = g_new( struct url_dialog_data, 1 );
    1313         data->core = core;
    1314         data->url = g_strdup( url );
    1315         core_inc_busy( data->core );
    1316         tr_webRun( session, url, NULL, NULL, on_url_done, data );
    1317     }
    1318 }
    1319 
    1320 /***
    1321 ****
    1322 ***/
    1323 
    1324 static void
    1325 add_filename( TrCore      * core,
    1326               const char  * filename,
    1327               gboolean      do_start,
    1328               gboolean      do_prompt,
    1329               gboolean      do_notify )
    1330 {
    1331     tr_session * session = gtr_core_session( core );
    1332 
    1333     if( session == NULL )
    1334         return;
    1335 
    1336     if( gtr_is_supported_url( filename ) || gtr_is_magnet_link( filename ) )
    1337     {
    1338         gtr_core_add_from_url( core, filename );
    1339     }
    1340     else if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
    1341     {
    1342         int err;
    1343 
    1344         tr_ctor * ctor = tr_ctorNew( session );
    1345         tr_ctorSetMetainfoFromFile( ctor, filename );
     1146
     1147    if( session != NULL )
     1148    {
     1149        tr_ctor * ctor;
     1150        bool tried = false;
     1151        bool loaded = false;
     1152
     1153        ctor = tr_ctorNew( session );
    13461154        core_apply_defaults( ctor );
    13471155        tr_ctorSetPaused( ctor, TR_FORCE, !do_start );
    13481156
    1349         err = core_add_ctor( core, ctor, do_prompt, do_notify );
    1350         if( err == TR_PARSE_ERR )
    1351             core_emit_err( core, TR_PARSE_ERR, filename );
    1352     }
    1353     else if( gtr_is_hex_hashcode( filename ) )
    1354     {
    1355         gtr_core_add_from_url( core, filename );
    1356     }
    1357 }
    1358 
    1359 void
    1360 gtr_core_add_list( TrCore    * core,
    1361                    GSList    * files,
    1362                    gboolean    do_start,
    1363                    gboolean    do_prompt,
    1364                    gboolean    do_notify )
     1157        /* local files... */
     1158        if( !tried ) {
     1159            char * str = g_file_get_path( file );
     1160            if(( tried = g_file_test( str, G_FILE_TEST_EXISTS )))
     1161               loaded = !tr_ctorSetMetainfoFromFile( ctor, str );
     1162            g_free( str );
     1163        }
     1164
     1165        /* magnet links... */
     1166        if( !tried && g_file_has_uri_scheme( file, "magnet" ) ) {
     1167            /* GFile mangles the original string with /// so we have to un-mangle */
     1168            char * str = g_file_get_parse_name( file );
     1169            char * magnet = g_strdup_printf( "magnet:%s", strchr( str, '?' ) );
     1170            tried = true;
     1171            loaded = !tr_ctorSetMetainfoFromMagnetLink( ctor, magnet );
     1172            g_free( magnet );
     1173            g_free( str );
     1174        }
     1175
     1176        /* hashcodes that we can turn into magnet links... */
     1177        if( !tried ) {
     1178            char * str = g_file_get_basename( file );
     1179            if( gtr_is_hex_hashcode( str ) ) {
     1180                char * magnet = g_strdup_printf( "magnet:?xt=urn:btih:%s", str );
     1181                tried = true;
     1182                loaded = !tr_ctorSetMetainfoFromMagnetLink( ctor, magnet );
     1183                g_free( magnet );
     1184            }
     1185            g_free( str );
     1186        }
     1187
     1188        /* if we were able to load the metainfo, add the torrent */
     1189        if( loaded )
     1190        {
     1191            handled = true;
     1192            core_add_ctor( core, ctor, do_prompt, do_notify );
     1193        }
     1194        else if( g_file_has_uri_scheme( file, "http" ) ||
     1195                 g_file_has_uri_scheme( file, "https" ) ||
     1196                 g_file_has_uri_scheme( file, "ftp" ) )
     1197        {
     1198            struct add_from_url_data * data;
     1199
     1200            data = g_new0( struct add_from_url_data, 1 );
     1201            data->core = core;
     1202            data->ctor = ctor;
     1203            data->do_prompt = do_prompt;
     1204            data->do_notify = do_notify;
     1205
     1206            handled = true;
     1207            core_inc_busy( core );
     1208            g_file_load_contents_async( file, NULL, add_file_async_callback, data );
     1209        }
     1210        else
     1211        {
     1212            tr_ctorFree( ctor );
     1213            g_message( _( "Skipping unknown torrent \"%s\"" ), g_file_get_parse_name( file ) );
     1214        }
     1215    }
     1216
     1217    return handled;
     1218}
     1219
     1220bool
     1221gtr_core_add_from_url( TrCore * core, const char * uri )
     1222{
     1223    bool handled;
     1224    const bool do_start = gtr_pref_flag_get( TR_PREFS_KEY_START );
     1225    const bool do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
     1226    const bool do_notify = false;
     1227
     1228    GFile * file = g_file_new_for_uri( uri );
     1229    handled = add_file( core, file, do_start, do_prompt, do_notify );
     1230    g_object_unref( file );
     1231    gtr_core_torrents_added( core );
     1232
     1233    return handled;
     1234}
     1235
     1236void
     1237gtr_core_add_files( TrCore     * core,
     1238                    GSList     * files,
     1239                    gboolean     do_start,
     1240                    gboolean     do_prompt,
     1241                    gboolean     do_notify )
    13651242{
    13661243    GSList * l;
    13671244
    13681245    for( l=files; l!=NULL; l=l->next )
    1369     {
    1370         char * filename = l->data;
    1371         add_filename( core, filename, do_start, do_prompt, do_notify );
    1372         g_free( filename );
    1373     }
     1246        add_file( core, l->data, do_start, do_prompt, do_notify );
    13741247
    13751248    gtr_core_torrents_added( core );
    1376 
    1377     g_slist_free( files );
    1378 }
    1379 
    1380 void
    1381 gtr_core_add_list_defaults( TrCore * core, GSList * files, gboolean do_notify )
    1382 {
    1383     const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START );
    1384     const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
    1385 
    1386     gtr_core_add_list( core, files, do_start, do_prompt, do_notify );
    13871249}
    13881250
  • trunk/gtk/tr-core.h

    r12638 r12656  
    107107 * May trigger one or more "error" signals with TR_CORE_ERR_ADD_TORRENT
    108108 */
    109 void gtr_core_add_list( TrCore *    self,
    110                         GSList *    torrentFiles,
    111                         gboolean    do_start,
    112                         gboolean    do_prompt,
    113                         gboolean    do_notify );
    114 
    115 void gtr_core_add_list_defaults( TrCore    * core,
    116                                  GSList    * torrentFiles,
    117                                  gboolean    do_notify );
    118 
     109void gtr_core_add_files( TrCore     * core,
     110                         GSList     * files,
     111                         gboolean     do_start,
     112                         gboolean     do_prompt,
     113                         gboolean     do_notify );
    119114
    120115/** @brief Add a torrent from a URL */
    121 void gtr_core_add_from_url( TrCore * core, const char * url );
     116bool gtr_core_add_from_url( TrCore * core, const char * url );
    122117
    123118/** @brief Add a torrent.
     
    201196
    202197
    203 #define TR_DBUS_SESSION_SERVICE_NAME  "com.transmissionbt.transmission.Session"
    204 #define TR_DBUS_SESSION_INTERFACE     "com.transmissionbt.transmission.Session"
    205 #define TR_DBUS_SESSION_OBJECT_PATH   "/com/transmissionbt/transmission/Session"
    206 
    207 #define TR_DBUS_DISPLAY_SERVICE_NAME  "com.transmissionbt.transmission.Display"
    208 #define TR_DBUS_DISPLAY_INTERFACE     "com.transmissionbt.transmission.Display"
    209 #define TR_DBUS_DISPLAY_OBJECT_PATH   "/com/transmissionbt/transmission/Display"
    210 
    211 
    212198#endif /* GTR_CORE_H */
  • trunk/gtk/util.c

    r12655 r12656  
    1616#include <string.h> /* strchr(), strrchr(), strlen(), strncmp(), strstr() */
    1717
    18 #include <sys/types.h> /* for gtr_lockfile()'s open() */
    19 #include <sys/stat.h> /* for gtr_lockfile()'s open() */
    20 #include <fcntl.h> /* for gtr_lockfile()'s open() */
    21 
    2218#include <gtk/gtk.h>
    2319#include <glib/gi18n.h>
     
    5551const char * speed_G_str = N_("GiB/s");
    5652const char * speed_T_str = N_("TiB/s");
    57 
    58 /***
    59 ****
    60 ***/
    61 
    62 gtr_lockfile_state_t
    63 gtr_lockfile( const char * filename )
    64 {
    65     gtr_lockfile_state_t ret;
    66 
    67 #ifdef WIN32
    68 
    69     HANDLE file = CreateFile( filename,
    70                               GENERIC_READ | GENERIC_WRITE,
    71                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    72                               NULL,
    73                               OPEN_ALWAYS,
    74                               FILE_ATTRIBUTE_NORMAL,
    75                               NULL );
    76     if( file == INVALID_HANDLE_VALUE )
    77         ret = GTR_LOCKFILE_EOPEN;
    78     else if( !LockFile( file, 0, 0, 1, 1 ) )
    79         ret = GTR_LOCKFILE_ELOCK;
    80     else
    81         ret = GTR_LOCKFILE_SUCCESS;
    82 
    83 #else
    84 
    85     int fd = open( filename, O_RDWR | O_CREAT, 0666 );
    86     if( fd < 0 )
    87         ret = GTR_LOCKFILE_EOPEN;
    88     else {
    89         struct flock lk;
    90         memset( &lk, 0,  sizeof( lk ) );
    91         lk.l_start = 0;
    92         lk.l_len = 0;
    93         lk.l_type = F_WRLCK;
    94         lk.l_whence = SEEK_SET;
    95         if( -1 == fcntl( fd, F_SETLK, &lk ) )
    96             ret = GTR_LOCKFILE_ELOCK;
    97         else
    98             ret = GTR_LOCKFILE_SUCCESS;
    99     }
    100 
    101 #endif
    102 
    103     return ret;
    104 }
    10553
    10654/***
     
    219167}
    220168
    221 gboolean
     169static gboolean
    222170gtr_is_supported_url( const char * str )
    223171{
     
    433381}
    434382
    435 gboolean
    436 gtr_dbus_add_torrent( const char * filename )
    437 {
    438     GVariant * response;
    439     GVariant * args;
    440     GVariant * parameters;
    441     GVariantBuilder * builder;
    442     GDBusConnection * connection;
    443     GError * err = NULL;
    444     gboolean handled = FALSE;
    445 
    446     /* "args" is a dict as described in the RPC spec's "torrent-add" section */
    447     builder = g_variant_builder_new( G_VARIANT_TYPE( "a{sv}" ) );
    448     g_variant_builder_add( builder, "{sv}", "filename", g_variant_new_string( filename ) );
    449     args = g_variant_builder_end( builder );
    450     parameters = g_variant_new_tuple( &args, 1 );
    451     g_variant_builder_unref( builder );
    452 
    453     connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
    454 
    455     response = g_dbus_connection_call_sync( connection,
    456                                             TR_DBUS_SESSION_SERVICE_NAME,
    457                                             TR_DBUS_SESSION_OBJECT_PATH,
    458                                             TR_DBUS_SESSION_INTERFACE,
    459                                             "TorrentAdd",
    460                                             parameters,
    461                                             G_VARIANT_TYPE_TUPLE,
    462                                             G_DBUS_CALL_FLAGS_NONE,
    463                                             10000, /* wait 10 sec */
    464                                             NULL,
    465                                             &err );
    466 
    467 
    468     handled = g_variant_get_boolean( g_variant_get_child_value( response, 0 ) );
    469 
    470     g_object_unref( connection );
    471     g_variant_unref( response );
    472     return handled;
    473 }
    474 
    475 gboolean
    476 gtr_dbus_present_window( void )
    477 {
    478     gboolean success;
    479     GDBusConnection * connection;
    480     GError * err = NULL;
    481 
    482     connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
    483 
    484     g_dbus_connection_call_sync( connection,
    485                                  TR_DBUS_DISPLAY_SERVICE_NAME,
    486                                  TR_DBUS_DISPLAY_OBJECT_PATH,
    487                                  TR_DBUS_DISPLAY_INTERFACE,
    488                                  "PresentWindow",
    489                                  NULL,
    490                                  NULL, G_DBUS_CALL_FLAGS_NONE,
    491                                  1000, NULL, &err );
    492 
    493     success = err == NULL;
    494 
    495     /* cleanup */
    496     if( err != NULL )
    497         g_error_free( err );
    498     g_object_unref( connection );
    499     return success;
    500 }
    501 
    502383/***
    503384****
  • trunk/gtk/util.h

    r12655 r12656  
    7171void gtr_get_host_from_url( char * buf, size_t buflen, const char * url );
    7272
    73 gboolean gtr_is_supported_url( const char * str );
    74 
    7573gboolean gtr_is_magnet_link( const char * str );
    7674
     
    8179***/
    8280
    83 typedef enum
    84 {
    85     GTR_LOCKFILE_SUCCESS = 0,
    86     GTR_LOCKFILE_EOPEN,
    87     GTR_LOCKFILE_ELOCK
    88 }
    89 gtr_lockfile_state_t;
    90 
    91 gtr_lockfile_state_t gtr_lockfile( const char * filename );
    92 
    93 /***
    94 ****
    95 ***/
    96 
    9781void        gtr_open_uri( const char * uri );
    9882
    9983void        gtr_open_file( const char * path );
    100 
    101 gboolean    gtr_dbus_add_torrent( const char * filename );
    102 
    103 gboolean    gtr_dbus_present_window( void );
    10484
    10585const char* gtr_get_help_uri( void );
Note: See TracChangeset for help on using the changeset viewer.