source: trunk/gtk/tr_backend.c @ 574

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

Add support to the GTK GUI for saving private copies of torrent files.
The prefs dialog for this sucks, but it should work.

  • Property svn:keywords set to Date Rev Author Id
File size: 7.5 KB
Line 
1/*
2  $Id: tr_backend.c 320 2006-06-10 06:53:20Z 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  for(ii = back->torrents; NULL != ii; ii = ii->next)
223    tr_torrent_state_saved(ii->data);
224}
225
226GList *
227tr_backend_load_state(TrBackend *back, benc_val_t *state, GList **errors) {
228  GList *ret = NULL;
229  int ii;
230  TrTorrent *tor;
231  char *errstr;
232
233  TR_IS_BACKEND(back);
234
235  if(TYPE_LIST != state->type)
236    return NULL;
237
238  for(ii = 0; ii < state->val.l.count; ii++) {
239    errstr = NULL;
240    tor = tr_torrent_new_with_state(G_OBJECT(back), state->val.l.vals + ii,
241                                    &errstr);
242    if(NULL != errstr)
243      *errors = g_list_append(*errors, errstr);
244    if(NULL != tor)
245      ret = g_list_append(ret, tor);
246  }
247
248  return ret;
249}
250
251void
252tr_backend_add_torrent(TrBackend *back, GObject *tor) {
253  TR_IS_BACKEND(back);
254  TR_IS_TORRENT(tor);
255
256  g_object_weak_ref(tor, tr_backend_torrent_finalized, back);
257  back->torrents = g_list_append(back->torrents, tor);
258}
259
260static void
261tr_backend_torrent_finalized(gpointer gdata, GObject *tor) {
262  TrBackend *back = gdata;
263
264  TR_IS_BACKEND(back);
265
266  back->torrents = g_list_remove(back->torrents, tor);
267}
268
269void
270tr_backend_stop_torrents(TrBackend *back) {
271  GList *ii;
272
273  TR_IS_BACKEND(back);
274
275  for(ii = back->torrents; NULL != ii; ii = ii->next)
276    tr_torrent_stop_politely(ii->data);
277}
278
279gboolean
280tr_backend_torrents_stopped(TrBackend *back) {
281  GList *ii, *list;
282  gboolean ret = TRUE;
283
284  TR_IS_BACKEND(back);
285
286  list = g_list_copy(back->torrents);
287  for(ii = list; NULL != ii; ii = ii->next)
288    if(!(TR_STATUS_PAUSE & tr_torrent_stat_polite(ii->data)->status))
289      ret = FALSE;
290  g_list_free(list);
291
292  return ret;
293}
Note: See TracBrowser for help on using the repository browser.