68
71
tr_session * session;
72
tr_core_marshal_err( GClosure * closure,
79
typedef void ( *TRMarshalErr )
80
( gpointer, enum tr_core_err, const char *,
82
TRMarshalErr callback;
83
GCClosure * cclosure = (GCClosure*) closure;
84
enum tr_core_err errcode;
88
g_return_if_fail( count == 3 );
90
inst = g_value_peek_pointer( vals );
91
errcode = g_value_get_int( vals + 1 );
92
errstr = g_value_get_string( vals + 2 );
93
gdata = closure->data;
95
callback = (TRMarshalErr)( marshal ? marshal : cclosure->callback );
96
callback( inst, errcode, errstr, gdata );
100
tr_core_marshal_blocklist( GClosure * closure,
104
gpointer hint UNUSED,
107
typedef void ( *TRMarshalErr )
108
( gpointer, enum tr_core_err, const char *,
110
TRMarshalErr callback;
111
GCClosure * cclosure = (GCClosure*) closure;
114
gpointer inst, gdata;
116
g_return_if_fail( count == 3 );
118
inst = g_value_peek_pointer( vals );
119
flag = g_value_get_boolean( vals + 1 );
120
str = g_value_get_string( vals + 2 );
121
gdata = closure->data;
123
callback = (TRMarshalErr)( marshal ? marshal : cclosure->callback );
124
callback( inst, flag, str, gdata );
128
tr_core_marshal_prompt( GClosure * closure,
132
gpointer hint UNUSED,
135
typedef void ( *TRMarshalPrompt )( gpointer, tr_ctor *, gpointer );
136
TRMarshalPrompt callback;
137
GCClosure * cclosure = (GCClosure*) closure;
139
gpointer inst, gdata;
141
g_return_if_fail( count == 2 );
143
inst = g_value_peek_pointer( vals );
144
ctor = g_value_peek_pointer( vals + 1 );
145
gdata = closure->data;
147
callback = (TRMarshalPrompt)( marshal ? marshal : cclosure->callback );
148
callback( inst, ctor, gdata );
152
75
isDisposed( const TrCore * core )
175
98
gpointer g_class_data UNUSED )
177
100
GObjectClass * gobject_class;
178
TrCoreClass * core_class;
180
103
g_type_class_add_private( g_class, sizeof( struct TrCorePrivate ) );
182
105
gobject_class = G_OBJECT_CLASS( g_class );
183
106
gobject_class->dispose = tr_core_dispose;
186
core_class = TR_CORE_CLASS( g_class );
187
core_class->blocksig = g_signal_new( "blocklist-status",
190
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
191
tr_core_marshal_blocklist,
193
2, G_TYPE_BOOLEAN, G_TYPE_STRING );
194
core_class->errsig = g_signal_new( "error", G_TYPE_FROM_CLASS( g_class ),
195
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
196
tr_core_marshal_err, G_TYPE_NONE,
197
2, G_TYPE_INT, G_TYPE_STRING );
198
core_class->promptsig = g_signal_new( "add-torrent-prompt",
201
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
202
tr_core_marshal_prompt,
205
core_class->quitsig = g_signal_new( "quit", G_TYPE_FROM_CLASS( g_class ),
206
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
207
g_cclosure_marshal_VOID__VOID,
209
core_class->prefsig = g_signal_new( "prefs-changed",
210
G_TYPE_FROM_CLASS( g_class ),
211
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
212
g_cclosure_marshal_VOID__STRING,
213
G_TYPE_NONE, 1, G_TYPE_STRING );
108
cc = TR_CORE_CLASS( g_class );
110
cc->blocklistSignal = g_signal_new( "blocklist-updated", /* name */
111
G_TYPE_FROM_CLASS( g_class ), /* applies to TrCore */
112
G_SIGNAL_RUN_FIRST, /* when to invoke */
113
0, NULL, NULL, /* accumulator */
114
g_cclosure_marshal_VOID__INT, /* marshaler */
115
G_TYPE_NONE, /* return type */
116
1, G_TYPE_INT ); /* signal arguments */
118
cc->portSignal = g_signal_new( "port-tested",
119
G_TYPE_FROM_CLASS( g_class ),
122
g_cclosure_marshal_VOID__BOOLEAN,
126
cc->errsig = g_signal_new( "error",
127
G_TYPE_FROM_CLASS( g_class ),
130
g_cclosure_marshal_VOID__UINT_POINTER,
132
2, G_TYPE_UINT, G_TYPE_POINTER );
134
cc->promptsig = g_signal_new( "add-torrent-prompt",
135
G_TYPE_FROM_CLASS( g_class ),
138
g_cclosure_marshal_VOID__POINTER,
142
cc->quitsig = g_signal_new( "quit",
143
G_TYPE_FROM_CLASS( g_class ),
146
g_cclosure_marshal_VOID__VOID,
150
cc->prefsig = g_signal_new( "prefs-changed",
151
G_TYPE_FROM_CLASS( g_class ),
154
g_cclosure_marshal_VOID__STRING,
215
158
#ifdef HAVE_DBUS_GLIB
310
compareBySize( GtkTreeModel * model,
313
gpointer user_data UNUSED )
316
const tr_info *ia, *ib;
318
gtk_tree_model_get( model, a, MC_TORRENT_RAW, &t, -1 );
319
ia = tr_torrentInfo( t );
320
gtk_tree_model_get( model, b, MC_TORRENT_RAW, &t, -1 );
321
ib = tr_torrentInfo( t );
323
if( ia->totalSize < ib->totalSize ) return 1;
324
if( ia->totalSize > ib->totalSize ) return -1;
352
329
compareByProgress( GtkTreeModel * model,
355
332
gpointer user_data UNUSED )
358
tr_torrent * ta, *tb;
359
336
const tr_stat *sa, *sb;
361
gtk_tree_model_get( model, a, MC_TORRENT_RAW, &ta, -1 );
362
gtk_tree_model_get( model, b, MC_TORRENT_RAW, &tb, -1 );
363
sa = tr_torrentStatCached( ta );
364
sb = tr_torrentStatCached( tb );
338
gtk_tree_model_get( model, a, MC_TORRENT_RAW, &t, -1 );
339
sa = tr_torrentStatCached( t );
340
gtk_tree_model_get( model, b, MC_TORRENT_RAW, &t, -1 );
341
sb = tr_torrentStatCached( t );
365
342
ret = compareDouble( sa->percentDone, sb->percentDone );
367
344
ret = compareRatio( sa->ratio, sb->ratio );
420
412
sort_func = compareByAge;
421
413
else if( !strcmp( mode, "sort-by-progress" ) )
422
414
sort_func = compareByProgress;
415
else if( !strcmp( mode, "sort-by-eta" ) )
416
sort_func = compareByETA;
423
417
else if( !strcmp( mode, "sort-by-ratio" ) )
424
418
sort_func = compareByRatio;
425
419
else if( !strcmp( mode, "sort-by-state" ) )
426
420
sort_func = compareByState;
427
421
else if( !strcmp( mode, "sort-by-tracker" ) )
428
422
sort_func = compareByTracker;
423
else if( !strcmp( mode, "sort-by-size" ) )
424
sort_func = compareBySize;
431
426
sort_func = compareByName;
432
427
type = isReversed ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING;
1272
tr_core_set_pref_double( TrCore * self,
1276
const double oldval = pref_double_get( key );
1278
if( oldval != newval )
1280
pref_double_set( key, newval );
1281
commitPrefsChange( self, key );
1291
/* #define DEBUG_RPC */
1293
static int nextTag = 1;
1295
typedef void ( server_response_func )( TrCore * core, tr_benc * response, gpointer user_data );
1297
struct pending_request_data
1301
server_response_func * responseFunc;
1302
gpointer responseFuncUserData;
1305
static GHashTable * pendingRequests = NULL;
1308
readResponseIdle( void * vresponse )
1310
GByteArray * response;
1314
struct pending_request_data * data;
1316
response = vresponse;
1317
tr_jsonParse( response->data, response->len, &top, NULL );
1318
tr_bencDictFindInt( &top, "tag", &intVal );
1321
data = g_hash_table_lookup( pendingRequests, &tag );
1323
(*data->responseFunc)(data->core, &top, data->responseFuncUserData );
1325
tr_bencFree( &top );
1326
g_hash_table_remove( pendingRequests, &tag );
1327
g_byte_array_free( response, TRUE );
1332
readResponse( tr_session * session UNUSED,
1333
const char * response,
1334
size_t response_len,
1335
void * unused UNUSED )
1337
GByteArray * bytes = g_byte_array_new( );
1339
g_message( "response: [%*.*s]", (int)response_len, (int)response_len, response );
1341
g_byte_array_append( bytes, (const uint8_t*)response, response_len );
1342
g_idle_add( readResponseIdle, bytes );
1346
sendRequest( TrCore * core, const char * json, int tag,
1347
server_response_func * responseFunc, void * responseFuncUserData )
1349
tr_session * session = tr_core_session( core );
1351
if( pendingRequests == NULL )
1353
pendingRequests = g_hash_table_new_full( g_int_hash, g_int_equal, NULL, g_free );
1356
if( session == NULL )
1358
g_error( "GTK+ client doesn't support connections to remote servers yet." );
1362
/* remember this request */
1363
struct pending_request_data * data;
1364
data = g_new0( struct pending_request_data, 1 );
1367
data->responseFunc = responseFunc;
1368
data->responseFuncUserData = responseFuncUserData;
1369
g_hash_table_insert( pendingRequests, &data->tag, data );
1371
/* make the request */
1373
g_message( "request: [%s]", json );
1375
tr_rpc_request_exec_json( session, json, strlen( json ), readResponse, GINT_TO_POINTER(tag) );
1380
**** Sending a test-port request via RPC
1384
portTestResponseFunc( TrCore * core, tr_benc * response, gpointer userData UNUSED )
1387
tr_bool isOpen = FALSE;
1389
if( tr_bencDictFindDict( response, "arguments", &args ) )
1390
tr_bencDictFindBool( args, "port-is-open", &isOpen );
1392
emitPortTested( core, isOpen );
1396
tr_core_port_test( TrCore * core )
1399
const int tag = nextTag++;
1400
g_snprintf( buf, sizeof( buf ), "{ \"method\": \"port-test\", \"tag\": %d }", tag );
1401
sendRequest( core, buf, tag, portTestResponseFunc, NULL );
1405
**** Updating a blocklist via RPC
1409
blocklistResponseFunc( TrCore * core, tr_benc * response, gpointer userData UNUSED )
1412
int64_t ruleCount = 0;
1414
if( tr_bencDictFindDict( response, "arguments", &args ) )
1415
tr_bencDictFindInt( args, "blocklist-size", &ruleCount );
1418
pref_int_set( "blocklist-date", time( NULL ) );
1420
emitBlocklistUpdated( core, ruleCount );
1424
tr_core_blocklist_update( TrCore * core )
1427
const int tag = nextTag++;
1428
g_snprintf( buf, sizeof( buf ), "{ \"method\": \"blocklist-update\", \"tag\": %d }", tag );
1429
sendRequest( core, buf, tag, blocklistResponseFunc, NULL );
1437
tr_core_exec_json( TrCore * core, const char * json )
1439
g_message( "executing %s", json );
1440
sendRequest( core, json, 0, NULL, NULL );
1444
tr_core_exec( TrCore * core, const tr_benc * top )
1446
char * json = tr_bencToJSON( top );
1447
tr_core_exec_json( core, json );