|
1 |
|
2 #include <lua.h> |
|
3 #include <lauxlib.h> |
|
4 #include <glib.h> |
|
5 |
|
6 #include "glib_types.h" |
|
7 |
|
8 /// g.main_context |
|
9 /// Glib main context object. Mainly useful when lua needs to |
|
10 /// manage glib-based libs. |
|
11 |
|
12 /// g.main_context.new |
|
13 /// Creates new main context object. |
|
14 /// R: g main context object |
|
15 static int lglib_main_context_new (lua_State *L) |
|
16 { |
|
17 GMainContext *context = g_main_context_new (); |
|
18 lglib_main_context_bless (L, context); |
|
19 g_main_context_unref (context); |
|
20 return 1; |
|
21 } |
|
22 |
|
23 /// g.main_context.bless |
|
24 /// Blesses given pointer to g main context object. |
|
25 /// A: lightuserdata (C g main context object) |
|
26 /// R: g main context object |
|
27 static int lglib_main_context_bless_lua (lua_State *L) |
|
28 { |
|
29 luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "g main context lightuserdata expected"); |
|
30 lglib_main_context_bless (L, lua_touserdata (L, 1)); |
|
31 return 1; |
|
32 } |
|
33 |
|
34 /// g.main_context.default |
|
35 /// Returns default main context object. |
|
36 /// R: g main context object |
|
37 static int lglib_main_context_default (lua_State *L) |
|
38 { |
|
39 GMainContext *context = g_main_context_default (); |
|
40 lglib_main_context_bless (L, context); |
|
41 // XXX g_main_context_unref (context); |
|
42 return 1; |
|
43 } |
|
44 |
|
45 /// main_context:iteration |
|
46 /// Performs single full iteration in blocking or non-blocking manner, |
|
47 /// depending on value of argument. |
|
48 /// Returns true, if some events have been handled. |
|
49 /// A: boolean (optional) |
|
50 /// R: boolean |
|
51 static int lglib_main_context_iteration (lua_State *L) |
|
52 { |
|
53 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
54 int may_block = 0; |
|
55 if ( lua_gettop (L) > 1 ) { |
|
56 luaL_checktype (L, 2, LUA_TBOOLEAN); |
|
57 may_block = lua_toboolean (L, 2); |
|
58 } |
|
59 lua_pushboolean (L, g_main_context_iteration (object->main_context, may_block)); |
|
60 return 1; |
|
61 } |
|
62 |
|
63 /// main_context:pending |
|
64 /// Indicates, if there are present events in sources. |
|
65 /// R: boolean |
|
66 static int lglib_main_context_pending (lua_State *L) |
|
67 { |
|
68 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
69 lua_pushboolean (L, g_main_context_pending (object->main_context)); |
|
70 return 1; |
|
71 } |
|
72 |
|
73 /// main_context:find_source |
|
74 /// Returns source with given id. |
|
75 /// A: integer (source id) |
|
76 /// R: g main context object or nil |
|
77 static int lglib_main_context_find_source (lua_State *L) |
|
78 { |
|
79 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
80 int id = luaL_checkint (L, 2); |
|
81 GSource *source = g_main_context_find_source_by_id (object->main_context, id); |
|
82 if (source) { |
|
83 lglib_source_bless (L, source); |
|
84 // XXX g_source_unref (source) |
|
85 } else |
|
86 lua_pushnil (L); |
|
87 return 1; |
|
88 } |
|
89 |
|
90 /// main_context:wakeup |
|
91 /// Awakes main context if it currently poll() ing. |
|
92 /// XXX Seems to be threading-related routine, how lua will work in this case? |
|
93 static int lglib_main_context_wakeup (lua_State *L) |
|
94 { |
|
95 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
96 g_main_context_wakeup (object->main_context); |
|
97 return 0; |
|
98 } |
|
99 |
|
100 /// main_context:acquire |
|
101 /// Tries to own main context. |
|
102 /// R: boolean (success) |
|
103 static int lglib_main_context_acquire (lua_State *L) |
|
104 { |
|
105 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
106 lua_pushboolean (L, g_main_context_acquire (object->main_context)); |
|
107 return 1; |
|
108 } |
|
109 |
|
110 /// main_context:release |
|
111 /// Disowns acquired context. |
|
112 /// Note: release context as many times, as you acquired it. |
|
113 static int lglib_main_context_release (lua_State *L) |
|
114 { |
|
115 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
116 g_main_context_release (object->main_context); |
|
117 return 0; |
|
118 } |
|
119 |
|
120 /// main_context:owner |
|
121 /// Indicates if current thread is owner of context. |
|
122 /// R: boolean |
|
123 static int lglib_main_context_owner (lua_State *L) |
|
124 { |
|
125 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
126 lua_pushboolean (L, g_main_context_is_owner (object->main_context)); |
|
127 return 1; |
|
128 } |
|
129 |
|
130 /// main_context:wait |
|
131 /// For now this will not be implemented, as it requires threading part of glib |
|
132 |
|
133 /// WARNING: conventions for next four methods are likely to change |
|
134 /// as I become more familiar with all that stuff. |
|
135 |
|
136 /// main_context:prepare |
|
137 /// Polling preparation step. |
|
138 /// R: boolean (indicates readiness for dispatching before polling), integer (priority of most important ready source, if first value is true) |
|
139 static int lglib_main_context_prepare (lua_State *L) |
|
140 { |
|
141 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
142 gint priority; |
|
143 gboolean ready = g_main_context_prepare (object->main_context, &priority); |
|
144 lua_pushboolean (L, ready); |
|
145 if (!ready) |
|
146 return 1; |
|
147 lua_pushnumber (L, priority); |
|
148 return 0; |
|
149 } |
|
150 |
|
151 /// main_context:query |
|
152 /// Get necessary for polling information. |
|
153 /// A: integer (maximum priority), integer (number of fds to allocate) |
|
154 /// R: userdata (GPollFDs), integer (number of fds required), integer (timeout) |
|
155 static int lglib_main_context_query (lua_State *L) |
|
156 { |
|
157 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
158 int priority = luaL_checkint (L, 2); |
|
159 int nfds = luaL_checkint (L, 3); |
|
160 gint timeout; |
|
161 GPollFD *fds = lua_newuserdata (L, sizeof (GPollFD) * nfds); |
|
162 lua_pushnumber (L, g_main_context_query (object->main_context, priority, &timeout, fds, nfds)); |
|
163 lua_pushnumber (L, timeout); |
|
164 return 3; |
|
165 } |
|
166 |
|
167 /// main_context:check |
|
168 /// Passes results of polling back to main loop. |
|
169 /// A: integer (priority), userdata (GPollFDs), integer (number of fds) |
|
170 /// R: boolean (readiness for dispatching) |
|
171 static int lglib_main_context_check (lua_State *L) |
|
172 { |
|
173 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
174 int priority = luaL_checkint (L, 2); |
|
175 GPollFD *fds = lua_touserdata (L, 3); // FIXME |
|
176 int nfds = luaL_checkint (L, 4); |
|
177 lua_pushboolean (L, g_main_context_check (object->main_context, priority, fds, nfds)); |
|
178 return 1; |
|
179 } |
|
180 |
|
181 /// main_context:dispatch |
|
182 /// Actually dispatches pending event sources |
|
183 static int lglib_main_context_dispatch (lua_State *L) |
|
184 { |
|
185 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
186 g_main_context_dispatch (object->main_context); |
|
187 return 0; |
|
188 } |
|
189 |
|
190 /// main_context:poll_function |
|
191 /// main_context:add_poll |
|
192 /// main_context:remove_poll |
|
193 /// Let's delay implementing this until fd objects will be ready... |
|
194 |
|
195 /// main_context:pointer |
|
196 /// Returns pointe to underlying C structure. |
|
197 /// A: g main context object |
|
198 /// R: lightuserdata |
|
199 static int lglib_main_context_pointer (lua_State *L) |
|
200 { |
|
201 lglib_main_context_t *object = luaL_checklglib_main_context (L, 1); |
|
202 lua_pushlightuserdata (L, object->main_context); |
|
203 return 1; |
|
204 } |
|
205 |
|
206 static int lglib_main_context_gc (lua_State *L) |
|
207 { |
|
208 lglib_main_context_t *object = lua_touserdata (L, 1); |
|
209 g_main_context_unref (object->main_context); |
|
210 return 0; |
|
211 } |
|
212 |
|
213 static const luaL_Reg lglib_main_context_reg_f[] = { |
|
214 { "new", lglib_main_context_new }, |
|
215 { "bless", lglib_main_context_bless_lua }, |
|
216 { "default", lglib_main_context_default }, |
|
217 { NULL, NULL }, |
|
218 }; |
|
219 |
|
220 static const luaL_Reg lglib_main_context_reg_m[] = { |
|
221 { "iteration", lglib_main_context_iteration }, |
|
222 { "pending", lglib_main_context_pending }, |
|
223 { "find_source", lglib_main_context_find_source }, |
|
224 { "wakeup", lglib_main_context_wakeup }, |
|
225 { "acquire", lglib_main_context_acquire }, |
|
226 { "release", lglib_main_context_release }, |
|
227 { "owner", lglib_main_context_owner }, |
|
228 { "prepare", lglib_main_context_prepare }, |
|
229 { "query", lglib_main_context_query }, |
|
230 { "check", lglib_main_context_check }, |
|
231 { "dispatch", lglib_main_context_dispatch }, |
|
232 { "pointer", lglib_main_context_pointer }, |
|
233 { "__gc", lglib_main_context_gc }, |
|
234 { NULL, NULL }, |
|
235 }; |
|
236 |
|
237 int luaopen_glib_main_context (lua_State *L) |
|
238 { |
|
239 luaL_newmetatable (L, "glib.main_context" ); |
|
240 lua_pushstring (L, "__index"); |
|
241 lua_pushvalue (L, -2); |
|
242 lua_settable (L, -3); |
|
243 luaL_register (L, NULL, lglib_main_context_reg_m); |
|
244 lua_pop (L, 1); |
|
245 luaL_register (L, "g.main_context", lglib_main_context_reg_f); |
|
246 return 1; |
|
247 } |
|
248 |