added trunc, round, ceil, floor and new method to Random
[k8lst.git] / src / lstiup.c
blob6dd5511015a09fc12e0c587c1f180a3b148082a0
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 int uid; /* unique id */
39 } IUPInfo;
40 static int iupUID = 1;
43 LST_FINALIZER(lpIUPHandleFinalizer) {
44 IUPInfo *fi = (IUPInfo *)udata;
45 if (fi) {
46 if (fi->ih) {
47 static char tbuf0[128];
48 sprintf(tbuf0, ":%08d", fi->uid);
49 IupSetFunction(tbuf0, NULL);
50 IupDestroy(fi->ih);
52 free(fi);
57 static lstObject *newIUPHandle (Ihandle *ih) {
58 IUPInfo *hh;
59 lstObject *res = lstNewBinary(NULL, 0);
60 hh = malloc(sizeof(IUPInfo));
61 if (!hh) { return NULL; }
62 hh->type = iupHId;
63 hh->ih = ih;
64 hh->uid = iupUID++;
65 lstSetFinalizer(res, lpIUPHandleFinalizer, hh);
66 return res;
70 static IUPInfo *getIUPInfo (lstObject *o) {
71 if (!LST_IS_BYTES_EX(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return NULL;
72 IUPInfo *fi = (IUPInfo *)o->fin->udata;
73 if (fi->type != iupHId) return NULL;
74 return fi;
78 static void setIUPHandle (lstObject *o, Ihandle *h) {
79 IUPInfo *fi = getIUPInfo(o);
80 if (fi) fi->ih = h;
84 static Ihandle *getIUPHandle (lstObject *o) {
85 IUPInfo *fi = getIUPInfo(o);
86 return fi ? fi->ih : NULL;
90 static int getIUPUID (lstObject *o) {
91 IUPInfo *fi = getIUPInfo(o);
92 return fi ? fi->uid : 0;
96 static void clearIUPHandle (lstObject *o) {
97 IUPInfo *fi = getIUPInfo(o);
98 if (!fi) return;
99 if (fi->ih) {
100 static char tbuf0[128];
101 sprintf(tbuf0, ":%08d", fi->uid);
102 IupSetFunction(tbuf0, NULL);
103 IupDestroy(fi->ih);
104 fi->uid = 0;
106 fi->ih = NULL;
110 typedef struct LstIUPEvent LstIUPEvent;
111 struct LstIUPEvent {
112 char *name; /* dynamic string */
113 LstIUPEvent *next;
116 static LstIUPEvent *head = NULL;
117 static LstIUPEvent *tail = NULL;
120 static lstObject *getEvent (void) {
121 if (!head) return NULL;
122 LstIUPEvent *i = head;
123 if ((head = head->next) == NULL) tail = NULL;
124 lstObject *res = lstNewString(i->name);
125 free(i->name);
126 free(i);
127 return res;
131 /*FIXME: check for 'out of memory'*/
132 static void addEvent (const char *str) {
133 LstIUPEvent *i = malloc(sizeof(LstIUPEvent));
134 i->name = strdup(str);
135 i->next = NULL;
136 if (tail) tail->next = i; else head = i;
137 tail = i;
141 int guiHasEvent (void) {
142 return (head != 0);
146 static int iupCallback (Ihandle *iHandle) {
147 /*fprintf(stderr, "ACTION: %s\n", IupGetActionName());*/
148 addEvent(IupGetActionName());
149 return IUP_DEFAULT;
153 static int iupListCallback (Ihandle *iHandle, const char *text, int index, int selectionFlag) {
154 static char buf[1024];
155 sprintf(buf, "%s %d %d", IupGetActionName(), index, selectionFlag);
156 addEvent(buf);
157 return IUP_DEFAULT;
161 LST_PRIMFN_NONSTATIC(lpIUPDispatcher) {
162 static char tbuf0[8192], tbuf1[8192]; /*FIXME*/
163 if (LST_PRIMARGC < 1) return NULL;
164 lstObject *op = LST_PRIMARG(0);
165 if (!LST_IS_SMALLINT(op)) return NULL;
166 int action = lstIntValue(op);
167 switch (action) {
168 case 1: /* show message; title text */
169 if (LST_PRIMARGC < 3) return NULL;
170 op = LST_PRIMARG(1);
171 if (!LST_IS_BYTES_EX(op)) return NULL;
172 lstGetString(tbuf0, sizeof(tbuf0), op);
173 op = LST_PRIMARG(2);
174 if (!LST_IS_BYTES_EX(op)) return NULL;
175 lstGetString(tbuf1, sizeof(tbuf1), op);
176 IupMessage(tbuf0, tbuf1);
177 break;
179 case 2: { /* create control; type targ0 [targ1] */
180 int controlType;
181 lstObject *res = NULL;
182 Ihandle *iHandle = 0, *ih1;
183 if (LST_PRIMARGC < 2) return NULL;
184 op = LST_PRIMARG(1);
185 if (!LST_IS_SMALLINT(op)) return NULL;
186 controlType = lstIntValue(op);
187 if (controlType < 0) return NULL;
188 /***/
189 if (controlType <= 6) {
190 res = newIUPHandle(iHandle);
191 if (LST_PRIMARGC < 3) return NULL;
192 /* 2nd arg is a text -- action name; can be nil */
193 op = LST_PRIMARG(2);
194 if (op == lstTrueObj) {
195 sprintf(tbuf0, ":%08d", getIUPUID(res));
196 } else if (op == lstNilObj) {
197 tbuf0[0] = '\0';
198 } else {
199 if (!LST_IS_BYTES_EX(op)) return NULL;
200 lstGetString(tbuf0, sizeof(tbuf0), op);
202 if (LST_PRIMARGC > 3) {
203 op = LST_PRIMARG(3);
204 if (!LST_IS_BYTES_EX(op)) return NULL;
205 lstGetString(tbuf1, sizeof(tbuf1), op);
206 } else tbuf1[0] = '\0';
207 /* register event */
208 if (controlType != 6 && tbuf0[0]) {
209 if (controlType == 5) IupSetFunction(tbuf0, (Icallback)iupListCallback);
210 else IupSetFunction(tbuf0, iupCallback);
212 switch (controlType) {
213 case 0: /* create a canvas; actionname */
214 setIUPHandle(res, IupCanvas(tbuf0[0] ? tbuf0 : NULL));
215 break;
216 case 1: /* create a button; actionname title */
217 setIUPHandle(res, IupButton(tbuf1, tbuf0[0] ? tbuf0 : NULL));
218 break;
219 case 2: /* create a toggle; actionname title */
220 setIUPHandle(res, IupToggle(tbuf1, tbuf0[0] ? tbuf0 : NULL));
221 break;
222 case 3: /* create an editable text field; actionname */
223 setIUPHandle(res, IupText(tbuf0[0] ? tbuf0 : NULL));
224 break;
225 case 4: /* create a multi line text control; actionname */
226 setIUPHandle(res, IupMultiLine(tbuf0[0] ? tbuf0 : NULL));
227 break;
228 case 5: /* create a list; actionname */
229 setIUPHandle(res, IupList(tbuf0[0] ? tbuf0 : NULL));
230 break;
231 case 6: /* create a label; title */
232 setIUPHandle(res, IupLabel(tbuf0));
233 break;
235 return res;
237 /***/
238 if (controlType <= 9) {
239 switch (controlType) {
240 case 7: /* create a progress bar */
241 iHandle = IupProgressBar();
242 break;
243 case 8: /* create a spin */
244 iHandle = IupSpin();
245 break;
246 case 9: /* create a tree */
247 iHandle = IupTree();
248 break;
250 return newIUPHandle(iHandle);
253 if (controlType == 10) {
254 /* create a frame; elid */
255 ih1 = NULL;
256 if (LST_PRIMARGC >= 3) {
257 op = LST_PRIMARG(2);
258 if (op != lstNilObj) {
259 if ((ih1 = getIUPHandle(op)) == NULL) return NULL;
262 return newIUPHandle(IupFrame(ih1));
264 /***/
265 if (controlType == 11) {
266 /* create a dialog; elid */
267 lstObject *res;
268 if (LST_PRIMARGC < 3) return NULL;
269 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
270 res = newIUPHandle(IupDialog(ih1));
271 sprintf(tbuf0, ":%08d", getIUPUID(res));
272 IupSetFunction(tbuf0, iupCallback);
273 /*IupSetAttribute(getIUPHandle(res), "CLOSE_CB", tbuf0);*/
274 return res;
276 /***/
277 if (controlType == 12) {
278 /* create a trackbar; vertflag */
279 lstObject *res;
280 if (LST_PRIMARGC < 3) return NULL;
281 op = LST_PRIMARG(2);
282 res = newIUPHandle(IupVal(op==lstNilObj||op==lstFalseObj ? "HORIZONTAL" : "VERTICAL"));
283 sprintf(tbuf0, ":%08d", getIUPUID(res));
284 IupSetFunction(tbuf0, iupCallback);
285 /*IupSetAttribute(getIUPHandle(res), "VALUECHANGED_CB", tbuf0);*/
286 return res;
288 return NULL;
291 case 3: {
292 int ctype;
293 Ihandle *iHandle = 0, *ih0, *ih1;
294 if (LST_PRIMARGC < 2) return NULL;
295 op = LST_PRIMARG(1);
296 if (!LST_IS_SMALLINT(op)) return NULL;
297 ctype = lstIntValue(op);
298 switch (ctype) {
299 case 0: /* fill */
300 iHandle = IupFill();
301 break;
302 case 1: /* hbox */
303 iHandle = IupHbox(NULL);
304 break;
305 case 2: /* vbox */
306 iHandle = IupVbox(NULL);
307 break;
308 case 3: /* zbox */
309 iHandle = IupZbox(NULL);
310 break;
311 case 4: /* radio box; contelem */
312 if (LST_PRIMARGC < 3) return NULL;
313 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
314 iHandle = IupRadio(ih1);
315 break;
316 case 5: /* cbox */
317 iHandle = IupCbox(NULL);
318 break;
319 case 6: /* sbox */
320 iHandle = IupCbox(NULL);
321 break;
322 case 7: /* normalizer */
323 iHandle = IupNormalizer(NULL);
324 break;
325 case 8: { /* split; elid0 elid1 */
326 if (LST_PRIMARGC == 2) {
327 iHandle = IupSplit(NULL, NULL);
328 } else if (LST_PRIMARGC >= 4) {
329 if ((ih0 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
330 if ((ih1 = getIUPHandle(LST_PRIMARG(3))) == NULL) return NULL;
331 iHandle = IupSplit(ih0, ih1);
333 } break;
334 default: return NULL;
336 if (iHandle) return newIUPHandle(iHandle);
337 return NULL;
340 case 4: { /* append element; boxid; elementid */
341 Ihandle *ih0, *ih1;
342 if (LST_PRIMARGC < 3) return NULL;
343 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
344 if ((ih1 = getIUPHandle(LST_PRIMARG(2))) == NULL) return NULL;
345 IupAppend(ih0, ih1);
346 } break;
348 case 5: { /* detach element; elementid */
349 Ihandle *ih0;
350 if (LST_PRIMARGC < 2) return NULL;
351 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
352 IupDetach(ih0);
353 } break;
355 case 6: { /* destroy a GUI element; elementid */
356 Ihandle *ih0;
357 if (LST_PRIMARGC < 2) return NULL;
358 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
359 IupDestroy(ih0);
360 clearIUPHandle(LST_PRIMARG(1));
361 } break;
363 case 7: { /* show/hide interface element; elementid [hideflag] */
364 Ihandle *ih0;
365 if (LST_PRIMARGC < 2) return NULL;
366 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
367 op = lstNilObj;
368 if (LST_PRIMARGC > 2) op = LST_PRIMARG(2);
369 if (op == lstNilObj || op == lstFalseObj) IupShow(ih0); else IupHide(ih0);
370 } break;
372 case 8: { /* register an event; actionname */
373 if (LST_PRIMARGC < 2) return NULL;
374 op = LST_PRIMARG(1);
375 if (!LST_IS_BYTES_EX(op)) return NULL;
376 lstGetString(tbuf0, sizeof(tbuf0), op);
377 /*fprintf(stderr, "REGISTER EVENT: [%s]\n", tbuf0);*/
378 if (LST_PRIMARGC == 2) IupSetFunction(tbuf0, iupCallback);
379 else IupSetFunction(tbuf0, NULL);
380 } break;
382 case 9: { /* register a list event; actionname */
383 if (LST_PRIMARGC < 2) return NULL;
384 op = LST_PRIMARG(1);
385 if (!LST_IS_BYTES_EX(op)) return NULL;
386 lstGetString(tbuf0, sizeof(tbuf0), op);
387 if (LST_PRIMARGC == 2) IupSetFunction(tbuf0, (Icallback)iupListCallback);
388 else IupSetFunction(tbuf0, NULL);
389 } break;
391 case 10: /* get next event (non blocking event polling) */
392 /*fprintf(stderr, "NEXT EVENT!\n");*/
393 if ((op = getEvent()) == NULL) {
394 IupLoopStep();
395 op = getEvent();
397 if (op) return op;
398 return lstNilObj;
399 break;
401 case 11: { /* set an attribute of a GUI element; elementid attrname value */
402 Ihandle *ih0;
403 if (LST_PRIMARGC < 4) return NULL;
404 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
405 op = LST_PRIMARG(2);
406 if (!LST_IS_BYTES_EX(op)) return NULL;
407 lstGetString(tbuf0, sizeof(tbuf0), op);
408 op = LST_PRIMARG(3);
409 if (!LST_IS_BYTES_EX(op)) return NULL;
410 lstGetString(tbuf1, sizeof(tbuf1), op);
411 IupStoreAttribute(ih0, tbuf0, tbuf1);
412 } break;
414 case 12: { /* read the value of a widget's attribute; elementid attrname */
415 Ihandle *ih0;
416 if (LST_PRIMARGC < 3) return NULL;
417 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
418 op = LST_PRIMARG(2);
419 if (!LST_IS_BYTES_EX(op)) return NULL;
420 lstGetString(tbuf0, sizeof(tbuf0), op);
421 return lstNewString(IupGetAttribute(ih0, tbuf0));
422 } break;
424 case 13: { /* delete an attribute (by setting its value to NULL); elementid attrname */
425 Ihandle *ih0;
426 if (LST_PRIMARGC < 3) return NULL;
427 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
428 op = LST_PRIMARG(2);
429 if (!LST_IS_BYTES_EX(op)) return NULL;
430 lstGetString(tbuf0, sizeof(tbuf0), op);
431 IupSetAttribute(ih0, tbuf0, NULL);
432 } break;
434 case 14: { /* popup interface element; elementid */
435 Ihandle *ih0;
436 if (LST_PRIMARGC < 2) return NULL;
437 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
438 IupPopup(ih0, IUP_MOUSEPOS, IUP_MOUSEPOS);
439 } break;
441 case 15: { /* show interface element; elementid */
442 Ihandle *ih0;
443 if (LST_PRIMARGC < 2) return NULL;
444 if ((ih0 = getIUPHandle(LST_PRIMARG(1))) == NULL) return NULL;
445 /*fprintf(stderr, "SHOW!\n");*/
446 IupShow(ih0);
447 } break;
449 case 250: { /* get handle as string; elementid */
450 if (LST_PRIMARGC < 2) return NULL;
451 if (getIUPHandle(LST_PRIMARG(1)) == NULL) return NULL;
452 sprintf(tbuf0, ":%08d", getIUPUID(LST_PRIMARG(1)));
453 return lstNewString(tbuf0);
455 default: return NULL;
457 return lstTrueObj;
461 void guiLoopStep (void) {
462 IupLoopStep();
466 static const LSTExtPrimitiveTable iupPrimTable[] = {
467 {"IUPDispatcher", lpIUPDispatcher, NULL},
468 {0}};
471 void lstInitPrimitivesIUP (void) {
472 lstRegisterExtPrimitiveTable(iupPrimTable);
475 #else
477 void guiInit (int *argc, char ***argv) {}
478 void guiShutdown (void) {}
479 void guiModalMessage (const char *title, const char *message) {
480 fprintf(stderr, "GUI MESSAGE [%s]: %s\n", title, message);
483 void lstInitPrimitivesIUP (void) {}
485 void guiLoopStep (void) {}
486 int guiHasEvent (void) { return 0; }
488 #endif