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