00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <glib.h>
00023 #include <glib-object.h>
00024 #include "rpc-systemui.h"
00025 #include "xml-common.h"
00026 #include "debug.h"
00027 #include "queue.h"
00028
00029 static void alarmd_queue_init(AlarmdQueue *queue);
00030 static void alarmd_queue_class_init(AlarmdQueueClass *klass);
00031 static void _alarmd_queue_set_property(GObject *object,
00032 guint param_id,
00033 const GValue *value,
00034 GParamSpec *pspec);
00035 static void _alarmd_queue_get_property(GObject *object,
00036 guint param_id,
00037 GValue *value,
00038 GParamSpec *pspec);
00039
00040 static void _alarmd_queue_real_time_changed(AlarmdObject *object);
00041 static void _alarmd_queue_finalize(GObject *object);
00042 static glong _alarmd_queue_real_add_event(AlarmdQueue *queue, AlarmdEvent *event);
00043 static gboolean _alarmd_queue_real_remove_event(AlarmdQueue *queue, glong event_id);
00044 static AlarmdEvent *_alarmd_queue_real_get_event(AlarmdQueue *queue, glong event_id);
00045 static xmlNode *_alarmd_queue_to_xml(AlarmdObject *object);
00046 static void _alarmd_queue_event_dequeued(AlarmdQueue *queue, AlarmdEvent *event);
00047 static void _alarmd_queue_event_queued(AlarmdQueue *queue, gpointer plugin, AlarmdEvent *event);
00048 static void _alarmd_queue_event_changed(AlarmdQueue *queue, AlarmdEvent *event);
00049 static void _alarmd_queue_event_fired(AlarmdQueue *queue, gboolean delayed,
00050 AlarmdEvent *event);
00051 static void _alarmd_queue_event_cancelled(AlarmdQueue *queue, AlarmdEvent *event);
00052
00053 static gint _alarmd_event_compare_func(gconstpointer lval, gconstpointer rval);
00054 static AlarmdEvent *_alarmd_queue_find_event(GSList *list, glong event_id);
00055 static AlarmdEvent *_alarmd_queue_find_first_event(GSList *list, gboolean need_power_up);
00056 static glong *_alarmd_queue_real_query_events(AlarmdQueue *queue, gint64 start_time, gint64 end_time, gint32 flag_mask, gint32 flags, guint *n_events);
00057 static GSList *_alarmd_queue_get_saved_properties(void);
00058
00059 enum properties {
00060 PROP_TIMER = 1,
00061 PROP_TIMER_POWERUP,
00062 PROP_SNOOZE,
00063 };
00064
00065 enum saved_props {
00066 S_SNOOZE,
00067 S_COUNT
00068 };
00069
00070 static const gchar * const saved_properties[S_COUNT] =
00071 {
00072 "snooze",
00073 };
00074
00075 typedef struct _AlarmdQueuePrivate AlarmdQueuePrivate;
00076 struct _AlarmdQueuePrivate {
00077 AlarmdEvent *queued;
00078 AlarmdEvent *queued_powerup;
00079 TimerPlugin *timer;
00080 TimerPlugin *timer_powerup;
00081 guint32 snooze;
00082 GSList *events;
00083 GSList *pending;
00084 };
00085
00086 #define ALARMD_QUEUE_GET_PRIVATE(obj) \
00087 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
00088 ALARMD_TYPE_QUEUE, AlarmdQueuePrivate));
00089
00090
00091 GType alarmd_queue_get_type(void)
00092 {
00093 static GType queue_type = 0;
00094
00095 if (!queue_type)
00096 {
00097 static const GTypeInfo queue_info =
00098 {
00099 sizeof (AlarmdQueueClass),
00100 NULL,
00101 NULL,
00102 (GClassInitFunc) alarmd_queue_class_init,
00103 NULL,
00104 NULL,
00105 sizeof (AlarmdQueue),
00106 0,
00107 (GInstanceInitFunc) alarmd_queue_init,
00108 NULL
00109 };
00110
00111 queue_type = g_type_register_static(ALARMD_TYPE_OBJECT,
00112 "AlarmdQueue",
00113 &queue_info, 0);
00114 }
00115
00116 return queue_type;
00117 }
00118
00119 AlarmdQueue *alarmd_queue_new(void)
00120 {
00121 AlarmdQueue *retval;
00122 ENTER_FUNC;
00123 retval = g_object_new(ALARMD_TYPE_QUEUE, NULL);
00124 LEAVE_FUNC;
00125 return retval;
00126 }
00127
00128 gulong alarmd_queue_add_event(AlarmdQueue *queue, AlarmdEvent *event)
00129 {
00130 gulong retval;
00131 ENTER_FUNC;
00132 retval = ALARMD_QUEUE_GET_CLASS(queue)->add_event(queue, event);
00133 LEAVE_FUNC;
00134 return retval;
00135 }
00136
00137 gboolean alarmd_queue_remove_event(AlarmdQueue *queue, gulong event_id)
00138 {
00139 gboolean retval;
00140 ENTER_FUNC;
00141 retval = ALARMD_QUEUE_GET_CLASS(queue)->remove_event(queue, event_id);
00142 LEAVE_FUNC;
00143 return retval;
00144 }
00145
00146 AlarmdEvent *alarmd_queue_get_event(AlarmdQueue *queue, gulong event_id)
00147 {
00148 AlarmdEvent *retval;
00149 ENTER_FUNC;
00150 retval = ALARMD_QUEUE_GET_CLASS(queue)->get_event(queue, event_id);
00151 LEAVE_FUNC;
00152 return retval;
00153 }
00154
00155 glong *alarmd_queue_query_events(AlarmdQueue *queue, gint64 start_time, gint64 end_time, gint32 flag_mask, gint32 flags, guint *n_events)
00156 {
00157 glong *retval;
00158 ENTER_FUNC;
00159 retval = ALARMD_QUEUE_GET_CLASS(queue)->query_events(queue, start_time, end_time, flag_mask, flags, n_events);
00160 LEAVE_FUNC;
00161 return retval;
00162 }
00163
00164 void alarmd_queue_class_init(AlarmdQueueClass *klass)
00165 {
00166 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
00167 AlarmdObjectClass *alarmd_object_class = ALARMD_OBJECT_CLASS(klass);
00168 ENTER_FUNC;
00169
00170 g_type_class_add_private(klass, sizeof(AlarmdQueuePrivate));
00171
00172 gobject_class->set_property = _alarmd_queue_set_property;
00173 gobject_class->get_property = _alarmd_queue_get_property;
00174 gobject_class->finalize = _alarmd_queue_finalize;
00175
00176 alarmd_object_class->to_xml = _alarmd_queue_to_xml;
00177 alarmd_object_class->get_saved_properties = _alarmd_queue_get_saved_properties;
00178 alarmd_object_class->time_changed = _alarmd_queue_real_time_changed;
00179
00180 klass->add_event = _alarmd_queue_real_add_event;
00181 klass->remove_event = _alarmd_queue_real_remove_event;
00182 klass->get_event = _alarmd_queue_real_get_event;
00183 klass->query_events = _alarmd_queue_real_query_events;
00184
00185 g_object_class_install_property(gobject_class,
00186 PROP_TIMER,
00187 g_param_spec_pointer("timer",
00188 "Timer plugin used by the queue.",
00189 "Timer plugin that will provide timed events.",
00190 G_PARAM_READABLE | G_PARAM_WRITABLE));
00191 g_object_class_install_property(gobject_class,
00192 PROP_TIMER_POWERUP,
00193 g_param_spec_pointer("timer_powerup",
00194 "Timer plugin used by the queue that can power up.",
00195 "Timer plugin that will provide timed events with power up capabilities.",
00196 G_PARAM_READABLE | G_PARAM_WRITABLE));
00197 g_object_class_install_property(gobject_class,
00198 PROP_SNOOZE,
00199 g_param_spec_uint("snooze",
00200 "Default snooze time in minutes.",
00201 "The time events will be snoozed by default.",
00202 0,
00203 G_MAXUINT,
00204 10,
00205 G_PARAM_READABLE | G_PARAM_WRITABLE));
00206
00207 LEAVE_FUNC;
00208 }
00209
00210 static void alarmd_queue_init(AlarmdQueue *queue)
00211 {
00212 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00213 ENTER_FUNC;
00214 priv->timer = NULL;
00215 priv->timer_powerup = NULL;
00216 priv->events = NULL;
00217 priv->pending = NULL;
00218 priv->queued = NULL;
00219 priv->queued_powerup = NULL;
00220 priv->snooze = 10;
00221 LEAVE_FUNC;
00222 }
00223
00224 static void _alarmd_queue_set_property(GObject *object,
00225 guint param_id,
00226 const GValue *value,
00227 GParamSpec *pspec)
00228 {
00229 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(object);
00230 ENTER_FUNC;
00231
00232 switch (param_id) {
00233 case PROP_TIMER:
00234 priv->timer = (TimerPlugin *)g_value_get_pointer(value);
00235
00236 if (priv->queued) {
00237 alarmd_event_dequeue(priv->queued);
00238 } else {
00239 _alarmd_queue_event_dequeued(ALARMD_QUEUE(object), NULL);
00240 }
00241 break;
00242 case PROP_TIMER_POWERUP:
00243 if (priv->timer_powerup ==
00244 (TimerPlugin *)g_value_get_pointer(value)) {
00245 break;
00246 }
00247 priv->timer_powerup = (TimerPlugin *)g_value_get_pointer(value);
00248
00249 if (priv->queued && alarmd_event_need_power_up(priv->queued)) {
00250 alarmd_event_dequeue(priv->queued);
00251 } else if (priv->queued_powerup) {
00252 alarmd_event_dequeue(priv->queued_powerup);
00253 } else {
00254 _alarmd_queue_event_dequeued(ALARMD_QUEUE(object), NULL);
00255 }
00256 break;
00257 case PROP_SNOOZE:
00258 priv->snooze = g_value_get_uint(value);
00259 alarmd_object_changed(ALARMD_OBJECT(object));
00260 break;
00261 default:
00262 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
00263 break;
00264 }
00265 LEAVE_FUNC;
00266 }
00267
00268 static void _alarmd_queue_get_property(GObject *object,
00269 guint param_id,
00270 GValue *value,
00271 GParamSpec *pspec)
00272 {
00273 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(object);
00274 ENTER_FUNC;
00275
00276 switch (param_id) {
00277 case PROP_SNOOZE:
00278 g_value_set_uint(value, priv->snooze);
00279 break;
00280 case PROP_TIMER_POWERUP:
00281 g_value_set_pointer(value, (gpointer)priv->timer);
00282 break;
00283 case PROP_TIMER:
00284 g_value_set_pointer(value, (gpointer)priv->timer);
00285 break;
00286 default:
00287 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
00288 break;
00289 }
00290 LEAVE_FUNC;
00291 }
00292
00293 static void _alarmd_queue_real_time_changed(AlarmdObject *object)
00294 {
00295 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(object);
00296 GSList *list = g_slist_concat(g_slist_copy(priv->events),
00297 g_slist_copy(priv->pending));
00298 ENTER_FUNC;
00299 g_slist_foreach(list, (GFunc)alarmd_object_time_changed, NULL);
00300 g_slist_free(list);
00301 if (priv->timer) {
00302 priv->timer->time_changed(priv->timer);
00303 }
00304 if (priv->timer_powerup) {
00305 priv->timer_powerup->time_changed(priv->timer_powerup);
00306 }
00307 LEAVE_FUNC;
00308 }
00309
00310 static void _alarmd_queue_remove_event(gpointer object, gpointer queue)
00311 {
00312 ENTER_FUNC;
00313 g_signal_handlers_disconnect_by_func(object, _alarmd_queue_event_queued, queue);
00314 g_signal_handlers_disconnect_by_func(object, _alarmd_queue_event_dequeued, queue);
00315 g_signal_handlers_disconnect_by_func(object, _alarmd_queue_event_changed, queue);
00316 g_signal_handlers_disconnect_by_func(object, _alarmd_queue_event_cancelled, queue);
00317 g_object_unref(object);
00318 LEAVE_FUNC;
00319 }
00320
00321 static void _alarmd_queue_finalize(GObject *object)
00322 {
00323 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(object);
00324 ENTER_FUNC;
00325
00326 g_slist_foreach(priv->events, _alarmd_queue_remove_event, NULL);
00327 g_slist_foreach(priv->pending, _alarmd_queue_remove_event, NULL);
00328 g_slist_free(priv->events);
00329 g_slist_free(priv->pending);
00330 priv->events = NULL;
00331 priv->pending = NULL;
00332 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(ALARMD_TYPE_QUEUE)))->finalize(object);
00333 LEAVE_FUNC;
00334 }
00335
00336 static glong _alarmd_queue_real_add_event(AlarmdQueue *queue, AlarmdEvent *event)
00337 {
00338 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00339 ENTER_FUNC;
00340 glong event_id;
00341
00342 DEBUG("Reffing %p", event);
00343 g_object_ref(event);
00344 g_object_get(event, "cookie", &event_id, NULL);
00345
00346 if (event_id == 0) {
00347 gint64 timed;
00348 g_object_get(event, "time", &timed, NULL);
00349 event_id = (glong)timed;
00350 if (event_id == 0) {
00351 event_id++;
00352 }
00353 while (_alarmd_queue_find_event(priv->events, event_id) ||
00354 _alarmd_queue_find_event(priv->pending, event_id)) {
00355 event_id += 1;
00356 }
00357 g_object_set(event, "cookie", event_id, NULL);
00358 }
00359
00360 priv->events = g_slist_insert_sorted(priv->events, event, _alarmd_event_compare_func);
00361 g_signal_connect_swapped(event, "queue", (GCallback)_alarmd_queue_event_queued, (gpointer)queue);
00362 g_signal_connect_swapped(event, "dequeue", (GCallback)_alarmd_queue_event_dequeued, (gpointer)queue);
00363 g_signal_connect_swapped(event, "changed", (GCallback)_alarmd_queue_event_changed, (gpointer)queue);
00364 g_signal_connect_swapped(event, "cancel", (GCallback)_alarmd_queue_event_cancelled, (gpointer)queue);
00365 g_signal_connect_swapped(event, "fire", (GCallback)_alarmd_queue_event_fired, (gpointer)queue);
00366
00367 if (!priv->timer_powerup) {
00368 if (priv->queued == NULL) {
00369 _alarmd_queue_event_dequeued(queue, NULL);
00370 } else if (ALARMD_EVENT(priv->events->data) != priv->queued) {
00371 alarmd_event_dequeue(priv->queued);
00372 }
00373 } else if (alarmd_event_need_power_up(event)) {
00374 if (priv->queued_powerup == NULL) {
00375 _alarmd_queue_event_dequeued(queue, NULL);
00376 } else {
00377 AlarmdEvent *first_powerup = _alarmd_queue_find_first_event(priv->events, TRUE);
00378 DEBUG("Finding event which needs power up.");
00379 if (first_powerup != priv->queued_powerup) {
00380 alarmd_event_dequeue(priv->queued_powerup);
00381 }
00382 }
00383 } else {
00384 if (priv->queued == NULL) {
00385 _alarmd_queue_event_dequeued(queue, NULL);
00386 } else {
00387 DEBUG("Finding event which does not need power up.");
00388 AlarmdEvent *first_nopowerup = _alarmd_queue_find_first_event(priv->events, FALSE);
00389 if (first_nopowerup != priv->queued) {
00390 alarmd_event_dequeue(priv->queued);
00391 }
00392 }
00393 }
00394
00395 g_object_set(G_OBJECT(event), "queue", queue, NULL);
00396
00397 LEAVE_FUNC;
00398 return event_id;
00399 }
00400
00401 static gboolean _alarmd_queue_real_remove_event(AlarmdQueue *queue, glong event_id)
00402 {
00403 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00404 AlarmdEvent *event = NULL;
00405 ENTER_FUNC;
00406
00407 event = _alarmd_queue_find_event(priv->events, event_id);
00408 if (event == NULL) {
00409 event = _alarmd_queue_find_event(priv->pending, event_id);
00410 }
00411
00412 if (event != NULL) {
00413 alarmd_event_cancel(event);
00414 LEAVE_FUNC;
00415 return TRUE;
00416 }
00417
00418 LEAVE_FUNC;
00419 return FALSE;
00420 }
00421
00422 static AlarmdEvent *_alarmd_queue_real_get_event(AlarmdQueue *queue, glong event_id)
00423 {
00424 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00425 AlarmdEvent *event = NULL;
00426 ENTER_FUNC;
00427
00428 event = _alarmd_queue_find_event(priv->events, event_id);
00429 if (event == NULL) {
00430 event = _alarmd_queue_find_event(priv->pending, event_id);
00431 }
00432
00433 LEAVE_FUNC;
00434 return event;
00435 }
00436
00437 static gint _alarmd_event_compare_func(gconstpointer lval, gconstpointer rval)
00438 {
00439 AlarmdEvent *lev = (AlarmdEvent *)lval;
00440 AlarmdEvent *rev = (AlarmdEvent *)rval;
00441 gint retval;
00442 ENTER_FUNC;
00443
00444 retval = alarmd_event_get_time(lev) - alarmd_event_get_time(rev);
00445
00446 LEAVE_FUNC;
00447 return retval;
00448 }
00449
00450 static void _alarmd_queue_event_to_xml(gpointer child, gpointer node)
00451 {
00452 AlarmdObject *object = NULL;
00453 xmlNode *x_node = NULL;
00454 xmlNode *new_child = NULL;
00455 ENTER_FUNC;
00456
00457 object = ALARMD_OBJECT(child);
00458 x_node = (xmlNode *)node;
00459 new_child = alarmd_object_to_xml(object);
00460
00461 if (new_child)
00462 {
00463 xmlAddChild(x_node, new_child);
00464 }
00465 LEAVE_FUNC;
00466 }
00467
00468 static xmlNode *_alarmd_queue_to_xml(AlarmdObject *object)
00469 {
00470 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(object);
00471 GParameter *properties = NULL;
00472 guint n_properties = 0;
00473 guint i;
00474
00475 xmlNode *node = xmlNewNode(NULL, "queue");
00476 ENTER_FUNC;
00477
00478 properties = alarmd_object_get_properties(object, &n_properties);
00479
00480 for (i = 0; i < n_properties; i++) {
00481 gchar *temp = NULL;
00482 xmlNode *children = NULL;
00483 xmlNode *added_node = NULL;
00484 guint j;
00485
00486 switch (G_VALUE_TYPE(&properties[i].value)) {
00487 case G_TYPE_BOOLEAN:
00488 temp = g_strdup_printf("%d", g_value_get_boolean(&properties[i].value));
00489 break;
00490 case G_TYPE_CHAR:
00491 temp = g_strdup_printf("%c", g_value_get_char(&properties[i].value));
00492 break;
00493 case G_TYPE_DOUBLE:
00494 temp = g_strdup_printf("%f", g_value_get_double(&properties[i].value));
00495 break;
00496 case G_TYPE_FLOAT:
00497 temp = g_strdup_printf("%f", g_value_get_float(&properties[i].value));
00498 break;
00499 case G_TYPE_INT:
00500 temp = g_strdup_printf("%d", g_value_get_int(&properties[i].value));
00501 break;
00502 case G_TYPE_INT64:
00503 temp = g_strdup_printf("%lld", g_value_get_int64(&properties[i].value));
00504 break;
00505 case G_TYPE_LONG:
00506 temp = g_strdup_printf("%ld", g_value_get_long(&properties[i].value));
00507 break;
00508 case G_TYPE_OBJECT:
00509 temp = NULL;
00510 if (g_value_get_object(&properties[i].value)) {
00511 children = alarmd_object_to_xml(ALARMD_OBJECT(g_value_get_object(&properties[i].value)));
00512 }
00513 break;
00514 case G_TYPE_STRING:
00515 temp = g_strdup(g_value_get_string(&properties[i].value));
00516 break;
00517 case G_TYPE_UCHAR:
00518 temp = g_strdup_printf("%c", g_value_get_uchar(&properties[i].value));
00519 break;
00520 case G_TYPE_UINT:
00521 temp = g_strdup_printf("%u", g_value_get_uint(&properties[i].value));
00522 break;
00523 case G_TYPE_UINT64:
00524 temp = g_strdup_printf("%llu", g_value_get_uint64(&properties[i].value));
00525 break;
00526 case G_TYPE_ULONG:
00527 temp = g_strdup_printf("%lu", g_value_get_long(&properties[i].value));
00528 break;
00529 default:
00530 temp = NULL;
00531 g_warning("Unsupported type: %s", g_type_name(G_VALUE_TYPE(&properties[i].value)));
00532 break;
00533 }
00534 added_node = xmlNewChild(node, NULL, "parameter", temp);
00535 if (temp) {
00536 g_free(temp);
00537 temp = NULL;
00538 }
00539 if (children) {
00540 xmlAddChild(added_node, children);
00541 }
00542 for (j = 0; j < Y_COUNT; j++) {
00543 if (G_VALUE_TYPE(&properties[i].value) == type_gtypes[j])
00544 break;
00545 }
00546 xmlNewProp(added_node, "name", properties[i].name);
00547 xmlNewProp(added_node, "type", type_names[j]);
00548 }
00549
00550 alarmd_gparameterv_free(properties, n_properties);
00551
00552 g_slist_foreach(priv->pending, _alarmd_queue_event_to_xml, (gpointer)node);
00553 g_slist_foreach(priv->events, _alarmd_queue_event_to_xml, (gpointer)node);
00554
00555 LEAVE_FUNC;
00556 return node;
00557 }
00558
00559 static void _alarmd_queue_event_dequeued(AlarmdQueue *queue, AlarmdEvent *event)
00560 {
00561 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00562 ENTER_FUNC;
00563
00564 if (priv->queued == event) {
00565 priv->queued = NULL;
00566 } else if (priv->queued_powerup == event) {
00567 priv->queued_powerup = NULL;
00568 }
00569
00570 if (priv->events &&
00571 ((!priv->queued &&
00572 priv->timer &&
00573 !priv->timer_powerup) ||
00574 (!priv->queued_powerup &&
00575 priv->timer_powerup &&
00576 !priv->timer))) {
00577 gpointer event = priv->events->data;
00578 DEBUG("event: %p", event);
00579 g_object_ref(event);
00580
00581 g_signal_handlers_block_by_func(event,
00582 _alarmd_queue_event_dequeued,
00583 queue);
00584 alarmd_event_queue((AlarmdEvent *)priv->events->data, priv->timer ? priv->timer : priv->timer_powerup);
00585 g_signal_handlers_unblock_by_func(event,
00586 _alarmd_queue_event_dequeued,
00587 queue);
00588
00589 g_object_unref(event);
00590 } else if (priv->events) {
00591 if (priv->queued == NULL && priv->timer) {
00592 AlarmdEvent *first_nopowerup = _alarmd_queue_find_first_event(priv->events, FALSE);
00593 if (first_nopowerup) {
00594 g_signal_handlers_block_by_func(first_nopowerup, _alarmd_queue_event_dequeued, queue);
00595 alarmd_event_queue(first_nopowerup, priv->timer);
00596 g_signal_handlers_unblock_by_func(first_nopowerup, _alarmd_queue_event_dequeued, queue);
00597 }
00598 }
00599 if (priv->queued_powerup == NULL && priv->timer_powerup) {
00600 AlarmdEvent *first_powerup = _alarmd_queue_find_first_event(priv->events, TRUE);
00601 if (first_powerup) {
00602 g_signal_handlers_block_by_func(first_powerup, _alarmd_queue_event_dequeued, queue);
00603 alarmd_event_queue(first_powerup, priv->timer_powerup);
00604 g_signal_handlers_unblock_by_func(first_powerup, _alarmd_queue_event_dequeued, queue);
00605 }
00606 }
00607 }
00608
00609 LEAVE_FUNC;
00610 }
00611
00612 static void _alarmd_queue_event_queued(AlarmdQueue *queue, gpointer plugin, AlarmdEvent *event)
00613 {
00614 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00615
00616 (void)plugin;
00617 ENTER_FUNC;
00618
00619 if (plugin == priv->timer_powerup) {
00620 priv->queued_powerup = event;
00621 } else {
00622 priv->queued = event;
00623 }
00624 LEAVE_FUNC;
00625 }
00626
00627 static void _alarmd_queue_event_changed(AlarmdQueue *queue, AlarmdEvent *event)
00628 {
00629 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00630 ENTER_FUNC;
00631
00632 priv->events = g_slist_remove(priv->events, event);
00633 priv->pending = g_slist_remove(priv->pending, event);
00634
00635 alarmd_event_dequeue(event);
00636
00637 priv->events = g_slist_insert_sorted(priv->events, event, _alarmd_event_compare_func);
00638
00639 if (priv->queued == NULL) {
00640 _alarmd_queue_event_dequeued(queue, NULL);
00641 } else if (priv->queued != ALARMD_EVENT(priv->events->data)) {
00642 alarmd_event_dequeue(priv->queued);
00643 }
00644
00645 alarmd_object_changed(ALARMD_OBJECT(queue));
00646
00647 LEAVE_FUNC;
00648 }
00649
00650 static void _alarmd_queue_event_fired(AlarmdQueue *queue, gboolean delayed,
00651 AlarmdEvent *event)
00652 {
00653 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00654 ENTER_FUNC;
00655
00656 (void)delayed;
00657
00658 priv->events = g_slist_remove(priv->events, event);
00659 priv->pending = g_slist_append(priv->pending, event);
00660
00661 _alarmd_queue_event_dequeued(queue, event);
00662 LEAVE_FUNC;
00663 }
00664
00665 static void _alarmd_queue_event_cancelled(AlarmdQueue *queue, AlarmdEvent *event)
00666 {
00667 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00668 ENTER_FUNC;
00669
00670 g_signal_handlers_disconnect_by_func(event, _alarmd_queue_event_queued, queue);
00671 g_signal_handlers_disconnect_by_func(event, _alarmd_queue_event_dequeued, queue);
00672 g_signal_handlers_disconnect_by_func(event, _alarmd_queue_event_changed, queue);
00673 g_signal_handlers_disconnect_by_func(event, _alarmd_queue_event_cancelled, queue);
00674 g_signal_handlers_disconnect_by_func(event, _alarmd_queue_event_fired, queue);
00675 priv->events = g_slist_remove(priv->events, event);
00676 priv->pending = g_slist_remove(priv->pending, event);
00677
00678 DEBUG("Unreffing %p", event);
00679 g_object_unref(event);
00680 alarmd_object_changed(ALARMD_OBJECT(queue));
00681 _alarmd_queue_event_dequeued(queue, event);
00682 LEAVE_FUNC;
00683 }
00684
00685 static AlarmdEvent *_alarmd_queue_find_event(GSList *list, glong event_id)
00686 {
00687 GSList *iter;
00688 ENTER_FUNC;
00689
00690 for (iter = list; iter != NULL; iter = iter->next) {
00691 AlarmdEvent *event = ALARMD_EVENT(iter->data);
00692 glong events_id;
00693 g_object_get(event, "cookie", &events_id, NULL);
00694 if (events_id == event_id) {
00695 LEAVE_FUNC;
00696 return iter->data;
00697 }
00698 }
00699
00700 LEAVE_FUNC;
00701 return NULL;
00702 }
00703
00704 static AlarmdEvent *_alarmd_queue_find_first_event(GSList *list, gboolean need_power_up)
00705 {
00706 GSList *iter;
00707 ENTER_FUNC;
00708
00709 for (iter = list; iter != NULL; iter = iter->next) {
00710 AlarmdEvent *event = ALARMD_EVENT(iter->data);
00711 if (alarmd_event_need_power_up(event) == need_power_up) {
00712 LEAVE_FUNC;
00713 return iter->data;
00714 }
00715 }
00716
00717 LEAVE_FUNC;
00718 return NULL;
00719 }
00720
00721 static glong *_alarmd_queue_real_query_events(AlarmdQueue *queue, gint64 start_time, gint64 end_time, gint32 flag_mask, gint32 flags, guint *n_events)
00722 {
00723 AlarmdQueuePrivate *priv = ALARMD_QUEUE_GET_PRIVATE(queue);
00724 GSList *events = g_slist_concat(g_slist_copy(priv->events), g_slist_copy(priv->pending));
00725 GSList *iter;
00726 GSList *result = NULL;
00727 glong *retval;
00728 guint i;
00729 ENTER_FUNC;
00730 if (n_events == NULL) {
00731 LEAVE_FUNC;
00732 return NULL;
00733 }
00734 *n_events = 0;
00735 for (iter = events; iter != NULL; iter = iter->next) {
00736 gint64 event_time = alarmd_event_get_time(ALARMD_EVENT(iter->data));
00737 glong event_id;
00738 if (event_time < start_time) {
00739 continue;
00740 } else if (event_time > end_time) {
00741 break;
00742 }
00743 if ((alarmd_event_get_flags(ALARMD_EVENT(iter->data)) & flag_mask) ==
00744 (flags & flag_mask)) {
00745 g_object_get(iter->data, "cookie", &event_id, NULL);
00746 result = g_slist_append(result, GINT_TO_POINTER(event_id));
00747 (*n_events)++;
00748 DEBUG("Count now %u", *n_events);
00749 }
00750 }
00751 g_slist_free(events);
00752 DEBUG("Allocated %u event id's", *n_events);
00753 retval = g_new0(glong, *n_events);
00754 for (i = 0; i < *n_events; i++) {
00755 retval[i] = GPOINTER_TO_INT(result->data);
00756 result = g_slist_delete_link(result, result);
00757 }
00758 g_slist_free(result);
00759 LEAVE_FUNC;
00760 return retval;
00761 }
00762
00763 static GSList *_alarmd_queue_get_saved_properties()
00764 {
00765 guint i;
00766 GSList *retval = NULL;
00767 ENTER_FUNC;
00768 retval = ALARMD_OBJECT_CLASS(g_type_class_peek(g_type_parent(ALARMD_TYPE_EVENT)))->get_saved_properties();
00769 for (i = 0; i < S_COUNT; i++) {
00770 retval = g_slist_append(retval, (gpointer)saved_properties[i]);
00771 }
00772 LEAVE_FUNC;
00773 return retval;
00774 }