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