source: trunk/gtk/tr_backend.c @ 269

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

Wait and try to send a stopped event when removing a torrent.

  • Property svn:keywords set to Date Rev Author Id
File size: 7.4 KB
Line 
1/*
2  $Id: tr_backend.c 269 2006-05-31 23:20:59Z joshe $
3
4  Copyright (c) 2006 Joshua Elsasser. All rights reserved.
5   
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions
8  are met:
9   
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   
16  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS "AS IS" AND
17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#include <string.h>
30
31#include <gtk/gtk.h>
32#include <glib/gi18n.h>
33
34#define TR_WANT_TORRENT_PRIVATE
35
36#include "transmission.h"
37#include "bencode.h"
38
39#include "conf.h"
40#include "tr_backend.h"
41#include "tr_torrent.h"
42#include "util.h"
43
44/*
45enum {
46  TR_BACKEND_HANDLE = 1,
47};
48*/
49
50static void
51tr_backend_init(GTypeInstance *instance, gpointer g_class);
52static void
53tr_backend_set_property(GObject *object, guint property_id,
54                        const GValue *value, GParamSpec *pspec);
55static void
56tr_backend_get_property(GObject *object, guint property_id,
57                        GValue *value, GParamSpec *pspec);
58static void
59tr_backend_class_init(gpointer g_class, gpointer g_class_data);
60static void
61tr_backend_dispose(GObject *obj);
62static void
63tr_backend_finalize(GObject *obj);
64static void
65tr_backend_torrent_finalized(gpointer gdata, GObject *tor);
66
67GType
68tr_backend_get_type(void) {
69  static GType type = 0;
70
71  if(0 == type) {
72    static const GTypeInfo info = {
73      sizeof (TrBackendClass),
74      NULL,   /* base_init */
75      NULL,   /* base_finalize */
76      tr_backend_class_init,   /* class_init */
77      NULL,   /* class_finalize */
78      NULL,   /* class_data */
79      sizeof (TrBackend),
80      0,      /* n_preallocs */
81      tr_backend_init, /* instance_init */
82      NULL,
83    };
84    type = g_type_register_static(G_TYPE_OBJECT, "TrBackendType", &info, 0);
85  }
86  return type;
87}
88
89static void
90tr_backend_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
91  GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
92  //GParamSpec *pspec;
93
94  gobject_class->set_property = tr_backend_set_property;
95  gobject_class->get_property = tr_backend_get_property;
96  gobject_class->dispose = tr_backend_dispose;
97  gobject_class->finalize = tr_backend_finalize;
98
99/*
100  pspec = g_param_spec_pointer("backend-handle", _("Backend handle"),
101                               _("Backend handle from libtransmission"),
102                               G_PARAM_READWRITE);
103  g_object_class_install_property(gobject_class, TR_BACKEND_HANDLE, pspec);
104*/
105}
106
107static void
108tr_backend_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
109  TrBackend *self = (TrBackend *)instance;
110
111  self->handle = tr_init();
112  self->disposed = FALSE;
113}
114
115static void
116tr_backend_set_property(GObject *object, guint property_id,
117                        const GValue *value SHUTUP, GParamSpec *pspec) {
118  TrBackend *self = (TrBackend*)object;
119
120  if(self->disposed)
121    return;
122
123  switch(property_id) {
124/*
125    case TR_BACKEND_HANDLE:
126      g_assert(NULL == self->handle);
127      self->handle = g_value_get_pointer(value);
128      break;
129*/
130    default:
131      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
132      break;
133  }
134}
135
136static void
137tr_backend_get_property(GObject *object, guint property_id,
138                        GValue *value SHUTUP, GParamSpec *pspec) {
139  TrBackend *self = (TrBackend*)object;
140
141  if(self->disposed)
142    return;
143
144  switch(property_id) {
145/*
146    case TR_BACKEND_HANDLE:
147      g_value_set_pointer(value, self->handle);
148      break;
149*/
150    default:
151      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
152      break;
153  }
154}
155
156static void
157tr_backend_dispose(GObject *obj) {
158  GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
159  TrBackend *self = (TrBackend*)obj;
160  GList *ii;
161
162  if(self->disposed)
163    return;
164  self->disposed = TRUE;
165
166  if(NULL != self->torrents) {
167    for(ii = self->torrents; NULL != ii; ii = ii->next)
168      g_object_weak_unref(ii->data, tr_backend_torrent_finalized, self);
169    g_list_free(self->torrents);
170    self->torrents = NULL;
171  }
172
173  /* Chain up to the parent class */
174  parent->dispose(obj);
175}
176
177static void
178tr_backend_finalize(GObject *obj) {
179  GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
180  TrBackend *self = (TrBackend *)obj;
181
182  if(NULL != self->handle)
183    tr_close(self->handle);
184
185  /* Chain up to the parent class */
186  parent->finalize(obj);
187}
188
189TrBackend *
190tr_backend_new(void) {
191  return g_object_new(TR_BACKEND_TYPE, NULL);
192}
193
194tr_handle_t *
195tr_backend_handle(TrBackend *back) {
196  TR_IS_BACKEND(back);
197
198  return back->handle;
199}
200
201void
202tr_backend_save_state(TrBackend *back, char **errstr) {
203  benc_val_t state;
204  GList *ii;
205
206  TR_IS_BACKEND(back);
207
208  bzero(&state, sizeof(state));
209  state.type = TYPE_LIST;
210  state.val.l.alloc = g_list_length(back->torrents);
211  state.val.l.vals = g_new0(benc_val_t, state.val.l.alloc);
212
213  for(ii = back->torrents; NULL != ii; ii = ii->next) {
214    tr_torrent_get_state(ii->data, state.val.l.vals + state.val.l.count);
215    if(0 != state.val.l.vals[state.val.l.count].type)
216      state.val.l.count++;
217  }
218
219  cf_savestate(&state, errstr);
220  tr_bencFree(&state);
221}
222
223GList *
224tr_backend_load_state(TrBackend *back, benc_val_t *state, GList **errors) {
225  GList *ret = NULL;
226  int ii;
227  TrTorrent *tor;
228  char *errstr;
229
230  TR_IS_BACKEND(back);
231
232  if(TYPE_LIST != state->type)
233    return NULL;
234
235  for(ii = 0; ii < state->val.l.count; ii++) {
236    errstr = NULL;
237    tor = tr_torrent_new_with_state(G_OBJECT(back), state->val.l.vals + ii,
238                                    &errstr);
239    if(NULL != errstr)
240      *errors = g_list_append(*errors, errstr);
241    if(NULL != tor)
242      ret = g_list_append(ret, tor);
243  }
244
245  return ret;
246}
247
248void
249tr_backend_add_torrent(TrBackend *back, GObject *tor) {
250  TR_IS_BACKEND(back);
251  TR_IS_TORRENT(tor);
252
253  g_object_weak_ref(tor, tr_backend_torrent_finalized, back);
254  back->torrents = g_list_append(back->torrents, tor);
255}
256
257static void
258tr_backend_torrent_finalized(gpointer gdata, GObject *tor) {
259  TrBackend *back = gdata;
260
261  TR_IS_BACKEND(back);
262
263  back->torrents = g_list_remove(back->torrents, tor);
264}
265
266void
267tr_backend_stop_torrents(TrBackend *back) {
268  GList *ii;
269
270  TR_IS_BACKEND(back);
271
272  for(ii = back->torrents; NULL != ii; ii = ii->next)
273    tr_torrent_stop_politely(ii->data);
274}
275
276gboolean
277tr_backend_torrents_stopped(TrBackend *back) {
278  GList *ii, *list;
279  gboolean ret = TRUE;
280
281  TR_IS_BACKEND(back);
282
283  list = g_list_copy(back->torrents);
284  for(ii = list; NULL != ii; ii = ii->next)
285    if(!(TR_STATUS_PAUSE & tr_torrent_stat_polite(ii->data)->status))
286      ret = FALSE;
287  g_list_free(list);
288
289  return ret;
290}
Note: See TracBrowser for help on using the repository browser.