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