## MANDATORY for the GTK+ client
##
##
-GLIB_MINIMUM=2.8.0
-AC_SUBST(GLIB_MINIMUM)
GTK_MINIMUM=2.8.0
AC_SUBST(GTK_MINIMUM)
+GLIB_MINIMUM=2.26.0
+AC_SUBST(GLIB_MINIMUM)
+GIO_MINIMUM=2.26.0
+AC_SUBST(GIO_MINIMUM)
##
##
## OPTIONAL for the GTK+ client
##
##
-# inhibit hibernation when a torrent is active...
-DBUS_GLIB_MINIMUM=0.70
-AC_SUBST(DBUS_GLIB_MINIMUM)
-# implement "watch" directories to use new .torrent files...
-GIO_MINIMUM=2.15.5
-AC_SUBST(GIO_MINIMUM)
+
# create the tray icon with AppIndicator
LIBAPPINDICATOR_MINIMUM=0.0.11
AC_SUBST(LIBAPPINDICATOR_MINIMUM)
PKG_CHECK_MODULES(GTK,
[gtk+-2.0 >= $GTK_MINIMUM
glib-2.0 >= $GLIB_MINIMUM
+ gio-2.0 >= $GIO_MINIMUM],
gmodule-2.0 >= $GLIB_MINIMUM
gthread-2.0 >= $GLIB_MINIMUM],
[have_gtk=yes],
[want_gtk=${enableval}],
[want_gtk=${have_gtk}])
build_gtk=no
-use_gio=no
use_libappindicator=no
-use_dbus_glib=no
if test "x$want_gtk" = "xyes" ; then
if test "x$have_gtk" = "xyes"; then
build_gtk=yes
if test "x$build_gtk" = "xyes"; then
- PKG_CHECK_MODULES([GIO],
- [gio-2.0 >= $GIO_MINIMUM],
- [use_gio=yes],
- [use_gio=no])
- if test "x$use_gio" = "xyes"; then
- AC_DEFINE([HAVE_GIO], 1)
- fi
-
PKG_CHECK_MODULES([LIBAPPINDICATOR],
[appindicator-0.1 >= $LIBAPPINDICATOR_MINIMUM],
[have_libappindicator=yes],
LIBAPPINDICATOR_LIBS=
fi
fi
-
- PKG_CHECK_MODULES([DBUS_GLIB],
- [dbus-glib-1 >= $DBUS_GLIB_MINIMUM],
- [use_dbus_glib=yes],
- [use_dbus_glib=no])
- if test "x$use_dbus_glib" = "xyes"; then
- AC_DEFINE([HAVE_DBUS_GLIB], 1)
- fi
- if test "x$use_dbus_glib" = "xyes"; then
- AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
- if test "x$DBUS_BINDING_TOOL" = xno; then
- AC_MSG_WARN([Cannot find dbus-binding-tool])
- use_dbus_glib="no (dbus-binding-tool not found)"
- fi
- fi
fi
AC_ARG_ENABLE([nls],
Compiler: ${CXX}
Build libtransmission: yes
-
* optimized for low-resource systems: ${enable_lightweight}
* µTP enabled: ${build_utp}
Build Command-Line client: ${build_cli}
Build GTK+ client: ${build_gtk}
-
- Optional dependencies for GTK+ client:
-
- * dbus support: ${use_dbus_glib}
- * gio for watchdir and mime-type support: ${use_gio}
* libappindicator for an Ubuntu-style tray: ${use_libappindicator}
Build Daemon: ${build_daemon}
@LIBEVENT_CFLAGS@ \
@GTK_CFLAGS@ \
@LIBCURL_CFLAGS@ \
- @GIO_CFLAGS@ \
- @DBUS_GLIB_CFLAGS@ \
@OPENSSL_CFLAGS@ \
@ZLIB_CFLAGS@ \
@PTHREAD_CFLAGS@
stats.h \
torrent-cell-renderer.h \
tr-core.h \
- tr-core-dbus.h \
tr-icon.h \
tr-prefs.h \
tr-window.h \
bin_PROGRAMS = transmission-gtk
-dbus_generated_sources = tr-core-dbus.h
-
transmission_gtk_SOURCES = \
actions.c \
conf.c \
tr-icon.c \
tr-prefs.c \
tr-window.c \
- util.c \
- $(dbus_generated_sources)
+ util.c
dist_man_MANS = transmission-gtk.1
@DHT_LIBS@ \
@LIBUTP_LIBS@ \
@GTK_LIBS@ \
- @GIO_LIBS@ \
@LIBAPPINDICATOR_LIBS@ \
@LIBEVENT_LIBS@ \
- @DBUS_GLIB_LIBS@ \
@LIBCURL_LIBS@ \
@OPENSSL_LIBS@ \
@ZLIB_LIBS@ \
EXTRA_DIST = \
$(DESKTOP_IN_FILES) \
marshal.list \
- tr-core-dbus.xml \
transmission.png
DISTCLEANFILES = \
transmission-gtk.desktop
-CLEANFILES = $(dbus_generated_sources)
-
-$(srcdir)/tr-core.c: tr-core-dbus.h
-
-tr-core-dbus.h: $(srcdir)/tr-core-dbus.xml
- $(DBUS_BINDING_TOOL) --mode=glib-server --prefix=gtr_core $< > $(@F)
-
if WIN32
transmission.res: transmission.rc
BUILT_SOURCES = \
setransmission.res
-CLEANFILES += \
+CLEANFILES = \
transmission.res
transmission_gtk_LDADD += \
{ "queue-move-top", GTK_STOCK_GOTO_TOP, N_( "Move to _Top" ), NULL, NULL, G_CALLBACK( action_cb ) },
{ "queue-move-up", GTK_STOCK_GO_UP, N_( "Move _Up" ), NULL, NULL, G_CALLBACK( action_cb ) },
{ "queue-move-down", GTK_STOCK_GO_DOWN, N_( "Move _Down" ), NULL, NULL, G_CALLBACK( action_cb ) },
- { "queue-move-bottom", GTK_STOCK_GOTO_BOTTOM, N_( "Move to _Bottom" ), NULL, NULL, G_CALLBACK( action_cb ) }
+ { "queue-move-bottom", GTK_STOCK_GOTO_BOTTOM, N_( "Move to _Bottom" ), NULL, NULL, G_CALLBACK( action_cb ) },
+ { "present-main-window", NULL, N_( "Present Main Window" ), NULL, NULL, G_CALLBACK( action_cb ) }
};
typedef struct
gl_confdir = g_strdup( configDir );
- if( gtr_mkdir_with_parents( gl_confdir, 0755 ) )
+ if( g_mkdir_with_parents( gl_confdir, 0755 ) )
return TRUE;
if( errstr != NULL )
cf_check_older_configs( );
-#ifdef HAVE_GIO
str = NULL;
if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP );
if( !str ) str = tr_getDefaultDownloadDir( );
tr_bencDictAddStr ( d, PREF_KEY_DIR_WATCH, str );
tr_bencDictAddBool( d, PREF_KEY_DIR_WATCH_ENABLED, FALSE );
-#endif
tr_bencDictAddBool( d, PREF_KEY_USER_HAS_GIVEN_INFORMED_CONSENT, FALSE );
tr_bencDictAddBool( d, PREF_KEY_INHIBIT_HIBERNATION, FALSE );
tr_bencDictAddInt( d, PREF_KEY_MAIN_WINDOW_X, 50 );
tr_bencDictAddInt( d, PREF_KEY_MAIN_WINDOW_Y, 50 );
- str = NULL;
-#if GLIB_CHECK_VERSION( 2, 14, 0 )
- if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
-#endif
- if( !str ) str = tr_getDefaultDownloadDir( );
+ str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, str );
tr_bencDictAddStr( d, PREF_KEY_SORT_MODE, "sort-by-name" );
#include <libtransmission/web.h> /* tr_webRun() */
#include "favicon.h"
-#include "util.h" /* gtr_mkdir_with_parents(), gtr_idle_add() */
+#include "util.h" /* gtr_idle_add() */
#define IMAGE_TYPES 4
static const char * image_types[IMAGE_TYPES] = { "ico", "png", "gif", "jpg" };
"transmission",
"favicons",
NULL );
- gtr_mkdir_with_parents( dir, 0777 );
+ g_mkdir_with_parents( dir, 0777 );
}
return dir;
#include <gtk/gtk.h>
#include "icons.h"
-#ifdef HAVE_GIO
- #if GTK_CHECK_VERSION( 2, 12, 0 )
- #define USE_GIO_ICONS
- #endif
+#if GTK_CHECK_VERSION( 2, 12, 0 )
+ #define USE_GIO_ICONS
#endif
#ifdef USE_GIO_ICONS
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-#ifdef HAVE_GIO
- #include <gio/gio.h>
-#endif
+#include <gio/gio.h>
#include <gtk/gtk.h>
#include <libtransmission/transmission.h>
static void
register_magnet_link_handler( void )
{
-#ifdef HAVE_GIO
GAppInfo * app_info = g_app_info_get_default_for_uri_scheme( "magnet" );
if( app_info == NULL )
{
g_clear_error( &error );
}
}
-#endif
}
static void
/* ensure the directories are created */
if(( str = gtr_pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR )))
- gtr_mkdir_with_parents( str, 0777 );
+ g_mkdir_with_parents( str, 0777 );
if(( str = gtr_pref_string_get( TR_PREFS_KEY_INCOMPLETE_DIR )))
- gtr_mkdir_with_parents( str, 0777 );
+ g_mkdir_with_parents( str, 0777 );
/* initialize the libtransmission session */
session = tr_sessionInit( "gtk", configDir, TRUE, gtr_pref_get_all( ) );
}
static void
-toggleMainWindow( struct cbdata * cbdata )
+presentMainWindow( struct cbdata * cbdata )
{
GtkWindow * window = cbdata->wind;
- const int doShow = cbdata->is_iconified;
- static int x = 0;
- static int y = 0;
- if( doShow )
+ if( cbdata->is_iconified )
{
- cbdata->is_iconified = 0;
+ cbdata->is_iconified = false;
+
gtk_window_set_skip_taskbar_hint( window, FALSE );
- gtk_window_move( window, x, y );
- gtr_widget_set_visible( GTK_WIDGET( window ), TRUE );
- gtr_window_present( window );
}
- else
+
+ if( !gtk_widget_get_visible( GTK_WIDGET( window ) ) )
{
- gtk_window_get_position( window, &x, &y );
- gtk_window_set_skip_taskbar_hint( window, TRUE );
- gtr_widget_set_visible( GTK_WIDGET( window ), FALSE );
- cbdata->is_iconified = 1;
+ gtk_window_resize( window, gtr_pref_int_get( PREF_KEY_MAIN_WINDOW_WIDTH ),
+ gtr_pref_int_get( PREF_KEY_MAIN_WINDOW_HEIGHT ) );
+ gtk_window_move( window, gtr_pref_int_get( PREF_KEY_MAIN_WINDOW_X ),
+ gtr_pref_int_get( PREF_KEY_MAIN_WINDOW_Y ) );
+ gtr_widget_set_visible( GTK_WIDGET( window ), TRUE );
}
+ gtr_window_present( window );
+}
+
+static void
+hideMainWindow( struct cbdata * cbdata )
+{
+ GtkWindow * window = cbdata->wind;
+ gtk_window_set_skip_taskbar_hint( window, TRUE );
+ gtr_widget_set_visible( GTK_WIDGET( window ), FALSE );
+ cbdata->is_iconified = true;
+}
+
+static void
+toggleMainWindow( struct cbdata * cbdata )
+{
+ if( cbdata->is_iconified )
+ presentMainWindow( cbdata );
+ else
+ hideMainWindow( cbdata );
}
static gboolean
{
toggleMainWindow( data );
}
+ else if( !strcmp( action_name, "present-main-window" ) )
+ {
+ presentMainWindow( data );
+ }
else g_error ( "Unhandled action: %s", action_name );
if( changed )
static const char *
getDefaultSavePath( void )
{
- const char * path;
-#if GLIB_CHECK_VERSION( 2,14,0 )
- path = g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP );
-#else
- path = g_get_home_dir( );
-#endif
- return path;
+ return g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP );
}
static void
g_object_set( p->text_renderer, "xpad", 0, "ypad", 0, NULL );
p->progress_renderer = gtk_cell_renderer_progress_new( );
p->icon_renderer = gtk_cell_renderer_pixbuf_new( );
- gtr_object_ref_sink( p->text_renderer );
- gtr_object_ref_sink( p->progress_renderer );
- gtr_object_ref_sink( p->icon_renderer );
+ g_object_ref_sink( p->text_renderer );
+ g_object_ref_sink( p->progress_renderer );
+ g_object_ref_sink( p->icon_renderer );
p->bar_height = DEFAULT_BAR_HEIGHT;
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<node>
- <interface name="com.transmissionbt.Transmission">
- <method name="AddMetainfo">
- <arg type="b" name="handled" direction="out"/>
- <arg type="s" name="metainfo" direction="in"/>
- </method>
- <method name="PresentWindow">
- <arg type="b" name="handled" direction="out"/>
- </method>
- </interface>
-</node>
-
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#ifdef HAVE_GIO
- #include <gio/gio.h>
-#endif
-#ifdef HAVE_DBUS_GLIB
- #include <dbus/dbus-glib.h>
-#endif
+#include <gio/gio.h>
#include <event2/buffer.h>
#include "conf.h"
#include "notify.h"
#include "tr-core.h"
-#ifdef HAVE_DBUS_GLIB
- #include "tr-core-dbus.h"
-#endif
#include "tr-prefs.h"
#include "util.h"
#include "actions.h"
static void core_maybe_inhibit_hibernation( TrCore * core );
-static gboolean our_instance_adds_remote_torrents = FALSE;
-
struct TrCorePrivate
{
-#ifdef HAVE_GIO
GFileMonitor * monitor;
gulong monitor_tag;
char * monitor_dir;
GSList * monitor_files;
guint monitor_idle_tag;
-#endif
+
gboolean adding_from_watch_dir;
gboolean inhibit_allowed;
gboolean have_inhibit_cookie;
gboolean dbus_error;
guint inhibit_cookie;
+ guint dbus_session_owner_id;
+ guint dbus_display_owner_id;
gint busy_count;
GtkTreeModel * raw_model;
GtkTreeModel * sorted_model;
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1, G_TYPE_STRING );
+}
-#ifdef HAVE_DBUS_GLIB
+static void
+handle_dbus_method( GDBusConnection * connection UNUSED,
+ const gchar * sender UNUSED,
+ const gchar * object_path,
+ const gchar * interface_name,
+ const gchar * method_name,
+ GVariant * parameters,
+ GDBusMethodInvocation * invocation,
+ gpointer core )
+{
+ gboolean handled = false;
+
+ if( !g_strcmp0( interface_name, TR_DBUS_SESSION_INTERFACE ) )
{
- DBusGConnection * bus = dbus_g_bus_get( DBUS_BUS_SESSION, NULL );
- DBusGProxy * bus_proxy = NULL;
- if( bus )
- bus_proxy =
- dbus_g_proxy_new_for_name( bus, "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus" );
- if( bus_proxy )
+ if( !g_strcmp0( method_name, "TorrentAdd" ) )
{
- int result = 0;
- dbus_g_proxy_call( bus_proxy, "RequestName", NULL,
- G_TYPE_STRING,
- "com.transmissionbt.Transmission",
- G_TYPE_UINT, 0,
- G_TYPE_INVALID,
- G_TYPE_UINT, &result,
- G_TYPE_INVALID );
- if( ( our_instance_adds_remote_torrents = result == 1 ) )
- dbus_g_object_type_install_info(
- TR_CORE_TYPE,
- &dbus_glib_gtr_core_object_info );
+ GVariant * args = g_variant_get_child_value( parameters, 0 );
+ GVariant * filename_variant = g_variant_lookup_value ( args, "filename", G_VARIANT_TYPE_STRING );
+ char * filename = g_variant_dup_string( filename_variant, NULL );
+ GSList * files = g_slist_append( NULL, filename );
+ gtr_core_add_list_defaults( TR_CORE( core ), files, TRUE );
+ g_dbus_method_invocation_return_value( invocation, g_variant_new( "(b)", true ) );
+ handled = true;
}
}
-#endif
+ else if( !g_strcmp0( interface_name, TR_DBUS_DISPLAY_INTERFACE ) )
+ {
+ if( !g_strcmp0( method_name, "PresentWindow" ) )
+ {
+ gtr_action_activate( "present-main-window" );
+ g_dbus_method_invocation_return_value( invocation, NULL );
+ handled = true;
+ }
+ }
+
+ if( !handled )
+ g_warning( "Unhandled method call:\n\tObject Path: %s\n\tInterface Name: %s\n\tMethod Name: %s",
+ object_path, interface_name, method_name );
+};
+
+static void
+on_session_registered_in_dbus( GDBusConnection *connection, const gchar *name UNUSED, gpointer core )
+{
+ GError * err = NULL;
+ GDBusNodeInfo * node_info;
+ GDBusInterfaceVTable vtable;
+ const char * interface_xml = "<node>"
+ " <interface name='" TR_DBUS_SESSION_INTERFACE "'>"
+ " <method name='TorrentAdd'>"
+ " <arg type='a{sv}' name='args' direction='in'/>"
+ " <arg type='b' name='response' direction='out'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+ node_info = g_dbus_node_info_new_for_xml( interface_xml, &err );
+
+ vtable.method_call = handle_dbus_method;
+ vtable.get_property = NULL;
+ vtable.set_property = NULL;
+
+ g_dbus_connection_register_object ( connection,
+ TR_DBUS_SESSION_OBJECT_PATH,
+ node_info->interfaces[0],
+ &vtable,
+ core,
+ NULL,
+ &err );
+
+ if( err != NULL ) {
+ g_warning( "%s:%d Error registering object: %s", __FILE__, __LINE__, err->message );
+ g_error_free( err );
+ }
+}
+
+static void
+on_display_registered_in_dbus( GDBusConnection *connection, const gchar *name UNUSED, gpointer core )
+{
+ GError * err = NULL;
+ const char * interface_xml = "<node>"
+ " <interface name='" TR_DBUS_DISPLAY_INTERFACE "'>"
+ " <method name='PresentWindow'>"
+ " </method>"
+ " </interface>"
+ "</node>";
+ GDBusInterfaceVTable vtable = { .method_call=handle_dbus_method };
+ GDBusNodeInfo * node_info = g_dbus_node_info_new_for_xml( interface_xml, &err );
+
+ g_dbus_connection_register_object ( connection,
+ TR_DBUS_DISPLAY_OBJECT_PATH,
+ node_info->interfaces[0],
+ &vtable,
+ core,
+ NULL,
+ &err );
+
+ if( err != NULL ) {
+ g_warning( "%s:%d Error registering object: %s", __FILE__, __LINE__, err->message );
+ g_error_free( err );
+ }
}
static void
p->string_chunk = g_string_chunk_new( 2048 );
g_object_unref( p->raw_model );
-#ifdef HAVE_DBUS_GLIB
- if( our_instance_adds_remote_torrents )
- {
- DBusGConnection * bus = dbus_g_bus_get( DBUS_BUS_SESSION, NULL );
- if( bus )
- dbus_g_connection_register_g_object(
- bus,
- "/com/transmissionbt/Transmission",
- G_OBJECT( self ) );
- }
-#endif
+ p->dbus_session_owner_id = g_bus_own_name( G_BUS_TYPE_SESSION,
+ TR_DBUS_SESSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ on_session_registered_in_dbus,
+ NULL,
+ self,
+ NULL );
+
+ p->dbus_display_owner_id = g_bus_own_name( G_BUS_TYPE_SESSION,
+ TR_DBUS_DISPLAY_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ on_display_registered_in_dbus,
+ NULL,
+ self,
+ NULL );
}
GType
****
***/
-#ifdef HAVE_GIO
-
struct watchdir_file
{
char * filename;
}
}
-#endif
-
/***
****
***/
{
core_maybe_inhibit_hibernation( core );
}
-#ifdef HAVE_GIO
else if( !strcmp( key, PREF_KEY_DIR_WATCH )
|| !strcmp( key, PREF_KEY_DIR_WATCH_ENABLED ) )
{
core_watchdir_update( core );
}
-#endif
}
/**
gtr_pref_save( session );
tr_sessionClose( session );
}
+
+ g_bus_unown_name( core->priv->dbus_display_owner_id );
+ g_bus_unown_name( core->priv->dbus_session_owner_id );
}
/***
core_add_ctor( core, ctor, do_prompt, do_notify );
}
-/* invoked remotely via dbus. */
-gboolean
-gtr_core_add_metainfo( TrCore * core,
- const char * payload,
- gboolean * setme_handled,
- GError ** gerr UNUSED )
-{
- tr_session * session = gtr_core_session( core );
-
- if( !session )
- {
- *setme_handled = FALSE;
- }
- else if( gtr_is_supported_url( payload ) || gtr_is_magnet_link( payload ) )
- {
- gtr_core_add_from_url( core, payload );
- *setme_handled = TRUE;
- }
- else /* base64-encoded metainfo */
- {
- int file_length;
- tr_ctor * ctor;
- char * file_contents;
- gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
-
- ctor = tr_ctorNew( session );
- core_apply_defaults( ctor );
-
- file_contents = tr_base64_decode( payload, -1, &file_length );
- tr_ctorSetMetainfo( ctor, (const uint8_t*)file_contents, file_length );
- core_add_ctor( core, ctor, do_prompt, TRUE );
-
- tr_free( file_contents );
- gtr_core_torrents_added( core );
- *setme_handled = TRUE;
- }
-
- return TRUE;
-}
-
/***
****
***/
*** Hibernate
**/
-#ifdef HAVE_DBUS_GLIB
-
-static DBusGProxy*
-get_hibernation_inhibit_proxy( void )
-{
- GError * error = NULL;
- const char * name = "org.gnome.SessionManager";
- const char * path = "/org/gnome/SessionManager";
- const char * interface = "org.gnome.SessionManager";
- DBusGConnection * conn = dbus_g_bus_get( DBUS_BUS_SESSION, &error );
-
- if( error )
- {
- g_warning ( "DBUS cannot connect : %s", error->message );
- g_error_free ( error );
- return NULL;
- }
-
- return dbus_g_proxy_new_for_name ( conn, name, path, interface );
-}
+#define SESSION_MANAGER_SERVICE_NAME "org.gnome.SessionManager"
+#define SESSION_MANAGER_INTERFACE "org.gnome.SessionManager"
+#define SESSION_MANAGER_OBJECT_PATH "/org/gnome/SessionManager"
static gboolean
gtr_inhibit_hibernation( guint * cookie )
{
- gboolean success = FALSE;
- DBusGProxy * proxy = get_hibernation_inhibit_proxy( );
-
- if( proxy )
- {
- GError * error = NULL;
- const int toplevel_xid = 0;
- const char * application = _( "Transmission Bittorrent Client" );
- const char * reason = _( "BitTorrent Activity" );
- const int flags = 4; /* Inhibit suspending the session or computer */
-
- success = dbus_g_proxy_call( proxy, "Inhibit", &error,
- G_TYPE_STRING, application,
- G_TYPE_UINT, toplevel_xid,
- G_TYPE_STRING, reason,
- G_TYPE_UINT, flags,
- G_TYPE_INVALID, /* sentinel - end of input args */
- G_TYPE_UINT, cookie,
- G_TYPE_INVALID /* senitnel - end of output args */ );
-
- if( success )
- tr_inf( "%s", _( "Disallowing desktop hibernation" ) );
- else
- {
- tr_err( _( "Couldn't disable desktop hibernation: %s" ),
- error->message );
- g_error_free( error );
- }
-
- g_object_unref( G_OBJECT( proxy ) );
+ gboolean success;
+ GVariant * response;
+ GDBusConnection * connection;
+ GError * err = NULL;
+ const char * application = "Transmission BitTorrent Client";
+ const char * reason = "BitTorrent Activity";
+ const int toplevel_xid = 0;
+ const int flags = 4; /* Inhibit suspending the session or computer */
+
+ connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
+
+ response = g_dbus_connection_call_sync( connection,
+ SESSION_MANAGER_SERVICE_NAME,
+ SESSION_MANAGER_OBJECT_PATH,
+ SESSION_MANAGER_INTERFACE,
+ "Inhibit",
+ g_variant_new( "(susu)", application, toplevel_xid, reason, flags ),
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ 1000, NULL, &err );
+
+ *cookie = g_variant_get_uint32( g_variant_get_child_value( response, 0 ) );
+
+ success = err == NULL;
+
+ /* logging */
+ if( success )
+ tr_inf( "%s", _( "Inhibiting desktop hibernation" ) );
+ else {
+ tr_err( _( "Couldn't inhibit desktop hibernation: %s" ), err->message );
+ g_error_free( err );
}
- return success != 0;
+ /* cleanup */
+ g_variant_unref( response );
+ g_object_unref( connection );
+ return success;
}
static void
gtr_uninhibit_hibernation( guint inhibit_cookie )
{
- DBusGProxy * proxy = get_hibernation_inhibit_proxy( );
+ GVariant * response;
+ GDBusConnection * connection;
+ GError * err = NULL;
- if( proxy )
- {
- GError * error = NULL;
- gboolean success = dbus_g_proxy_call( proxy, "Uninhibit", &error,
- G_TYPE_UINT, inhibit_cookie,
- G_TYPE_INVALID,
- G_TYPE_INVALID );
- if( success )
- tr_inf( "%s", _( "Allowing desktop hibernation" ) );
- else
- {
- g_warning( "Couldn't uninhibit the system from suspending: %s.",
- error->message );
- g_error_free( error );
- }
+ connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
- g_object_unref( G_OBJECT( proxy ) );
+ response = g_dbus_connection_call_sync( connection,
+ SESSION_MANAGER_SERVICE_NAME,
+ SESSION_MANAGER_OBJECT_PATH,
+ SESSION_MANAGER_INTERFACE,
+ "Uninhibit",
+ g_variant_new( "(u)", inhibit_cookie ),
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ 1000, NULL, &err );
+
+ /* logging */
+ if( err == NULL )
+ tr_inf( "%s", _( "Allowing desktop hibernation" ) );
+ else {
+ g_warning( "Couldn't uninhibit desktop hibernation: %s.", err->message );
+ g_error_free( err );
}
-}
-#endif
+ /* cleanup */
+ g_variant_unref( response );
+ g_object_unref( connection );
+}
static void
gtr_core_set_hibernation_allowed( TrCore * core, gboolean allowed )
{
-#ifdef HAVE_DBUS_GLIB
g_return_if_fail( core );
g_return_if_fail( core->priv );
else
core->priv->dbus_error = TRUE;
}
-#endif
}
static void
}
}
}
-
-gboolean
-gtr_core_present_window( TrCore * core UNUSED,
- gboolean * success,
- GError ** err UNUSED )
-{
- /* Setting the toggle-main-window GtkCheckMenuItem to
- make sure its state is correctly set */
- gtr_action_set_toggled( "toggle-main-window", TRUE);
-
- *success = TRUE;
- return TRUE;
-}
GSList * torrentFiles,
gboolean do_notify );
-/** @brief Add a torrent. */
-gboolean gtr_core_add_metainfo( TrCore * core,
- const char * base64_metainfo,
- gboolean * setme_success,
- GError ** err );
/** @brief Add a torrent from a URL */
void gtr_core_add_from_url( TrCore * core, const char * url );
/** Add a torrent. */
void gtr_core_add_torrent( TrCore*, tr_torrent*, gboolean do_notify );
-/** Present the main window */
-gboolean gtr_core_present_window( TrCore*, gboolean * setme_success, GError ** err );
-
/**
* Notifies listeners that torrents have been added.
* This should be called after one or more tr_core_add*() calls.
MC_ROW_COUNT
};
+
+#define TR_DBUS_SESSION_SERVICE_NAME "com.transmissionbt.transmission.Session"
+#define TR_DBUS_SESSION_INTERFACE "com.transmissionbt.transmission.Session"
+#define TR_DBUS_SESSION_OBJECT_PATH "/com/transmissionbt/transmission/Session"
+
+#define TR_DBUS_DISPLAY_SERVICE_NAME "com.transmissionbt.transmission.Display"
+#define TR_DBUS_DISPLAY_INTERFACE "com.transmissionbt.transmission.Display"
+#define TR_DBUS_DISPLAY_OBJECT_PATH "/com/transmissionbt/transmission/Display"
+
+
#endif /* GTR_CORE_H */
w = new_check_button( s, TR_PREFS_KEY_TRASH_ORIGINAL, core );
hig_workarea_add_wide_control( t, &row, w );
-#ifdef HAVE_GIO
s = _( "Automatically _add torrents from:" );
l = new_check_button( s, PREF_KEY_DIR_WATCH_ENABLED, core );
w = new_path_chooser_button( PREF_KEY_DIR_WATCH, core );
- gtk_widget_set_sensitive( GTK_WIDGET( w ),
- gtr_pref_flag_get( PREF_KEY_DIR_WATCH_ENABLED ) );
+ gtk_widget_set_sensitive( GTK_WIDGET( w ), gtr_pref_flag_get( PREF_KEY_DIR_WATCH_ENABLED ) );
g_signal_connect( l, "toggled", G_CALLBACK( target_cb ), w );
hig_workarea_add_row_w( t, &row, l, w, NULL );
-#endif
hig_workarea_add_section_divider( t, &row );
hig_workarea_add_section_title( t, &row, _( "Seeding" ) );
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h> /* g_unlink() */
-#ifdef HAVE_GIO
- #include <gio/gio.h> /* g_file_trash() */
-#endif
-#ifdef HAVE_DBUS_GLIB
- #include <dbus/dbus-glib.h>
-#endif
+#include <gio/gio.h> /* g_file_trash() */
#include <libtransmission/transmission.h> /* TR_RATIO_NA, TR_RATIO_INF */
#include <libtransmission/utils.h> /* tr_strratio() */
#include <libtransmission/version.h> /* SHORT_VERSION_STRING */
#include "hig.h"
+#include "tr-core.h" /* dbus names */
#include "util.h"
/***
return buf;
}
-int
-gtr_mkdir_with_parents( const char * path, int mode )
-{
-#if GLIB_CHECK_VERSION( 2, 8, 0 )
- return !g_mkdir_with_parents( path, mode );
-#else
- return !tr_mkdirp( path, mode );
-#endif
-}
-
/* pattern-matching text; ie, legaltorrents.com */
void
gtr_get_host_from_url( char * buf, size_t buflen, const char * url )
return FALSE;
}
-gpointer
-gtr_object_ref_sink( gpointer object )
-{
-#if GLIB_CHECK_VERSION( 2, 10, 0 )
- g_object_ref_sink( object );
-#else
- g_object_ref( object );
- gtk_object_sink( GTK_OBJECT( object ) );
-#endif
- return object;
-}
-
int
gtr_file_trash_or_remove( const char * filename )
{
if( filename && g_file_test( filename, G_FILE_TEST_EXISTS ) )
{
gboolean trashed = FALSE;
-#ifdef HAVE_GIO
GError * err = NULL;
GFile * file = g_file_new_for_path( filename );
trashed = g_file_trash( file, NULL, &err );
g_message( "Unable to trash file \"%s\": %s", filename, err->message );
g_clear_error( &err );
g_object_unref( G_OBJECT( file ) );
-#endif
if( !trashed && g_remove( filename ) )
{
{
char * uri = NULL;
-#ifdef HAVE_GIO
GFile * file = g_file_new_for_path( path );
uri = g_file_get_uri( file );
g_object_unref( G_OBJECT( file ) );
-#else
+
if( g_path_is_absolute( path ) )
uri = g_strdup_printf( "file://%s", path );
else {
uri = g_strdup_printf( "file://%s/%s", cwd, path );
g_free( cwd );
}
-#endif
gtr_open_uri( uri );
g_free( uri );
opened = gtk_show_uri( NULL, uri, GDK_CURRENT_TIME, NULL );
#endif
-#ifdef HAVE_GIO
if( !opened )
opened = g_app_info_launch_default_for_uri( uri, NULL, NULL );
-#endif
if( !opened ) {
char * argv[] = { (char*)"xdg-open", (char*)uri, NULL };
}
}
-#define VALUE_SERVICE_NAME "com.transmissionbt.Transmission"
-#define VALUE_SERVICE_OBJECT_PATH "/com/transmissionbt/Transmission"
-#define VALUE_SERVICE_INTERFACE "com.transmissionbt.Transmission"
-
gboolean
gtr_dbus_add_torrent( const char * filename )
{
- /* FIXME: why is this static? */
- static gboolean handled = FALSE;
-
-#ifdef HAVE_DBUS_GLIB
- char * payload;
- gsize file_length;
- char * file_contents = NULL;
-
- /* If it's a file, load its contents and send them over the wire...
- * it might be a temporary file that's going to disappear. */
- if( g_file_get_contents( filename, &file_contents, &file_length, NULL ) )
- payload = tr_base64_encode( file_contents, file_length, NULL );
- else if( gtr_is_supported_url( filename ) || gtr_is_magnet_link( filename ) )
- payload = tr_strdup( filename );
- else
- payload = NULL;
-
- if( payload != NULL )
- {
- GError * err = NULL;
- DBusGConnection * conn;
- DBusGProxy * proxy = NULL;
-
- if(( conn = dbus_g_bus_get( DBUS_BUS_SESSION, &err )))
- proxy = dbus_g_proxy_new_for_name (conn, VALUE_SERVICE_NAME,
- VALUE_SERVICE_OBJECT_PATH,
- VALUE_SERVICE_INTERFACE );
- else if( err )
- g_message( "err: %s", err->message );
-
- if( proxy )
- dbus_g_proxy_call( proxy, "AddMetainfo", &err,
- G_TYPE_STRING, payload,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &handled,
- G_TYPE_INVALID );
- if( err )
- g_message( "err: %s", err->message );
-
- if( proxy )
- g_object_unref( proxy );
- if( conn )
- dbus_g_connection_unref( conn );
-
- tr_free( payload );
- }
-
- g_free( file_contents );
-
-#endif
+ GVariant * response;
+ GVariant * args;
+ GVariant * parameters;
+ GVariantBuilder * builder;
+ GDBusConnection * connection;
+ GError * err = NULL;
+ gboolean handled = FALSE;
+
+ /* "args" is a dict as described in the RPC spec's "torrent-add" section */
+ builder = g_variant_builder_new( G_VARIANT_TYPE( "a{sv}" ) );
+ g_variant_builder_add( builder, "{sv}", "filename", g_variant_new_string( filename ) );
+ args = g_variant_builder_end( builder );
+ parameters = g_variant_new_tuple( &args, 1 );
+ g_variant_builder_unref( builder );
+
+ connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
+
+ response = g_dbus_connection_call_sync( connection,
+ TR_DBUS_SESSION_SERVICE_NAME,
+ TR_DBUS_SESSION_OBJECT_PATH,
+ TR_DBUS_SESSION_INTERFACE,
+ "TorrentAdd",
+ parameters,
+ G_VARIANT_TYPE_TUPLE,
+ G_DBUS_CALL_FLAGS_NONE,
+ 10000, /* wait 10 sec */
+ NULL,
+ &err );
+
+
+ handled = g_variant_get_boolean( g_variant_get_child_value( response, 0 ) );
+
+ g_object_unref( connection );
+ g_variant_unref( response );
return handled;
}
gboolean
gtr_dbus_present_window( void )
{
- static gboolean success = FALSE;
-
-#ifdef HAVE_DBUS_GLIB
- DBusGProxy * proxy = NULL;
- GError * err = NULL;
- DBusGConnection * conn;
- if( ( conn = dbus_g_bus_get( DBUS_BUS_SESSION, &err ) ) )
- proxy = dbus_g_proxy_new_for_name ( conn, VALUE_SERVICE_NAME,
- VALUE_SERVICE_OBJECT_PATH,
- VALUE_SERVICE_INTERFACE );
- else if( err )
- g_message( "err: %s", err->message );
- if( proxy )
- dbus_g_proxy_call( proxy, "PresentWindow", &err,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &success,
- G_TYPE_INVALID );
- if( err )
- g_message( "err: %s", err->message );
-
- g_object_unref( proxy );
- dbus_g_connection_unref( conn );
-#endif
+ gboolean success;
+ GDBusConnection * connection;
+ GError * err = NULL;
+
+ connection = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, &err );
+
+ g_dbus_connection_call_sync( connection,
+ TR_DBUS_DISPLAY_SERVICE_NAME,
+ TR_DBUS_DISPLAY_OBJECT_PATH,
+ TR_DBUS_DISPLAY_INTERFACE,
+ "PresentWindow",
+ NULL,
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ 1000, NULL, &err );
+
+ success = err == NULL;
+
+ /* cleanup */
+ if( err != NULL )
+ g_error_free( err );
+ g_object_unref( connection );
return success;
}
****
***/
-/* backwards-compatible wrapper around g_mkdir_with_parents() */
-int gtr_mkdir_with_parents( const char *name, int mode );
-
/* backwards-compatible wrapper around gdk_threads_add_timeout_seconds() */
guint gtr_timeout_add_seconds( guint seconds, GSourceFunc func, gpointer data );
/* backwards-compatible wrapper around gtk_widget_set_visible() */
void gtr_widget_set_visible( GtkWidget *, gboolean );
-/* backwards-compatible wrapper around g_object_ref_sink() */
-gpointer gtr_object_ref_sink( gpointer object );
-
void gtr_dialog_set_content( GtkDialog * dialog, GtkWidget * content );
/***
BuildRequires: gtk2-devel >= @GTK_MINIMUM@
Requires: glib2 >= @GLIB_MINIMUM@
Requires: gtk2 >= @GTK_MINIMUM@
-# OPTIONAL for the gtk+ client... see configure.ac for details
-BuildRequires: dbus-glib-devel >= @DBUS_GLIB_MINIMUM@
-Requires: dbus-glib >= @DBUS_GLIB_MINIMUM@
Provides: %{name}