1 /*
2  *  Copyright (C) 2004 Colin Walters <walters@rhythmbox.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 #ifndef RHYTHMDB_PRIVATE_H
29 #define RHYTHMDB_PRIVATE_H
30 
31 #include <rhythmdb/rhythmdb.h>
32 #include <rhythmdb/rb-refstring.h>
33 #include <metadata/rb-metadata.h>
34 
35 G_BEGIN_DECLS
36 
37 RhythmDBEntry * rhythmdb_entry_allocate		(RhythmDB *db, RhythmDBEntryType *type);
38 void		rhythmdb_entry_insert		(RhythmDB *db, RhythmDBEntry *entry);
39 
40 typedef struct {
41 	/* podcast */
42 	RBRefString *description;
43 	RBRefString *subtitle;
44 	RBRefString *summary;
45 	RBRefString *lang;
46 	RBRefString *copyright;
47 	RBRefString *image;
48 	gulong status;	/* 0-99: downloading
49 			   100: Complete
50 			   101: Error
51 			   102: wait
52 			   103: pause */
53 	gulong post_time;
54 } RhythmDBPodcastFields;
55 
56 enum {
57 	RHYTHMDB_ENTRY_HIDDEN = 1,
58 	RHYTHMDB_ENTRY_INSERTED = 2,
59 	RHYTHMDB_ENTRY_LAST_PLAYED_DIRTY = 4,
60 	RHYTHMDB_ENTRY_FIRST_SEEN_DIRTY = 8,
61 	RHYTHMDB_ENTRY_LAST_SEEN_DIRTY = 16,
62 
63 	/* the backend can use the top 16 bits for private flags */
64 	RHYTHMDB_ENTRY_PRIVATE_FLAG_BASE = 65536,
65 };
66 
67 struct _RhythmDBEntry {
68 	/* internal bits */
69 	guint flags;
70 	volatile gint refcount;
71 	void *data;
72 	RhythmDBEntryType *type;
73 	guint id;
74 
75 	/* metadata */
76 	RBRefString *title;
77 	RBRefString *artist;
78 	RBRefString *composer;
79 	RBRefString *album;
80 	RBRefString *album_artist;
81 	RBRefString *genre;
82 	RBRefString *comment;
83 	RBRefString *musicbrainz_trackid;
84 	RBRefString *musicbrainz_artistid;
85 	RBRefString *musicbrainz_albumid;
86 	RBRefString *musicbrainz_albumartistid;
87 	RBRefString *artist_sortname;
88 	RBRefString *composer_sortname;
89 	RBRefString *album_sortname;
90 	RBRefString *album_artist_sortname;
91 	gulong tracknum;
92 	gulong tracktotal;
93 	gulong discnum;
94 	gulong disctotal;
95 	gulong duration;
96 	gulong bitrate;
97 	double bpm;
98 	GDate date;
99 
100 	/* filesystem */
101 	RBRefString *location;
102 	RBRefString *mountpoint;
103 	guint64 file_size;
104 	RBRefString *media_type;
105 	gulong mtime;
106 	gulong first_seen;
107 	gulong last_seen;
108 
109 	/* user data */
110 	gdouble rating;
111 	glong play_count;
112 	gulong last_played;
113 
114 	/* cached data */
115 	gpointer last_played_str;
116 	gpointer first_seen_str;
117 	gpointer last_seen_str;
118 
119 	/* playback error string */
120 	RBRefString *playback_error;
121 };
122 
123 struct _RhythmDBPrivate
124 {
125 	char *name;
126 
127 	gint read_counter;
128 
129 	RBMetaData *metadata;
130 
131 	RBRefString *empty_string;
132 	RBRefString *octet_stream_str;
133 
134 	gboolean action_thread_running;
135 	gint outstanding_threads;
136 	GAsyncQueue *action_queue;
137 	GAsyncQueue *event_queue;
138 	GAsyncQueue *restored_queue;
139 	GAsyncQueue *delayed_write_queue;
140 	GThreadPool *query_thread_pool;
141 
142 	GList *stat_list;
143 	GList *outstanding_stats;
144 	GList *active_mounts;
145 	GList *mount_list;
146 	GMutex stat_mutex;
147 	gboolean stat_thread_running;
148 	int stat_thread_count;
149 	int stat_thread_done;
150 
151 	GVolumeMonitor *volume_monitor;
152 	GHashTable *monitored_directories;
153 	GHashTable *changed_files;
154 	guint changed_files_id;
155 	char **library_locations;
156 	GMutex monitor_mutex;
157 
158 	gboolean dry_run;
159 	gboolean no_update;
160 
161 	GMutex change_mutex;
162 	GHashTable *added_entries;
163 	GHashTable *changed_entries;
164 	GHashTable *deleted_entries;
165 
166 	GHashTable *propname_map;
167 
168 	GMutex exit_mutex;
169 	GCancellable *exiting;		/* hrm, name? */
170 
171 	GCond saving_condition;
172 	GMutex saving_mutex;
173 	guint save_count;
174 
175 	guint event_queue_watch_id;
176 	guint commit_timeout_id;
177 	guint save_timeout_id;
178 
179 	guint emit_entry_signals_id;
180 	GList *added_entries_to_emit;
181 	GList *deleted_entries_to_emit;
182 	GHashTable *changed_entries_to_emit;
183 
184 	gboolean can_save;
185 	gboolean saving;
186 	gboolean dirty;
187 
188 	GHashTable *entry_type_map;
189 	GMutex entry_type_map_mutex;
190 	GMutex entry_type_mutex;
191 
192 	gint next_entry_id;
193 
194 	GSettings *settings;
195 
196 	guint dbus_object_id;
197 };
198 
199 typedef struct
200 {
201 	enum {
202 		RHYTHMDB_EVENT_STAT,
203 		RHYTHMDB_EVENT_METADATA_LOAD,
204 		RHYTHMDB_EVENT_METADATA_CACHE,
205 		RHYTHMDB_EVENT_DB_LOAD,
206 		RHYTHMDB_EVENT_THREAD_EXITED,
207 		RHYTHMDB_EVENT_DB_SAVED,
208 		RHYTHMDB_EVENT_QUERY_COMPLETE,
209 		RHYTHMDB_EVENT_ENTRY_SET
210 	} type;
211 	RBRefString *uri;
212 	RBRefString *real_uri; /* Target of a symlink, if any */
213 	RhythmDBEntryType *entry_type;
214 	RhythmDBEntryType *ignore_type;
215 	RhythmDBEntryType *error_type;
216 
217 	GError *error;
218 	RhythmDB *db;
219 
220 	/* STAT */
221 	GFileInfo *file_info;
222 	/* LOAD */
223 	GArray cached_metadata;
224 	RBMetaData *metadata;
225 	/* QUERY_COMPLETE */
226 	RhythmDBQueryResults *results;
227 	/* ENTRY_SET */
228 	RhythmDBEntry *entry;
229 	/* ENTRY_SET */
230 	gboolean signal_change;
231 	RhythmDBEntryChange change;
232 } RhythmDBEvent;
233 
234 /* from rhythmdb.c */
235 void rhythmdb_entry_set_visibility (RhythmDB *db, RhythmDBEntry *entry,
236 				    gboolean visibility);
237 void rhythmdb_entry_set_internal (RhythmDB *db, RhythmDBEntry *entry,
238 				  gboolean notify_if_inserted, guint propid,
239 				  const GValue *value);
240 void rhythmdb_entry_type_foreach (RhythmDB *db, GHFunc func, gpointer data);
241 RhythmDBEntry *	rhythmdb_entry_lookup_by_location_refstring (RhythmDB *db, RBRefString *uri);
242 
243 /* from rhythmdb-monitor.c */
244 void rhythmdb_init_monitoring (RhythmDB *db);
245 void rhythmdb_dispose_monitoring (RhythmDB *db);
246 void rhythmdb_finalize_monitoring (RhythmDB *db);
247 void rhythmdb_stop_monitoring (RhythmDB *db);
248 void rhythmdb_start_monitoring (RhythmDB *db);
249 void rhythmdb_monitor_uri_path (RhythmDB *db, const char *uri, GError **error);
250 GList *rhythmdb_get_active_mounts (RhythmDB *db);
251 
252 /* from rhythmdb-query.c */
253 GPtrArray *rhythmdb_query_parse_valist (RhythmDB *db, va_list args);
254 void       rhythmdb_read_encoded_property (RhythmDB *db, const char *data, RhythmDBPropType propid, GValue *val);
255 
256 /* from rhythmdb-song-entry-types.c */
257 void       rhythmdb_register_song_entry_types (RhythmDB *db);
258 
259 /* from rhythmdb-dbus.c */
260 void rhythmdb_dbus_register (RhythmDB *db);
261 void rhythmdb_dbus_unregister (RhythmDB *db);
262 
263 G_END_DECLS
264 
265 #endif /* __RHYTHMDB_PRIVATE_H */
266