0
|
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 |
|