Mercurial > audlegacy-plugins
annotate src/alarm/alarm.c @ 2284:d19b53359b24
cleaned up the sndfile wav plugin, currently limiting it ONLY TO WAV
PLAYBACK. if somebody is more experienced with it and wants to restore
the other formats, go ahead (maybe change the name of the plugin too?).
author | mf0102 <0102@gmx.at> |
---|---|
date | Wed, 09 Jan 2008 15:41:22 +0100 |
parents | cf20f1bd2f1e |
children | 4d6045c20cc5 |
rev | line source |
---|---|
121 | 1 /* |
2 * Copyright (C) Adam Feakin <adamf@snika.uklinux.net> | |
3 * | |
4 * modified by Daniel Stodden <stodden@in.tum.de> | |
5 * | |
6 * This program is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License | |
8 * as published by the Free Software Foundation; either version 2 | |
9 * of the License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 */ | |
20 | |
21 /* | |
22 * xmms-alarm.c - a XMMS plugin which allows you to set a time for it to | |
23 * start playing a playlist with the volume fading up and more things | |
24 * the next time I get bored | |
25 */ | |
26 | |
27 /* this file really should get split/cleaned up sometime ;) */ | |
28 #include "config.h" | |
29 | |
30 #if STDC_HEADERS | |
31 # include <stdlib.h> | |
32 #endif | |
33 | |
34 #include <time.h> | |
35 #if TM_IN_SYS_TIME | |
36 # include <sys/time.h> | |
37 #endif | |
38 | |
39 #include <string.h> | |
40 #include <stdio.h> | |
41 #include <audacious/plugin.h> | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
42 #include <audacious/auddrct.h> |
121 | 43 #include <audacious/configdb.h> |
44 #include <gdk/gdk.h> | |
45 #include <gtk/gtk.h> | |
46 #include <pthread.h> | |
47 #include <assert.h> | |
48 #include <math.h> | |
49 | |
50 #include "alarm.h" | |
51 #include "interface.h" | |
52 #include "callbacks.h" | |
53 | |
54 static pthread_t start_tid; /* thread id of alarm loop */ | |
55 static pthread_t stop_tid; /* thread id of stop loop */ | |
56 static pthread_mutex_t fader_lock = PTHREAD_MUTEX_INITIALIZER; | |
57 | |
58 static GeneralPlugin alarm_plugin; | |
59 | |
60 /* string tokens to allow loops and shorten code */ | |
61 static char day_cb[7][7] = {"sun_cb", "mon_cb", "tue_cb", | |
62 "wed_cb", "thu_cb", "fri_cb", "sat_cb"}; | |
63 | |
64 static char day_flags[7][10] = {"sun_flags", "mon_flags", "tue_flags", | |
65 "wed_flags", "thu_flags", "fri_flags", "sat_flags"}; | |
66 | |
67 static char day_h[7][6] = {"sun_h", "mon_h", "tue_h", | |
68 "wed_h", "thu_h", "fri_h", "sat_h"}; | |
69 | |
70 static char day_m[7][6] = {"sun_m", "mon_m", "tue_m", | |
71 "wed_m", "thu_m", "fri_m", "sat_m"}; | |
72 | |
73 static char day_def[7][8] = {"sun_def", "mon_def", "tue_def", | |
74 "wed_def", "thu_def", "fri_def", "sat_def"}; | |
75 | |
76 static struct | |
77 { | |
78 GtkSpinButton *alarm_h; | |
79 GtkSpinButton *alarm_m; | |
80 | |
81 GtkToggleButton *stop_on; | |
82 GtkSpinButton *stop_h; | |
83 GtkSpinButton *stop_m; | |
84 | |
85 GtkRange *volume; | |
86 GtkRange *quietvol; | |
87 | |
88 GtkSpinButton *fading; | |
89 | |
90 GtkEntry *cmdstr; | |
91 GtkToggleButton *cmd_on; | |
92 | |
93 GtkEntry *playlist; | |
94 | |
95 int default_hour; | |
96 int default_min; | |
97 | |
98 // array allows looping of days | |
99 alarmday day[7]; | |
100 | |
101 | |
102 GtkEntry *reminder; | |
103 GtkToggleButton *reminder_cb; | |
104 gchar *reminder_msg; | |
105 gboolean reminder_on; | |
106 } | |
107 alarm_conf; | |
108 | |
109 static gint alarm_h, alarm_m; | |
110 | |
111 static gboolean stop_on; | |
112 static gint stop_h, stop_m; | |
113 | |
114 static gint volume, quietvol; | |
115 | |
116 static gint fading; | |
117 | |
118 static gchar *cmdstr = NULL; | |
119 static gboolean cmd_on; | |
120 | |
121 static gchar *playlist = NULL; | |
122 | |
123 static GtkWidget *config_dialog = NULL; | |
124 static GtkWidget *alarm_dialog = NULL; | |
125 | |
126 static GtkWidget *lookup_widget(GtkWidget *w, const gchar *name) | |
127 { | |
128 GtkWidget *widget; | |
129 | |
130 widget = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(w), | |
131 name); | |
132 g_return_val_if_fail(widget != NULL, NULL); | |
133 | |
134 return widget; | |
135 } | |
136 | |
137 static void dialog_destroyed(GtkWidget *dialog, gpointer data) | |
138 { | |
139 DEBUG("dialog destroyed\n"); | |
140 *(GtkObject**)data = NULL; | |
141 } | |
142 | |
143 static inline gboolean dialog_visible(GtkWidget *dialog) | |
144 { | |
145 return(((dialog != NULL) && GTK_WIDGET_VISIBLE(dialog))); | |
146 } | |
147 | |
148 /* | |
149 * tell the user about that bug | |
150 */ | |
151 static void alarm_warning(void) | |
152 { | |
153 | |
154 static GtkWidget *warning_dialog = NULL; | |
155 | |
156 if(dialog_visible(warning_dialog)) | |
157 return; | |
158 | |
159 warning_dialog = create_warning_dialog(); | |
160 | |
161 gtk_signal_connect(GTK_OBJECT(warning_dialog), "destroy", | |
162 GTK_SIGNAL_FUNC(dialog_destroyed), &warning_dialog); | |
163 | |
164 gtk_widget_show_all(warning_dialog); | |
165 | |
166 return; | |
167 } | |
168 | |
169 /* | |
170 * the callback function that is called when the save button is | |
171 * pressed saves configuration to ~/.bmp/alarmconfig | |
172 */ | |
173 void alarm_save(GtkButton *w, gpointer data) | |
174 { | |
175 int daynum = 0; // used to identify day number | |
176 ConfigDb *conf; | |
177 | |
178 DEBUG("alarm_save\n"); | |
179 | |
2124 | 180 conf = aud_cfg_db_open(); |
121 | 181 |
182 /* | |
183 * update the live values and write them out | |
184 */ | |
185 alarm_h = alarm_conf.default_hour = | |
186 gtk_spin_button_get_value_as_int(alarm_conf.alarm_h); | |
2124 | 187 aud_cfg_db_set_int(conf, "alarm", "alarm_h", alarm_h); |
121 | 188 |
189 alarm_m = alarm_conf.default_min = | |
190 gtk_spin_button_get_value_as_int(alarm_conf.alarm_m); | |
2124 | 191 aud_cfg_db_set_int(conf, "alarm", "alarm_m", alarm_m); |
121 | 192 |
193 | |
194 stop_h = | |
195 gtk_spin_button_get_value_as_int( alarm_conf.stop_h); | |
196 | |
197 stop_m = | |
198 gtk_spin_button_get_value_as_int(alarm_conf.stop_m); | |
199 | |
200 stop_on = | |
201 gtk_toggle_button_get_active(alarm_conf.stop_on); | |
202 | |
203 /* days of the week */ | |
204 for(; daynum < 7; daynum++) | |
205 { | |
206 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb))) | |
207 alarm_conf.day[daynum].flags = 0; | |
208 else | |
209 alarm_conf.day[daynum].flags = ALARM_OFF; | |
210 | |
211 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def))) | |
212 alarm_conf.day[daynum].flags |= ALARM_DEFAULT; | |
213 | |
214 alarm_conf.day[daynum].hour = | |
215 gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_hr); | |
216 alarm_conf.day[daynum].min = | |
217 gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_min); | |
218 | |
2124 | 219 aud_cfg_db_set_int(conf, "alarm", day_flags[daynum], alarm_conf.day[daynum].flags); |
220 aud_cfg_db_set_int(conf, "alarm", day_h[daynum], alarm_conf.day[daynum].hour); | |
221 aud_cfg_db_set_int(conf, "alarm", day_m[daynum], alarm_conf.day[daynum].min); | |
121 | 222 } |
223 | |
224 /* END: days of week */ | |
225 | |
226 volume = | |
227 gtk_range_get_adjustment(alarm_conf.volume)->value; | |
2124 | 228 aud_cfg_db_set_int(conf, "alarm", "volume", volume); |
121 | 229 |
230 quietvol = | |
231 gtk_range_get_adjustment(alarm_conf.quietvol)->value; | |
2124 | 232 aud_cfg_db_set_int(conf, "alarm", "quietvol", quietvol); |
121 | 233 |
234 fading = | |
235 gtk_spin_button_get_value_as_int(alarm_conf.fading); | |
236 //xmms_cfg_write_int(conf, "alarm", "fading", fading); | |
237 | |
238 /* lets check to see if we need to show the bug warning */ | |
239 if((stop_on == TRUE) && | |
240 ((((stop_h * 60) + stop_m) * 60) < (fading + 65))) | |
241 { | |
242 DEBUG("Displaying bug warning, stop %dh %dm, fade %d\n", | |
243 stop_h, stop_m, fading); | |
244 alarm_warning(); | |
245 } | |
246 else if((stop_on == TRUE) && (fading < 10)) | |
247 { | |
248 DEBUG("Displaying bug warning, stop %dh %dm, fade %d\n", | |
249 stop_h, stop_m, fading); | |
250 alarm_warning(); | |
251 } | |
252 else | |
253 { | |
254 /* write the new values */ | |
2124 | 255 aud_cfg_db_set_int(conf, "alarm", "stop_h", stop_h); |
256 aud_cfg_db_set_int(conf, "alarm", "stop_m", stop_m); | |
257 aud_cfg_db_set_int(conf, "alarm", "fading", fading); | |
258 aud_cfg_db_set_bool(conf, "alarm", "stop_on", stop_on); | |
121 | 259 } |
260 | |
261 | |
262 g_free(cmdstr); | |
263 cmdstr = gtk_editable_get_chars(GTK_EDITABLE(alarm_conf.cmdstr), | |
264 0, -1); | |
2124 | 265 aud_cfg_db_set_string(conf, "alarm", "cmdstr", cmdstr); |
121 | 266 |
267 cmd_on = | |
268 gtk_toggle_button_get_active(alarm_conf.cmd_on); | |
2124 | 269 aud_cfg_db_set_bool(conf, "alarm", "cmd_on", cmd_on); |
121 | 270 |
271 g_free(playlist); | |
272 playlist = gtk_editable_get_chars(GTK_EDITABLE(alarm_conf.playlist), | |
273 0, -1); | |
2124 | 274 aud_cfg_db_set_string(conf, "alarm", "playlist", playlist); |
121 | 275 |
276 /* reminder */ | |
277 g_free(alarm_conf.reminder_msg); | |
278 alarm_conf.reminder_msg = gtk_editable_get_chars(GTK_EDITABLE(alarm_conf.reminder), | |
279 0, -1); | |
2124 | 280 aud_cfg_db_set_string(conf, "alarm", "reminder_msg", alarm_conf.reminder_msg); |
121 | 281 |
282 alarm_conf.reminder_on = | |
283 gtk_toggle_button_get_active(alarm_conf.reminder_cb); | |
2124 | 284 aud_cfg_db_set_bool(conf, "alarm", "reminder_on", alarm_conf.reminder_on); |
121 | 285 |
2124 | 286 aud_cfg_db_close(conf); |
121 | 287 } |
288 | |
289 /* | |
290 * read the current configuration from the file | |
291 */ | |
292 static void alarm_read_config() | |
293 { | |
294 int daynum = 0; // used for day number | |
295 ConfigDb *conf; | |
296 | |
297 DEBUG("alarm_read_config\n"); | |
298 | |
2124 | 299 conf = aud_cfg_db_open(); |
121 | 300 |
2124 | 301 if(!aud_cfg_db_get_int(conf, "alarm", "alarm_h", &alarm_h)) |
121 | 302 alarm_h = DEFAULT_ALARM_HOUR; |
2124 | 303 if(!aud_cfg_db_get_int(conf, "alarm", "alarm_m", &alarm_m)) |
121 | 304 alarm_m = DEFAULT_ALARM_MIN; |
305 | |
306 /* save them here too */ | |
307 alarm_conf.default_hour = alarm_h; | |
308 alarm_conf.default_min = alarm_m; | |
309 | |
2124 | 310 if(!aud_cfg_db_get_int( conf, "alarm", "stop_h", &stop_h)) |
121 | 311 stop_h = DEFAULT_STOP_HOURS; |
2124 | 312 if(!aud_cfg_db_get_int( conf, "alarm", "stop_m", &stop_m)) |
121 | 313 stop_m = DEFAULT_STOP_MINS; |
2124 | 314 if(!aud_cfg_db_get_bool(conf, "alarm", "stop_on", &stop_on)) |
121 | 315 stop_on = TRUE; |
316 | |
2124 | 317 if(!aud_cfg_db_get_int(conf, "alarm", "volume", &volume)) |
121 | 318 volume = DEFAULT_VOLUME; |
2124 | 319 if(!aud_cfg_db_get_int(conf, "alarm", "quietvol", &quietvol)) |
121 | 320 quietvol = DEFAULT_QUIET_VOL; |
321 | |
2124 | 322 if(!aud_cfg_db_get_int(conf, "alarm", "fading", &fading)) |
121 | 323 fading = DEFAULT_FADING; |
324 | |
2124 | 325 if(!aud_cfg_db_get_string(conf, "alarm", "cmdstr", &cmdstr)) |
121 | 326 cmdstr = g_strdup(""); |
2124 | 327 if(!aud_cfg_db_get_bool(conf, "alarm", "cmd_on", &cmd_on)) |
121 | 328 cmd_on = FALSE; |
329 | |
2124 | 330 if(!aud_cfg_db_get_string(conf, "alarm", "playlist", &playlist)) |
121 | 331 playlist = g_strdup(""); |
332 | |
2124 | 333 if(!aud_cfg_db_get_string(conf, "alarm", "reminder_msg", &alarm_conf.reminder_msg)) |
121 | 334 alarm_conf.reminder_msg = g_strdup(""); |
2124 | 335 if(!aud_cfg_db_get_bool(conf, "alarm", "reminder_on", &alarm_conf.reminder_on)) |
121 | 336 alarm_conf.reminder_on = FALSE; |
337 | |
338 /* day flags and times */ | |
339 for(; daynum < 7; daynum++) | |
340 { | |
341 /* read the flags */ | |
2124 | 342 if(!aud_cfg_db_get_int(conf, "alarm", day_flags[daynum], &alarm_conf.day[daynum].flags)) { |
121 | 343 // only turn alarm off by default on a sunday |
344 if(daynum != 0) | |
345 alarm_conf.day[daynum].flags = DEFAULT_FLAGS; | |
346 else | |
347 alarm_conf.day[daynum].flags = DEFAULT_FLAGS | ALARM_OFF; | |
348 } | |
349 | |
350 /* read the times */ | |
2124 | 351 if(!aud_cfg_db_get_int(conf, "alarm", day_h[daynum], &alarm_conf.day[daynum].hour)) |
121 | 352 alarm_conf.day[daynum].hour = DEFAULT_ALARM_HOUR; |
353 | |
2124 | 354 if(!aud_cfg_db_get_int(conf, "alarm", day_m[daynum], &alarm_conf.day[daynum].min)) |
121 | 355 alarm_conf.day[daynum].min = DEFAULT_ALARM_MIN; |
356 } | |
357 | |
358 DEBUG("END alarm_read_config\n"); | |
359 } | |
360 | |
361 /* | |
362 * display an about box | |
363 */ | |
364 static void alarm_about() | |
365 { | |
366 static GtkWidget *about_dialog = NULL; | |
367 | |
368 DEBUG("alarm_about\n"); | |
369 | |
370 if(dialog_visible(about_dialog)) | |
371 return; | |
372 | |
373 about_dialog = create_about_dialog(); | |
374 | |
375 gtk_signal_connect(GTK_OBJECT(about_dialog), "destroy", | |
376 GTK_SIGNAL_FUNC(dialog_destroyed), &about_dialog); | |
377 | |
378 gtk_widget_show_all(about_dialog); | |
379 | |
380 return; | |
381 } | |
382 | |
383 /* | |
384 * create a playlist file selection dialog | |
385 */ | |
386 static void alarm_playlist_browse(GtkButton *button, gpointer data) | |
387 { | |
388 GtkWidget *fs; | |
389 gchar *dirname, *path; | |
390 | |
391 dirname = g_dirname(playlist); | |
392 DEBUG("dirname = %s\n", dirname); | |
393 path = g_strdup_printf("%s/", dirname); | |
394 DEBUG("path = %s\n", path); | |
395 g_free(dirname); | |
396 | |
397 fs = create_playlist_fileselection(); | |
398 | |
399 gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), path); | |
400 g_free(path); | |
401 | |
402 gtk_widget_show_all(fs); | |
403 } | |
404 | |
405 /* | |
406 * save selected playlist to the corresponding text entry | |
407 */ | |
408 void alarm_store_playlistname(GtkButton *button, gpointer data) | |
409 { | |
410 GtkFileSelection *fs = GTK_FILE_SELECTION(data); | |
411 gchar *plist; | |
412 | |
413 DEBUG("alarm_store_playlistname\n"); | |
414 | |
132
26a5aef73955
[svn] Fixes compiler warnings that "Joker" was talking about in #audacious.
asheldon
parents:
129
diff
changeset
|
415 plist = g_strdup(gtk_file_selection_get_filename(fs)); |
121 | 416 |
417 gtk_entry_set_text(alarm_conf.playlist, plist); | |
132
26a5aef73955
[svn] Fixes compiler warnings that "Joker" was talking about in #audacious.
asheldon
parents:
129
diff
changeset
|
418 g_free(plist); |
121 | 419 } |
420 | |
421 /* | |
422 * displays the configuration window and opens the config file. | |
423 */ | |
424 static void alarm_configure(void) | |
425 { | |
426 int daynum = 0; // used to loop days | |
427 GtkWidget *w; | |
428 | |
429 DEBUG("alarm_configure\n"); | |
430 | |
431 /* | |
432 * dont want to show more than one config window | |
433 */ | |
434 if(dialog_visible(config_dialog)) | |
435 return; | |
436 | |
437 alarm_read_config(); | |
438 | |
439 /* | |
440 * Create the widgets | |
441 */ | |
442 config_dialog = create_config_dialog(); | |
443 | |
444 w = lookup_widget(config_dialog, "alarm_h_spin"); | |
445 alarm_conf.alarm_h = GTK_SPIN_BUTTON(w); | |
446 gtk_spin_button_set_value(alarm_conf.alarm_h, alarm_h); | |
447 | |
448 w = lookup_widget(config_dialog, "alarm_m_spin"); | |
449 alarm_conf.alarm_m = GTK_SPIN_BUTTON(w); | |
450 gtk_spin_button_set_value(alarm_conf.alarm_m, alarm_m); | |
451 | |
452 w = lookup_widget(config_dialog, "stop_h_spin"); | |
453 alarm_conf.stop_h = GTK_SPIN_BUTTON(w); | |
454 gtk_spin_button_set_value(alarm_conf.stop_h, stop_h); | |
455 | |
456 w = lookup_widget(config_dialog, "stop_m_spin"); | |
457 alarm_conf.stop_m = GTK_SPIN_BUTTON(w); | |
458 gtk_spin_button_set_value(alarm_conf.stop_m, stop_m); | |
459 | |
460 w = lookup_widget(config_dialog, "stop_checkb"); | |
461 alarm_conf.stop_on = GTK_TOGGLE_BUTTON(w); | |
462 gtk_toggle_button_set_active(alarm_conf.stop_on, stop_on); | |
463 | |
464 w = lookup_widget(config_dialog, "vol_scale"); | |
465 alarm_conf.volume = GTK_RANGE(w); | |
466 gtk_range_set_adjustment(alarm_conf.volume, | |
467 GTK_ADJUSTMENT(gtk_adjustment_new(volume, | |
468 0, | |
469 100, 1, | |
470 5, 0))); | |
471 | |
472 w = lookup_widget(config_dialog, "quiet_vol_scale"); | |
473 alarm_conf.quietvol = GTK_RANGE(w); | |
474 gtk_range_set_adjustment(alarm_conf.quietvol, | |
475 GTK_ADJUSTMENT(gtk_adjustment_new(quietvol, | |
476 0, | |
477 100, 1, | |
478 5, 0))); | |
479 | |
480 /* days of week */ | |
481 for(; daynum < 7; daynum++) | |
482 { | |
483 w = lookup_widget(config_dialog, day_cb[daynum]); | |
484 alarm_conf.day[daynum].cb = GTK_CHECK_BUTTON(w); | |
485 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb), | |
486 !(alarm_conf.day[daynum].flags & ALARM_OFF)); | |
487 | |
488 w = lookup_widget(config_dialog, day_def[daynum]); | |
489 alarm_conf.day[daynum].cb_def = GTK_CHECK_BUTTON(w); | |
490 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def), | |
491 alarm_conf.day[daynum].flags & ALARM_DEFAULT); | |
492 | |
493 | |
494 /* Changed to show default time instead of set time when ALARM_DEFAULT set, | |
495 * as suggested by Mark Brown | |
496 */ | |
497 /* w = lookup_widget(config_dialog, day_h[daynum]); | |
498 alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w); | |
499 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour); | |
500 | |
501 w = lookup_widget(config_dialog, day_m[daynum]); | |
502 alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w); | |
503 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min); | |
504 */ | |
505 if(alarm_conf.day[daynum].flags & ALARM_DEFAULT) | |
506 { | |
507 w = lookup_widget(config_dialog, day_h[daynum]); | |
508 alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w); | |
509 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.default_hour); | |
510 | |
511 w = lookup_widget(config_dialog, day_m[daynum]); | |
512 alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w); | |
513 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.default_min); | |
514 | |
515 gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, FALSE); | |
516 gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, FALSE); | |
517 } | |
518 else | |
519 { | |
520 w = lookup_widget(config_dialog, day_h[daynum]); | |
521 alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w); | |
522 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour); | |
523 | |
524 w = lookup_widget(config_dialog, day_m[daynum]); | |
525 alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w); | |
526 gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min); | |
527 | |
528 gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, TRUE); | |
529 gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, TRUE); | |
530 } | |
531 } | |
532 | |
533 /* END: days of week */ | |
534 | |
535 w = lookup_widget(config_dialog,"fading_spin"); | |
536 alarm_conf.fading = GTK_SPIN_BUTTON(w); | |
537 gtk_spin_button_set_value(alarm_conf.fading, fading); | |
538 | |
539 w = lookup_widget(config_dialog, "cmd_entry"); | |
540 alarm_conf.cmdstr = GTK_ENTRY(w); | |
541 gtk_entry_set_text(alarm_conf.cmdstr, cmdstr); | |
542 | |
543 w = lookup_widget(config_dialog, "cmd_checkb"); | |
544 alarm_conf.cmd_on = GTK_TOGGLE_BUTTON(w); | |
545 gtk_toggle_button_set_active(alarm_conf.cmd_on, cmd_on); | |
546 | |
547 w = lookup_widget(config_dialog, "playlist"); | |
548 alarm_conf.playlist = GTK_ENTRY(w); | |
549 gtk_entry_set_text(alarm_conf.playlist, playlist); | |
550 | |
551 w = lookup_widget(config_dialog, "reminder_text"); | |
552 alarm_conf.reminder = GTK_ENTRY(w); | |
553 gtk_entry_set_text(alarm_conf.reminder, alarm_conf.reminder_msg); | |
554 | |
555 w = lookup_widget(config_dialog, "reminder_cb"); | |
556 alarm_conf.reminder_cb = GTK_TOGGLE_BUTTON(w); | |
557 gtk_toggle_button_set_active(alarm_conf.reminder_cb, alarm_conf.reminder_on); | |
558 | |
559 w = lookup_widget(config_dialog, "playlist_browse_button"); | |
560 gtk_signal_connect(GTK_OBJECT(w), "clicked", | |
561 GTK_SIGNAL_FUNC(alarm_playlist_browse), NULL); | |
562 | |
563 gtk_signal_connect(GTK_OBJECT(config_dialog), "destroy", | |
564 GTK_SIGNAL_FUNC(dialog_destroyed), &config_dialog); | |
565 | |
566 gtk_widget_show_all(config_dialog); | |
567 | |
568 DEBUG("END alarm_configure\n"); | |
569 } | |
570 | |
571 /* functions for greying out the time for days */ | |
572 void on_day_def_toggled(GtkToggleButton *togglebutton, gpointer user_data, int daynum) | |
573 { | |
574 GtkWidget *w; | |
575 | |
576 /* change the time shown too */ | |
577 w = lookup_widget(config_dialog, day_h[daynum]); | |
578 if(w == NULL) | |
579 return; | |
580 | |
581 if(gtk_toggle_button_get_active(togglebutton) == TRUE) | |
582 { | |
583 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_hour); | |
584 gtk_widget_set_sensitive(w, FALSE); | |
585 } | |
586 else | |
587 { | |
588 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].hour); | |
589 gtk_widget_set_sensitive(w, TRUE); | |
590 } | |
591 | |
592 w = lookup_widget(config_dialog, day_m[daynum]); | |
593 if(gtk_toggle_button_get_active(togglebutton) == TRUE) | |
594 { | |
595 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_min); | |
596 gtk_widget_set_sensitive(w, FALSE); | |
597 } | |
598 else | |
599 { | |
600 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].min); | |
601 gtk_widget_set_sensitive(w, TRUE); | |
602 } | |
603 } | |
604 | |
605 void on_sun_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
606 { | |
607 on_day_def_toggled(togglebutton, user_data, 0); | |
608 } | |
609 | |
610 void on_mon_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
611 { | |
612 on_day_def_toggled(togglebutton, user_data, 1); | |
613 } | |
614 | |
615 void on_tue_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
616 { | |
617 on_day_def_toggled(togglebutton, user_data, 2); | |
618 } | |
619 | |
620 void on_wed_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
621 { | |
622 on_day_def_toggled(togglebutton, user_data, 3); | |
623 } | |
624 | |
625 void on_thu_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
626 { | |
627 on_day_def_toggled(togglebutton, user_data, 4); | |
628 } | |
629 | |
630 void on_fri_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
631 { | |
632 on_day_def_toggled(togglebutton, user_data, 5); | |
633 } | |
634 | |
635 void on_sat_def_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
636 { | |
637 on_day_def_toggled(togglebutton, user_data, 6); | |
638 } | |
639 | |
640 /* END: greying things */ | |
641 | |
642 void alarm_current_volume(GtkButton *button, gpointer data) | |
643 { | |
644 gint vol; | |
645 GtkAdjustment *adj; | |
646 | |
647 DEBUG("on_current_button_clicked\n"); | |
648 | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
649 audacious_drct_get_volume_main(&vol); |
121 | 650 |
651 adj = gtk_range_get_adjustment(alarm_conf.volume); | |
652 gtk_adjustment_set_value(adj, (gfloat)vol); | |
653 } | |
654 | |
655 /* | |
656 * a thread safe sleeping function - | |
657 * and it even works in solaris (I think) | |
658 */ | |
659 static void threadsleep(float x) | |
660 { | |
661 DEBUG("threadsleep: waiting %f seconds\n", x); | |
662 | |
122
96fc1ef32c99
[svn] - push fixes from p4://depot/svn-audacious-plugins-devel/virt-branches/audalarm/src
nenolod
parents:
121
diff
changeset
|
663 g_usleep((int) ((float) x * (float) 1000000.0)); |
121 | 664 |
665 return; | |
666 } | |
667 | |
668 static inline pthread_t alarm_thread_create(void *(*start_routine)(void *), void *args, unsigned int detach) | |
669 { | |
670 pthread_t tid; | |
671 pthread_attr_t attr; | |
672 | |
673 pthread_attr_init(&attr); | |
674 | |
675 if(detach != 0) | |
676 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
677 | |
678 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); | |
679 pthread_attr_setschedpolicy(&attr, SCHED_OTHER); | |
680 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); | |
681 | |
682 pthread_create(&tid, &attr, start_routine, args); | |
683 | |
684 return(tid); | |
685 } | |
686 | |
687 static void *alarm_fade(void *arg) | |
688 { | |
689 fader *vols = (fader *)arg; | |
2149 | 690 guint i; |
691 gint v; | |
121 | 692 gint inc, diff, adiff; |
693 | |
694 /* lock */ | |
695 pthread_mutex_lock(&fader_lock); | |
696 | |
697 /* slide volume */ | |
698 /* the Kaspar Giger way of fading, check the current mixer volume and | |
699 * increment from there so that if you have some other app lowering the | |
700 * volume at the same time xmms-alarm will not ignore it. If you have some | |
701 * other app increasing the volume, then it could get louder that you expect | |
702 * though - because the loop does not recalculate the difference each time. | |
703 */ | |
704 | |
705 /* difference between the 2 volumes */ | |
706 diff = vols->end - vols->start; | |
707 adiff = abs(diff); | |
708 | |
709 /* Are we going up or down? */ | |
710 if(diff < 0) | |
711 inc = -1; | |
712 else | |
713 inc = 1; | |
714 | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
715 audacious_drct_set_volume_main((gint)vols->start); |
121 | 716 //for(i=0;i<(vols->end - vols->start);i++) |
717 for(i=0;i<adiff;i++) | |
718 { | |
719 //threadsleep((gfloat)fading / (vols->end - vols->start)); | |
720 threadsleep((gfloat)fading / (gfloat)adiff); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
721 audacious_drct_get_volume_main(&v); |
2149 | 722 audacious_drct_set_volume_main(v + inc); |
121 | 723 } |
724 /* Setting the volume to the end volume sort of defeats the point if having | |
725 * the code in there to allow other apps to control volume too :) | |
726 */ | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
727 //audacious_drct_set_volume_main((gint)vols->end); |
121 | 728 |
729 /* and */ | |
730 pthread_mutex_unlock(&fader_lock); | |
731 | |
732 DEBUG("volume = %f%%\n", (gdouble)vols->end); | |
733 return(0); | |
734 } | |
735 | |
736 static void *alarm_stop_thread( void *args ) | |
737 { | |
738 gint currvol; | |
739 fader fade_vols; | |
740 pthread_t f_tid; | |
741 | |
742 DEBUG("alarm_stop_thread\n"); | |
743 | |
744 | |
745 /* sleep for however long we are meant to be sleeping for until | |
746 * its time to shut up | |
747 */ | |
748 threadsleep(((stop_h * 60) + stop_m) * 60); | |
749 | |
750 DEBUG("alarm_stop triggered\n"); | |
751 | |
752 if (dialog_visible(alarm_dialog)) | |
753 gtk_widget_destroy(alarm_dialog); | |
754 | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
755 audacious_drct_get_volume_main(&currvol), |
121 | 756 |
757 /* fade back to zero */ | |
758 fade_vols.start = currvol; | |
759 fade_vols.end = 0; | |
760 | |
761 /* The fader thread locks the fader_mutex now */ | |
762 f_tid = alarm_thread_create(alarm_fade, &fade_vols, 0); | |
763 | |
764 pthread_join(f_tid, NULL); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
765 audacious_drct_stop(); |
121 | 766 |
767 /* might as well set the volume to something higher than zero so we | |
768 * dont confuse the poor people who just woke up and cant work out why | |
769 * theres no music playing when they press the little play button :) | |
770 */ | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
771 audacious_drct_set_volume_main(currvol); |
121 | 772 |
773 DEBUG("alarm_stop done\n"); | |
774 return(NULL); | |
775 } | |
776 | |
777 void alarm_stop_cancel(GtkButton *w, gpointer data) | |
778 { | |
779 DEBUG("alarm_stop_cancel\n"); | |
780 pthread_cancel(stop_tid); | |
781 } | |
782 | |
783 /* the main alarm thread */ | |
784 static void *alarm_start_thread(void *args) | |
785 { | |
786 struct tm *currtime; | |
787 time_t timenow; | |
788 unsigned int play_start = 0; | |
789 guint today; | |
790 | |
791 /* give it time to set start_tid to something */ | |
792 threadsleep(1); | |
793 | |
794 while(start_tid != 0) | |
795 { | |
796 /* sit around and wait for the faders to not be doing anything */ | |
797 DEBUG("Waiting for fader to be unlocked.."); | |
798 pthread_mutex_lock(&fader_lock); | |
799 DEBUG("Ok\n"); | |
800 pthread_mutex_unlock(&fader_lock); | |
801 | |
802 DEBUG("Getting time\n"); | |
803 timenow = time(NULL); | |
804 currtime = localtime(&timenow); | |
805 today = currtime->tm_wday; | |
806 DEBUG("Today is %d\n", today); | |
807 | |
808 /* see if its time to do something */ | |
809 DEBUG("Checking Day\n"); | |
810 | |
811 /* Had to put something here so I put the hour string. | |
812 ** Its only debug stuff anyway */ | |
813 DEBUG(day_h[today]); | |
814 | |
815 if(alarm_conf.day[today].flags & ALARM_OFF) | |
816 { | |
817 threadsleep(8.5); | |
818 continue; | |
819 } | |
820 else | |
821 { | |
822 /* set the alarm_h and alarm_m for today, if not default */ | |
823 if(!(alarm_conf.day[today].flags & ALARM_DEFAULT)) | |
824 { | |
825 alarm_h = alarm_conf.day[today].hour; | |
826 alarm_m = alarm_conf.day[today].min; | |
827 } | |
828 else | |
829 { | |
830 alarm_h = alarm_conf.default_hour; | |
831 alarm_m = alarm_conf.default_min; | |
832 } | |
833 } | |
834 | |
835 DEBUG("Alarm time is %d:%d (def: %d:%d)\n", alarm_h, alarm_m, | |
836 alarm_conf.default_hour, alarm_conf.default_min); | |
837 | |
838 DEBUG("Checking time (%d:%d)\n", currtime->tm_hour, currtime->tm_min); | |
839 if((currtime->tm_hour != alarm_h) || (currtime->tm_min != alarm_m)) | |
840 { | |
841 threadsleep(8.5); | |
842 continue; | |
843 } | |
844 | |
845 if(cmd_on == TRUE) | |
846 { | |
847 DEBUG("Executing %s, cmd_on is true\n", cmdstr); | |
963 | 848 if(system(cmdstr) == -1) |
849 { | |
850 DEBUG("Executing %s failed\n",cmdstr); | |
851 } | |
121 | 852 } |
853 | |
854 DEBUG("strcmp playlist, playlist is [%s]\n", playlist); | |
855 if(strcmp(playlist, "")) | |
856 { | |
857 DEBUG("playlist is not blank, aparently\n"); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
858 GList list; |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
859 |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
860 list.prev = list.next = NULL; |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
861 list.data = playlist; |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
862 |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
863 audacious_drct_pl_clear(); |
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
864 audacious_drct_pl_add(&list); |
121 | 865 } |
866 | |
867 if(fading) | |
868 { | |
869 fader fade_vols; | |
870 | |
871 DEBUG("Fading is true\n"); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
872 audacious_drct_set_volume_main(quietvol); |
121 | 873 |
874 /* start playing */ | |
875 play_start = time(NULL); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
876 audacious_drct_play(); |
121 | 877 |
878 /* fade volume */ | |
879 fade_vols.start = quietvol; | |
880 fade_vols.end = volume; | |
881 | |
882 //alarm_fade(quietvol, volume); | |
883 alarm_thread_create(alarm_fade, &fade_vols, 0); | |
884 } | |
885 else | |
886 { | |
887 /* no fading */ | |
888 | |
889 /* set volume */ | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
890 audacious_drct_set_volume_main(volume); |
121 | 891 |
892 /* start playing */ | |
893 play_start = time(NULL); | |
1035
711ec8d39ca6
[svn] Changed alarm and projectm plugins so they use auddrct now.
magma
parents:
1005
diff
changeset
|
894 audacious_drct_play(); |
121 | 895 } |
896 | |
897 if(alarm_conf.reminder_on == TRUE) | |
898 { | |
899 GtkWidget *reminder_dialog; | |
900 DEBUG("Showing reminder '%s'\n", alarm_conf.reminder_msg); | |
901 | |
902 GDK_THREADS_ENTER(); | |
132
26a5aef73955
[svn] Fixes compiler warnings that "Joker" was talking about in #audacious.
asheldon
parents:
129
diff
changeset
|
903 reminder_dialog = (GtkWidget*) create_reminder_dialog(alarm_conf.reminder_msg); |
121 | 904 gtk_signal_connect(GTK_OBJECT(reminder_dialog), "destroy", |
905 GTK_SIGNAL_FUNC(dialog_destroyed), &reminder_dialog); | |
906 gtk_widget_show_all(reminder_dialog); | |
907 GDK_THREADS_LEAVE(); | |
908 } | |
909 | |
910 /* bring up the wakeup call dialog if stop_on is set TRUE, this | |
911 * has been moved to after making xmms play so that it doesnt | |
912 * get in the way for people with manual window placement turned on | |
913 * | |
914 * this means that the dialog doesnt get shown until the volume has | |
915 * finished fading though !, so thats something else to fix | |
916 */ | |
917 if(stop_on == TRUE) | |
918 { | |
919 /* ok, so when we want to open dialogs in threaded programs | |
920 * we use this do we? | |
921 * anyone? | |
922 */ | |
923 GDK_THREADS_ENTER(); | |
924 { | |
925 DEBUG("stop_on is true\n"); | |
926 alarm_dialog = create_alarm_dialog(); | |
927 DEBUG("created alarm dialog, %p\n", alarm_dialog); | |
928 | |
929 gtk_signal_connect(GTK_OBJECT(alarm_dialog), "destroy", | |
930 GTK_SIGNAL_FUNC(dialog_destroyed), &alarm_dialog); | |
931 DEBUG("attached destroy signal to alarm dialog, %p\n", alarm_dialog); | |
932 gtk_widget_show_all(alarm_dialog); | |
933 DEBUG("dialog now showing\n"); | |
934 | |
935 DEBUG("now starting stop thread\n"); | |
936 stop_tid = alarm_thread_create(alarm_stop_thread, NULL, 0); | |
937 DEBUG("Created wakeup dialog and started stop thread(%d)\n", (int)stop_tid); | |
938 | |
939 } | |
940 GDK_THREADS_LEAVE(); | |
941 | |
942 /* now wait for the stop thread */ | |
943 DEBUG("Waiting for stop to stop.... (%d)", (int)stop_tid); | |
944 pthread_join(stop_tid, NULL); | |
945 /* loop until we are out of the starting minute */ | |
946 while(time(NULL) < (play_start + 61)) | |
947 { | |
948 DEBUG("Waiting until out of starting minute\n"); | |
949 threadsleep(5.0); | |
950 } | |
951 DEBUG("OK\n"); | |
952 } | |
953 /* loop until we are out of the starting minute */ | |
954 while(time(NULL) < (play_start + 61)) | |
955 { | |
956 threadsleep(5.0); | |
957 } | |
958 threadsleep(fading); | |
959 } | |
960 | |
961 DEBUG("Main thread has gone...\n"); | |
962 return NULL; | |
963 } | |
964 | |
965 /* | |
966 * initialization | |
967 * opens the config file and reads the value, creates a new | |
968 * config in memory if the file doesnt exist and sets default vals | |
969 */ | |
970 static void alarm_init() | |
971 { | |
972 DEBUG("alarm_init\n"); | |
973 | |
974 alarm_read_config(); | |
975 | |
976 /* start the main thread running */ | |
977 start_tid = alarm_thread_create(alarm_start_thread, NULL, 1); | |
978 } | |
979 | |
980 /* | |
981 * kill the main thread | |
982 */ | |
983 static void alarm_cleanup() | |
984 { | |
985 DEBUG("alarm_cleanup\n"); | |
986 | |
129
dae03298753f
[svn] - don't cancel threads that don't exist (TODO: GThreadify)
nenolod
parents:
122
diff
changeset
|
987 if (start_tid) |
dae03298753f
[svn] - don't cancel threads that don't exist (TODO: GThreadify)
nenolod
parents:
122
diff
changeset
|
988 pthread_cancel(start_tid); |
121 | 989 start_tid = 0; |
990 if(stop_tid) | |
991 pthread_cancel(stop_tid); | |
129
dae03298753f
[svn] - don't cancel threads that don't exist (TODO: GThreadify)
nenolod
parents:
122
diff
changeset
|
992 stop_tid = 0; |
121 | 993 } |
994 | |
995 static GeneralPlugin alarm_plugin = | |
996 { | |
1654 | 997 .description = "Alarm "VERSION, |
998 .init = alarm_init, | |
999 .about = alarm_about, | |
1000 .configure = alarm_configure, | |
1001 .cleanup = alarm_cleanup, | |
121 | 1002 }; |
1003 | |
1120 | 1004 GeneralPlugin *alarm_gplist[] = { &alarm_plugin, NULL }; |
1654 | 1005 SIMPLE_GENERAL_PLUGIN(alarm, alarm_gplist); |