116
116
PROP_NOTIFY_TYPE,
123
122
#define PROP_NAME_DIR "gconf-dir"
124
123
#define PROP_NAME_ID "id"
124
#define PROP_NAME_TRIGGERED "triggered"
125
125
#define PROP_NAME_TYPE "type"
126
126
#define PROP_NAME_TIME "time"
127
127
#define PROP_NAME_TIMESTAMP "timestamp"
128
128
#define PROP_NAME_ACTIVE "active"
129
129
#define PROP_NAME_MESSAGE "message"
130
130
#define PROP_NAME_REPEAT "repeat"
131
#define PROP_NAME_SNOOZE "snooze"
132
#define PROP_NAME_NOTIFY_TYPE "notify_type"
133
#define PROP_NAME_SOUND_FILE "sound_file"
134
#define PROP_NAME_SOUND_LOOP "sound_repeat"
131
#define PROP_NAME_NOTIFY_TYPE "notify-type"
132
#define PROP_NAME_SOUND_FILE "sound-file"
133
#define PROP_NAME_SOUND_LOOP "sound-repeat"
135
134
#define PROP_NAME_COMMAND "command"
136
#define PROP_NAME_NOTIFY_BUBBLE "notify_bubble"
138
136
/* Signal indexes */
147
146
/* Signal identifier map */
148
static guint alarm_signal[LAST_SIGNAL] = {0, 0, 0};
147
static guint alarm_signal[LAST_SIGNAL] = {0, 0, 0, 0};
150
149
/* Prototypes for signal handlers */
151
150
static void alarm_alarm (Alarm *alarm);
151
static void alarm_cleared (Alarm *alarm);
152
152
static void alarm_error (Alarm *alarm, GError *err);
153
153
static void alarm_player_changed (Alarm *alarm, MediaPlayerState state);
155
/* For debugging purposes only */
157
dump_list (GSList *list)
162
for (l = list; l; l = l->next) {
163
g_print ("%s", (gchar *)l->data);
171
156
/* Initialize the Alarm class */
304
279
/* install properties */
305
280
g_object_class_install_property (g_object_class, PROP_DIR, dir_param);
306
281
g_object_class_install_property (g_object_class, PROP_ID, id_param);
282
g_object_class_install_property (g_object_class, PROP_TRIGGERED, triggered_param);
307
283
g_object_class_install_property (g_object_class, PROP_TYPE, type_param);
308
284
g_object_class_install_property (g_object_class, PROP_TIME, time_param);
309
285
g_object_class_install_property (g_object_class, PROP_TIMESTAMP, timestamp_param);
310
286
g_object_class_install_property (g_object_class, PROP_ACTIVE, active_param);
311
287
g_object_class_install_property (g_object_class, PROP_MESSAGE, message_param);
312
288
g_object_class_install_property (g_object_class, PROP_REPEAT, repeat_param);
313
g_object_class_install_property (g_object_class, PROP_SNOOZE, snooze_param);
314
289
g_object_class_install_property (g_object_class, PROP_NOTIFY_TYPE, notify_type_param);
315
290
g_object_class_install_property (g_object_class, PROP_SOUND_FILE, sound_file_param);
316
291
g_object_class_install_property (g_object_class, PROP_SOUND_LOOP, sound_loop_param);
317
292
g_object_class_install_property (g_object_class, PROP_COMMAND, command_param);
318
g_object_class_install_property (g_object_class, PROP_NOTIFY_BUBBLE, notify_bubble_param);
320
294
g_type_class_add_private (class, sizeof (AlarmPrivate));
322
296
/* set signal handlers */
323
297
class->alarm = alarm_alarm;
298
class->cleared = alarm_cleared;
324
299
class->error = alarm_error;
325
300
class->player_changed = alarm_player_changed;
327
302
/* install signals and default handlers */
328
303
alarm_signal[SIGNAL_ALARM] = g_signal_new ("alarm", /* name */
329
304
TYPE_ALARM, /* class type identifier */
330
G_SIGNAL_RUN_LAST, /* options */
305
G_SIGNAL_RUN_FIRST, /* options */
331
306
G_STRUCT_OFFSET (AlarmClass, alarm), /* handler offset */
332
307
NULL, /* accumulator function */
333
308
NULL, /* accumulator data */
334
309
g_cclosure_marshal_VOID__VOID, /* marshaller */
335
310
G_TYPE_NONE, /* type of return value */
313
alarm_signal[SIGNAL_CLEARED] = g_signal_new ("cleared",
316
G_STRUCT_OFFSET (AlarmClass, cleared),
319
g_cclosure_marshal_VOID__VOID,
338
323
alarm_signal[SIGNAL_ERROR] = g_signal_new ("error",
340
325
G_SIGNAL_RUN_LAST,
1017
952
alarm_alarm (Alarm *alarm)
1019
g_debug ("[%p] #%d: alarm_alarm", alarm, alarm->id);
954
g_debug ("Alarm(%p) #%d: alarm() DING!", alarm, alarm->id);
1023
alarm_trigger (Alarm *alarm)
1025
g_signal_emit (alarm, alarm_signal[SIGNAL_ALARM], 0, NULL);
956
// Clear first, if needed
959
// Update triggered flag
960
alarm->triggered = TRUE;
1028
* Do we want to repeat this alarm?
962
// Do we want to repeat this alarm?
1030
963
if (alarm_should_repeat (alarm)) {
1031
g_debug ("alarm_trigger REPEATING");
964
g_debug ("Alarm(%p) #%d: alarm() Repeating...", alarm, alarm->id);
1032
965
alarm_update_timestamp_full (alarm, FALSE);
1034
967
alarm_disable (alarm);
1037
970
switch (alarm->notify_type) {
1038
971
case ALARM_NOTIFY_SOUND:
1039
972
// Start sound playback
1040
g_debug("[%p] #%d Start player", alarm, alarm->id);
973
g_debug("Alarm(%p) #%d: alarm() Start player", alarm, alarm->id);
1041
974
alarm_player_start (alarm);
1043
976
case ALARM_NOTIFY_COMMAND:
1045
g_debug("[%p] #%d Start command", alarm, alarm->id);
978
g_debug("Alarm(%p) #%d: alarm() Start command", alarm, alarm->id);
1046
979
alarm_command_run (alarm);
1049
g_debug ("NOTIFICATION TYPE %d Not yet implemented.", alarm->notify_type);
982
g_warning ("Alarm(%p) #%d: UNKNOWN NOTIFICATION TYPE %d",
983
alarm, alarm->id, alarm->notify_type);
988
alarm_trigger (Alarm *alarm)
990
g_signal_emit (alarm, alarm_signal[SIGNAL_ALARM], 0, NULL);
1054
994
* Convenience functions for enabling/disabling the alarm.
1094
1034
// Remove configuration
1095
1035
key = alarm_gconf_get_dir (alarm);
1096
g_debug ("alarm_delete: recursive unset on %s", key);
1036
g_debug ("Alarm(%p) #%d: alarm_delete() recursive unset on %s", alarm, alarm->id, key);
1097
1037
gconf_client_recursive_unset (client, key, GCONF_UNSET_INCLUDING_SCHEMA_NAMES, NULL);
1098
1038
gconf_client_suggest_sync (client, NULL);
1043
* Snooze the alarm for a number of seconds.
1106
alarm_snooze (Alarm *alarm)
1046
alarm_snooze (Alarm *alarm, guint seconds)
1109
if (alarm->snooze == 0) {
1110
alarm_clear (alarm);
1114
if (!alarm_is_playing (alarm)) return;
1116
g_debug ("alarm_snooze SNOOZING FOR %d minutes", alarm->snooze);
1118
time_t now = time (NULL);
1048
g_assert (alarm->triggered);
1050
g_debug ("Alarm(%p) #%d: snooze() for %d minutes", alarm, alarm->id, seconds / 60);
1053
alarm_clear (alarm);
1056
time_t now = time (NULL);
1120
1058
g_object_set (alarm,
1121
"timestamp", now + alarm->snooze * 60,
1059
"timestamp", now + seconds,
1125
alarm_clear (alarm);
1063
// alarm_timer_start (alarm);
1067
* Alarm cleared signal
1070
alarm_cleared (Alarm *alarm)
1072
g_debug ("Alarm(%p) #%d: cleared()", alarm, alarm->id);
1074
// Update triggered flag
1075
alarm->triggered = FALSE;
1078
alarm_player_stop (alarm);
1129
* Clear the alarm. This will stop any running players.
1082
* Clear the alarm. Resets the triggered flag and emits the "cleared" signal.
1083
* This will also stop any running players.
1132
1086
alarm_clear (Alarm *alarm)
1134
alarm_player_stop (alarm);
1088
if (alarm->triggered) {
1089
g_signal_emit (alarm, alarm_signal[SIGNAL_CLEARED], 0, NULL);
1542
1488
alarm_gconf_get_full_key (Alarm *alarm, const gchar *key)
1544
1491
gchar *full_key;
1546
1493
g_return_val_if_fail (IS_ALARM (alarm), NULL);
1551
full_key = g_strdup_printf ("%s/" ALARM_GCONF_DIR_PREFIX "%d/%s", alarm->gconf_dir, alarm->id, key);
1498
// Replace dashes with underscores
1499
gconf_key = g_strdup (key);
1500
g_strcanon (gconf_key, "abcdefghijklmnopqrstuvwxyz", '_');
1502
full_key = g_strdup_printf ("%s/" ALARM_GCONF_DIR_PREFIX "%d/%s",
1503
alarm->gconf_dir, alarm->id, gconf_key);
1553
1507
return full_key;
1562
static AlarmBindArg *
1563
alarm_bind_arg_new (GObject *object, const gchar *name, gulong handler_id)
1567
arg = g_new (AlarmBindArg, 1);
1568
arg->object = object;
1570
arg->handler_id = handler_id;
1576
alarm_bind_arg_free (AlarmBindArg *arg)
1581
g_free ((gpointer)arg);
1585
alarm_bind_update (GObject *object,
1590
AlarmBindArg *arg = (AlarmBindArg *)data;
1594
* Determine which argument is the alarm
1596
/*if (IS_ALARM (object)) {
1597
alarm = ALARM (object);
1599
alarm = ALARM (arg->object);
1602
g_debug ("alarm_bind_update #%d(%p) [%s] -> %p [%s]", alarm->id, alarm, pspec->name, arg->object, arg->name);
1604
g_object_get (object, pspec->name, &d, NULL);
1606
// Block other signal handler
1607
g_signal_handlers_block_matched(arg->object,
1608
G_SIGNAL_MATCH_FUNC,
1609
0, 0, NULL, alarm_bind_update, NULL);
1611
g_object_set (arg->object, arg->name, d, NULL);
1613
g_signal_handlers_unblock_matched(arg->object,
1614
G_SIGNAL_MATCH_FUNC,
1615
0, 0, NULL, alarm_bind_update, NULL);
1619
* We would like to disconnect any signal handlers from the alarm
1620
* when the destination object is finalized. And vice versa.
1623
alarm_bind_weak_notify (gpointer data, GObject *where_the_object_was)
1625
AlarmBindArg *arg = (AlarmBindArg *)data;
1628
g_assert (arg->object);
1629
g_assert (arg->handler_id);
1631
if (G_IS_OBJECT (arg->object)) {
1632
if (g_signal_handler_is_connected (arg->object, arg->handler_id)) {
1633
g_signal_handler_disconnect (arg->object, arg->handler_id);
1637
alarm_bind_arg_free (arg);
1644
alarm_bind (Alarm *alarm,
1647
const gchar *dest_prop)
1649
AlarmBindArg *arg, *obj_arg;
1652
gulong handler, obj_handler;
1654
param = g_object_class_find_property (G_OBJECT_GET_CLASS(alarm), prop);
1656
param = g_object_class_find_property (G_OBJECT_GET_CLASS(dest), dest_prop);
1659
// g_debug ("Bind from %p [%s] -> %p [%s]", alarm, prop, dest, dest_prop);
1662
tmp = g_strdup_printf("notify::%s", prop);
1663
arg = alarm_bind_arg_new (dest, dest_prop, 0);
1664
handler = g_signal_connect (alarm, tmp, G_CALLBACK (alarm_bind_update), arg);
1668
tmp = g_strdup_printf ("notify::%s", dest_prop);
1669
obj_arg = alarm_bind_arg_new (G_OBJECT (alarm), prop, handler);
1670
obj_handler = g_signal_connect (dest, tmp, G_CALLBACK (alarm_bind_update), obj_arg);
1673
arg->handler_id = obj_handler;
1675
// Disconnect Object when Alarm is finalized (freed)
1676
g_object_weak_ref (G_OBJECT (alarm), alarm_bind_weak_notify, arg);
1678
// Disconnect Alarm when Object is finalized (freed)
1679
g_object_weak_ref (dest, alarm_bind_weak_notify, obj_arg);
1511
* Compare two alarms based on ID
1683
1514
alarm_list_item_compare (gconstpointer a, gconstpointer b)
1738
1569
id = alarm_gconf_dir_get_id (tmp);
1740
g_debug ("alarm_get_list: found VALID %s #%d", tmp, id);
1571
g_debug ("Alarm: get_list() found '%s' #%d", tmp, id);
1742
1573
alarm = alarm_new (gconf_dir, id);
1743
g_debug ("\tref = %d", G_OBJECT (alarm)->ref_count);
1574
// g_debug ("\tref = %d", G_OBJECT (alarm)->ref_count);
1744
1575
ret = g_list_insert_sorted (ret, alarm, alarm_list_item_compare);
1745
g_debug ("\tappend ref = %d", G_OBJECT (alarm)->ref_count);
1576
// g_debug ("\tappend ref = %d", G_OBJECT (alarm)->ref_count);
2012
* Create a pretty string representation of AlarmRepeat
2014
* The return value must be freed afterwards
2017
alarm_repeat_to_pretty (AlarmRepeat repeat)
2028
case ALARM_REPEAT_NONE:
2029
str = g_strdup (_("Once"));
2031
case ALARM_REPEAT_WEEKDAYS:
2032
str = g_strdup (_("Weekdays"));
2034
case ALARM_REPEAT_WEEKENDS:
2035
str = g_strdup (_("Weekends"));
2037
case ALARM_REPEAT_ALL:
2038
str = g_strdup (_("Every day"));
2041
// Custom repeat, create a list of weekdays
2042
s = g_string_new ("");
2044
for (r = ALARM_REPEAT_SUN, i = 0; r <= ALARM_REPEAT_SAT; r = 1 << ++i) {
2047
strftime (tmp, sizeof(tmp), "%a", &tm);
2048
g_string_append_printf (s, "%s, ", tmp);
2052
g_string_truncate (s, s->len - 2);
2056
g_string_free (s, FALSE);
2163
2064
* }} AlarmRepeat utilities