Code

337d7677d6d7334fc4453be4bf05b691614f9457
[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         if (seek_id < 0)
36                 return;
38         if (!mpdclient_is_connected(c)) {
39                 seek_id = -1;
40                 return;
41         }
43         if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song))
44                 if (!mpd_run_seek_id(c->connection, seek_id, seek_target_time))
45                         mpdclient_handle_error(c);
47         seek_id = -1;
48 }
50 /**
51  * This timer is invoked after seeking when the user hasn't typed a
52  * key for 500ms.  It is used to do the real seeking.
53  */
54 static gboolean
55 seek_timer(gpointer data)
56 {
57         struct mpdclient *c = data;
59         seek_source_id = 0;
60         commit_seek(c);
61         return false;
62 }
64 static void
65 schedule_seek_timer(struct mpdclient *c)
66 {
67         assert(seek_source_id == 0);
69         seek_source_id = g_timeout_add(500, seek_timer, c);
70 }
72 void
73 cancel_seek_timer(void)
74 {
75         if (seek_source_id != 0) {
76                 g_source_remove(seek_source_id);
77                 seek_source_id = 0;
78         }
79 }
81 bool
82 handle_player_command(struct mpdclient *c, command_t cmd)
83 {
84         const struct mpd_song *song;
86         if (!mpdclient_is_connected(c) || c->status == NULL)
87                 return false;
89         cancel_seek_timer();
91         switch(cmd) {
92                 /*
93         case CMD_PLAY:
94                 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
95                 break;
96                 */
97         case CMD_PAUSE:
98                 if (!mpd_run_pause(c->connection,
99                                    mpd_status_get_state(c->status) != MPD_STATE_PAUSE))
100                         mpdclient_handle_error(c);
101                 break;
102         case CMD_STOP:
103                 if (!mpd_run_stop(c->connection))
104                         mpdclient_handle_error(c);
105                 break;
106         case CMD_CROP:
107                 mpdclient_cmd_crop(c);
108                 break;
109         case CMD_SEEK_FORWARD:
110                 song = mpdclient_get_current_song(c);
111                 if (song != NULL) {
112                         if (seek_id != (int)mpd_song_get_id(song)) {
113                                 seek_id = mpd_song_get_id(song);
114                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
115                         }
116                         seek_target_time+=options.seek_time;
117                         if (seek_target_time > (int)mpd_status_get_total_time(c->status))
118                                 seek_target_time = mpd_status_get_total_time(c->status);
119                         schedule_seek_timer(c);
120                 }
121                 break;
122                 /* fall through... */
123         case CMD_TRACK_NEXT:
124                 if (!mpd_run_next(c->connection))
125                         mpdclient_handle_error(c);
126                 break;
127         case CMD_SEEK_BACKWARD:
128                 song = mpdclient_get_current_song(c);
129                 if (song != NULL) {
130                         if (seek_id != (int)mpd_song_get_id(song)) {
131                                 seek_id = mpd_song_get_id(c->song);
132                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
133                         }
134                         seek_target_time-=options.seek_time;
135                         if (seek_target_time < 0)
136                                 seek_target_time=0;
137                         schedule_seek_timer(c);
138                 }
139                 break;
140         case CMD_TRACK_PREVIOUS:
141                 if (!mpd_run_previous(c->connection))
142                         mpdclient_handle_error(c);
143                 break;
144         case CMD_SHUFFLE:
145                 if (mpd_run_shuffle(c->connection))
146                         screen_status_message(_("Shuffled playlist"));
147                 else
148                         mpdclient_handle_error(c);
149                 break;
150         case CMD_CLEAR:
151                 if (mpdclient_cmd_clear(c))
152                         screen_status_message(_("Cleared playlist"));
153                 break;
154         case CMD_REPEAT:
155                 if (!mpd_run_repeat(c->connection,
156                                     !mpd_status_get_repeat(c->status)))
157                         mpdclient_handle_error(c);
158                 break;
159         case CMD_RANDOM:
160                 if (!mpd_run_random(c->connection,
161                                     !mpd_status_get_random(c->status)))
162                         mpdclient_handle_error(c);
163                 break;
164         case CMD_SINGLE:
165                 if (!mpd_run_single(c->connection,
166                                     !mpd_status_get_single(c->status)))
167                         mpdclient_handle_error(c);
168                 break;
169         case CMD_CONSUME:
170                 if (!mpd_run_consume(c->connection,
171                                      !mpd_status_get_consume(c->status)))
172                         mpdclient_handle_error(c);
173                 break;
174         case CMD_CROSSFADE:
175                 if (!mpd_run_crossfade(c->connection,
176                                        mpd_status_get_crossfade(c->status) > 0
177                                        ? 0 : options.crossfade_time))
178                         mpdclient_handle_error(c);
179                 break;
180         case CMD_DB_UPDATE:
181                 screen_database_update(c, NULL);
182                 break;
183         case CMD_VOLUME_UP:
184                 mpdclient_cmd_volume_up(c);
185                 break;
186         case CMD_VOLUME_DOWN:
187                 mpdclient_cmd_volume_down(c);
188                 break;
190         default:
191                 return false;
192         }
194         return true;