wmclockmon: update change-log
[dockapps.git] / wmmp3 / mpg123ctl.c
bloba4b457b339021e662473068c3cb993b91868024b
1 /*
2 * wmmp3
3 * Copyright (c)1999 Patrick Crosby <xb@dotfiles.com>.
4 * This software covered by the GPL. See COPYING file for details.
6 * mpg123ctl.c
8 * This file contains all the functions for controlling the
9 * mpg123 backend processes.
11 * Random play functionality courtesy of:
12 * Matthew D. Campbell <matt@campbellhome.dhs.org>
14 * $Id: mpg123ctl.c,v 1.15 1999/10/12 04:41:20 pcrosby Exp $
17 #include <time.h>
18 #include <ctype.h>
19 #include "mpg123ctl.h"
21 #define MAXDIRS 100
22 #define MAX_TITLE_LEN 9
24 void set_playlist();
25 void signal_play();
26 void play();
27 void play_next();
28 void play_prev();
29 void init_ctl();
30 void push_dir(char *s);
31 void push_dirname(char *s);
32 char *pop_dir();
33 char *next_mp3dir();
34 char *prev_mp3dir();
35 char *current_mp3dir();
36 void show_directory_name();
37 void load_next_dir();
38 void load_prev_dir();
39 void alarmhandler(int sig);
40 void scroll_title();
41 void finish();
42 void dostuff();
44 char *dirs[MAXDIRS];
45 int top = 0;
46 int max_dirs = 0;
47 int current_dir = 0;
49 char *dirnames[MAXDIRS];
50 int ntop = 0;
51 int nmax_dirs = 0;
53 char mpg123_cmd[512];
54 char mp3ext[12];
55 char playlistext[12];
57 int next_song = 0;
58 int num_songs = 0;
59 int play_pid = 0;
61 char title[512];
62 int scroll_pos = 0;
63 int do_scroll = 0;
64 int always_scroll = 0;
66 int repeat_flag = 0;
67 int random_flag = 0;
68 int *rand_song_num = NULL;
70 int is_playing()
72 if (play_pid > 0)
73 return 1;
74 else
75 return 0;
79 * patch received from Steven Jorgensen to fix following function
82 void set_playlist()
84 char *directory;
85 DIR *dp;
86 struct dirent *entry;
87 char filename[512];
89 int i, tempnum, temppos;
91 directory = (char *) current_mp3dir();
93 if (directory)
95 dp = opendir(directory);
96 if (dp == NULL) {
97 char *new_directory;
98 new_directory = (char *) next_mp3dir();
99 dp = opendir(new_directory);
100 while (new_directory && (strcmp(new_directory, directory) != 0) &&
101 (dp == NULL)) {
102 strcpy(directory, new_directory);
103 new_directory = (char *) next_mp3dir();
104 dp = opendir(new_directory);
106 if (new_directory)
107 strcpy(directory, new_directory);
109 if (dp != NULL) {
110 show_directory_name();
111 num_songs = 0;
112 empty_hash();
113 entry = readdir(dp);
114 while (entry != NULL) {
115 if (strstr(entry->d_name, mp3ext)) {
116 sprintf(filename, "%s/%s", directory, entry->d_name);
117 insert_song(num_songs, entry->d_name, filename);
118 num_songs++;
120 entry = readdir(dp);
122 next_song = 0;
124 /* Create Pseudo-random permutation of list */
125 srand(time(NULL));
126 rand_song_num = (int *)malloc(sizeof(int)*num_songs);
127 if (!rand_song_num) {
128 /* This shouldn't happen - the list isn't that big */
129 fprintf(stderr,
130 "Error: cannot allocate randomized list\n");
131 exit(1);
133 for (i=0; i<num_songs; i++) rand_song_num[i] = i;
134 for (i=0; i<num_songs; i++) {
135 tempnum = rand_song_num[i];
136 temppos = rand()%num_songs;
137 rand_song_num[i] = rand_song_num[temppos];
138 rand_song_num[temppos] = tempnum;
146 * functions that actually control mpg123
149 void signal_play()
151 int status;
153 waitpid(play_pid, &status, 0);
154 play_pid = 0;
155 play_next();
158 void play(char *song_name)
160 if ((play_pid = fork()) == 0) {
161 execl(mpg123_cmd, mpg123_cmd, "-q",
162 song_name, 0);
163 _exit(1);
167 void play_next()
169 struct hash_elt *song;
171 if (next_song >= num_songs) {
172 if (repeat_flag == 0) {
173 load_next_dir();
174 } else {
175 next_song = 0;
178 song = get_song(next_song);
179 if (random_flag) {
180 song = get_song(rand_song_num[next_song]);
182 if (song) {
183 strcpy(title, song->title);
184 strcat(title, " ");
185 scroll_pos = 0;
186 do_scroll = 1;
187 scroll_title();
189 play(song->filename);
190 next_song++;
191 signal(SIGCHLD, signal_play);
192 signal(SIGALRM, alarmhandler);
193 alarm(1);
197 void play_prev()
199 struct hash_elt *song;
201 if (next_song <= 1) {
202 next_song = 0;
204 else {
205 next_song = next_song - 2;
208 play_next();
211 void user_play()
213 if (play_pid == 0) {
214 signal(SIGCHLD, signal_play);
215 set_playlist();
216 play_next();
220 void stop()
222 int status;
224 if (play_pid > 0) {
225 signal(SIGCHLD, SIG_IGN);
226 kill(play_pid, SIGINT);
227 kill(play_pid, SIGTERM);
228 kill(play_pid, SIGKILL);
229 waitpid(play_pid, &status, 0);
230 play_pid = 0;
234 void next()
236 stop();
237 play_next();
240 void back()
242 stop();
243 play_prev();
247 * initialization functions
250 void init_ctl()
252 signal(SIGINT, finish);
253 signal(SIGCHLD, dostuff);
254 set_playlist();
257 void set_mpg123(char *s)
260 strcpy(mpg123_cmd, s);
263 void set_mp3ext(char *s)
265 strcpy(mp3ext, s);
268 void set_playlistext(char *s)
270 strcpy(playlistext, s);
273 void set_alwaysscroll(char *s) {
274 char *temp = s;
275 while (*temp) {
276 *temp = tolower(*temp);
277 temp++;
279 if ( !strcmp(s, "on") || !strcmp(s, "yes") || !strcmp(s, "1") ||
280 !strcmp(s, "true")) {
281 always_scroll = 1;
282 } else {
283 always_scroll = 0;
288 void push_dir(char *s)
290 dirs[top] = (char *) malloc(strlen(s) + 1);
291 strcpy(dirs[top], s);
292 top++;
293 max_dirs++;
296 void push_dirname(char *s)
298 /* from Steven Jorgensen */
299 if ((strlen(s) + 1) < 10)
300 dirnames[ntop] = (char *) malloc(10);
301 else
302 dirnames[ntop] = (char *) malloc(strlen(s) + 1);
303 strcpy(dirnames[ntop], s);
304 ntop++;
305 nmax_dirs++;
308 char *pop_dir()
310 max_dirs--;
311 return (dirs[top--]);
314 void add_mp3dir(char *s)
316 push_dir(s);
319 void add_mp3dirname(char *s)
321 push_dirname(s);
325 * directory manipulation
328 char *next_mp3dir()
330 if (current_dir < (max_dirs - 1)) {
331 current_dir++;
333 return (dirs[current_dir]);
336 char *prev_mp3dir()
338 if (current_dir > 0) {
339 current_dir--;
341 return (dirs[current_dir]);
344 char *current_mp3dir()
346 return (dirs[current_dir]);
349 void show_directory_name()
351 if (dirnames[current_dir] != NULL) {
352 while (strlen(dirnames[current_dir]) < 9) {
353 strcat(dirnames[current_dir], " ");
355 draw_string(dirnames[current_dir], 5, 5);
356 } else {
357 draw_string("no dirname", 5, 5);
361 void dir_up(int button_num)
363 if (!is_playing()) {
364 button_down(button_num);
365 load_prev_dir();
369 void dir_down(int button_num)
371 if (!is_playing()) {
372 button_down(button_num);
373 load_next_dir();
377 void load_next_dir()
379 next_mp3dir();
380 set_playlist();
383 void load_prev_dir()
385 prev_mp3dir();
386 set_playlist();
390 * song title functions
393 void alarmhandler(int sig)
395 if ((play_pid > 0) && (do_scroll == 1)) {
396 scroll_title();
397 signal(SIGALRM, alarmhandler);
398 alarm(1);
402 void scroll_title()
404 char s[MAX_TITLE_LEN + 1];
405 int i;
406 int title_len;
408 title_len = strlen(title);
409 if (do_scroll) {
410 for (i = 0; i < MAX_TITLE_LEN; i++) {
411 s[i] = title[(i + scroll_pos) % title_len];
413 s[i] = '\0';
414 draw_string(s, 5, 19);
415 scroll_pos++;
416 if (scroll_pos > title_len) {
417 scroll_pos = 0;
418 if (!always_scroll) {
419 do_scroll = 0;
422 } else {
423 draw_string(title, 5, 19);
425 RedrawWindow();
428 void turn_on_scroll()
430 if ((!do_scroll) && (is_playing())) {
431 do_scroll = 1;
432 scroll_pos = 0;
433 signal(SIGALRM, alarmhandler);
434 alarm(1);
439 * toggles
442 void random_toggle(int button_num)
444 /* button_gray(button_num); */
445 if (random_flag == 0) {
446 button_down(button_num);
447 random_flag = 1;
448 } else {
449 button_up(button_num);
450 random_flag = 0;
454 void repeat_toggle(int button_num)
456 if (repeat_flag == 0) {
457 button_down(button_num);
458 repeat_flag = 1;
459 } else {
460 button_up(button_num);
461 repeat_flag = 0;
466 * cleanup
469 void finish()
471 stop();
475 * misc
477 void dostuff()
479 /* empty */