Add:core:Further works on event system abstraction
[navit-package] / navit / event_glib.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <glib.h>
21 #include "event.h"
22 #include "event_glib.h"
23 #include "debug.h"
24 #include "callback.h"
25
26 static GMainLoop *loop;
27
28 static void event_glib_main_loop_run(void)
29 {
30         loop = g_main_loop_new (NULL, TRUE);
31         if (g_main_loop_is_running (loop))
32         {
33                 g_main_loop_run (loop);
34         }
35 }
36
37 static void event_glib_main_loop_quit(void)
38 {
39         if (loop)
40                 g_main_loop_quit(loop);
41 }
42
43 struct event_watch {
44         GIOChannel *iochan;
45         guint source;
46 };
47
48 static gboolean
49 event_glib_call_watch(GIOChannel * iochan, GIOCondition condition, gpointer t)
50 {
51         struct callback *cb=t;
52         callback_call_0(cb);
53         return TRUE;
54 }
55
56 static struct event_watch *
57 event_glib_add_watch(int fd, int w, struct callback *cb)
58 {
59         struct event_watch *ret=g_new0(struct event_watch, 1);
60         ret->iochan = g_io_channel_unix_new(fd);
61         ret->source = g_io_add_watch(ret->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP, event_glib_call_watch, (gpointer)cb);
62         return ret;
63 }
64
65 static void
66 event_glib_remove_watch(struct event_watch *ev)
67 {
68         GError *error = NULL;
69         g_source_remove(ev->source);
70         g_io_channel_shutdown(ev->iochan, 0, &error);
71         g_free(ev);
72 }
73
74 struct event_timeout {
75         guint source;
76 };
77
78 static gboolean
79 event_glib_call_timeout_single(gpointer t)
80 {
81         struct callback *cb=t;
82         callback_call_0(cb);
83         return FALSE;
84 }
85
86 static gboolean
87 event_glib_call_timeout_multi(gpointer t)
88 {
89         struct callback *cb=t;
90         callback_call_0(cb);
91         return TRUE;
92 }
93
94
95 static struct event_timeout *
96 event_glib_add_timeout(int timeout, int multi, struct callback *cb)
97 {
98         struct event_timeout *ret=g_new0(struct event_timeout, 1);
99         ret->source = g_timeout_add(timeout, multi ? (GSourceFunc)event_glib_call_timeout_multi : (GSourceFunc)event_glib_call_timeout_single, (gpointer)cb);
100
101         return ret;
102 }
103
104 static void
105 event_glib_remove_timeout(struct event_timeout *ev)
106 {
107         g_source_remove(ev->source);
108         g_free(ev);
109 }
110
111 static struct event_idle *
112 event_glib_add_idle(struct callback *cb)
113 {
114         return NULL;
115 }
116
117 static void
118 event_glib_remove_idle(struct event_idle *ev)
119 {
120 }
121
122 static struct event_methods event_glib_methods = {
123         event_glib_main_loop_run,
124         event_glib_main_loop_quit,
125         event_glib_add_watch,
126         event_glib_remove_watch,
127         event_glib_add_timeout,
128         event_glib_remove_timeout,
129         event_glib_add_idle,
130         event_glib_remove_idle,
131 };
132
133 static void
134 event_glib_new(struct event_methods *meth)
135 {
136         *meth=event_glib_methods;
137 }
138
139 void
140 event_glib_init(void)
141 {
142         plugin_register_event_type("glib", event_glib_new);
143 }