00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <glib/gmain.h>
00023 #include <glib/gtypes.h>
00024 #include <time.h>
00025 #include <stdio.h>
00026 #include <osso-log.h>
00027 #include "include/timer-interface.h"
00028 #include "debug.h"
00029
00030 static gboolean gtimeout_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data);
00031 static gboolean gtimeout_remove_event(TimerPlugin *plugin);
00032 static time_t gtimeout_get_time(TimerPlugin *plugin);
00033 static void gtimeout_time_changed(TimerPlugin *plugin);
00034 static void gtimeout_plugin_deinit(TimerPlugin *plugin);
00035
00036 typedef struct _GTimeoutTimerEvent GTimeoutTimerEvent;
00037 struct _GTimeoutTimerEvent {
00038 guint timer_id;
00039 time_t timer_time;
00040 TimerCallback cb;
00041 TimerCancel cancel;
00042 gpointer cb_data;
00043
00044 TimerPlugin *plugin;
00045 };
00046
00047 typedef struct _GTimeoutIdleEvent GTimeoutIdleEvent;
00048 struct _GTimeoutIdleEvent {
00049 TimerCallback cb;
00050 gpointer cb_data;
00051 gboolean delayed;
00052 };
00053
00054 gboolean plugin_initialize(TimerPlugin *plugin)
00055 {
00056 ENTER_FUNC;
00057 plugin->remove_event = gtimeout_remove_event;
00058 plugin->get_time = gtimeout_get_time;
00059 plugin->plugin_deinit = gtimeout_plugin_deinit;
00060 plugin->set_event = gtimeout_set_event;
00061 plugin->time_changed = gtimeout_time_changed;
00062
00063 plugin->can_power_up = FALSE;
00064 plugin->priority = 10;
00065 plugin->plugin_data = NULL;
00066
00067 LEAVE_FUNC;
00068 return TRUE;
00069 }
00070
00071 static gboolean _gtimeout_event_fire(gpointer event)
00072 {
00073 GTimeoutTimerEvent *ev = (GTimeoutTimerEvent *)event;
00074 ENTER_FUNC;
00075
00076 ev->plugin->plugin_data = NULL;
00077
00078 if (ev->cb) {
00079 ev->cb(ev->cb_data, FALSE);
00080 }
00081
00082 g_free(event);
00083
00084 LEAVE_FUNC;
00085 return FALSE;
00086 }
00087
00088 static gboolean _gtimeout_idle_event_fire(gpointer event) {
00089 GTimeoutIdleEvent *ev = event;
00090 ENTER_FUNC;
00091
00092 if (ev->cb) {
00093 ev->cb(ev->cb_data, ev->delayed);
00094 }
00095
00096 g_free(event);
00097
00098 LEAVE_FUNC;
00099 return FALSE;
00100 }
00101
00102 static gboolean gtimeout_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data)
00103 {
00104 GTimeoutTimerEvent *event = NULL;
00105 time_t time_now = time(NULL);
00106 ENTER_FUNC;
00107
00108 DEBUG("wanted time = %lu", wanted_time);
00109
00110 if (plugin == NULL || cb == NULL) {
00111 DEBUG("plugin == NULL || cb == NULL");
00112 LEAVE_FUNC;
00113 return FALSE;
00114 }
00115
00116 plugin->remove_event(plugin);
00117
00118 if (time_now > wanted_time) {
00119 GTimeoutIdleEvent *ev = g_new0(GTimeoutIdleEvent, 1);
00120 ev->cb = cb;
00121 ev->cb_data = user_data;
00122 ev->delayed = time_now > wanted_time + 10 ? TRUE : FALSE;
00123 g_idle_add(_gtimeout_idle_event_fire, ev);
00124
00125 LEAVE_FUNC;
00126 return TRUE;
00127 }
00128
00129 event = g_new0(GTimeoutTimerEvent, 1);
00130
00131 event->timer_id = g_timeout_add((wanted_time - time_now) * 1000, _gtimeout_event_fire, event);
00132
00133 if (event->timer_id == 0) {
00134 ULOG_WARN_F("Adding timeout failed.");
00135 g_free(event);
00136
00137 LEAVE_FUNC;
00138 return FALSE;
00139 }
00140
00141 event->timer_time = wanted_time;
00142 event->cb = cb;
00143 event->cancel = cancel;
00144 event->cb_data = user_data;
00145
00146 event->plugin = plugin;
00147
00148 plugin->plugin_data = (gpointer)event;
00149
00150 LEAVE_FUNC;
00151 return TRUE;
00152 }
00153
00154 static gboolean gtimeout_remove_event(TimerPlugin *plugin)
00155 {
00156 ENTER_FUNC;
00157 if (plugin && plugin->plugin_data) {
00158 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00159
00160 g_source_remove(event->timer_id);
00161
00162 if (event->cancel) {
00163 event->cancel(event->cb_data);
00164 }
00165
00166 plugin->plugin_data = NULL;
00167
00168 g_free(event);
00169
00170 LEAVE_FUNC;
00171 return TRUE;
00172 }
00173
00174 LEAVE_FUNC;
00175 return FALSE;
00176 }
00177
00178 static time_t gtimeout_get_time(TimerPlugin *plugin)
00179 {
00180 ENTER_FUNC;
00181 if (plugin->plugin_data) {
00182 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00183
00184 LEAVE_FUNC;
00185 return event->timer_time;
00186 }
00187
00188 LEAVE_FUNC;
00189 return 0;
00190 }
00191
00192 static void gtimeout_plugin_deinit(TimerPlugin *plugin)
00193 {
00194 ENTER_FUNC;
00195 plugin->remove_event(plugin);
00196 LEAVE_FUNC;
00197 }
00198
00199 static void gtimeout_time_changed(TimerPlugin *plugin)
00200 {
00201 ENTER_FUNC;
00202 if (plugin->plugin_data) {
00203 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00204 time_t now = time(NULL);
00205 g_source_remove(event->timer_id);
00206 if (now > event->timer_time) {
00207 plugin->plugin_data = NULL;
00208
00209 if (event->cb) {
00210 event->cb(event->cb_data, FALSE);
00211 }
00212
00213 g_free(event);
00214 } else {
00215 event->timer_id = g_timeout_add((event->timer_time - now) * 1000, _gtimeout_event_fire, event);
00216 }
00217 }
00218 LEAVE_FUNC;
00219 }