transmission 2.51 update
[tomato.git] / release / src / router / transmission / gtk / notify.c
blob32a8b6c31fb90edd11d892cf53d166fb47bbde49
1 /*
2 * This file Copyright (C) Mnemosyne LLC
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
10 * $Id: notify.c 13265 2012-04-07 00:30:37Z jordan $
13 #include <string.h> /* strcmp() */
15 #include <gio/gio.h>
17 #include <glib/gi18n.h>
18 #include "conf.h"
19 #include "notify.h"
20 #include "tr-prefs.h"
21 #include "util.h"
23 #define NOTIFICATIONS_DBUS_NAME "org.freedesktop.Notifications"
24 #define NOTIFICATIONS_DBUS_CORE_OBJECT "/org/freedesktop/Notifications"
25 #define NOTIFICATIONS_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
27 static GDBusProxy *proxy = NULL;
28 static GHashTable *active_notifications = NULL;
29 static gboolean server_supports_actions = FALSE;
31 typedef struct _TrNotification
33 guint id;
34 TrCore * core;
35 int torrent_id;
36 } TrNotification;
38 static void
39 tr_notification_free( gpointer data )
41 TrNotification * n = data;
42 if( n->core )
43 g_object_unref( G_OBJECT( n->core ) );
44 g_free( n );
47 static void
48 get_capabilities_callback( GObject * source,
49 GAsyncResult * res,
50 gpointer user_data UNUSED )
52 GVariant *result;
53 char **caps;
54 int i;
56 result = g_dbus_proxy_call_finish( G_DBUS_PROXY( source ), res, NULL );
57 if( !result || !g_variant_is_of_type( result, G_VARIANT_TYPE( "(as)" ) ) )
59 if( result )
60 g_variant_unref( result );
61 return;
64 g_variant_get( result, "(^a&s)", &caps );
65 for( i = 0; caps[i]; i++ )
67 if( strcmp( caps[i], "actions" ) == 0 )
69 server_supports_actions = TRUE;
70 break;
73 g_free( caps );
74 g_variant_unref( result );
77 static void
78 g_signal_callback( GDBusProxy * proxy UNUSED,
79 char * sender_name UNUSED,
80 char * signal_name,
81 GVariant * params,
82 gpointer user_data UNUSED )
84 TrNotification * n;
85 guint id;
87 g_return_if_fail( g_variant_is_of_type( params, G_VARIANT_TYPE( "(u*)" ) ) );
89 g_variant_get( params, "(u*)", &id, NULL );
90 n = g_hash_table_lookup( active_notifications,
91 GINT_TO_POINTER( (int *) &id ) );
92 if( n == NULL )
93 return;
95 if( strcmp( signal_name, "NotificationClosed" ) == 0 )
97 g_hash_table_remove( active_notifications,
98 GINT_TO_POINTER( (int *) &n->id ) );
100 else if( strcmp( signal_name, "ActionInvoked" ) == 0 &&
101 g_variant_is_of_type( params, G_VARIANT_TYPE( "(us)" ) ) )
103 char * action;
104 tr_torrent * tor;
106 tor = gtr_core_find_torrent( n->core, n->torrent_id );
107 if( tor == NULL )
108 return;
110 g_variant_get( params, "(u&s)", NULL, &action );
111 if( strcmp( action, "folder" ) == 0 )
113 gtr_core_open_folder( n->core, n->torrent_id );
115 else if( strcmp( action, "file" ) == 0)
117 const tr_info * inf = tr_torrentInfo( tor );
118 const char * dir = tr_torrentGetDownloadDir( tor );
119 char * path = g_build_filename( dir, inf->files[0].name, NULL );
120 gtr_open_file( path );
121 g_free( path );
126 static void
127 dbus_proxy_ready_callback( GObject * source UNUSED,
128 GAsyncResult * res,
129 gpointer user_data UNUSED )
131 proxy = g_dbus_proxy_new_for_bus_finish( res, NULL );
132 if( proxy == NULL )
134 g_warning( "Failed to create proxy for %s", NOTIFICATIONS_DBUS_NAME );
135 return;
138 g_signal_connect( proxy, "g-signal",
139 G_CALLBACK( g_signal_callback ), NULL );
140 g_dbus_proxy_call( proxy,
141 "GetCapabilities",
142 g_variant_new( "()" ),
143 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
144 get_capabilities_callback, NULL );
147 void
148 gtr_notify_init( void )
150 active_notifications = g_hash_table_new_full( g_int_hash, g_int_equal,
151 NULL, tr_notification_free );
152 g_dbus_proxy_new_for_bus( G_BUS_TYPE_SESSION,
153 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
154 NULL,
155 NOTIFICATIONS_DBUS_NAME,
156 NOTIFICATIONS_DBUS_CORE_OBJECT,
157 NOTIFICATIONS_DBUS_CORE_INTERFACE,
158 NULL, dbus_proxy_ready_callback, NULL );
161 static void
162 notify_callback( GObject * source,
163 GAsyncResult * res,
164 gpointer user_data )
166 TrNotification * n = user_data;
167 GVariant * result;
169 result = g_dbus_proxy_call_finish( G_DBUS_PROXY( source ), res, NULL );
170 if( !result || !g_variant_is_of_type( result, G_VARIANT_TYPE( "(u)" ) ) )
172 if( result )
173 g_variant_unref( result );
174 tr_notification_free( n );
175 return;
178 g_variant_get( result, "(u)", &n->id );
179 g_hash_table_insert( active_notifications,
180 GINT_TO_POINTER( ( int * )&n->id ), n );
182 g_variant_unref( result );
185 void
186 gtr_notify_torrent_completed( TrCore * core, int torrent_id )
188 GVariantBuilder actions_builder;
189 TrNotification * n;
190 tr_torrent * tor;
191 const char * cmd = gtr_pref_string_get( PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND );
193 if( gtr_pref_flag_get( PREF_KEY_TORRENT_COMPLETE_SOUND_ENABLED ) )
194 g_spawn_command_line_async( cmd, NULL );
196 if( ! gtr_pref_flag_get( PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED ) )
197 return;
199 g_return_if_fail( G_IS_DBUS_PROXY( proxy ) );
201 tor = gtr_core_find_torrent( core, torrent_id );
203 n = g_new0( TrNotification, 1 );
204 n->core = g_object_ref( G_OBJECT( core ) );
205 n->torrent_id = torrent_id;
207 g_variant_builder_init( &actions_builder, G_VARIANT_TYPE( "as" ) );
209 if( server_supports_actions )
211 const tr_info * inf = tr_torrentInfo( tor );
212 if( inf->fileCount == 1 )
214 g_variant_builder_add( &actions_builder, "s", "file" );
215 g_variant_builder_add( &actions_builder, "s", _( "Open File" ) );
217 else
219 g_variant_builder_add( &actions_builder, "s", "folder" );
220 g_variant_builder_add( &actions_builder, "s", _( "Open Folder" ) );
224 g_dbus_proxy_call( proxy,
225 "Notify",
226 g_variant_new( "(susssasa{sv}i)",
227 "Transmission", n->id, "transmission",
228 _( "Torrent Complete" ),
229 tr_torrentName( tor ),
230 &actions_builder, NULL, -1 ),
231 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
232 notify_callback, n );
235 void
236 gtr_notify_torrent_added( const char * name )
238 TrNotification * n;
240 g_return_if_fail( G_IS_DBUS_PROXY( proxy ) );
242 if( !gtr_pref_flag_get( PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED ) )
243 return;
245 n = g_new0( TrNotification, 1 );
246 g_dbus_proxy_call( proxy,
247 "Notify",
248 g_variant_new( "(susssasa{sv}i)",
249 "Transmission", 0, "transmission",
250 _( "Torrent Added" ), name,
251 NULL, NULL, -1 ),
252 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
253 notify_callback, n );