1 /*
2 fxasq_lua.c - Lua bindings for fxasq.cpp
3 Copyright (c) 2007-2012 Jeffrey Pohlmeyer <yetanothergeek@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 */
20
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <lua.h>
26 #include <lualib.h>
27 #include <lauxlib.h>
28
29 #include "fxasq_c.h"
30
31 #include "intl.h"
32 #include "fxasq_lua.h"
33
34 #if LUA_VERSION_NUM<502
35 # define lua_rawlen lua_objlen
36 #endif
37
38 #define DLG_MODULE_NAME "dialog"
39 #define MetaName "_fxasq_metatable"
40
41
42 static const char*DialogBoxType="DialogBox";
43
44 typedef struct _DialogBox {
45 const char*id;
46 FxAsqDlg *dlg;
47 } DialogBox;
48
49
50
todialog(lua_State * L,int argnum)51 static DialogBox* todialog(lua_State *L, int argnum)
52 {
53 DialogBox*rv=(DialogBox*)lua_touserdata(L,argnum);
54 return (rv && (DialogBoxType==rv->id))?rv:NULL;
55 }
56
57
58
59 #define DLG_REQUIRE \
60 DialogBox*D=todialog(L,1); \
61 luaL_argcheck(L,D,1,_("expected DialogBox"))
62
63
64
65
asq_checkbox(lua_State * L)66 static int asq_checkbox(lua_State *L)
67 {
68 DLG_REQUIRE;
69 const char*label=luaL_checkstring(L,4);
70 luaL_argcheck(L,lua_isboolean(L,3),3,_("expected boolean"));
71 int value=lua_toboolean(L,3);
72 const char*key=luaL_checkstring(L,2);
73 fxasq_checkbox(D->dlg, key,value,label);
74 return 0;
75 }
76
77
78
asq_hr(lua_State * L)79 static int asq_hr(lua_State *L)
80 {
81 DLG_REQUIRE;
82 fxasq_hr(D->dlg);
83 return 0;
84 }
85
86
87
asq_text(lua_State * L)88 static int asq_text(lua_State *L)
89 {
90 DLG_REQUIRE;
91 const char*label=luaL_checkstring(L,4);
92 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
93 const char*key=luaL_checkstring(L,2);
94 fxasq_text(D->dlg, key,value,label);
95 return 0;
96 }
97
98
99
asq_password(lua_State * L)100 static int asq_password(lua_State *L)
101 {
102 DLG_REQUIRE;
103 const char*label=luaL_checkstring(L,4);
104 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
105 const char*key=luaL_checkstring(L,2);
106 fxasq_password(D->dlg, key,value,label);
107 return 0;
108 }
109
110
111
asq_file(lua_State * L)112 static int asq_file(lua_State *L)
113 {
114 DLG_REQUIRE;
115 const char*label=luaL_checkstring(L,4);
116 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
117 const char*key=luaL_checkstring(L,2);
118 fxasq_file(D->dlg, key,value,label);
119 return 0;
120 }
121
122
123
asq_color(lua_State * L)124 static int asq_color(lua_State *L)
125 {
126 DLG_REQUIRE;
127 const char*label=lua_isnil(L,4)?NULL:luaL_checkstring(L,4);
128 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
129 const char*key=luaL_checkstring(L,2);
130 fxasq_color(D->dlg, key,value,label);
131 return 0;
132 }
133
134
135
asq_font(lua_State * L)136 static int asq_font(lua_State *L)
137 {
138 DLG_REQUIRE;
139 const char*label=lua_isnil(L,4)?NULL:luaL_checkstring(L,4);
140 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
141 const char*key=luaL_checkstring(L,2);
142 fxasq_font(D->dlg, key,value,label);
143 return 0;
144 }
145
146
147
asq_textarea(lua_State * L)148 static int asq_textarea(lua_State *L)
149 {
150 DLG_REQUIRE;
151 const char*label=lua_isnil(L,4)?NULL:luaL_checkstring(L,4);
152 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
153 const char*key=luaL_checkstring(L,2);
154 fxasq_textarea(D->dlg, key,value,label);
155 return 0;
156 }
157
158
159
asq_group(lua_State * L)160 static int asq_group(lua_State *L)
161 {
162 DLG_REQUIRE;
163 const char*label=lua_isnil(L,4)?NULL:luaL_checkstring(L,4);
164 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
165 const char*key=luaL_checkstring(L,2);
166 fxasq_group(D->dlg,key,value,label);
167 return 0;
168 }
169
170
171
asq_select(lua_State * L)172 static int asq_select(lua_State *L)
173 {
174 DLG_REQUIRE;
175 const char*label=lua_isnil(L,4)?NULL:luaL_checkstring(L,4);
176 const char*value=lua_isnil(L,3)?NULL:luaL_checkstring(L,3);
177 const char*key=luaL_checkstring(L,2);
178 fxasq_select(D->dlg, key,value,label);
179 return 0;
180 }
181
182
183
asq_radio(lua_State * L)184 static int asq_radio(lua_State *L)
185 {
186 DLG_REQUIRE;
187 const char*label=luaL_checkstring(L,4);
188 const char*value=luaL_checkstring(L,3);
189 const char*key=luaL_checkstring(L,2);
190 fxasq_radio(D->dlg, key,value,label);
191 return 0;
192 }
193
194
195
asq_option(lua_State * L)196 static int asq_option(lua_State *L)
197 {
198 DLG_REQUIRE;
199 const char*label=luaL_checkstring(L,4);
200 const char*value=luaL_checkstring(L,3);
201 const char*key=luaL_checkstring(L,2);
202 fxasq_option(D->dlg,key,value,label);
203 return 0;
204 }
205
206
207
asq_label(lua_State * L)208 static int asq_label(lua_State *L)
209 {
210 DLG_REQUIRE;
211 const char*text=luaL_checkstring(L,2);
212 fxasq_label(D->dlg,text);
213 return 0;
214 }
215
216
217
asq_heading(lua_State * L)218 static int asq_heading(lua_State *L)
219 {
220 DLG_REQUIRE;
221 const char*text=luaL_checkstring(L,2);
222 fxasq_heading(D->dlg,text);
223 return 0;
224 }
225
226
227
asq_new(lua_State * L)228 static int asq_new(lua_State *L) {
229 int argc=lua_gettop(L);
230 FxAsqStr title=NULL;
231 FxAsqStr *btns;
232 int i,n;
233 DialogBox*D;
234 if (argc>=1) {
235 title=luaL_checkstring(L,1);
236 }
237 if (argc>=2) {
238 luaL_argcheck(L,lua_istable(L,2),2,_("expected table"));
239 }
240 n=lua_rawlen(L,2);
241 for (i=1;i<=n; i++) {
242 lua_rawgeti(L,2,i);
243 char msg[64];
244 memset(msg,0,sizeof(msg));
245 snprintf(msg,sizeof(msg)-1, _("table element #%d is not a string"), i);
246 luaL_argcheck(L,lua_isstring(L, -1),2,msg);
247 lua_pop(L, 1);
248 }
249 btns=(const char**)calloc(sizeof(char*)*(n+1), 1);
250 for (i=1;i<=n; i++) {
251 lua_rawgeti(L,2,i);
252 btns[i-1]=lua_tostring(L, -1);
253 lua_pop(L, 1);
254 }
255 D=(DialogBox*)lua_newuserdata(L,sizeof(DialogBox));
256 luaL_getmetatable(L, MetaName);
257 lua_setmetatable(L, -2);
258 D->id=DialogBoxType;
259 D->dlg=fxasq_new(title,btns);
260 free(btns);
261 return 1;
262 }
263
264
265
asq_run(lua_State * L)266 static int asq_run(lua_State *L)
267 {
268 int rv=-1;
269 FxAsqItem *results;
270 DLG_REQUIRE;
271 results=fxasq_run(D->dlg, &rv, L);
272 lua_pushnumber(L,(rv+1));
273 if (results) {
274 FxAsqItem*p;
275 lua_newtable(L);
276 for (p=results; p; p=p->next) {
277 lua_pushstring(L, p->key);
278 lua_pushstring(L, p->value);
279 lua_rawset(L,-3);
280 }
281 fxasq_free_results(results);
282 return 2;
283 }
284 return 1;
285 }
286
287
288
asq_done(lua_State * L)289 static int asq_done(lua_State *L)
290 {
291 DialogBox*D;
292 if (lua_isnil(L, 1)) {
293 return 0;
294 }
295 D=(DialogBox*)lua_touserdata(L,1);
296 if (D->id!=DialogBoxType) {
297
298 return 1;
299 }
300 fxasq_free(D->dlg);
301 return 1;
302 }
303
304
305
306
307 static const struct luaL_Reg asq_funcs[] = {
308 {"new", asq_new},
309 {"run", asq_run},
310 {"label", asq_label},
311 {"text", asq_text},
312 {"select", asq_select},
313 {"option", asq_option},
314 {"group", asq_group},
315 {"radio", asq_radio},
316 {"password", asq_password},
317 {"heading", asq_heading},
318 {"checkbox", asq_checkbox},
319 {"hr", asq_hr},
320 {"textarea", asq_textarea},
321 {"file", asq_file},
322 {"color", asq_color},
323 {"font", asq_font},
324 {0,0}
325 };
326
327
328
luaopen_dialog(lua_State * L)329 int luaopen_dialog(lua_State *L)
330 {
331 luaL_newmetatable(L, MetaName);
332 lua_pushstring(L, "__index");
333 lua_pushvalue(L, -2);
334 lua_settable(L, -3);
335
336 lua_pushstring(L,"__gc");
337 lua_pushcfunction(L,asq_done);
338 lua_rawset(L,-3);
339
340 #if LUA_VERSION_NUM < 502
341 luaL_Register(L, NULL, &asq_funcs[1]);
342 luaL_Register(L, DLG_MODULE_NAME, asq_funcs);
343 #else
344 luaL_setfuncs(L,asq_funcs,0);
345 #endif
346 return 1;
347 }
348