1 /*
2  *  Copyright (C) 2009 Jonathan Matthew  <jonathan@d14n.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
10  *  GStreamer plugins to be used and distributed together with GStreamer
11  *  and Rhythmbox. This permission is above and beyond the permissions granted
12  *  by the GPL license by which Rhythmbox is covered. If you modify this code
13  *  you may extend this exception to your version of the code, but you are not
14  *  obligated to do so. If you do not wish to do so, delete this exception
15  *  statement from your version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
25  *
26  */
27 
28 #include <libmtp.h>
29 
30 #include <gio/gio.h>
31 #include <glib.h>
32 #include <glib-object.h>
33 #include <gdk-pixbuf/gdk-pixbuf.h>
34 
35 /*
36  * Worker thread for dealing with MTP devices.
37  * libmtp isn't thread-aware, and some operations are pretty slow
38  * (getting track listings, sending and retrieving tracks), so
39  * we do everything except the initial setup in a dedicated thread.
40  */
41 
42 #ifndef __RB_MTP_THREAD_H
43 #define __RB_MTP_THREAD_H
44 
45 typedef enum
46 {
47 	RB_MTP_THREAD_ERROR_NO_SPACE,
48 	RB_MTP_THREAD_ERROR_TEMPFILE,
49 	RB_MTP_THREAD_ERROR_GET_TRACK,
50 	RB_MTP_THREAD_ERROR_SEND_TRACK
51 } RBMtpThreadError;
52 
53 GType rb_mtp_thread_error_get_type (void);
54 #define RB_TYPE_MTP_THREAD_ERROR (rb_mtp_thread_error_get_type ())
55 GQuark rb_mtp_thread_error_quark (void);
56 #define RB_MTP_THREAD_ERROR rb_mtp_thread_error_quark ()
57 
58 #define RB_TYPE_MTP_THREAD         (rb_mtp_thread_get_type ())
59 #define RB_MTP_THREAD(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_MTP_THREAD, RBMtpThread))
60 #define RB_MTP_THREAD_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_MTP_THREAD, RBMtpThreadClass))
61 #define RB_IS_MTP_THREAD(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_MTP_THREAD))
62 #define RB_IS_MTP_THREAD_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_MTP_THREAD))
63 #define RB_MTP_THREAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_MTP_THREAD, RBMtpThreadClass))
64 
65 typedef struct
66 {
67 	GObject parent;
68 	LIBMTP_mtpdevice_t *device;
69 	GHashTable *albums;
70 
71 	GThread *thread;
72 	GAsyncQueue *queue;
73 } RBMtpThread;
74 
75 typedef struct
76 {
77 	GObjectClass parent;
78 } RBMtpThreadClass;
79 
80 /* callback types */
81 typedef void (*RBMtpOpenCallback) (LIBMTP_mtpdevice_t *device, gpointer user_data);
82 typedef void (*RBMtpTrackListCallback) (LIBMTP_track_t *tracklist, gpointer user_data);
83 typedef void (*RBMtpUploadCallback) (LIBMTP_track_t *track, GError *error, gpointer user_data);
84 typedef void (*RBMtpDownloadCallback) (uint32_t track_id, const char *filename, GError *error, gpointer user_data);
85 typedef void (*RBMtpThreadCallback) (LIBMTP_mtpdevice_t *device, gpointer user_data);
86 typedef void (*RBMtpCreateFolderCallback) (uint32_t folder_id, gpointer user_data);
87 
88 GType		rb_mtp_thread_get_type (void);
89 RBMtpThread *	rb_mtp_thread_new (void);
90 void            _rb_mtp_thread_register_type (GTypeModule *module);
91 
92 void		rb_mtp_thread_report_errors (RBMtpThread *thread);
93 
94 void		rb_mtp_thread_open_device (RBMtpThread *thread,
95 					   LIBMTP_raw_device_t *raw_device,
96 					   RBMtpOpenCallback func,
97 					   gpointer data,
98 					   GDestroyNotify destroy_data);
99 void		rb_mtp_thread_get_track_list (RBMtpThread *thread,
100 					      RBMtpTrackListCallback func,
101 					      gpointer data,
102 					      GDestroyNotify destroy_data);
103 
104 void		rb_mtp_thread_set_device_name (RBMtpThread *thread, const char *name);
105 
106 void		rb_mtp_thread_queue_callback (RBMtpThread *thread,
107 					      RBMtpThreadCallback func,
108 					      gpointer data,
109 					      GDestroyNotify destroy_data);
110 
111 /* folders */
112 void		rb_mtp_thread_create_folder (RBMtpThread *thread,
113 					     const char **path,
114 					     RBMtpCreateFolderCallback func,
115 					     gpointer data,
116 					     GDestroyNotify destroy_data);
117 
118 /* albums */
119 void		rb_mtp_thread_add_to_album (RBMtpThread *thread, LIBMTP_track_t *track, const char *album);
120 void		rb_mtp_thread_remove_from_album (RBMtpThread *thread, LIBMTP_track_t *track, const char *album);
121 void		rb_mtp_thread_set_album_image (RBMtpThread *thread, const char *album, GdkPixbuf *image);
122 
123 /* tracks */
124 void		rb_mtp_thread_delete_track (RBMtpThread *thread, LIBMTP_track_t *track);
125 void		rb_mtp_thread_upload_track (RBMtpThread *thread,
126 					    LIBMTP_track_t *track,
127 					    const char *filename,
128 					    RBMtpUploadCallback func,
129 					    gpointer data,
130 					    GDestroyNotify destroy_data);
131 void		rb_mtp_thread_download_track (RBMtpThread *thread,
132 					      uint32_t track_id,
133 					      const char *filename,
134 					      RBMtpDownloadCallback func,
135 					      gpointer data,
136 					      GDestroyNotify destroy_data);
137 
138 #endif
139 
140