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