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 "screen.h"
24 #include "i18n.h"
26 #define IS_PLAYING(s) (s==MPD_STATE_PLAY)
27 #define IS_PAUSED(s) (s==MPD_STATE_PAUSE)
28 #define IS_STOPPED(s) (!(IS_PLAYING(s) | IS_PAUSED(s)))
30 int seek_id = -1;
31 int seek_target_time;
33 static guint seek_source_id;
35 static void
36 commit_seek(struct mpdclient *c)
37 {
38 if (seek_id < 0)
39 return;
41 if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song))
42 mpdclient_cmd_seek(c, seek_id, seek_target_time);
44 seek_id = -1;
45 }
47 /**
48 * This timer is invoked after seeking when the user hasn't typed a
49 * key for 500ms. It is used to do the real seeking.
50 */
51 static gboolean
52 seek_timer(gpointer data)
53 {
54 struct mpdclient *c = data;
56 seek_source_id = 0;
57 commit_seek(c);
58 return false;
59 }
61 static void
62 schedule_seek_timer(struct mpdclient *c)
63 {
64 assert(seek_source_id == 0);
66 seek_source_id = g_timeout_add(500, seek_timer, c);
67 }
69 void
70 cancel_seek_timer(void)
71 {
72 if (seek_source_id != 0) {
73 g_source_remove(seek_source_id);
74 seek_source_id = 0;
75 }
76 }
78 bool
79 handle_player_command(struct mpdclient *c, command_t cmd)
80 {
81 if (c->connection == NULL || c->status == NULL)
82 return false;
84 cancel_seek_timer();
86 switch(cmd) {
87 /*
88 case CMD_PLAY:
89 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
90 break;
91 */
92 case CMD_PAUSE:
93 mpdclient_cmd_pause(c, !IS_PAUSED(mpd_status_get_state(c->status)));
94 break;
95 case CMD_STOP:
96 mpdclient_cmd_stop(c);
97 break;
98 case CMD_CROP:
99 mpdclient_cmd_crop(c);
100 break;
101 case CMD_SEEK_FORWARD:
102 if (!IS_STOPPED(mpd_status_get_state(c->status))) {
103 if (c->song != NULL &&
104 seek_id != (int)mpd_song_get_id(c->song)) {
105 seek_id = mpd_song_get_id(c->song);
106 seek_target_time = mpd_status_get_elapsed_time(c->status);
107 }
108 seek_target_time+=options.seek_time;
109 if (seek_target_time > (int)mpd_status_get_total_time(c->status))
110 seek_target_time = mpd_status_get_total_time(c->status);
111 schedule_seek_timer(c);
112 }
113 break;
114 /* fall through... */
115 case CMD_TRACK_NEXT:
116 if (!IS_STOPPED(mpd_status_get_state(c->status)))
117 mpdclient_cmd_next(c);
118 break;
119 case CMD_SEEK_BACKWARD:
120 if (!IS_STOPPED(mpd_status_get_state(c->status))) {
121 if (seek_id != (int)mpd_song_get_id(c->song)) {
122 seek_id = mpd_song_get_id(c->song);
123 seek_target_time = mpd_status_get_elapsed_time(c->status);
124 }
125 seek_target_time-=options.seek_time;
126 if (seek_target_time < 0)
127 seek_target_time=0;
128 schedule_seek_timer(c);
129 }
130 break;
131 case CMD_TRACK_PREVIOUS:
132 if (!IS_STOPPED(mpd_status_get_state(c->status)))
133 mpdclient_cmd_prev(c);
134 break;
135 case CMD_SHUFFLE:
136 if (mpdclient_cmd_shuffle(c) == 0)
137 screen_status_message(_("Shuffled playlist"));
138 break;
139 case CMD_CLEAR:
140 if (mpdclient_cmd_clear(c) == 0)
141 screen_status_message(_("Cleared playlist"));
142 break;
143 case CMD_REPEAT:
144 mpdclient_cmd_repeat(c, !mpd_status_get_repeat(c->status));
145 break;
146 case CMD_RANDOM:
147 mpdclient_cmd_random(c, !mpd_status_get_random(c->status));
148 break;
149 case CMD_SINGLE:
150 mpdclient_cmd_single(c, !mpd_status_get_single(c->status));
151 break;
152 case CMD_CONSUME:
153 mpdclient_cmd_consume(c, !mpd_status_get_consume(c->status));
154 break;
155 case CMD_CROSSFADE:
156 if (mpd_status_get_crossfade(c->status))
157 mpdclient_cmd_crossfade(c, 0);
158 else
159 mpdclient_cmd_crossfade(c, options.crossfade_time);
160 break;
161 case CMD_DB_UPDATE:
162 if (!mpd_status_get_update_id(c->status)) {
163 if( mpdclient_cmd_db_update(c,NULL)==0 )
164 screen_status_printf(_("Database update started"));
165 } else
166 screen_status_printf(_("Database update running..."));
167 break;
168 case CMD_VOLUME_UP:
169 mpdclient_cmd_volume_up(c);
170 break;
171 case CMD_VOLUME_DOWN:
172 mpdclient_cmd_volume_down(c);
173 break;
175 default:
176 return false;
177 }
179 return true;
180 }