Code

mpdclient: wrap access in mpdclient_get_connection()
[ncmpc.git] / src / player_command.c
1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2009 The Music Player Daemon Project
3  * Project homepage: http://musicpd.org
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
20 #include "player_command.h"
21 #include "mpdclient.h"
22 #include "options.h"
23 #include "i18n.h"
24 #include "screen_client.h"
25 #include "screen_message.h"
27 int seek_id = -1;
28 int seek_target_time;
30 static guint seek_source_id;
32 static void
33 commit_seek(struct mpdclient *c)
34 {
35         struct mpd_connection *connection;
37         if (seek_id < 0)
38                 return;
40         if (!mpdclient_is_connected(c)) {
41                 seek_id = -1;
42                 return;
43         }
45         connection = mpdclient_get_connection(c);
47         if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song))
48                 if (!mpd_run_seek_id(connection, seek_id, seek_target_time))
49                         mpdclient_handle_error(c);
51         seek_id = -1;
52 }
54 /**
55  * This timer is invoked after seeking when the user hasn't typed a
56  * key for 500ms.  It is used to do the real seeking.
57  */
58 static gboolean
59 seek_timer(gpointer data)
60 {
61         struct mpdclient *c = data;
63         seek_source_id = 0;
64         commit_seek(c);
65         mpdclient_put_connection(c);
66         return false;
67 }
69 static void
70 schedule_seek_timer(struct mpdclient *c)
71 {
72         assert(seek_source_id == 0);
74         seek_source_id = g_timeout_add(500, seek_timer, c);
75 }
77 void
78 cancel_seek_timer(void)
79 {
80         if (seek_source_id != 0) {
81                 g_source_remove(seek_source_id);
82                 seek_source_id = 0;
83         }
84 }
86 bool
87 handle_player_command(struct mpdclient *c, command_t cmd)
88 {
89         struct mpd_connection *connection;
90         const struct mpd_song *song;
92         if (!mpdclient_is_connected(c) || c->status == NULL)
93                 return false;
95         cancel_seek_timer();
97         switch(cmd) {
98                 /*
99         case CMD_PLAY:
100                 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
101                 break;
102                 */
103         case CMD_PAUSE:
104                 connection = mpdclient_get_connection(c);
105                 if (!mpd_run_pause(connection,
106                                    mpd_status_get_state(c->status) != MPD_STATE_PAUSE))
107                         mpdclient_handle_error(c);
108                 break;
109         case CMD_STOP:
110                 connection = mpdclient_get_connection(c);
111                 if (!mpd_run_stop(connection))
112                         mpdclient_handle_error(c);
113                 break;
114         case CMD_CROP:
115                 mpdclient_cmd_crop(c);
116                 break;
117         case CMD_SEEK_FORWARD:
118                 song = mpdclient_get_current_song(c);
119                 if (song != NULL) {
120                         if (seek_id != (int)mpd_song_get_id(song)) {
121                                 seek_id = mpd_song_get_id(song);
122                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
123                         }
124                         seek_target_time+=options.seek_time;
125                         if (seek_target_time > (int)mpd_status_get_total_time(c->status))
126                                 seek_target_time = mpd_status_get_total_time(c->status);
127                         schedule_seek_timer(c);
128                 }
129                 break;
130         case CMD_TRACK_NEXT:
131                 connection = mpdclient_get_connection(c);
132                 if (!mpd_run_next(connection))
133                         mpdclient_handle_error(c);
134                 break;
135         case CMD_SEEK_BACKWARD:
136                 song = mpdclient_get_current_song(c);
137                 if (song != NULL) {
138                         if (seek_id != (int)mpd_song_get_id(song)) {
139                                 seek_id = mpd_song_get_id(c->song);
140                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
141                         }
142                         seek_target_time-=options.seek_time;
143                         if (seek_target_time < 0)
144                                 seek_target_time=0;
145                         schedule_seek_timer(c);
146                 }
147                 break;
148         case CMD_TRACK_PREVIOUS:
149                 connection = mpdclient_get_connection(c);
150                 if (!mpd_run_previous(connection))
151                         mpdclient_handle_error(c);
152                 break;
153         case CMD_SHUFFLE:
154                 connection = mpdclient_get_connection(c);
155                 if (mpd_run_shuffle(connection))
156                         screen_status_message(_("Shuffled playlist"));
157                 else
158                         mpdclient_handle_error(c);
159                 break;
160         case CMD_CLEAR:
161                 connection = mpdclient_get_connection(c);
162                 if (mpdclient_cmd_clear(c))
163                         screen_status_message(_("Cleared playlist"));
164                 break;
165         case CMD_REPEAT:
166                 connection = mpdclient_get_connection(c);
167                 if (!mpd_run_repeat(connection,
168                                     !mpd_status_get_repeat(c->status)))
169                         mpdclient_handle_error(c);
170                 break;
171         case CMD_RANDOM:
172                 connection = mpdclient_get_connection(c);
173                 if (!mpd_run_random(connection,
174                                     !mpd_status_get_random(c->status)))
175                         mpdclient_handle_error(c);
176                 break;
177         case CMD_SINGLE:
178                 connection = mpdclient_get_connection(c);
179                 if (!mpd_run_single(connection,
180                                     !mpd_status_get_single(c->status)))
181                         mpdclient_handle_error(c);
182                 break;
183         case CMD_CONSUME:
184                 connection = mpdclient_get_connection(c);
185                 if (!mpd_run_consume(connection,
186                                      !mpd_status_get_consume(c->status)))
187                         mpdclient_handle_error(c);
188                 break;
189         case CMD_CROSSFADE:
190                 connection = mpdclient_get_connection(c);
191                 if (!mpd_run_crossfade(connection,
192                                        mpd_status_get_crossfade(c->status) > 0
193                                        ? 0 : options.crossfade_time))
194                         mpdclient_handle_error(c);
195                 break;
196         case CMD_DB_UPDATE:
197                 screen_database_update(c, NULL);
198                 break;
199         case CMD_VOLUME_UP:
200                 mpdclient_cmd_volume_up(c);
201                 break;
202         case CMD_VOLUME_DOWN:
203                 mpdclient_cmd_volume_down(c);
204                 break;
206         default:
207                 return false;
208         }
210         return true;