Simple fixes to get navit compiling with MSVC
[profile/ivi/navit.git] / navit / 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 #include "plugin.h"
26
27 static GMainLoop *loop;
28
29 static void event_glib_main_loop_run(void)
30 {
31         loop = g_main_loop_new (NULL, TRUE);
32         if (g_main_loop_is_running (loop))
33         {
34                 g_main_loop_run (loop);
35         }
36 }
37
38 static void event_glib_main_loop_quit(void)
39 {
40         if (loop) {
41                 g_main_loop_quit(loop);
42                 g_main_loop_unref(loop);
43         }
44
45 }
46
47 struct event_watch {
48         GIOChannel *iochan;
49         guint source;
50 };
51
52 static gboolean
53 event_glib_call_watch(GIOChannel * iochan, GIOCondition condition, gpointer t)
54 {
55         struct callback *cb=t;
56         callback_call_0(cb);
57         return TRUE;
58 }
59
60 static struct event_watch *
61 event_glib_add_watch(void *fd, enum event_watch_cond cond, struct callback *cb)
62 {
63         struct event_watch *ret=g_new0(struct event_watch, 1);
64         int flags=0;
65         ret->iochan = g_io_channel_unix_new(GPOINTER_TO_INT(fd));
66         switch (cond) {
67         case event_watch_cond_read:
68                 flags=G_IO_IN;
69                 break;
70         case event_watch_cond_write:
71                 flags=G_IO_OUT;
72                 break;
73         case event_watch_cond_except:
74                 flags=G_IO_ERR|G_IO_HUP;
75                 break;
76         }       
77         ret->source = g_io_add_watch(ret->iochan, flags, event_glib_call_watch, (gpointer)cb);
78         return ret;
79 }
80
81 static void
82 event_glib_remove_watch(struct event_watch *ev)
83 {
84         if (! ev)
85                 return;
86         g_source_remove(ev->source);
87         g_io_channel_unref(ev->iochan);
88         g_free(ev);
89 }
90
91 struct event_timeout {
92         guint source;
93         struct callback *cb;
94 };
95
96 static gboolean
97 event_glib_call_timeout_single(struct event_timeout *ev)
98 {
99         callback_call_0(ev->cb);
100         g_free(ev);
101         return FALSE;
102 }
103
104 static gboolean
105 event_glib_call_timeout_multi(struct event_timeout *ev)
106 {
107         callback_call_0(ev->cb);
108         return TRUE;
109 }
110
111
112 static struct event_timeout *
113 event_glib_add_timeout(int timeout, int multi, struct callback *cb)
114 {
115         struct event_timeout *ret=g_new0(struct event_timeout, 1);
116         ret->cb=cb;
117         ret->source = g_timeout_add(timeout, multi ? (GSourceFunc)event_glib_call_timeout_multi : (GSourceFunc)event_glib_call_timeout_single, (gpointer)ret);
118
119         return ret;
120 }
121
122 static void
123 event_glib_remove_timeout(struct event_timeout *ev)
124 {
125         if (! ev)
126                 return;
127         g_source_remove(ev->source);
128         g_free(ev);
129 }
130
131 struct event_idle {
132         guint source;
133         struct callback *cb;
134 };
135
136 static gboolean
137 event_glib_call_idle(struct event_idle *ev)
138 {
139         callback_call_0(ev->cb);
140         return TRUE;
141 }
142
143 static struct event_idle *
144 event_glib_add_idle(int priority, struct callback *cb)
145 {
146         struct event_idle *ret=g_new0(struct event_idle, 1);
147         ret->cb=cb;
148         ret->source = g_idle_add_full(priority+100, (GSourceFunc)event_glib_call_idle, (gpointer)ret, NULL);
149         return ret;
150 }
151
152 static void
153 event_glib_remove_idle(struct event_idle *ev)
154 {
155         if (! ev)
156                 return;
157         g_source_remove(ev->source);
158         g_free(ev);
159 }
160
161 static void
162 event_glib_call_callback(struct callback_list *cb)
163 {
164 /* 
165  Idea for implementation:
166  Create a pipe then use add_watch
167  add callback to a queue
168  from here write to the pipe to wakeup the pool
169  then from the gui thread process the callback queue
170 */
171 }
172
173 static struct event_methods event_glib_methods = {
174         event_glib_main_loop_run,
175         event_glib_main_loop_quit,
176         event_glib_add_watch,
177         event_glib_remove_watch,
178         event_glib_add_timeout,
179         event_glib_remove_timeout,
180         event_glib_add_idle,
181         event_glib_remove_idle,
182         event_glib_call_callback,
183 };
184
185 struct event_priv {
186         int data;
187 };
188
189 static struct event_priv*
190 event_glib_new(struct event_methods *meth)
191 {
192         *meth=event_glib_methods;
193         return (struct event_priv *)event_glib_new;
194 }
195
196 void
197 event_glib_init(void)
198 {
199         plugin_register_event_type("glib", event_glib_new);
200 }