2006-11-10 James Livingston <doclivingston@gmail.com>
[rhythmbox.git] / plugins / generic-player / rb-psp-source.c
blob915dd766e611e192aa338d5e8334f2d109091675
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * arch-tag: Implementation of PSP source object
5 * Copyright (C) 2006 James Livingston <jrl@ids.org.au>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23 #define __EXTENSIONS__
25 #include "config.h"
27 #include <string.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31 #include <libgnomevfs/gnome-vfs-volume.h>
32 #include <libgnomevfs/gnome-vfs-volume-monitor.h>
34 #ifdef HAVE_HAL
35 #include <libhal.h>
36 #include <dbus/dbus.h>
37 #endif
39 #include "eel-gconf-extensions.h"
40 #include "rb-psp-source.h"
41 #include "rb-debug.h"
42 #include "rb-util.h"
43 #include "rb-file-helpers.h"
44 #include "rb-auto-playlist-source.h"
45 #include "rhythmdb.h"
46 #include "rb-plugin.h"
48 static void rb_psp_source_create_playlists (RBGenericPlayerSource *source);
49 static gchar *impl_get_mount_path (RBGenericPlayerSource *source);
51 typedef struct
53 #ifdef __SUNPRO_C
54 char x; /* To build with Solaris forte compiler. */
55 #endif
56 } RBPspSourcePrivate;
59 RB_PLUGIN_DEFINE_TYPE (RBPspSource, rb_psp_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
60 #define PSP_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_PSP_SOURCE, RBPspSourcePrivate))
63 static void
64 rb_psp_source_class_init (RBPspSourceClass *klass)
66 RBGenericPlayerSourceClass *generic_class = RB_GENERIC_PLAYER_SOURCE_CLASS (klass);
68 generic_class->impl_get_mount_path = impl_get_mount_path;
69 generic_class->impl_load_playlists = rb_psp_source_create_playlists;
71 g_type_class_add_private (klass, sizeof (RBPspSourcePrivate));
74 static void
75 rb_psp_source_init (RBPspSource *source)
80 RBRemovableMediaSource *
81 rb_psp_source_new (RBShell *shell, GnomeVFSVolume *volume)
83 RBPspSource *source;
84 RhythmDBEntryType entry_type;
85 RhythmDB *db;
87 g_assert (rb_psp_is_volume_player (volume));
89 g_object_get (G_OBJECT (shell), "db", &db, NULL);
90 entry_type = rhythmdb_entry_register_type (db, NULL);
91 g_object_unref (G_OBJECT (db));
93 source = RB_PSP_SOURCE (g_object_new (RB_TYPE_PSP_SOURCE,
94 "entry-type", entry_type,
95 "volume", volume,
96 "shell", shell,
97 "sourcelist-group", RB_SOURCELIST_GROUP_REMOVABLE,
98 NULL));
100 rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type);
102 return RB_REMOVABLE_MEDIA_SOURCE (source);
105 static char *
106 impl_get_mount_path (RBGenericPlayerSource *source)
108 char *uri;
109 char *path;
110 GnomeVFSVolume *volume;
112 g_object_get (G_OBJECT (source), "volume", &volume, NULL);
113 uri = gnome_vfs_volume_get_activation_uri (volume);
114 g_object_unref (volume);
116 path = rb_uri_append_path (uri, "PSP/MUSIC");
118 g_free (uri);
120 return path;
123 static gboolean
124 visit_playlist_dirs (const gchar *rel_path,
125 GnomeVFSFileInfo *info,
126 gboolean recursing_will_loop,
127 RBPspSource *source,
128 gboolean *recurse)
130 RBShell *shell;
131 RhythmDB *db;
132 RhythmDBEntryType entry_type;
133 char *main_path;
134 char *playlist_path;
135 RBSource *playlist;
136 GPtrArray *query;
138 *recurse = FALSE;
140 /* add playlist */
141 main_path = rb_generic_player_source_get_mount_path (RB_GENERIC_PLAYER_SOURCE (source));
142 playlist_path = rb_uri_append_path (main_path, rel_path);
143 g_free (main_path);
145 if (!rb_uri_is_directory (playlist_path)) {
146 g_free (playlist_path);
147 return TRUE;
150 g_object_get (source,
151 "shell", &shell,
152 "entry-type", &entry_type,
153 NULL);
154 g_object_get (shell,
155 "db", &db,
156 NULL);
158 query = rhythmdb_query_parse (db,
159 RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type,
160 RHYTHMDB_QUERY_PROP_PREFIX, RHYTHMDB_PROP_LOCATION, playlist_path,
161 RHYTHMDB_QUERY_END);
162 g_free (playlist_path);
164 playlist = rb_auto_playlist_source_new (shell, rel_path, FALSE);
165 rb_auto_playlist_source_set_query (RB_AUTO_PLAYLIST_SOURCE (playlist), query,
166 RHYTHMDB_QUERY_MODEL_LIMIT_NONE, NULL,
167 NULL, 0);
168 rb_generic_player_source_add_playlist (RB_GENERIC_PLAYER_SOURCE (source), shell, RB_SOURCE (playlist));
169 rhythmdb_query_free (query);
171 g_object_unref (shell);
172 g_object_unref (db);
174 return TRUE;
178 static void
179 rb_psp_source_create_playlists (RBGenericPlayerSource *source)
181 char *mount_path;
183 mount_path = rb_generic_player_source_get_mount_path (source);
184 gnome_vfs_directory_visit (mount_path,
185 GNOME_VFS_FILE_INFO_DEFAULT,
186 GNOME_VFS_DIRECTORY_VISIT_DEFAULT,
187 (GnomeVFSDirectoryVisitFunc) visit_playlist_dirs,
188 source);
189 g_free (mount_path);
192 #ifdef HAVE_HAL_0_5
194 static gboolean
195 hal_udi_is_psp (const char *udi)
197 LibHalContext *ctx;
198 DBusConnection *conn;
199 char *parent_udi;
200 char *parent_name;
201 gboolean result;
202 DBusError error;
203 gboolean inited = FALSE;
205 result = FALSE;
206 dbus_error_init (&error);
208 parent_udi = NULL;
209 parent_name = NULL;
211 conn = NULL;
212 ctx = libhal_ctx_new ();
213 if (ctx == NULL) {
214 rb_debug ("cannot connect to HAL");
215 goto end;
217 conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
218 if (conn == NULL || dbus_error_is_set (&error))
219 goto end;
221 libhal_ctx_set_dbus_connection (ctx, conn);
222 if (!libhal_ctx_init (ctx, &error) || dbus_error_is_set (&error))
223 goto end;
225 inited = TRUE;
226 parent_udi = libhal_device_get_property_string (ctx, udi,
227 "info.parent", &error);
228 if (parent_udi == NULL || dbus_error_is_set (&error))
229 goto end;
231 parent_name = libhal_device_get_property_string (ctx, parent_udi,
232 "storage.model", &error);
233 if (parent_name == NULL || dbus_error_is_set (&error))
234 goto end;
236 if (strcmp (parent_name, "PSP") == 0) {
237 result = TRUE;
240 end:
241 g_free (parent_udi);
242 g_free (parent_name);
244 if (dbus_error_is_set (&error)) {
245 rb_debug ("Error: %s\n", error.message);
246 dbus_error_free (&error);
247 dbus_error_init (&error);
250 if (ctx) {
251 if (inited)
252 libhal_ctx_shutdown (ctx, &error);
253 libhal_ctx_free(ctx);
256 dbus_error_free (&error);
258 return result;
261 #elif HAVE_HAL_0_2
263 static gboolean
264 hal_udi_is_psp (const char *udi)
266 LibHalContext *ctx;
267 char *parent_udi;
268 char *parent_name;
269 gboolean result;
271 result = FALSE;
272 ctx = hal_initialize (NULL, FALSE);
273 if (ctx == NULL) {
274 return FALSE;
276 parent_udi = hal_device_get_property_string (ctx, udi,
277 "info.parent");
278 parent_name = hal_device_get_property_string (ctx, parent_udi,
279 "storage.model");
280 g_free (parent_udi);
282 if (parent_name != NULL && strcmp (parent_name, "PSP") == 0) {
283 result = TRUE;
286 g_free (parent_name);
287 hal_shutdown (ctx);
289 return result;
292 #endif
294 gboolean
295 rb_psp_is_volume_player (GnomeVFSVolume *volume)
297 gboolean result = FALSE;
298 gchar *str;
300 if (gnome_vfs_volume_get_volume_type (volume) != GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) {
301 return FALSE;
304 #ifndef HAVE_HAL
305 str = gnome_vfs_volume_get_activation_uri (volume);
306 if (str) {
307 char *path;
309 path = rb_uri_append_path (str, "PSP/MUSIC");
310 g_free (str);
311 result = rb_uri_exists (path);
312 g_free (path);
313 return result;
315 #else
316 str = gnome_vfs_volume_get_hal_udi (volume);
317 if (str != NULL) {
318 gboolean result;
320 result = hal_udi_is_psp (str);
321 g_free (str);
322 return result;
324 #endif
325 return result;