source: trunk/gtk/tr_backend.c @ 249

Last change on this file since 249 was 249, checked in by joshe, 16 years ago

Some minor code cleanups.
Handle things a little better when quitting.

File size: 6.0 KB
Line 
1#include <string.h>
2
3#include <gtk/gtk.h>
4#include <glib/gi18n.h>
5
6#define TR_WANT_TORRENT_PRIVATE
7
8#include "transmission.h"
9#include "bencode.h"
10
11#include "conf.h"
12#include "tr_backend.h"
13#include "tr_torrent.h"
14#include "util.h"
15
16/*
17enum {
18  TR_BACKEND_HANDLE = 1,
19};
20*/
21
22static void
23tr_backend_init(GTypeInstance *instance, gpointer g_class);
24static void
25tr_backend_set_property(GObject *object, guint property_id,
26                        const GValue *value, GParamSpec *pspec);
27static void
28tr_backend_get_property(GObject *object, guint property_id,
29                        GValue *value, GParamSpec *pspec);
30static void
31tr_backend_class_init(gpointer g_class, gpointer g_class_data);
32static void
33tr_backend_dispose(GObject *obj);
34static void
35tr_backend_finalize(GObject *obj);
36static void
37tr_backend_torrent_finalized(gpointer gdata, GObject *tor);
38
39GType
40tr_backend_get_type(void) {
41  static GType type = 0;
42
43  if(0 == type) {
44    static const GTypeInfo info = {
45      sizeof (TrBackendClass),
46      NULL,   /* base_init */
47      NULL,   /* base_finalize */
48      tr_backend_class_init,   /* class_init */
49      NULL,   /* class_finalize */
50      NULL,   /* class_data */
51      sizeof (TrBackend),
52      0,      /* n_preallocs */
53      tr_backend_init, /* instance_init */
54      NULL,
55    };
56    type = g_type_register_static(G_TYPE_OBJECT, "TrBackendType", &info, 0);
57  }
58  return type;
59}
60
61static void
62tr_backend_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
63  GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
64  //GParamSpec *pspec;
65
66  gobject_class->set_property = tr_backend_set_property;
67  gobject_class->get_property = tr_backend_get_property;
68  gobject_class->dispose = tr_backend_dispose;
69  gobject_class->finalize = tr_backend_finalize;
70
71/*
72  pspec = g_param_spec_pointer("backend-handle", _("Backend handle"),
73                               _("Backend handle from libtransmission"),
74                               G_PARAM_READWRITE);
75  g_object_class_install_property(gobject_class, TR_BACKEND_HANDLE, pspec);
76*/
77}
78
79static void
80tr_backend_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
81  TrBackend *self = (TrBackend *)instance;
82
83  self->handle = tr_init();
84  self->disposed = FALSE;
85}
86
87static void
88tr_backend_set_property(GObject *object, guint property_id,
89                        const GValue *value SHUTUP, GParamSpec *pspec) {
90  TrBackend *self = (TrBackend*)object;
91
92  if(self->disposed)
93    return;
94
95  switch(property_id) {
96/*
97    case TR_BACKEND_HANDLE:
98      g_assert(NULL == self->handle);
99      self->handle = g_value_get_pointer(value);
100      break;
101*/
102    default:
103      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
104      break;
105  }
106}
107
108static void
109tr_backend_get_property(GObject *object, guint property_id,
110                        GValue *value SHUTUP, GParamSpec *pspec) {
111  TrBackend *self = (TrBackend*)object;
112
113  if(self->disposed)
114    return;
115
116  switch(property_id) {
117/*
118    case TR_BACKEND_HANDLE:
119      g_value_set_pointer(value, self->handle);
120      break;
121*/
122    default:
123      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
124      break;
125  }
126}
127
128static void
129tr_backend_dispose(GObject *obj) {
130  GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
131  TrBackend *self = (TrBackend*)obj;
132  GList *ii;
133
134  if(self->disposed)
135    return;
136  self->disposed = TRUE;
137
138  if(NULL != self->torrents) {
139    for(ii = self->torrents; NULL != ii; ii = ii->next)
140      g_object_weak_unref(ii->data, tr_backend_torrent_finalized, self);
141    g_list_free(self->torrents);
142    self->torrents = NULL;
143  }
144
145  /* Chain up to the parent class */
146  parent->dispose(obj);
147}
148
149static void
150tr_backend_finalize(GObject *obj) {
151  GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
152  TrBackend *self = (TrBackend *)obj;
153
154  if(NULL != self->handle)
155    tr_close(self->handle);
156
157  /* Chain up to the parent class */
158  parent->finalize(obj);
159}
160
161TrBackend *
162tr_backend_new(void) {
163  return g_object_new(TR_BACKEND_TYPE, NULL);
164}
165
166tr_handle_t *
167tr_backend_handle(TrBackend *back) {
168  TR_IS_BACKEND(back);
169
170  return back->handle;
171}
172
173void
174tr_backend_save_state(TrBackend *back, char **errstr) {
175  benc_val_t state;
176  int ii;
177  GList *jj;
178
179  TR_IS_BACKEND(back);
180
181  bzero(&state, sizeof(state));
182  state.type = TYPE_LIST;
183  state.val.l.alloc = state.val.l.count = g_list_length(back->torrents);
184  state.val.l.vals = g_new0(benc_val_t, state.val.l.alloc);
185
186  for(ii = 0, jj = back->torrents; NULL != jj; ii++, jj = jj->next)
187    tr_torrent_get_state(jj->data, state.val.l.vals + ii);
188
189  cf_savestate(&state, errstr);
190  tr_bencFree(&state);
191}
192
193GList *
194tr_backend_load_state(TrBackend *back, benc_val_t *state, GList **errors) {
195  GList *ret = NULL;
196  int ii;
197  TrTorrent *tor;
198  char *errstr;
199
200  TR_IS_BACKEND(back);
201
202  if(TYPE_LIST != state->type)
203    return NULL;
204
205  for(ii = 0; ii < state->val.l.count; ii++) {
206    errstr = NULL;
207    tor = tr_torrent_new_with_state(G_OBJECT(back), state->val.l.vals + ii,
208                                    &errstr);
209    if(NULL != errstr)
210      *errors = g_list_append(*errors, errstr);
211    if(NULL != tor)
212      ret = g_list_append(ret, tor);
213  }
214
215  return ret;
216}
217
218void
219tr_backend_add_torrent(TrBackend *back, GObject *tor) {
220  TR_IS_BACKEND(back);
221  TR_IS_TORRENT(tor);
222
223  g_object_weak_ref(tor, tr_backend_torrent_finalized, back);
224  back->torrents = g_list_append(back->torrents, tor);
225}
226
227static void
228tr_backend_torrent_finalized(gpointer gdata, GObject *tor) {
229  TrBackend *back = gdata;
230
231  TR_IS_BACKEND(back);
232
233  back->torrents = g_list_remove(back->torrents, tor);
234}
235
236void
237tr_backend_stop_torrents(TrBackend *back) {
238  GList *ii;
239
240  TR_IS_BACKEND(back);
241
242  for(ii = back->torrents; NULL != ii; ii = ii->next)
243    if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status)
244      tr_torrentStop(tr_torrent_handle(ii->data));
245}
246
247gboolean
248tr_backend_torrents_stopped(TrBackend *back) {
249  GList *ii;
250
251  TR_IS_BACKEND(back);
252
253  for(ii = back->torrents; NULL != ii; ii = ii->next)
254    if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status)
255      return FALSE;
256
257  return TRUE;
258}
Note: See TracBrowser for help on using the repository browser.