Mercurial > audlegacy
annotate Plugins/General/song_change/song_change.c @ 1390:dfa069085cbb trunk
[svn] - use default 'plugins' icon for now.
author | nenolod |
---|---|
date | Mon, 10 Jul 2006 14:04:49 -0700 |
parents | 3e44e4df1e35 |
children |
rev | line source |
---|---|
117 | 1 /* |
2 * Audacious: A cross-platform multimedia player. | |
3 * Copyright (c) 2005 Audacious Team | |
4 */ | |
5 #include "config.h" | |
6 | |
7 #include <glib.h> | |
8 #include <glib/gi18n.h> | |
9 #include <gtk/gtk.h> | |
10 #include <sys/types.h> | |
11 #include <sys/wait.h> | |
12 | |
13 #include <signal.h> | |
14 #include <unistd.h> | |
15 #include <stdio.h> | |
16 | |
17 #include <string.h> | |
18 | |
19 #include "audacious/plugin.h" | |
1221 | 20 #include "audacious/prefswin.h" |
308 | 21 #include "libaudacious/configdb.h" |
117 | 22 #include "libaudacious/beepctrl.h" |
23 #include "libaudacious/formatter.h" | |
24 | |
25 static void init(void); | |
26 static void cleanup(void); | |
1221 | 27 static GtkWidget *configure(void); |
117 | 28 static int timeout_func(gpointer); |
29 | |
30 static int timeout_tag = 0; | |
31 static int previous_song = -1; | |
32 static char *cmd_line = NULL; | |
33 static char *cmd_line_after = NULL; | |
34 static char *cmd_line_end = NULL; | |
35 static gboolean possible_pl_end; | |
36 | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
37 static GtkWidget *configure_vbox = NULL; |
117 | 38 static GtkWidget *cmd_entry, *cmd_after_entry, *cmd_end_entry; |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
39 static GtkWidget *cmd_warn_label, *cmd_warn_img; |
117 | 40 |
41 GeneralPlugin sc_gp = | |
42 { | |
43 NULL, /* handle */ | |
44 NULL, /* filename */ | |
45 -1, /* xmms_session */ | |
46 NULL, /* Description */ | |
47 init, | |
48 NULL, | |
1221 | 49 NULL, |
117 | 50 cleanup, |
51 }; | |
52 | |
53 GeneralPlugin *get_gplugin_info(void) | |
54 { | |
751 | 55 sc_gp.description = g_strdup_printf(_("Song Change %s"), PACKAGE_VERSION); |
117 | 56 return &sc_gp; |
57 } | |
58 | |
59 static void read_config(void) | |
60 { | |
308 | 61 ConfigDb *db; |
117 | 62 |
308 | 63 cmd_line = g_strdup(""); |
64 cmd_line_after = g_strdup(""); | |
65 cmd_line_end = g_strdup(""); | |
117 | 66 |
308 | 67 db = bmp_cfg_db_open(); |
68 bmp_cfg_db_get_string(db, "song_change", "cmd_line", &cmd_line); | |
69 bmp_cfg_db_get_string(db, "song_change", "cmd_line_after", &cmd_line_after); | |
70 bmp_cfg_db_get_string(db, "song_change", "cmd_line_end", &cmd_line_end); | |
71 bmp_cfg_db_close(db); | |
117 | 72 } |
73 | |
74 static void cleanup(void) | |
75 { | |
76 if (timeout_tag) | |
77 gtk_timeout_remove(timeout_tag); | |
78 timeout_tag = 0; | |
79 | |
80 g_free(cmd_line); | |
81 g_free(cmd_line_after); | |
82 g_free(cmd_line_end); | |
83 cmd_line = NULL; | |
84 cmd_line_after = NULL; | |
85 cmd_line_end = NULL; | |
86 signal(SIGCHLD, SIG_DFL); | |
1221 | 87 |
88 prefswin_page_destroy(configure_vbox); | |
117 | 89 } |
90 | |
91 static void save_and_close(GtkWidget *w, gpointer data) | |
92 { | |
308 | 93 ConfigDb *db; |
117 | 94 char *cmd, *cmd_after, *cmd_end; |
95 | |
247
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
96 cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_entry))); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
97 cmd_after = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_after_entry))); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
98 cmd_end = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_end_entry))); |
117 | 99 |
308 | 100 db = bmp_cfg_db_open(); |
101 bmp_cfg_db_set_string(db, "song_change", "cmd_line", cmd); | |
102 bmp_cfg_db_set_string(db, "song_change", "cmd_line_after", cmd_after); | |
103 bmp_cfg_db_set_string(db, "song_change", "cmd_line_end", cmd_end); | |
104 bmp_cfg_db_close(db); | |
117 | 105 |
106 if (timeout_tag) | |
107 { | |
108 g_free(cmd_line); | |
109 cmd_line = g_strdup(cmd); | |
110 g_free(cmd_line_after); | |
111 cmd_line_after = g_strdup(cmd_after); | |
112 g_free(cmd_line_end); | |
113 cmd_line_end = g_strdup(cmd_end); | |
114 } | |
931
26b580493ce2
[svn] Moved the free, based on Joker's report of string corruptions.
nemo
parents:
859
diff
changeset
|
115 |
26b580493ce2
[svn] Moved the free, based on Joker's report of string corruptions.
nemo
parents:
859
diff
changeset
|
116 g_free(cmd); |
26b580493ce2
[svn] Moved the free, based on Joker's report of string corruptions.
nemo
parents:
859
diff
changeset
|
117 g_free(cmd_after); |
26b580493ce2
[svn] Moved the free, based on Joker's report of string corruptions.
nemo
parents:
859
diff
changeset
|
118 g_free(cmd_end); |
117 | 119 } |
120 | |
121 static int check_command(char *command) | |
122 { | |
123 const char *dangerous = "fns"; | |
124 char *c; | |
125 int qu = 0; | |
126 | |
127 for (c = command; *c != '\0'; c++) | |
128 { | |
129 if (*c == '"' && (c == command || *(c - 1) != '\\')) | |
130 qu = !qu; | |
131 else if (*c == '%' && !qu && strchr(dangerous, *(c + 1))) | |
132 return -1; | |
133 } | |
134 return 0; | |
135 } | |
136 | |
137 static void configure_ok_cb(GtkWidget *w, gpointer data) | |
138 { | |
139 char *cmd, *cmd_after, *cmd_end; | |
140 | |
247
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
141 cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_entry))); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
142 cmd_after = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_after_entry))); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
143 cmd_end = g_strdup(gtk_entry_get_text(GTK_ENTRY(cmd_end_entry))); |
117 | 144 |
145 if (check_command(cmd) < 0 || check_command(cmd_after) < 0 | |
146 || check_command(cmd_end) < 0) | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
147 { |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
148 gtk_widget_show(cmd_warn_img); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
149 gtk_widget_show(cmd_warn_label); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
150 } |
117 | 151 else |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
152 { |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
153 gtk_widget_hide(cmd_warn_img); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
154 gtk_widget_hide(cmd_warn_label); |
117 | 155 save_and_close(NULL, NULL); |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
156 } |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
157 |
247
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
158 g_free(cmd); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
159 g_free(cmd_after); |
95f7737919b1
[svn] Avoid discarding pointer type qualifiers by not using the result of gtk_entry_get_text directly.
chainsaw
parents:
119
diff
changeset
|
160 g_free(cmd_end); |
117 | 161 } |
162 | |
163 | |
1221 | 164 static GtkWidget *configure(void) |
117 | 165 { |
166 GtkWidget *sep1, *sep2, *sep3; | |
167 GtkWidget *cmd_hbox, *cmd_label; | |
168 GtkWidget *cmd_after_hbox, *cmd_after_label; | |
169 GtkWidget *cmd_end_hbox, *cmd_end_label; | |
170 GtkWidget *cmd_desc, *cmd_after_desc, *cmd_end_desc, *f_desc; | |
171 GtkWidget *song_frame, *song_vbox; | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
172 GtkWidget *bbox_hbox; |
117 | 173 char *temp; |
174 | |
175 read_config(); | |
176 | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
177 configure_vbox = gtk_vbox_new(FALSE, 12); |
117 | 178 |
179 song_frame = gtk_frame_new(_("Commands")); | |
180 gtk_box_pack_start(GTK_BOX(configure_vbox), song_frame, FALSE, FALSE, 0); | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
181 song_vbox = gtk_vbox_new(FALSE, 12); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
182 gtk_container_set_border_width(GTK_CONTAINER(song_vbox), 6); |
117 | 183 gtk_container_add(GTK_CONTAINER(song_frame), song_vbox); |
184 | |
185 cmd_desc = gtk_label_new(_( | |
1378
27d9eb18c7cf
[svn] - some improvements to song_change, still sucky
nenolod
parents:
1328
diff
changeset
|
186 "Command to run when Audacious starts a new song.")); |
117 | 187 gtk_label_set_justify(GTK_LABEL(cmd_desc), GTK_JUSTIFY_LEFT); |
188 gtk_misc_set_alignment(GTK_MISC(cmd_desc), 0, 0.5); | |
189 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_desc, FALSE, FALSE, 0); | |
190 gtk_label_set_line_wrap(GTK_LABEL(cmd_desc), TRUE); | |
191 | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
192 cmd_hbox = gtk_hbox_new(FALSE, 6); |
117 | 193 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_hbox, FALSE, FALSE, 0); |
194 | |
195 cmd_label = gtk_label_new(_("Command:")); | |
196 gtk_box_pack_start(GTK_BOX(cmd_hbox), cmd_label, FALSE, FALSE, 0); | |
197 | |
198 cmd_entry = gtk_entry_new(); | |
199 if (cmd_line) | |
200 gtk_entry_set_text(GTK_ENTRY(cmd_entry), cmd_line); | |
201 gtk_widget_set_usize(cmd_entry, 200, -1); | |
202 gtk_box_pack_start(GTK_BOX(cmd_hbox), cmd_entry, TRUE, TRUE, 0); | |
203 | |
204 sep1 = gtk_hseparator_new(); | |
205 gtk_box_pack_start(GTK_BOX(song_vbox), sep1, TRUE, TRUE, 0); | |
206 | |
207 | |
208 cmd_after_desc = gtk_label_new(_( | |
1378
27d9eb18c7cf
[svn] - some improvements to song_change, still sucky
nenolod
parents:
1328
diff
changeset
|
209 "Command to run toward the end of a song.")); |
117 | 210 gtk_label_set_justify(GTK_LABEL(cmd_after_desc), GTK_JUSTIFY_LEFT); |
211 gtk_misc_set_alignment(GTK_MISC(cmd_after_desc), 0, 0.5); | |
212 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_after_desc, FALSE, FALSE, 0); | |
213 | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
214 cmd_after_hbox = gtk_hbox_new(FALSE, 6); |
117 | 215 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_after_hbox, FALSE, FALSE, 0); |
216 | |
217 cmd_after_label = gtk_label_new(_("Command:")); | |
218 gtk_box_pack_start(GTK_BOX(cmd_after_hbox), cmd_after_label, FALSE, FALSE, 0); | |
219 | |
220 cmd_after_entry = gtk_entry_new(); | |
221 if (cmd_line_after) | |
222 gtk_entry_set_text(GTK_ENTRY(cmd_after_entry), cmd_line_after); | |
223 gtk_widget_set_usize(cmd_after_entry, 200, -1); | |
224 gtk_box_pack_start(GTK_BOX(cmd_after_hbox), cmd_after_entry, TRUE, TRUE, 0); | |
225 sep2 = gtk_hseparator_new(); | |
226 gtk_box_pack_start(GTK_BOX(song_vbox), sep2, TRUE, TRUE, 0); | |
227 | |
228 cmd_end_desc = gtk_label_new(_( | |
1378
27d9eb18c7cf
[svn] - some improvements to song_change, still sucky
nenolod
parents:
1328
diff
changeset
|
229 "Command to run when Audacious reaches the end " |
117 | 230 "of the playlist.")); |
231 gtk_label_set_justify(GTK_LABEL(cmd_end_desc), GTK_JUSTIFY_LEFT); | |
232 gtk_misc_set_alignment(GTK_MISC(cmd_end_desc), 0, 0.5); | |
233 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_end_desc, FALSE, FALSE, 0); | |
234 | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
235 cmd_end_hbox = gtk_hbox_new(FALSE, 6); |
117 | 236 gtk_box_pack_start(GTK_BOX(song_vbox), cmd_end_hbox, FALSE, FALSE, 0); |
237 | |
238 cmd_end_label = gtk_label_new(_("Command:")); | |
239 gtk_box_pack_start(GTK_BOX(cmd_end_hbox), cmd_end_label, FALSE, FALSE, 0); | |
240 | |
241 cmd_end_entry = gtk_entry_new(); | |
242 if (cmd_line_end) | |
243 gtk_entry_set_text(GTK_ENTRY(cmd_end_entry), cmd_line_end); | |
244 gtk_widget_set_usize(cmd_end_entry, 200, -1); | |
245 gtk_box_pack_start(GTK_BOX(cmd_end_hbox), cmd_end_entry, TRUE, TRUE, 0); | |
246 sep3 = gtk_hseparator_new(); | |
247 gtk_box_pack_start(GTK_BOX(song_vbox), sep3, TRUE, TRUE, 0); | |
248 | |
249 temp = g_strdup_printf( | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
250 _("You can use the following format strings which\n" |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
251 "will be substituted before calling the command\n" |
117 | 252 "(not all are useful for the end-of-playlist command).\n\n" |
253 "%%F: Frequency (in hertz)\n" | |
254 "%%c: Number of channels\n" | |
255 "%%f: filename (full path)\n" | |
256 "%%l: length (in milliseconds)\n" | |
257 "%%n or %%s: Song name\n" | |
258 "%%r: Rate (in bits per second)\n" | |
259 "%%t: Playlist position (%%02d)\n" | |
260 "%%p: Currently playing (1 or 0)")); | |
261 f_desc = gtk_label_new(temp); | |
262 g_free(temp); | |
263 | |
264 gtk_label_set_justify(GTK_LABEL(f_desc), GTK_JUSTIFY_LEFT); | |
265 gtk_misc_set_alignment(GTK_MISC(f_desc), 0, 0.5); | |
266 gtk_box_pack_start(GTK_BOX(song_vbox), f_desc, FALSE, FALSE, 0); | |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
267 |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
268 bbox_hbox = gtk_hbox_new(FALSE, 6); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
269 gtk_box_pack_start(GTK_BOX(configure_vbox), bbox_hbox, FALSE, FALSE, 0); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
270 |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
271 cmd_warn_img = gtk_image_new_from_stock("gtk-dialog-warning", GTK_ICON_SIZE_MENU); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
272 gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_img, FALSE, FALSE, 0); |
117 | 273 |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
274 temp = g_strdup_printf( |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
275 _("<span size='small'>Parameters passed to the shell should be encapsulated in quotes. Doing otherwise is a security risk.</span>")); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
276 cmd_warn_label = gtk_label_new(temp); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
277 gtk_label_set_markup(GTK_LABEL(cmd_warn_label), temp); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
278 gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_label, FALSE, FALSE, 0); |
117 | 279 |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
280 g_signal_connect(GTK_OBJECT(cmd_entry), "changed", GTK_SIGNAL_FUNC(configure_ok_cb), NULL); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
281 g_signal_connect(GTK_OBJECT(cmd_after_entry), "changed", GTK_SIGNAL_FUNC(configure_ok_cb), NULL); |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
282 g_signal_connect(GTK_OBJECT(cmd_end_entry), "changed", GTK_SIGNAL_FUNC(configure_ok_cb), NULL); |
117 | 283 |
1221 | 284 gtk_widget_show_all(configure_vbox); |
285 | |
286 return configure_vbox; | |
287 } | |
117 | 288 |
1221 | 289 static void init(void) |
290 { | |
291 read_config(); | |
292 | |
293 previous_song = -1; | |
294 timeout_tag = gtk_timeout_add(100, timeout_func, NULL); | |
295 | |
296 configure_vbox = configure(); | |
1390 | 297 prefswin_page_new(configure_vbox, "Song Change", DATA_DIR "/images/plugins.png"); |
1385
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
298 |
3e44e4df1e35
[svn] - vast improvements to the songchange plugin
nenolod
parents:
1378
diff
changeset
|
299 configure_ok_cb(NULL, NULL); |
117 | 300 } |
301 | |
1221 | 302 |
117 | 303 static void bury_child(int signal) |
304 { | |
305 waitpid(-1, NULL, WNOHANG); | |
306 } | |
307 | |
308 static void execute_command(char *cmd) | |
309 { | |
310 char *argv[4] = {"/bin/sh", "-c", NULL, NULL}; | |
311 int i; | |
312 argv[2] = cmd; | |
313 signal(SIGCHLD, bury_child); | |
314 if (fork() == 0) | |
315 { | |
316 /* We don't want this process to hog the audio device etc */ | |
317 for (i = 3; i < 255; i++) | |
318 close(i); | |
319 execv("/bin/sh", argv); | |
320 } | |
321 } | |
322 | |
323 /* | |
324 * escape_shell_chars() | |
325 * | |
326 * Escapes characters that are special to the shell inside double quotes. | |
327 */ | |
328 | |
329 static char* escape_shell_chars(const char *string) | |
330 { | |
331 const char *special = "$`\"\\"; /* Characters to escape */ | |
332 const char *in = string; | |
333 char *out; | |
334 char *escaped; | |
335 int num = 0; | |
336 | |
337 while (*in != '\0') | |
338 if (strchr(special, *in++)) | |
339 num++; | |
340 | |
341 escaped = g_malloc(strlen(string) + num + 1); | |
342 | |
343 in = string; | |
344 out = escaped; | |
345 | |
346 while (*in != '\0') | |
347 { | |
348 if (strchr(special, *in)) | |
349 *out++ = '\\'; | |
350 *out++ = *in++; | |
351 } | |
352 *out = '\0'; | |
353 | |
354 return escaped; | |
355 } | |
356 | |
357 | |
358 | |
359 /* Format codes: | |
360 * | |
361 * F - frequency (in hertz) | |
362 * c - number of channels | |
363 * f - filename (full path) | |
364 * l - length (in milliseconds) | |
365 * n - name | |
366 * r - rate (in bits per second) | |
367 * s - name (since everyone's used to it) | |
368 * t - playlist position (%02d) | |
369 * p - currently playing (1 or 0) | |
370 */ | |
371 /* do_command(): do @cmd after replacing the format codes | |
372 @cmd: command to run | |
373 @current_file: file name of current song | |
374 @pos: playlist_pos */ | |
375 void do_command(char *cmd, const char *current_file, int pos) | |
376 { | |
377 int length, rate, freq, nch; | |
378 char *str, *shstring = NULL, *temp, numbuf[16]; | |
379 gboolean playing; | |
380 Formatter *formatter; | |
381 | |
382 if (cmd && strlen(cmd) > 0) | |
383 { | |
384 formatter = xmms_formatter_new(); | |
385 str = xmms_remote_get_playlist_title(sc_gp.xmms_session, pos); | |
386 if (str) | |
387 { | |
388 temp = escape_shell_chars(str); | |
389 xmms_formatter_associate(formatter, 's', temp); | |
390 xmms_formatter_associate(formatter, 'n', temp); | |
391 g_free(str); | |
392 g_free(temp); | |
393 } | |
394 else | |
395 { | |
396 xmms_formatter_associate(formatter, 's', ""); | |
397 xmms_formatter_associate(formatter, 'n', ""); | |
398 } | |
399 | |
400 if (current_file) | |
401 { | |
402 temp = escape_shell_chars(current_file); | |
403 xmms_formatter_associate(formatter, 'f', temp); | |
404 g_free(temp); | |
405 } | |
406 else | |
407 xmms_formatter_associate(formatter, 'f', ""); | |
408 sprintf(numbuf, "%02d", pos + 1); | |
409 xmms_formatter_associate(formatter, 't', numbuf); | |
410 length = xmms_remote_get_playlist_time(sc_gp.xmms_session, pos); | |
411 if (length != -1) | |
412 { | |
413 sprintf(numbuf, "%d", length); | |
414 xmms_formatter_associate(formatter, 'l', numbuf); | |
415 } | |
416 else | |
417 xmms_formatter_associate(formatter, 'l', "0"); | |
418 xmms_remote_get_info(sc_gp.xmms_session, &rate, &freq, &nch); | |
419 sprintf(numbuf, "%d", rate); | |
420 xmms_formatter_associate(formatter, 'r', numbuf); | |
421 sprintf(numbuf, "%d", freq); | |
422 xmms_formatter_associate(formatter, 'F', numbuf); | |
423 sprintf(numbuf, "%d", nch); | |
424 xmms_formatter_associate(formatter, 'c', numbuf); | |
425 playing = xmms_remote_is_playing(sc_gp.xmms_session); | |
426 sprintf(numbuf, "%d", playing); | |
427 xmms_formatter_associate(formatter, 'p', numbuf); | |
428 shstring = xmms_formatter_format(formatter, cmd); | |
429 xmms_formatter_destroy(formatter); | |
430 | |
431 if (shstring) | |
432 { | |
433 execute_command(shstring); | |
434 /* FIXME: This can possibly be freed too early */ | |
435 g_free(shstring); | |
436 } | |
437 } | |
438 } | |
439 | |
440 | |
441 static int timeout_func(gpointer data) | |
442 { | |
443 int pos; | |
444 gboolean playing; | |
445 static char *previous_file = NULL; | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
446 static char *previous_track = NULL; |
117 | 447 static gboolean cmd_after_already_run = FALSE; |
448 char *current_file; | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
449 char *current_track; |
117 | 450 |
451 GDK_THREADS_ENTER(); | |
452 | |
453 playing = xmms_remote_is_playing(sc_gp.xmms_session); | |
454 pos = xmms_remote_get_playlist_pos(sc_gp.xmms_session); | |
455 current_file = xmms_remote_get_playlist_file(sc_gp.xmms_session, pos); | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
456 current_track = xmms_remote_get_playlist_title(sc_gp.xmms_session, pos); |
117 | 457 |
458 if ((pos != previous_song || | |
459 (!previous_file && current_file) || | |
460 (previous_file && !current_file) || | |
461 (previous_file && current_file && | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
462 strcmp(previous_file, current_file)) || |
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
463 (!previous_track && current_track) || |
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
464 (previous_track && !current_track) || |
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
465 (previous_track && current_track && |
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
466 strcmp(previous_track, current_track))) && |
117 | 467 xmms_remote_get_output_time(sc_gp.xmms_session) > 0) |
468 { | |
469 do_command(cmd_line, current_file, pos); | |
470 g_free(previous_file); | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
471 g_free(previous_track); |
117 | 472 previous_file = g_strdup(current_file); |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
473 previous_track = g_strdup(current_track); |
117 | 474 previous_song = pos; |
475 cmd_after_already_run = FALSE; | |
476 } | |
477 if (!cmd_after_already_run && | |
478 ((xmms_remote_get_playlist_time(sc_gp.xmms_session,pos) - | |
479 xmms_remote_get_output_time(sc_gp.xmms_session)) < 100)) | |
480 { | |
481 do_command(cmd_line_after, current_file, pos); | |
482 cmd_after_already_run = TRUE; | |
483 } | |
484 | |
485 if (playing) | |
486 { | |
487 int playlist_length = xmms_remote_get_playlist_length(sc_gp.xmms_session); | |
488 if (pos + 1 == playlist_length) | |
489 possible_pl_end = TRUE; | |
490 else | |
491 possible_pl_end = FALSE; | |
492 } | |
493 else if (possible_pl_end) | |
494 { | |
495 if (pos == 0) | |
496 do_command(cmd_line_end, current_file, pos); | |
497 possible_pl_end = FALSE; | |
498 g_free(previous_file); | |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
499 g_free(previous_track); |
117 | 500 previous_file = NULL; |
859
df6712e1959d
[svn] - Also determine a change by track name, patch by nixphoeni.
nenolod
parents:
751
diff
changeset
|
501 previous_track = NULL; |
117 | 502 } |
503 | |
504 g_free(current_file); | |
505 current_file = NULL; | |
506 | |
507 GDK_THREADS_LEAVE(); | |
508 | |
509 return TRUE; | |
510 } |