source: trunk/gtk/tr_backend.c @ 1125

Last change on this file since 1125 was 760, checked in by joshe, 15 years ago

Change all my 2-clause BSD licenses to the same MIT/X11 license as libtransmission.

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