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

initialize.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 <libxml/parser.h>
00025 #include <libxml/tree.h>
00026 #include <string.h>
00027 #include "include/alarm_event.h"
00028 #include "initialize.h"
00029 #include "timer-loader.h"
00030 #include "xmlobjectfactory.h"
00031 #include "queue.h"
00032 #include "eventrecurring.h"
00033 #include "action.h"
00034 #include "actiondbus.h"
00035 #include "actionexec.h"
00036 #include "debug.h"
00037 
00038 struct files_t {
00039         AlarmdQueue *queue;
00040         gchar *queue_file;
00041         gchar *next_time_file;
00042         gchar *next_mode_file;
00043         guint timer_id;
00044 };
00045 
00046 static void _write_data(AlarmdQueue *queue, struct files_t *files);
00047 static gboolean _real_write_data(struct files_t *files);
00048 static void _free_data(struct files_t *files);
00049 static void _queue_changed(gpointer user_data);
00050 
00051 AlarmdQueue *init_queue(const gchar *queue_file, const gchar *next_time_file,
00052                 const gchar *next_mode_file)
00053 {
00054         AlarmdQueue *retval = NULL;
00055         xmlDoc *doc = NULL;
00056         xmlNode *root = NULL;
00057         struct files_t *files = NULL;
00058         GSList *timers = NULL;
00059         gboolean do_save = FALSE;
00060 
00061         if (queue_file == NULL) {
00062                 return NULL;
00063         }
00064 
00065         retval = alarmd_queue_new();
00066         timers = load_timer_plugins(NULL);
00067 
00068         g_object_set(retval, "timer", timers_get_plugin(timers, FALSE), NULL);
00069         g_object_set(retval, "timer_powerup", timers_get_plugin(timers, TRUE), NULL);
00070         g_object_set_data_full(G_OBJECT(retval), "timers", timers,
00071                         (GDestroyNotify)close_timer_plugins);
00072 
00073         DEBUG("%s", queue_file);
00074 
00075         doc = xmlReadFile(queue_file, NULL, 0);
00076 
00077         if (doc) {
00078                 root = xmlDocGetRootElement(doc);
00079 
00080                 if (strcmp(root->name, "queue") == 0) {
00081                         guint n_params, i;
00082                         GParameter *param = elements_to_parameters(root,
00083                                         &n_params);
00084                         gulong signal_id;
00085 
00086                         for (i = 0; i < n_params; i++) {
00087                                 g_object_set_property(G_OBJECT(retval), param[i].name, &param[i].value);
00088                         }
00089                         alarmd_gparameterv_free(param, n_params);
00090                         signal_id = g_signal_connect_swapped(retval, "changed",
00091                                         G_CALLBACK(_queue_changed), 
00092                                         &do_save);
00093 
00094                         for (root = root->children; root != NULL; root = root->next) {
00095                                 AlarmdObject *object = NULL;
00096                                 if (root->type != XML_ELEMENT_NODE) {
00097                                         continue;
00098                                 }
00099                                 object = object_factory(root);
00100 
00101                                 if (!object) continue;
00102 
00103                                 if (ALARMD_IS_EVENT(object)) {
00104                                         alarmd_queue_add_event(retval, ALARMD_EVENT(object));
00105                                 }
00106                                 g_object_unref(object);
00107                         }
00108 
00109                         g_signal_handler_disconnect(retval, signal_id);
00110                 }
00111 
00112                 xmlFreeDoc(doc);
00113                 xmlCleanupParser();
00114         }
00115 
00116         DEBUG("Connecting...");
00117         files = g_new(struct files_t, 1);
00118         files->queue = retval;
00119         files->queue_file = g_strdup(queue_file);
00120         files->next_time_file = g_strdup(next_time_file);
00121         files->next_mode_file = g_strdup(next_mode_file);
00122         files->timer_id = 0;
00123 
00124         if (do_save) {
00125                 _write_data(retval, files);
00126         }
00127         g_signal_connect_data(retval, "changed", (GCallback)_write_data, files, (GClosureNotify)_free_data, G_CONNECT_AFTER);
00128 
00129         timer_plugins_set_startup(timers, FALSE);
00130 
00131         return retval;
00132 }
00133 
00134 void alarmd_type_init(void)
00135 {
00136         (void)ALARMD_TYPE_EVENT_RECURRING;
00137         (void)ALARMD_TYPE_ACTION;
00138         (void)ALARMD_TYPE_ACTION_DBUS;
00139         (void)ALARMD_TYPE_ACTION_EXEC;
00140 }
00141 
00142 static void _write_data(AlarmdQueue *queue, struct files_t *files)
00143 {
00144         ENTER_FUNC;
00145 
00146         (void)queue;
00147 
00148         if (files->timer_id == 0) {
00149                 files->timer_id = g_idle_add((GSourceFunc)_real_write_data,
00150                                 files);
00151         }
00152         LEAVE_FUNC;
00153 }
00154 
00155 static gboolean _real_write_data(struct files_t *files)
00156 {
00157         ENTER_FUNC;
00158         xmlDoc *doc = xmlNewDoc("1.0");
00159         xmlNode *root_node = alarmd_object_to_xml(ALARMD_OBJECT(files->queue));
00160         glong *events = NULL;
00161         guint n_events = 0;
00162         FILE *write = NULL;
00163         gint flags = 0;
00164         time_t event_time = 0;
00165         const char *mode = "n/a";
00166         gchar *old_contents = NULL;
00167         gchar *new_contents = NULL;
00168 
00169         files->timer_id = 0;
00170 
00171         xmlDocSetRootElement(doc, root_node);
00172 
00173         xmlSaveFormatFileEnc(files->queue_file, doc, "UTF-8", 1);
00174 
00175         xmlFreeDoc(doc);
00176         xmlCleanupParser();
00177 
00178         events = alarmd_queue_query_events(files->queue, 0, G_MAXINT64,
00179                         ALARM_EVENT_BOOT, ALARM_EVENT_BOOT,
00180                         &n_events);
00181 
00182         if (n_events > 0) {
00183                 AlarmdEvent *event = alarmd_queue_get_event(files->queue,
00184                                 events[0]);
00185                 event_time = alarmd_event_get_time(event);
00186                 AlarmdAction *action = NULL;
00187                 g_object_get(event, "action", &action, NULL);
00188                 if (action) {
00189                         g_object_get(action, "flags", &flags, NULL);
00190                         g_object_unref(action);
00191                 }
00192                 mode = (flags & ALARM_EVENT_ACTDEAD) ? "actdead" : "powerup";
00193                 g_free(events);
00194         }
00195 
00196         
00197         g_file_get_contents(files->next_time_file,
00198                         &old_contents,
00199                         NULL,
00200                         NULL);
00201         new_contents = g_strdup_printf("%ld", event_time);
00202         if (!(old_contents && new_contents &&
00203                                 strcmp(g_strchomp(old_contents),
00204                                         new_contents) == 0)) {
00205                 write = fopen(files->next_time_file, "w");
00206                 if (write) {
00207                         fprintf(write, "%s\n", new_contents);
00208                         fclose(write);
00209                 }
00210         }
00211         g_free(new_contents);
00212         g_free(old_contents);
00213         old_contents = NULL;
00214         g_file_get_contents(files->next_mode_file,
00215                         &old_contents,
00216                         NULL,
00217                         NULL);
00218 
00219         if (!(old_contents && mode &&
00220                                 strcmp(g_strchomp(old_contents),
00221                                         mode) == 0)) {
00222                 write = fopen(files->next_mode_file, "w");
00223                 if (write) {
00224                         fprintf(write, "%s\n", mode);
00225                         fclose(write);
00226                 }
00227         }
00228         
00229         LEAVE_FUNC;
00230         return FALSE;
00231 }
00232 
00233 static void _free_data(struct files_t *files)
00234 {
00235         g_free(files->queue_file);
00236         g_free(files->next_time_file);
00237         g_free(files->next_mode_file);
00238         g_free(files);
00239 }
00240 
00241 static void _queue_changed(gpointer user_data)
00242 {
00243         gboolean *changed = user_data;
00244         *changed = TRUE;
00245 }

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