added sample GUI module with UIP
[k8lst.git] / src / lstiup.c
blobdaf0f485fb601a2be112d0252c047d42c4d6f0b7
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
6 #include "lstiup.h"
9 #ifdef USE_IUP
10 #include "iup.h"
11 #include "iupcontrols.h"
12 #include "iupim.h"
14 void guiInit (int *argc, char ***argv) {
15 IupOpen(argc, argv);
16 IupControlsOpen();
17 IupImageLibOpen();
21 void guiShutdown (void) {
22 /*IupImageLibClose();*/
23 IupControlsClose();
24 IupClose();
28 void guiModalMessage (const char *title, const char *message) {
29 IupMessage((char *)title, (char *)message);
33 static const char *iupHId = "IUPHandle";
35 typedef struct {
36 const char *type;
37 Ihandle *ih;
38 } IUPInfo;
41 LST_FINALIZER(lpIUPHandleFinalizer) {
42 IUPInfo *fi = (IUPInfo *)udata;
43 if (fi) {
44 if (fi->ih) {
45 static char tbuf0[128];
46 sprintf(tbuf0, "%p", fi);
47 IupSetFunction(tbuf0, NULL);
48 IupDestroy(fi->ih);
50 free(fi);
55 static lstObject *newIUPHandle (Ihandle *ih) {
56 IUPInfo *hh;
57 lstObject *res = lstNewBinary(NULL, 0);
58 hh = malloc(sizeof(IUPInfo));
59 if (!hh) { return NULL; }
60 hh->type = iupHId;
61 hh->ih = ih;
62 lstSetFinalizer(res, lpIUPHandleFinalizer, hh);
63 return res;
67 static void setIUPHandle (lstObject *o, Ihandle *h) {
68 if (!LST_IS_BYTES_EX(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return;
69 IUPInfo *fi = (IUPInfo *)o->fin->udata;
70 if (fi->type != iupHId) return;
71 fi->ih = h;
75 static Ihandle *getIUPHandle (lstObject *o) {
76 if (!LST_IS_BYTES_EX(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return NULL;
77 IUPInfo *fi = (IUPInfo *)o->fin->udata;
78 if (fi->type != iupHId) return NULL;
79 return fi->ih;
83 static void *getIUPHandleForId (lstObject *o) {
84 if (!LST_IS_BYTES_EX(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return NULL;
85 IUPInfo *fi = (IUPInfo *)o->fin->udata;
86 if (fi->type != iupHId) return NULL;
87 return fi;
91 static void clearIUPHandle (lstObject *o) {
92 if (!LST_IS_BYTES_EX(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return;
93 IUPInfo *fi = (IUPInfo *)o->fin->udata;
94 if (fi->type != iupHId) return;
95 if (fi->ih) {
96 static char tbuf0[128];
97 sprintf(tbuf0, "%p", fi);
98 IupSetFunction(tbuf0, NULL);
99 IupDestroy(fi->ih);
101 fi->ih = NULL;
105 typedef struct LstIUPEvent LstIUPEvent;
106 struct LstIUPEvent {
107 char *name; /* dynamic string */
108 LstIUPEvent *next;
111 static LstIUPEvent *head = NULL;
112 static LstIUPEvent *tail = NULL;
115 static lstObject *getEvent (void) {
116 if (!head) return NULL;
117 LstIUPEvent *i = head;
118 if ((head = head->next) == NULL) tail = NULL;
119 lstObject *res = lstNewString(i->name);
120 free(i->name);
121 free(i);
122 return res;
126 /*FIXME: check for 'out of memory'*/
127 static void addEvent (const char *str) {
128 LstIUPEvent *i = malloc(sizeof(LstIUPEvent));
129 i->name = strdup(str);
130 i->next = NULL;
131 if (tail) tail->next = i; else head = i;
132 tail = i;
136 int guiHasEvent (void) {
137 return (head != 0);
141 static int iupCallback (Ihandle *iHandle) {
142 addEvent(IupGetActionName());
143 return IUP_DEFAULT;
147 static int iupListCallback (Ihandle *iHandle, const char *text, int index, int selectionFlag) {
148 static char buf[128];
149 addEvent(""); /* empty string: list event */
150 addEvent(IupGetActionName());
151 addEvent(text);
152 sprintf(buf, "%d", index);
153 addEvent(buf);
154 sprintf(buf, "%d", selectionFlag);
155 addEvent(buf);
156 return IUP_DEFAULT;
160 LST_PRIMFN_NONSTATIC(lpIUPDispatcher) {
161 static char tbuf0[8192], tbuf1[8192]; /*FIXME*/
162 if (LST_PRIMARGC < 1) return NULL;
163 lstObject *op = LST_PRIMARG(0);
164 if (!LST_IS_SMALLINT(op)) return NULL;
165 int action = lstIntValue(op);
166 switch (action) {
167 case 1: /* show message; title text */
168 if (LST_PRIMARGC < 3) return NULL;
169 op = LST_PRIMARG(1);
170 if (!LST_IS_BYTES_EX(op)) return NULL;
171 lstGetString(tbuf0, sizeof(tbuf0), op);
172 op = LST_PRIMARG(2);
173 if (!LST_IS_BYTES_EX(op)) return NULL;
174 lstGetString(tbuf1, sizeof(tbuf1), op);
175 IupMessage(tbuf0, tbuf1);
176 break;
178 case 2: { /* create control; type targ0 [targ1] */
179 int controlType;
180 lstObject *res = NULL;
181 Ihandle *iHandle = 0, *ih1;
182 if (LST_PRIMARGC < 2) return NULL;
183 op = LST_PRIMARG(1);
184 if (!LST_IS_SMALLINT(op)) return NULL;
185 controlType = lstIntValue(op);
186 if (controlType < 0) return NULL;
187 /***/
188 if (controlType <= 6) {
189 res = newIUPHandle(iHandle);
190 if (LST_PRIMARGC < 3) return NULL;
191 /* 2nd arg is a text -- action name; can be nil */
192 op = LST_PRIMARG(2);
193 if (op == lstTrueObj) {
194 sprintf(tbuf0, "%p", getIUPHandleForId(res));
195 } else if (op == lstNilObj) {
196 tbuf0[0] = '\0';
197 } else {
198 if (!LST_IS_BYTES_EX(op)) return NULL;
199 lstGetString(tbuf0, sizeof(tbuf0), op);
201 if (LST_PRIMARGC > 3) {
202 op = LST_PRIMARG(3);
203 if (!LST_IS_BYTES_EX(op)) return NULL;
204 lstGetString(tbuf1, sizeof(tbuf1), op);
205 } else tbuf1[0] = '\0';
206 /* register event */
207 if (controlType != 6 && tbuf0[0]) {
208 /*fprintf(stderr, "xREGISTER EVENT: [%s]\n", tbuf0);*/
209 if (controlType == 5) {
210 IupSetFunction(tbuf0, (Icallback)iupListCallback);
211 } else {
212 IupSetFunction(tbuf0, iupCallback);
215 switch (controlType) {
216 case 0: /* create a canvas; actionname */
217 setIUPHandle(res, IupCanvas(tbuf0[0] ? tbuf0 : NULL));
218 break;
219 case 1: /* create a button; actionname title */
220 setIUPHandle(res, IupButton(tbuf1, tbuf0[0] ? tbuf0 : NULL));
221 break;
222 case 2: /* create a toggle; actionname title */
223 setIUPHandle(res, IupToggle(tbuf1, tbuf0[0] ? tbuf0 : NULL));
224 break;
225 case 3: /* create an editable text field; actionname */
226 setIUPHandle(res, IupText(tbuf0[0] ? tbuf0 : NULL));
227 break;
228 case 4: /* create a multi line text control; actionname */
229 setIUPHandle(res, IupMultiLine(tbuf0[0] ? tbuf0 : NULL));
230 break;
231 case 5: /* create a list; actionname */
232 setIUPHandle(res, IupList(tbuf0[0] ? tbuf0 : NULL));
233 break;
234 case 6: /* create a label; title */
235 setIUPHandle(res, IupLabel(tbuf0));
236 break;
238 return res;
240 /***/
241 if (controlType <= 9) {
242 switch (controlType) {
243 case 7: /* create a progress bar */
244 iHandle = IupProgressBar();
245 break;
246 case 8: /* create a spin */
247 iHandle = IupSpin();
248 break;
249 case 9: /* create a tree */
250 iHandle = IupTree();
251 break;
253 return newIUPHandle(iHandle);
256 if (controlType == 10) {
257 /* create a frame; elid */
258 ih1 = NULL;
259 if (LST_PRIMARGC >= 3) {
260 op = LST_PRIMARG(2);
261 if (op != lstNilObj) {
262 if ((ih1 = getIUPHandle(op)) == NULL) return NULL;
265 return newIUPHandle(IupFrame(ih1));
267 /***/
268 if (controlType == 11) {
269 /* create a dialog; elid */
270 if (LST_PRIMARGC < 3) return NULL;
271 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
272 return newIUPHandle(IupDialog(ih1));
274 return NULL;
277 case 3: {
278 int ctype;
279 Ihandle *iHandle = 0, *ih0, *ih1;
280 if (LST_PRIMARGC < 2) return NULL;
281 op = LST_PRIMARG(1);
282 if (!LST_IS_SMALLINT(op)) return NULL;
283 ctype = lstIntValue(op);
284 switch (ctype) {
285 case 0: /* fill */
286 iHandle = IupFill();
287 break;
288 case 1: /* hbox */
289 iHandle = IupHbox(NULL);
290 break;
291 case 2: /* vbox */
292 iHandle = IupVbox(NULL);
293 break;
294 case 3: /* zbox */
295 iHandle = IupZbox(NULL);
296 break;
297 case 4: /* radio box; contelem */
298 if (LST_PRIMARGC < 3) return NULL;
299 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
300 iHandle = IupRadio(ih1);
301 break;
302 case 5: /* cbox */
303 iHandle = IupCbox(NULL);
304 break;
305 case 6: /* sbox */
306 iHandle = IupCbox(NULL);
307 break;
308 case 7: /* normalizer */
309 iHandle = IupNormalizer(NULL);
310 break;
311 case 8: { /* split; elid0 elid1 */
312 if (LST_PRIMARGC == 2) {
313 iHandle = IupSplit(NULL, NULL);
314 } else if (LST_PRIMARGC >= 4) {
315 if ((ih0 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
316 if ((ih1 = getIUPHandle(LST_PRIMARG(3))) == NULL) return NULL;
317 iHandle = IupSplit(ih0, ih1);
319 } break;
320 default: return NULL;
322 if (iHandle) return newIUPHandle(iHandle);
323 return NULL;
326 case 4: { /* append element; boxid; elementid */
327 Ihandle *ih0, *ih1;
328 if (LST_PRIMARGC < 3) return NULL;
329 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
330 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
331 IupAppend(ih0, ih1);
332 } break;
334 case 5: { /* detach element; elementid */
335 Ihandle *ih0;
336 if (LST_PRIMARGC < 2) return NULL;
337 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
338 IupDetach(ih0);
339 } break;
341 case 6: { /* destroy a GUI element; elementid */
342 Ihandle *ih0;
343 if (LST_PRIMARGC < 2) return NULL;
344 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
345 IupDestroy(ih0);
346 clearIUPHandle(LST_PRIMARG(1));
347 } break;
349 case 7: { /* show/hide interface element; elementid [hideflag] */
350 Ihandle *ih0;
351 if (LST_PRIMARGC < 2) return NULL;
352 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
353 op = lstNilObj;
354 if (LST_PRIMARGC > 2) op = LST_PRIMARG(2);
355 if (op == lstNilObj || op == lstFalseObj) IupShow(ih0); else IupHide(ih0);
356 } break;
358 case 8: { /* register an event; actionname */
359 if (LST_PRIMARGC < 2) return NULL;
360 op = LST_PRIMARG(1);
361 if (!LST_IS_BYTES_EX(op)) return NULL;
362 lstGetString(tbuf0, sizeof(tbuf0), op);
363 /*fprintf(stderr, "REGISTER EVENT: [%s]\n", tbuf0);*/
364 if (LST_PRIMARGC == 2) IupSetFunction(tbuf0, iupCallback);
365 else IupSetFunction(tbuf0, NULL);
366 } break;
368 case 9: { /* register a list event; actionname */
369 if (LST_PRIMARGC < 2) return NULL;
370 op = LST_PRIMARG(1);
371 if (!LST_IS_BYTES_EX(op)) return NULL;
372 lstGetString(tbuf0, sizeof(tbuf0), op);
373 if (LST_PRIMARGC == 2) IupSetFunction(tbuf0, (Icallback)iupListCallback);
374 else IupSetFunction(tbuf0, NULL);
375 } break;
377 case 10: /* get next event (non blocking event polling) */
378 /*fprintf(stderr, "NEXT EVENT!\n");*/
379 if ((op = getEvent()) == NULL) {
380 IupLoopStep();
381 op = getEvent();
383 if (op) return op;
384 return lstNilObj;
385 break;
387 case 11: { /* set an attribute of a GUI element; elementid attrname value */
388 Ihandle *ih0;
389 if (LST_PRIMARGC < 4) return NULL;
390 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
391 op = LST_PRIMARG(2);
392 if (!LST_IS_BYTES_EX(op)) return NULL;
393 lstGetString(tbuf0, sizeof(tbuf0), op);
394 op = LST_PRIMARG(3);
395 if (!LST_IS_BYTES_EX(op)) return NULL;
396 lstGetString(tbuf1, sizeof(tbuf1), op);
397 IupStoreAttribute(ih0, tbuf0, tbuf1);
398 } break;
400 case 12: { /* read the value of a widget's attribute; elementid attrname */
401 Ihandle *ih0;
402 if (LST_PRIMARGC < 3) return NULL;
403 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
404 op = LST_PRIMARG(2);
405 if (!LST_IS_BYTES_EX(op)) return NULL;
406 lstGetString(tbuf0, sizeof(tbuf0), op);
407 return lstNewString(IupGetAttribute(ih0, tbuf0));
408 } break;
410 case 13: { /* delete an attribute (by setting its value to NULL); elementid attrname */
411 Ihandle *ih0;
412 if (LST_PRIMARGC < 3) return NULL;
413 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
414 op = LST_PRIMARG(2);
415 if (!LST_IS_BYTES_EX(op)) return NULL;
416 lstGetString(tbuf0, sizeof(tbuf0), op);
417 IupSetAttribute(ih0, tbuf0, NULL);
418 } break;
420 case 14: { /* popup interface element; elementid */
421 Ihandle *ih0;
422 if (LST_PRIMARGC < 2) return NULL;
423 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
424 IupPopup(ih0, IUP_MOUSEPOS, IUP_MOUSEPOS);
425 } break;
427 case 15: { /* show interface element; elementid */
428 Ihandle *ih0;
429 if (LST_PRIMARGC < 2) return NULL;
430 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
431 /*fprintf(stderr, "SHOW!\n");*/
432 IupShow(ih0);
433 } break;
435 case 250: { /* get handle as string; elementid */
436 void *ih0;
437 if (LST_PRIMARGC < 2) return NULL;
438 if ((ih0 = getIUPHandleForId(LST_PRIMARG(1))) == NULL) return NULL;
439 sprintf(tbuf0, "%p", ih0);
440 return lstNewString(tbuf0);
442 default: return NULL;
444 return lstTrueObj;
448 void guiLoopStep (void) {
449 IupLoopStep();
453 static const LSTExtPrimitiveTable iupPrimTable[] = {
454 {"IUPDispatcher", lpIUPDispatcher, NULL},
455 {0}};
458 void lstInitPrimitivesIUP (void) {
459 lstRegisterExtPrimitiveTable(iupPrimTable);
462 #else
464 void guiInit (int *argc, char ***argv) {}
465 void guiShutdown (void) {}
466 void guiModalMessage (const char *title, const char *message) {
467 fprintf(stderr, "GUI MESSAGE [%s]: %s\n", title, message);
470 void lstInitPrimitivesIUP (void) {}
472 void guiLoopStep (void) {}
473 int guiHasEvent (void) { return 0; }
475 #endif