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 playback_play (0, FALSE); 00054 } 00055 00056 void drct_pause (void) 00057 { 00058 if (playback_get_playing ()) 00059 playback_pause (); 00060 } 00061 00062 void drct_stop (void) 00063 { 00064 if (playback_get_playing ()) 00065 playback_stop (); 00066 } 00067 00068 gboolean drct_get_playing (void) 00069 { 00070 return playback_get_playing (); 00071 } 00072 00073 gboolean drct_get_ready (void) 00074 { 00075 return playback_get_ready (); 00076 } 00077 00078 gboolean drct_get_paused (void) 00079 { 00080 return playback_get_paused (); 00081 } 00082 00083 gchar * drct_get_title (void) 00084 { 00085 return playback_get_title (); 00086 } 00087 00088 void drct_get_info (gint * bitrate, gint * samplerate, gint * channels) 00089 { 00090 playback_get_info (bitrate, samplerate, channels); 00091 } 00092 00093 gint drct_get_time (void) 00094 { 00095 return playback_get_time (); 00096 } 00097 00098 gint drct_get_length (void) 00099 { 00100 return playback_get_length (); 00101 } 00102 00103 void drct_seek (gint time) 00104 { 00105 playback_seek (time); 00106 } 00107 00108 /* --- VOLUME CONTROL --- */ 00109 00110 void drct_get_volume (gint * left, gint * right) 00111 { 00112 playback_get_volume (left, right); 00113 * left = CLAMP (* left, 0, 100); 00114 * right = CLAMP (* right, 0, 100); 00115 } 00116 00117 void drct_set_volume (gint left, gint right) 00118 { 00119 playback_set_volume (CLAMP (left, 0, 100), CLAMP (right, 0, 100)); 00120 } 00121 00122 void drct_get_volume_main (gint * volume) 00123 { 00124 gint left, right; 00125 drct_get_volume (& left, & right); 00126 * volume = MAX (left, right); 00127 } 00128 00129 void drct_set_volume_main (gint volume) 00130 { 00131 gint left, right, current; 00132 drct_get_volume (& left, & right); 00133 current = MAX (left, right); 00134 00135 if (current > 0) 00136 drct_set_volume (volume * left / current, volume * right / current); 00137 else 00138 drct_set_volume (volume, volume); 00139 } 00140 00141 void drct_get_volume_balance (gint * balance) 00142 { 00143 gint left, right; 00144 drct_get_volume (& left, & right); 00145 00146 if (left == right) 00147 * balance = 0; 00148 else if (left > right) 00149 * balance = -100 + right * 100 / left; 00150 else 00151 * balance = 100 - left * 100 / right; 00152 } 00153 00154 void drct_set_volume_balance (gint balance) 00155 { 00156 gint left, right; 00157 drct_get_volume_main (& left); 00158 00159 if (balance < 0) 00160 right = left * (100 + balance) / 100; 00161 else 00162 { 00163 right = left; 00164 left = right * (100 - balance) / 100; 00165 } 00166 00167 drct_set_volume (left, right); 00168 } 00169 00170 /* --- PLAYLIST CONTROL --- */ 00171 00172 gint drct_pl_get_length (void) 00173 { 00174 return playlist_entry_count (playlist_get_active ()); 00175 } 00176 00177 void drct_pl_next (void) 00178 { 00179 gboolean play = playback_get_playing (); 00180 if (playlist_get_playing () < 0) 00181 playlist_set_playing (playlist_get_active ()); 00182 if (playlist_next_song (playlist_get_playing (), cfg.repeat) && play) 00183 playback_play (0, FALSE); 00184 } 00185 00186 void drct_pl_prev (void) 00187 { 00188 gboolean play = playback_get_playing (); 00189 if (playlist_get_playing () < 0) 00190 playlist_set_playing (playlist_get_active ()); 00191 if (playlist_prev_song (playlist_get_playing ()) && play) 00192 playback_play (0, FALSE); 00193 } 00194 00195 gint drct_pl_get_pos (void) 00196 { 00197 return playlist_get_position (playlist_get_active ()); 00198 } 00199 00200 void drct_pl_set_pos (gint pos) 00201 { 00202 gint playlist = playlist_get_active (); 00203 gboolean play = playback_get_playing (); 00204 00205 playlist_set_position (playlist, pos); 00206 00207 if (play) 00208 { 00209 playlist_set_playing (playlist); 00210 playback_play (0, FALSE); 00211 } 00212 } 00213 00214 gboolean drct_pl_repeat_is_enabled (void) 00215 { 00216 return cfg.repeat; 00217 } 00218 00219 void drct_pl_repeat_toggle (void) 00220 { 00221 cfg.repeat = ! cfg.repeat; 00222 hook_call ("toggle repeat", NULL); 00223 } 00224 00225 gboolean drct_pl_shuffle_is_enabled (void) 00226 { 00227 return cfg.shuffle; 00228 } 00229 00230 void drct_pl_shuffle_toggle (void) 00231 { 00232 cfg.shuffle = ! cfg.shuffle; 00233 hook_call ("toggle shuffle", NULL); 00234 } 00235 00236 gchar * drct_pl_get_file (gint entry) 00237 { 00238 const gchar * filename = playlist_entry_get_filename 00239 (playlist_get_active (), entry); 00240 return (filename == NULL) ? NULL : g_strdup (filename); 00241 } 00242 00243 gchar * drct_pl_get_title (gint entry) 00244 { 00245 const gchar * title = playlist_entry_get_title (playlist_get_active (), 00246 entry, FALSE); 00247 return (title == NULL) ? NULL : g_strdup (title); 00248 } 00249 00250 gint drct_pl_get_time (gint pos) 00251 { 00252 return playlist_entry_get_length (playlist_get_active (), pos, FALSE); 00253 } 00254 00255 static void activate_temp (void) 00256 { 00257 gint playlists = playlist_count (); 00258 const gchar * title = _("Temporary Playlist"); 00259 00260 for (gint playlist = 0; playlist < playlists; playlist ++) 00261 { 00262 if (! strcmp (playlist_get_title (playlist), title)) 00263 { 00264 playlist_set_active (playlist); 00265 return; 00266 } 00267 } 00268 00269 if (! playlist_entry_count (playlist_get_active ())) 00270 playlist_set_title (playlist_get_active (), title); 00271 else 00272 { 00273 playlist_insert (playlists); 00274 playlist_set_title (playlists, title); 00275 playlist_set_active (playlists); 00276 } 00277 } 00278 00279 static void add_list (GList * list, gint at, gboolean to_temp, gboolean play) 00280 { 00281 if (to_temp) 00282 activate_temp (); 00283 00284 gint playlist = playlist_get_active (); 00285 00286 if (play) 00287 { 00288 if (cfg.clear_playlist) 00289 playlist_entry_delete (playlist, 0, playlist_entry_count (playlist)); 00290 else 00291 playlist_queue_delete (playlist, 0, playlist_queue_count (playlist)); 00292 } 00293 00294 gint entries = playlist_entry_count (playlist); 00295 if (at < 0) 00296 at = entries; 00297 00298 gint added = 0; 00299 GQueue folders = G_QUEUE_INIT; 00300 struct index * filenames = index_new (); 00301 00302 for (; list != NULL; list = list->next) 00303 { 00304 if (filename_is_playlist (list->data)) 00305 { 00306 playlist_insert_playlist (playlist, at + added, list->data); 00307 added += playlist_entry_count (playlist) - entries; 00308 entries = playlist_entry_count (playlist); 00309 } 00310 else if (vfs_file_test (list->data, G_FILE_TEST_IS_DIR)) 00311 g_queue_push_tail (& folders, list->data); 00312 else 00313 index_append (filenames, g_strdup (list->data)); 00314 } 00315 00316 playlist_entry_insert_batch (playlist, at + added, filenames, NULL); 00317 added += playlist_entry_count (playlist) - entries; 00318 00319 if (added && play) 00320 { 00321 playlist_set_playing (playlist); 00322 if (! cfg.shuffle) 00323 playlist_set_position (playlist, at); 00324 playback_play (0, FALSE); 00325 play = FALSE; 00326 } 00327 00328 const gchar * folder; 00329 while ((folder = g_queue_pop_head (& folders)) != NULL) 00330 { 00331 playlist_insert_folder (playlist, at + added, folder, play); 00332 play = FALSE; 00333 } 00334 } 00335 00336 void drct_pl_add (const gchar * filename, gint at) 00337 { 00338 GList * list = g_list_prepend (NULL, (void *) filename); 00339 add_list (list, at, FALSE, FALSE); 00340 g_list_free (list); 00341 } 00342 00343 void drct_pl_add_list (GList * list, gint at) 00344 { 00345 add_list (list, at, FALSE, FALSE); 00346 } 00347 00348 void drct_pl_open (const gchar * filename) 00349 { 00350 GList * list = g_list_prepend (NULL, (void *) filename); 00351 add_list (list, -1, cfg.open_to_temporary, TRUE); 00352 g_list_free (list); 00353 } 00354 00355 void drct_pl_open_list (GList * list) 00356 { 00357 add_list (list, -1, cfg.open_to_temporary, TRUE); 00358 } 00359 00360 void drct_pl_open_temp (const gchar * filename) 00361 { 00362 GList * list = g_list_prepend (NULL, (void *) filename); 00363 add_list (list, -1, TRUE, TRUE); 00364 g_list_free (list); 00365 } 00366 00367 void drct_pl_open_temp_list (GList * list) 00368 { 00369 add_list (list, -1, TRUE, TRUE); 00370 } 00371 00372 void drct_pl_delete (gint entry) 00373 { 00374 playlist_entry_delete (playlist_get_active (), entry, 1); 00375 } 00376 00377 /* Advancing to the next song when the current one is deleted is tricky. First, 00378 * we delete all the selected songs except the current one. We can then advance 00379 * to a new song without worrying about picking one that is also selected. 00380 * Finally, we can delete the former current song without stopping playback. */ 00381 00382 void drct_pl_delete_selected (void) 00383 { 00384 gint list = playlist_get_active (); 00385 gint pos = playlist_get_position (list); 00386 00387 if (cfg.advance_on_delete && ! cfg.no_playlist_advance 00388 && playback_get_playing () && list == playlist_get_playing () 00389 && pos >= 0 && playlist_entry_get_selected (list, pos)) 00390 { 00391 playlist_entry_set_selected (list, pos, FALSE); 00392 playlist_delete_selected (list); 00393 pos = playlist_get_position (list); /* it may have moved */ 00394 00395 if (playlist_next_song (list, cfg.repeat) 00396 && playlist_get_position (list) != pos) 00397 playback_play (0, FALSE); 00398 00399 playlist_entry_delete (list, pos, 1); 00400 } 00401 else 00402 playlist_delete_selected (list); 00403 } 00404 00405 void drct_pl_clear (void) 00406 { 00407 gint playlist = playlist_get_active (); 00408 playlist_entry_delete (playlist, 0, playlist_entry_count (playlist)); 00409 } 00410 00411 /* --- PLAYLIST QUEUE CONTROL --- */ 00412 00413 gint drct_pq_get_length (void) 00414 { 00415 return playlist_queue_count (playlist_get_active ()); 00416 } 00417 00418 gint drct_pq_get_entry (gint queue_position) 00419 { 00420 return playlist_queue_get_entry (playlist_get_active (), queue_position); 00421 } 00422 00423 gboolean drct_pq_is_queued (gint entry) 00424 { 00425 return (drct_pq_get_queue_position (entry) >= 0); 00426 } 00427 00428 gint drct_pq_get_queue_position (gint entry) 00429 { 00430 return playlist_queue_find_entry (playlist_get_active (), entry); 00431 } 00432 00433 void drct_pq_add (gint entry) 00434 { 00435 playlist_queue_insert (playlist_get_active (), -1, entry); 00436 } 00437 00438 void drct_pq_remove (gint entry) 00439 { 00440 gint playlist = playlist_get_active (); 00441 playlist_queue_delete (playlist, playlist_queue_find_entry (playlist, 00442 entry), 1); 00443 } 00444 00445 void drct_pq_clear (void) 00446 { 00447 gint playlist = playlist_get_active (); 00448 playlist_queue_delete (playlist, 0, playlist_queue_count (playlist)); 00449 }