Merge TrBackend into TrCore.
This commit is contained in:
parent
61263c844e
commit
a19989c544
|
@ -574,6 +574,7 @@ exitcheck( gpointer gdata )
|
|||
{
|
||||
gtk_widget_destroy( GTK_WIDGET( cbdata->wind ) );
|
||||
}
|
||||
tr_core_clear( cbdata->core ); /* XXX god these circular references suck */
|
||||
g_object_unref( cbdata->core );
|
||||
if( NULL != cbdata->icon )
|
||||
{
|
||||
|
|
299
gtk/tr_backend.c
299
gtk/tr_backend.c
|
@ -1,299 +0,0 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2006-2007 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#define TR_WANT_TORRENT_PRIVATE
|
||||
|
||||
#include "transmission.h"
|
||||
#include "bencode.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "tr_backend.h"
|
||||
#include "tr_torrent.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
enum {
|
||||
TR_BACKEND_HANDLE = 1,
|
||||
};
|
||||
*/
|
||||
|
||||
static void
|
||||
tr_backend_init(GTypeInstance *instance, gpointer g_class);
|
||||
static void
|
||||
tr_backend_set_property(GObject *object, guint property_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static void
|
||||
tr_backend_get_property(GObject *object, guint property_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
static void
|
||||
tr_backend_class_init(gpointer g_class, gpointer g_class_data);
|
||||
static void
|
||||
tr_backend_dispose(GObject *obj);
|
||||
static void
|
||||
tr_backend_finalize(GObject *obj);
|
||||
static void
|
||||
tr_backend_torrent_finalized(gpointer gdata, GObject *tor);
|
||||
|
||||
GType
|
||||
tr_backend_get_type(void) {
|
||||
static GType type = 0;
|
||||
|
||||
if(0 == type) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (TrBackendClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
tr_backend_class_init, /* class_init */
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (TrBackend),
|
||||
0, /* n_preallocs */
|
||||
tr_backend_init, /* instance_init */
|
||||
NULL,
|
||||
};
|
||||
type = g_type_register_static(G_TYPE_OBJECT, "TrBackendType", &info, 0);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
|
||||
//GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = tr_backend_set_property;
|
||||
gobject_class->get_property = tr_backend_get_property;
|
||||
gobject_class->dispose = tr_backend_dispose;
|
||||
gobject_class->finalize = tr_backend_finalize;
|
||||
|
||||
/*
|
||||
pspec = g_param_spec_pointer("backend-handle", _("Backend handle"),
|
||||
_("Backend handle from libtransmission"),
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property(gobject_class, TR_BACKEND_HANDLE, pspec);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
|
||||
TrBackend *self = (TrBackend *)instance;
|
||||
|
||||
self->handle = tr_init( "gtk" );
|
||||
self->disposed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_set_property(GObject *object, guint property_id,
|
||||
const GValue *value SHUTUP, GParamSpec *pspec) {
|
||||
TrBackend *self = (TrBackend*)object;
|
||||
|
||||
if(self->disposed)
|
||||
return;
|
||||
|
||||
switch(property_id) {
|
||||
/*
|
||||
case TR_BACKEND_HANDLE:
|
||||
g_assert(NULL == self->handle);
|
||||
self->handle = g_value_get_pointer(value);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_get_property(GObject *object, guint property_id,
|
||||
GValue *value SHUTUP, GParamSpec *pspec) {
|
||||
TrBackend *self = (TrBackend*)object;
|
||||
|
||||
if(self->disposed)
|
||||
return;
|
||||
|
||||
switch(property_id) {
|
||||
/*
|
||||
case TR_BACKEND_HANDLE:
|
||||
g_value_set_pointer(value, self->handle);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_dispose(GObject *obj) {
|
||||
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
|
||||
TrBackend *self = (TrBackend*)obj;
|
||||
GList *ii;
|
||||
|
||||
if(self->disposed)
|
||||
return;
|
||||
self->disposed = TRUE;
|
||||
|
||||
if(NULL != self->torrents) {
|
||||
for(ii = self->torrents; NULL != ii; ii = ii->next)
|
||||
g_object_weak_unref(ii->data, tr_backend_torrent_finalized, self);
|
||||
g_list_free(self->torrents);
|
||||
self->torrents = NULL;
|
||||
}
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent->dispose(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_finalize(GObject *obj) {
|
||||
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
|
||||
TrBackend *self = (TrBackend *)obj;
|
||||
|
||||
if(NULL != self->handle)
|
||||
tr_close(self->handle);
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent->finalize(obj);
|
||||
}
|
||||
|
||||
TrBackend *
|
||||
tr_backend_new(void) {
|
||||
return g_object_new(TR_BACKEND_TYPE, NULL);
|
||||
}
|
||||
|
||||
tr_handle_t *
|
||||
tr_backend_handle(TrBackend *back) {
|
||||
TR_IS_BACKEND(back);
|
||||
|
||||
return back->handle;
|
||||
}
|
||||
|
||||
void
|
||||
tr_backend_save_state(TrBackend *back, char **errstr) {
|
||||
benc_val_t state;
|
||||
GList *ii;
|
||||
|
||||
TR_IS_BACKEND(back);
|
||||
|
||||
bzero(&state, sizeof(state));
|
||||
state.type = TYPE_LIST;
|
||||
state.val.l.alloc = g_list_length(back->torrents);
|
||||
state.val.l.vals = g_new0(benc_val_t, state.val.l.alloc);
|
||||
|
||||
for(ii = back->torrents; NULL != ii; ii = ii->next) {
|
||||
tr_torrent_get_state(ii->data, state.val.l.vals + state.val.l.count);
|
||||
if(0 != state.val.l.vals[state.val.l.count].type)
|
||||
state.val.l.count++;
|
||||
}
|
||||
|
||||
cf_savestate(&state, errstr);
|
||||
tr_bencFree(&state);
|
||||
|
||||
for(ii = back->torrents; NULL != ii; ii = ii->next)
|
||||
tr_torrent_state_saved(ii->data);
|
||||
}
|
||||
|
||||
GList *
|
||||
tr_backend_load_state( TrBackend * back, benc_val_t * state,
|
||||
guint flags, GList ** errors )
|
||||
{
|
||||
GList *ret = NULL;
|
||||
int ii;
|
||||
TrTorrent *tor;
|
||||
char *errstr;
|
||||
|
||||
TR_IS_BACKEND(back);
|
||||
|
||||
if(TYPE_LIST != state->type)
|
||||
return NULL;
|
||||
|
||||
for(ii = 0; ii < state->val.l.count; ii++) {
|
||||
errstr = NULL;
|
||||
tor = tr_torrent_new_with_state( G_OBJECT( back ), state->val.l.vals + ii,
|
||||
flags, &errstr );
|
||||
if(NULL != errstr)
|
||||
*errors = g_list_append(*errors, errstr);
|
||||
if(NULL != tor)
|
||||
ret = g_list_append(ret, tor);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
tr_backend_add_torrent(TrBackend *back, GObject *tor) {
|
||||
TR_IS_BACKEND(back);
|
||||
TR_IS_TORRENT(tor);
|
||||
|
||||
g_object_weak_ref(tor, tr_backend_torrent_finalized, back);
|
||||
back->torrents = g_list_append(back->torrents, tor);
|
||||
}
|
||||
|
||||
static void
|
||||
tr_backend_torrent_finalized(gpointer gdata, GObject *tor) {
|
||||
TrBackend *back = gdata;
|
||||
|
||||
TR_IS_BACKEND(back);
|
||||
|
||||
back->torrents = g_list_remove(back->torrents, tor);
|
||||
}
|
||||
|
||||
void
|
||||
tr_backend_stop_torrents(TrBackend *back) {
|
||||
GList *ii;
|
||||
|
||||
TR_IS_BACKEND(back);
|
||||
|
||||
for(ii = back->torrents; NULL != ii; ii = ii->next)
|
||||
tr_torrent_stop_politely(ii->data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
tr_backend_torrents_stopped( TrBackend * back, gboolean timeout )
|
||||
{
|
||||
GList * ii, * list;
|
||||
tr_stat_t * st;
|
||||
gboolean ret;
|
||||
|
||||
TR_IS_BACKEND( back );
|
||||
|
||||
ret = TRUE;
|
||||
list = g_list_copy( back->torrents );
|
||||
for( ii = list; NULL != ii; ii = ii->next )
|
||||
{
|
||||
st = tr_torrent_stat_polite( ii->data, timeout );
|
||||
if( NULL == st || !( TR_STATUS_PAUSE & st->status ) )
|
||||
{
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
g_list_free( list );
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2006-2007 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef TR_BACKEND_H
|
||||
#define TR_BACKEND_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "bencode.h"
|
||||
|
||||
#define TR_BACKEND_TYPE (tr_backend_get_type ())
|
||||
#define TR_BACKEND(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TR_BACKEND_TYPE, TrBackend))
|
||||
#define TR_BACKEND_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), TR_BACKEND_TYPE, TrBackendClass))
|
||||
#define TR_IS_BACKEND(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TR_BACKEND_TYPE))
|
||||
#define TR_IS_BACKEND_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), TR_BACKEND_TYPE))
|
||||
#define TR_BACKEND_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), TR_BACKEND_TYPE, TrBackendClass))
|
||||
|
||||
typedef struct _TrBackend TrBackend;
|
||||
typedef struct _TrBackendClass TrBackendClass;
|
||||
|
||||
/* treat the contents of this structure as private */
|
||||
struct _TrBackend {
|
||||
GObject parent;
|
||||
tr_handle_t *handle;
|
||||
GList *torrents;
|
||||
gboolean disposed;
|
||||
};
|
||||
|
||||
struct _TrBackendClass {
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
GType
|
||||
tr_backend_get_type(void);
|
||||
|
||||
TrBackend *
|
||||
tr_backend_new(void);
|
||||
|
||||
tr_handle_t *
|
||||
tr_backend_handle(TrBackend *back);
|
||||
|
||||
void
|
||||
tr_backend_save_state(TrBackend *back, char **errstr);
|
||||
|
||||
GList *
|
||||
tr_backend_load_state( TrBackend * back, benc_val_t * state,
|
||||
guint flags, GList ** errors );
|
||||
|
||||
void
|
||||
tr_backend_stop_torrents(TrBackend *back);
|
||||
|
||||
gboolean
|
||||
tr_backend_torrents_stopped( TrBackend * back, gboolean timeout );
|
||||
|
||||
#ifdef TR_WANT_BACKEND_PRIVATE
|
||||
void
|
||||
tr_backend_add_torrent(TrBackend *back, GObject *tor);
|
||||
#endif
|
||||
|
||||
#endif
|
157
gtk/tr_core.c
157
gtk/tr_core.c
|
@ -30,7 +30,10 @@
|
|||
#include "bencode.h"
|
||||
#include "transmission.h"
|
||||
|
||||
#include "tr_backend.h"
|
||||
/* XXX */
|
||||
#define TR_WANT_TORRENT_PRIVATE
|
||||
|
||||
#include "conf.h"
|
||||
#include "tr_core.h"
|
||||
#include "tr_torrent.h"
|
||||
#include "util.h"
|
||||
|
@ -42,6 +45,10 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data );
|
|||
static void
|
||||
tr_core_dispose( GObject * obj );
|
||||
static void
|
||||
tr_core_torrent_finalized( gpointer gdata, GObject * tor );
|
||||
static int
|
||||
tr_core_check_torrents( TrCore * self, gboolean timeout );
|
||||
static void
|
||||
tr_core_insert( TrCore * self, TrTorrent * tor );
|
||||
|
||||
GType
|
||||
|
@ -106,7 +113,8 @@ tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
|
|||
store = gtk_list_store_newv( MC_ROW_COUNT, types );
|
||||
|
||||
self->model = GTK_TREE_MODEL( store );
|
||||
self->backend = tr_backend_new();
|
||||
self->handle = tr_init( "gtk" );
|
||||
self->torrents = NULL;
|
||||
self->quitting = FALSE;
|
||||
self->disposed = FALSE;
|
||||
}
|
||||
|
@ -114,8 +122,9 @@ tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
|
|||
void
|
||||
tr_core_dispose( GObject * obj )
|
||||
{
|
||||
TrCore * self = (TrCore *) obj;
|
||||
TrCore * self = (TrCore *) obj;
|
||||
GObjectClass * parent;
|
||||
GList * ii;
|
||||
|
||||
if( self->disposed )
|
||||
{
|
||||
|
@ -123,14 +132,39 @@ tr_core_dispose( GObject * obj )
|
|||
}
|
||||
self->disposed = TRUE;
|
||||
|
||||
g_object_unref( self->model );
|
||||
g_object_unref( self->backend );
|
||||
if( NULL != self->model )
|
||||
{
|
||||
g_object_unref( self->model );
|
||||
self->model = NULL;
|
||||
}
|
||||
|
||||
if( NULL != self->torrents )
|
||||
{
|
||||
for( ii = g_list_first( self->torrents ); NULL != ii; ii = ii->next )
|
||||
{
|
||||
g_object_weak_unref( ii->data, tr_core_torrent_finalized, self );
|
||||
}
|
||||
g_list_free( self->torrents );
|
||||
self->torrents = NULL;
|
||||
}
|
||||
|
||||
tr_close( self->handle );
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent = g_type_class_peek( g_type_parent( TR_CORE_TYPE ) );
|
||||
parent->dispose( obj );
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_torrent_finalized( gpointer gdata, GObject * tor )
|
||||
{
|
||||
TrCore * self = gdata;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
self->torrents = g_list_remove( self->torrents, tor );
|
||||
}
|
||||
|
||||
TrCore *
|
||||
tr_core_new( void )
|
||||
{
|
||||
|
@ -150,7 +184,7 @@ tr_core_handle( TrCore * self )
|
|||
{
|
||||
TR_IS_CORE( self );
|
||||
|
||||
return tr_backend_handle( self->backend );
|
||||
return self->handle;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -158,6 +192,7 @@ tr_core_quit( TrCore * self )
|
|||
{
|
||||
GtkTreeIter iter;
|
||||
TrTorrent * tor;
|
||||
GList * ii;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
|
@ -180,10 +215,13 @@ tr_core_quit( TrCore * self )
|
|||
}
|
||||
|
||||
/* try to politely stop all the torrents */
|
||||
tr_backend_stop_torrents( self->backend );
|
||||
for( ii = g_list_first( self->torrents ); NULL != ii; ii = ii->next )
|
||||
{
|
||||
tr_torrent_stop_politely( ii->data );
|
||||
}
|
||||
|
||||
/* shut down nat traversal */
|
||||
tr_natTraversalEnable( tr_backend_handle( self->backend ), 0 );
|
||||
tr_natTraversalEnable( self->handle, 0 );
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -194,9 +232,9 @@ tr_core_did_quit( TrCore * self )
|
|||
TR_IS_CORE( self );
|
||||
g_assert( self->quitting );
|
||||
|
||||
hstat = tr_handleStatus( tr_backend_handle( self->backend ) );
|
||||
hstat = tr_handleStatus( self->handle );
|
||||
|
||||
return ( tr_backend_torrents_stopped( self->backend, FALSE ) &&
|
||||
return ( 0 == tr_core_check_torrents( self, FALSE ) &&
|
||||
TR_NAT_TRAVERSAL_DISABLED == hstat->natTraversalStatus );
|
||||
}
|
||||
|
||||
|
@ -207,7 +245,19 @@ tr_core_force_quit( TrCore * self )
|
|||
g_assert( self->quitting );
|
||||
|
||||
/* time the remaining torrents out so they signal politely-stopped */
|
||||
tr_backend_torrents_stopped( self->backend, TRUE );
|
||||
tr_core_check_torrents( self, TRUE );
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_clear( TrCore * self )
|
||||
{
|
||||
TR_IS_CORE( self );
|
||||
|
||||
if( NULL != self->model )
|
||||
{
|
||||
g_object_unref( self->model );
|
||||
self->model = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,32 +265,93 @@ tr_core_reap( TrCore * self )
|
|||
{
|
||||
TR_IS_CORE( self );
|
||||
|
||||
tr_core_check_torrents( self, FALSE );
|
||||
}
|
||||
|
||||
int
|
||||
tr_core_check_torrents( TrCore * self, gboolean timeout )
|
||||
{
|
||||
tr_stat_t * st;
|
||||
GList * ii, * list;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
list = g_list_copy( self->torrents );
|
||||
for( ii = g_list_first( list ); NULL != ii; ii = ii->next )
|
||||
{
|
||||
st = tr_torrent_stat_polite( ii->data, timeout );
|
||||
if( NULL == st || !( TR_STATUS_PAUSE & st->status ) )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
g_list_free( list );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_save( TrCore * self, char ** error )
|
||||
{
|
||||
benc_val_t state;
|
||||
GList * ii;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
tr_backend_save_state( self->backend, error );
|
||||
tr_bencInit( &state, TYPE_LIST );
|
||||
if( tr_bencListReserve( &state, g_list_length( self->torrents ) ) )
|
||||
{
|
||||
if( NULL != error )
|
||||
{
|
||||
*error = g_strdup( "malloc failure" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for( ii = g_list_first( self->torrents ); NULL != ii; ii = ii->next )
|
||||
{
|
||||
tr_torrent_get_state( ii->data, tr_bencListAdd( &state ) );
|
||||
}
|
||||
|
||||
cf_savestate( &state, error );
|
||||
tr_bencFree( &state );
|
||||
|
||||
for( ii = g_list_first( self->torrents ); NULL != ii; ii = ii->next )
|
||||
{
|
||||
tr_torrent_state_saved( ii->data );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tr_core_load( TrCore * self, benc_val_t * state, GList ** errors )
|
||||
{
|
||||
GList * tors, * ii;
|
||||
int count;
|
||||
int ii, count;
|
||||
char * errstr;
|
||||
TrTorrent * tor;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
count = 0;
|
||||
tors = tr_backend_load_state( self->backend, state, 0, errors );
|
||||
for( ii = g_list_first( tors ); NULL != ii; ii = ii->next )
|
||||
if( TYPE_LIST != state->type )
|
||||
{
|
||||
tr_core_insert( self, ii->data );
|
||||
count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for( ii = 0; ii < state->val.l.count; ii++ )
|
||||
{
|
||||
errstr = NULL;
|
||||
tor = tr_torrent_new_with_state( G_OBJECT( self ),
|
||||
state->val.l.vals + ii, 0, &errstr );
|
||||
if( NULL != errstr )
|
||||
{
|
||||
*errors = g_list_append( *errors, errstr );
|
||||
}
|
||||
if( NULL != tor )
|
||||
{
|
||||
tr_core_insert( self, tor );
|
||||
count++;
|
||||
}
|
||||
}
|
||||
g_list_free( tors );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -253,8 +364,7 @@ tr_core_add_torrent( TrCore * self, const char * torrent, const char * dir,
|
|||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
tor = tr_torrent_new( G_OBJECT( self->backend ),
|
||||
torrent, dir, flags, err );
|
||||
tor = tr_torrent_new( G_OBJECT( self ), torrent, dir, flags, err );
|
||||
if( NULL == tor )
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -287,6 +397,9 @@ tr_core_insert( TrCore * self, TrTorrent * tor )
|
|||
GtkTreeIter iter;
|
||||
tr_info_t * inf;
|
||||
|
||||
g_object_weak_ref( G_OBJECT( tor ), tr_core_torrent_finalized, self );
|
||||
self->torrents = g_list_append( self->torrents, tor );
|
||||
|
||||
gtk_list_store_append( GTK_LIST_STORE( self->model ), &iter );
|
||||
inf = tr_torrent_info( tor );
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ struct _TrCore
|
|||
{
|
||||
GObject parent;
|
||||
GtkTreeModel * model;
|
||||
struct _TrBackend * backend;
|
||||
tr_handle_t * handle;
|
||||
GList * torrents;
|
||||
gboolean quitting;
|
||||
gboolean disposed;
|
||||
};
|
||||
|
@ -93,6 +94,10 @@ tr_core_did_quit( TrCore * self );
|
|||
void
|
||||
tr_core_force_quit( TrCore * self );
|
||||
|
||||
/* XXX temporary hack to deal with circular references */
|
||||
void
|
||||
tr_core_clear( TrCore * self );
|
||||
|
||||
/* Check for stopped torrents */
|
||||
void
|
||||
tr_core_reap( TrCore * self );
|
||||
|
|
|
@ -28,12 +28,13 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#define TR_WANT_BACKEND_PRIVATE
|
||||
|
||||
#include "transmission.h"
|
||||
#include "bencode.h"
|
||||
|
||||
#include "tr_backend.h"
|
||||
/* XXX */
|
||||
#define TR_WANT_TORRENT_PRIVATE
|
||||
|
||||
#include "tr_core.h"
|
||||
#include "tr_prefs.h"
|
||||
#include "tr_torrent.h"
|
||||
#include "util.h"
|
||||
|
@ -127,7 +128,7 @@ tr_torrent_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
|
|||
|
||||
pspec = g_param_spec_object("backend", "Backend",
|
||||
"Libtransmission backend object",
|
||||
TR_BACKEND_TYPE,
|
||||
TR_CORE_TYPE,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property(gobject_class, TR_TORRENT_BACKEND, pspec);
|
||||
|
||||
|
@ -153,7 +154,7 @@ tr_torrent_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
|
|||
TrTorrent *self = (TrTorrent *)instance;
|
||||
|
||||
self->handle = NULL;
|
||||
self->back = NULL;
|
||||
self->core = NULL;
|
||||
self->dir = NULL;
|
||||
self->closing = FALSE;
|
||||
self->delfile = NULL;
|
||||
|
@ -176,8 +177,8 @@ tr_torrent_set_property(GObject *object, guint property_id,
|
|||
tr_torrent_set_folder(self);
|
||||
break;
|
||||
case TR_TORRENT_BACKEND:
|
||||
g_assert(NULL == self->back);
|
||||
self->back = g_object_ref(g_value_get_object(value));
|
||||
g_assert(NULL == self->core);
|
||||
self->core = g_object_ref( g_value_get_object( value ) );
|
||||
break;
|
||||
case TR_TORRENT_DIR:
|
||||
g_assert(NULL == self->dir);
|
||||
|
@ -210,7 +211,7 @@ tr_torrent_get_property(GObject *object, guint property_id,
|
|||
g_value_set_pointer(value, self->handle);
|
||||
break;
|
||||
case TR_TORRENT_BACKEND:
|
||||
g_value_set_object(value, self->back);
|
||||
g_value_set_object( value, self->core );
|
||||
break;
|
||||
case TR_TORRENT_DIR:
|
||||
g_value_set_string(value, (NULL != self->dir ? self->dir :
|
||||
|
@ -237,13 +238,14 @@ tr_torrent_dispose(GObject *obj) {
|
|||
if(NULL != self->handle) {
|
||||
if(!tr_torrent_paused(self))
|
||||
tr_torrentStop(self->handle);
|
||||
tr_torrentClose(tr_backend_handle(TR_BACKEND(self->back)), self->handle);
|
||||
tr_torrentClose( tr_core_handle( TR_CORE( self->core) ) , self->handle );
|
||||
self->handle = NULL;
|
||||
}
|
||||
|
||||
if(NULL != self->back) {
|
||||
g_object_unref(self->back);
|
||||
self->back = NULL;
|
||||
if( NULL != self->core )
|
||||
{
|
||||
g_object_unref( self->core );
|
||||
self->core = NULL;
|
||||
}
|
||||
|
||||
if(NULL != self->delfile)
|
||||
|
@ -284,7 +286,7 @@ tr_torrent_info(TrTorrent *tor) {
|
|||
}
|
||||
|
||||
TrTorrent *
|
||||
tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
|
||||
tr_torrent_new( GObject * core, const char *torrent, const char *dir,
|
||||
guint flags, char **err) {
|
||||
TrTorrent *ret;
|
||||
tr_torrent_t *handle;
|
||||
|
@ -292,12 +294,12 @@ tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
|
|||
int errcode, trflags;
|
||||
gboolean boolval;
|
||||
|
||||
TR_IS_BACKEND(backend);
|
||||
TR_IS_CORE( core );
|
||||
g_assert(NULL != dir);
|
||||
|
||||
*err = NULL;
|
||||
|
||||
back = tr_backend_handle(TR_BACKEND(backend));
|
||||
back = tr_core_handle( TR_CORE( core ) );
|
||||
trflags = 0;
|
||||
if((TR_TORNEW_SAVE_COPY|TR_TORNEW_SAVE_MOVE) & flags)
|
||||
trflags |= TR_FLAG_SAVE;
|
||||
|
@ -329,8 +331,7 @@ tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
|
|||
tr_torrentDisablePex( handle, !boolval );
|
||||
|
||||
ret = g_object_new(TR_TORRENT_TYPE, "torrent-handle", handle,
|
||||
"backend", backend, "download-directory", dir, NULL);
|
||||
tr_backend_add_torrent(TR_BACKEND(backend), G_OBJECT(ret));
|
||||
"backend", core, "download-directory", dir, NULL);
|
||||
|
||||
g_object_set(ret, "paused", (TR_TORNEW_PAUSED & flags ? TRUE : FALSE), NULL);
|
||||
|
||||
|
@ -341,7 +342,7 @@ tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
|
|||
}
|
||||
|
||||
TrTorrent *
|
||||
tr_torrent_new_with_state( GObject * backend, benc_val_t * state,
|
||||
tr_torrent_new_with_state( GObject * core, benc_val_t * state,
|
||||
guint forcedflags, char ** err)
|
||||
{
|
||||
int ii;
|
||||
|
@ -395,7 +396,7 @@ tr_torrent_new_with_state( GObject * backend, benc_val_t * state,
|
|||
flags |= forcedflags;
|
||||
}
|
||||
|
||||
return tr_torrent_new(backend, torrent, dir, flags, err);
|
||||
return tr_torrent_new( core, torrent, dir, flags, err );
|
||||
}
|
||||
|
||||
#define SETSTRVAL(vv, ss) \
|
||||
|
|
|
@ -54,7 +54,7 @@ typedef struct _TrTorrentClass TrTorrentClass;
|
|||
struct _TrTorrent {
|
||||
GObject parent;
|
||||
tr_torrent_t *handle;
|
||||
GObject *back;
|
||||
GObject *core;
|
||||
char *dir;
|
||||
gboolean closing;
|
||||
char *delfile;
|
||||
|
@ -88,6 +88,8 @@ tr_torrent_info(TrTorrent *tor);
|
|||
/* save a private copy of the torrent file and remove the original */
|
||||
#define TR_TORNEW_SAVE_MOVE 0x10
|
||||
|
||||
#ifdef TR_WANT_TORRENT_PRIVATE
|
||||
|
||||
TrTorrent *
|
||||
tr_torrent_new(GObject *backend, const char *torrent, const char *dir,
|
||||
guint flags, char **err);
|
||||
|
@ -102,11 +104,12 @@ tr_torrent_stop_politely(TrTorrent *tor);
|
|||
tr_stat_t *
|
||||
tr_torrent_stat_polite( TrTorrent * tor, gboolean timeout );
|
||||
|
||||
#ifdef TR_WANT_TORRENT_PRIVATE
|
||||
void
|
||||
tr_torrent_get_state(TrTorrent *tor, benc_val_t *state);
|
||||
|
||||
void
|
||||
tr_torrent_state_saved(TrTorrent *tor);
|
||||
#endif
|
||||
|
||||
#endif /* TR_WANT_TORRENT_PRIVATE */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
include ../mk/config.mk
|
||||
include ../mk/common.mk
|
||||
|
||||
SRCS = conf.c dialogs.c io.c ipc.c main.c msgwin.c tr_backend.c \
|
||||
SRCS = conf.c dialogs.c io.c ipc.c main.c msgwin.c \
|
||||
tr_cell_renderer_progress.c tr_core.c tr_icon.c tr_prefs.c \
|
||||
tr_torrent.c tr_window.c util.c
|
||||
OBJS = $(SRCS:%.c=%.o)
|
||||
|
|
Loading…
Reference in New Issue