Main Page | Data Structures | File List | Data Fields | Globals

queue.c

Go to the documentation of this file.
00001 /**
00002  * This file is part of alarmd
00003  *
00004  * Contact Person: David Weinehall <david.weinehall@nokia.com>
00005  *
00006  * Copyright (C) 2006 Nokia Corporation
00007  * alarmd and libalarm are free software; you can redistribute them
00008  * and/or modify them under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  *
00011  * alarmd and libalarm are distributed in the hope that they will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this software; if not, write to the Free
00018  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
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 }

Generated on Thu Dec 21 18:23:30 2006 for Alarmd by  doxygen 1.4.2