Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * drct.c 00003 * Copyright 2009-2011 John Lindgren 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 00020 */ 00021 00022 #include <glib.h> 00023 #include <libaudcore/hook.h> 00024 #include <libaudcore/vfs.h> 00025 00026 #include "audconfig.h" 00027 #include "config.h" 00028 #include "drct.h" 00029 #include "glib-compat.h" 00030 #include "i18n.h" 00031 #include "playback.h" 00032 #include "playlist.h" 00033 00034 /* --- PROGRAM CONTROL --- */ 00035 00036 void drct_quit (void) 00037 { 00038 hook_call ("quit", NULL); 00039 } 00040 00041 /* --- PLAYBACK CONTROL --- */ 00042 00043 void drct_play (void) 00044 { 00045 if (playback_get_playing ()) 00046 { 00047 if (playback_get_paused ()) 00048 playback_pause (); 00049 else 00050 playback_seek (0); 00051 } 00052 else 00053 { 00054 playlist_set_playing (playlist_get_active ()); 00055 playback_play (0, FALSE); 00056 } 00057 } 00058 00059 void drct_pause (void) 00060 { 00061 if (playback_get_playing ()) 00062 playback_pause (); 00063 } 00064 00065 void drct_stop (void) 00066 { 00067 if (playback_get_playing ()) 00068 playback_stop (); 00069 } 00070 00071 gboolean drct_get_playing (void) 00072 { 00073 return playback_get_playing (); 00074 } 00075 00076 gboolean drct_get_ready (void) 00077 { 00078 return playback_get_ready (); 00079 } 00080 00081 gboolean drct_get_paused (void) 00082 { 00083 return playback_get_paused (); 00084 } 00085 00086 gchar * drct_get_title (void) 00087 { 00088 return playback_get_title (); 00089 } 00090 00091 void drct_get_info (gint * bitrate, gint * samplerate, gint * channels) 00092 { 00093 playback_get_info (bitrate, samplerate, channels); 00094 } 00095 00096 gint drct_get_time (void) 00097 { 00098 return playback_get_time (); 00099 } 00100 00101 gint drct_get_length (void) 00102 { 00103 return playback_get_length (); 00104 } 00105 00106 void drct_seek (gint time) 00107 { 00108 playback_seek (time); 00109 } 00110 00111 /* --- VOLUME CONTROL --- */ 00112 00113 void drct_get_volume (gint * left, gint * right) 00114 { 00115 playback_get_volume (left, right); 00116 * left = CLAMP (* left, 0, 100); 00117 * right = CLAMP (* right, 0, 100); 00118 } 00119 00120 void drct_set_volume (gint left, gint right) 00121 { 00122 playback_set_volume (CLAMP (left, 0, 100), CLAMP (right, 0, 100)); 00123 } 00124 00125 void drct_get_volume_main (gint * volume) 00126 { 00127 gint left, right; 00128 drct_get_volume (& left, & right); 00129 * volume = MAX (left, right); 00130 } 00131 00132 void drct_set_volume_main (gint volume) 00133 { 00134 gint left, right, current; 00135 drct_get_volume (& left, & right); 00136 current = MAX (left, right); 00137 00138 if (current > 0) 00139 drct_set_volume (volume * left / current, volume * right / current); 00140 else 00141 drct_set_volume (volume, volume); 00142 } 00143 00144 void drct_get_volume_balance (gint * balance) 00145 { 00146 gint left, right; 00147 drct_get_volume (& left, & right); 00148 00149 if (left == right) 00150 * balance = 0; 00151 else if (left > right) 00152 * balance = -100 + right * 100 / left; 00153 else 00154 * balance = 100 - left * 100 / right; 00155 } 00156 00157 void drct_set_volume_balance (gint balance) 00158 { 00159 gint left, right; 00160 drct_get_volume_main (& left); 00161 00162 if (balance < 0) 00163 right = left * (100 + balance) / 100; 00164 else 00165 { 00166 right = left; 00167 left = right * (100 - balance) / 100; 00168 } 00169 00170 drct_set_volume (left, right); 00171 } 00172 00173 /* --- PLAYLIST CONTROL --- */ 00174 00175 gint drct_pl_get_length (void) 00176 { 00177 return playlist_entry_count (playlist_get_active ()); 00178 } 00179 00180 void drct_pl_next (void) 00181 { 00182 gboolean play = playback_get_playing (); 00183 if (playlist_get_playing () < 0) 00184 playlist_set_playing (playlist_get_active ()); 00185 if (playlist_next_song (playlist_get_playing (), cfg.repeat) && play) 00186 playback_play (0, FALSE); 00187 } 00188 00189 void drct_pl_prev (void) 00190 { 00191 gboolean play = playback_get_playing (); 00192 if (playlist_get_playing () < 0) 00193 playlist_set_playing (playlist_get_active ()); 00194 if (playlist_prev_song (playlist_get_playing ()) && play) 00195 playback_play (0, FALSE); 00196 } 00197 00198 gint drct_pl_get_pos (void) 00199 { 00200 return playlist_get_position (playlist_get_active ()); 00201 } 00202 00203 void drct_pl_set_pos (gint pos) 00204 { 00205 gint playlist = playlist_get_active (); 00206 gboolean play = playback_get_playing (); 00207 00208 playlist_set_position (playlist, pos); 00209 00210 if (play) 00211 { 00212 playlist_set_playing (playlist); 00213 playback_play (0, FALSE); 00214 } 00215 } 00216 00217 gboolean drct_pl_repeat_is_enabled (void) 00218 { 00219 return cfg.repeat; 00220 } 00221 00222 void drct_pl_repeat_toggle (void) 00223 { 00224 cfg.repeat = ! cfg.repeat; 00225 hook_call ("toggle repeat", NULL); 00226 } 00227 00228 gboolean drct_pl_shuffle_is_enabled (void) 00229 { 00230 return cfg.shuffle; 00231 } 00232 00233 void drct_pl_shuffle_toggle (void) 00234 { 00235 cfg.shuffle = ! cfg.shuffle; 00236 hook_call ("toggle shuffle", NULL); 00237 } 00238 00239 gchar * drct_pl_get_file (gint entry) 00240 { 00241 const gchar * filename = playlist_entry_get_filename 00242 (playlist_get_active (), entry); 00243 return (filename == NULL) ? NULL : g_strdup (filename); 00244 } 00245 00246 gchar * drct_pl_get_title (gint entry) 00247 { 00248 const gchar * title = playlist_entry_get_title (playlist_get_active (), 00249 entry, FALSE); 00250 return (title == NULL) ? NULL : g_strdup (title); 00251 } 00252 00253 gint drct_pl_get_time (gint pos) 00254 { 00255 return playlist_entry_get_length (playlist_get_active (), pos, FALSE); 00256 } 00257 00258 static void activate_temp (void) 00259 { 00260 gint playlists = playlist_count (); 00261 const gchar * title = _("Temporary Playlist"); 00262 00263 for (gint playlist = 0; playlist < playlists; playlist ++) 00264 { 00265 if (! strcmp (playlist_get_title (playlist), title)) 00266 { 00267 playlist_set_active (playlist); 00268 return; 00269 } 00270 } 00271 00272 if (! playlist_entry_count (playlist_get_active ())) 00273 playlist_set_title (playlist_get_active (), title); 00274 else 00275 { 00276 playlist_insert (playlists); 00277 playlist_set_title (playlists, title); 00278 playlist_set_active (playlists); 00279 } 00280 } 00281 00282 static void add_list (GList * list, gint at, gboolean to_temp, gboolean play) 00283 { 00284 if (to_temp) 00285 activate_temp (); 00286 00287 gint playlist = playlist_get_active (); 00288 00289 if (play) 00290 { 00291 if (cfg.clear_playlist) 00292 playlist_entry_delete (playlist, 0, playlist_entry_count (playlist)); 00293 else 00294 playlist_queue_delete (playlist, 0, playlist_queue_count (playlist)); 00295 } 00296 00297 gint entries = playlist_entry_count (playlist); 00298 if (at < 0) 00299 at = entries; 00300 00301 gint added = 0; 00302 GQueue folders = G_QUEUE_INIT; 00303 struct index * filenames = index_new (); 00304 00305 for (; list != NULL; list = list->next) 00306 { 00307 if (filename_is_playlist (list->data)) 00308 { 00309 playlist_insert_playlist (playlist, at + added, list->data); 00310 added += playlist_entry_count (playlist) - entries; 00311 entries = playlist_entry_count (playlist); 00312 } 00313 else if (vfs_file_test (list->data, G_FILE_TEST_IS_DIR)) 00314 g_queue_push_tail (& folders, list->data); 00315 else 00316 index_append (filenames, g_strdup (list->data)); 00317 } 00318 00319 playlist_entry_insert_batch (playlist, at + added, filenames, NULL); 00320 added += playlist_entry_count (playlist) - entries; 00321 00322 if (added && play) 00323 { 00324 playlist_set_playing (playlist); 00325 if (! cfg.shuffle) 00326 playlist_set_position (playlist, at); 00327 playback_play (0, FALSE); 00328 play = FALSE; 00329 } 00330 00331 const gchar * folder; 00332 while ((folder = g_queue_pop_head (& folders)) != NULL) 00333 { 00334 playlist_insert_folder (playlist, at + added, folder, play); 00335 play = FALSE; 00336 } 00337 } 00338 00339 void drct_pl_add (const gchar * filename, gint at) 00340 { 00341 GList * list = g_list_prepend (NULL, (void *) filename); 00342 add_list (list, at, FALSE, FALSE); 00343 g_list_free (list); 00344 } 00345 00346 void drct_pl_add_list (GList * list, gint at) 00347 { 00348 add_list (list, at, FALSE, FALSE); 00349 } 00350 00351 void drct_pl_open (const gchar * filename) 00352 { 00353 GList * list = g_list_prepend (NULL, (void *) filename); 00354 add_list (list, -1, cfg.open_to_temporary, TRUE); 00355 g_list_free (list); 00356 } 00357 00358 void drct_pl_open_list (GList * list) 00359 { 00360 add_list (list, -1, cfg.open_to_temporary, TRUE); 00361 } 00362 00363 void drct_pl_open_temp (const gchar * filename) 00364 { 00365 GList * list = g_list_prepend (NULL, (void *) filename); 00366 add_list (list, -1, TRUE, TRUE); 00367 g_list_free (list); 00368 } 00369 00370 void drct_pl_open_temp_list (GList * list) 00371 { 00372 add_list (list, -1, TRUE, TRUE); 00373 } 00374 00375 void drct_pl_delete (gint entry) 00376 { 00377 playlist_entry_delete (playlist_get_active (), entry, 1); 00378 } 00379 00380 /* Advancing to the next song when the current one is deleted is tricky. First, 00381 * we delete all the selected songs except the current one. We can then advance 00382 * to a new song without worrying about picking one that is also selected. 00383 * Finally, we can delete the former current song without stopping playback. */ 00384 00385 void drct_pl_delete_selected (void) 00386 { 00387 gint list = playlist_get_active (); 00388 gint pos = playlist_get_position (list); 00389 00390 if (cfg.advance_on_delete && ! cfg.no_playlist_advance 00391 && playback_get_playing () && list == playlist_get_playing () 00392 && pos >= 0 && playlist_entry_get_selected (list, pos)) 00393 { 00394 playlist_entry_set_selected (list, pos, FALSE); 00395 playlist_delete_selected (list); 00396 pos = playlist_get_position (list); /* it may have moved */ 00397 00398 if (playlist_next_song (list, cfg.repeat) 00399 && playlist_get_position (list) != pos) 00400 playback_play (0, FALSE); 00401 00402 playlist_entry_delete (list, pos, 1); 00403 } 00404 else 00405 playlist_delete_selected (list); 00406 } 00407 00408 void drct_pl_clear (void) 00409 { 00410 gint playlist = playlist_get_active (); 00411 playlist_entry_delete (playlist, 0, playlist_entry_count (playlist)); 00412 } 00413 00414 /* --- PLAYLIST QUEUE CONTROL --- */ 00415 00416 gint drct_pq_get_length (void) 00417 { 00418 return playlist_queue_count (playlist_get_active ()); 00419 } 00420 00421 gint drct_pq_get_entry (gint queue_position) 00422 { 00423 return playlist_queue_get_entry (playlist_get_active (), queue_position); 00424 } 00425 00426 gboolean drct_pq_is_queued (gint entry) 00427 { 00428 return (drct_pq_get_queue_position (entry) >= 0); 00429 } 00430 00431 gint drct_pq_get_queue_position (gint entry) 00432 { 00433 return playlist_queue_find_entry (playlist_get_active (), entry); 00434 } 00435 00436 void drct_pq_add (gint entry) 00437 { 00438 playlist_queue_insert (playlist_get_active (), -1, entry); 00439 } 00440 00441 void drct_pq_remove (gint entry) 00442 { 00443 gint playlist = playlist_get_active (); 00444 playlist_queue_delete (playlist, playlist_queue_find_entry (playlist, 00445 entry), 1); 00446 } 00447 00448 void drct_pq_clear (void) 00449 { 00450 gint playlist = playlist_get_active (); 00451 playlist_queue_delete (playlist, 0, playlist_queue_count (playlist)); 00452 }