Mercurial > audlegacy-plugins
annotate src/alarm/alarm.c @ 2181:bbb631ab78e9
started initial (very humble) efforts on making FileWriter a general
plugin
author | mf0102 <0102@gmx.at> |
---|---|
date | Wed, 21 Nov 2007 17:02:26 +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); |