sqfltk.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. #ifdef WITH_FLTK
  2. #define LUAFLTK
  3. #include <FL/Fl.H>
  4. #include <FL/Fl_Widget.H>
  5. #include <FL/Fl_Box.H>
  6. #include <FL/Fl_Button.H>
  7. #include <FL/Fl_Group.H>
  8. #include <FL/Fl_Window.H>
  9. #include <FL/Fl_Double_Window.H>
  10. #include <FL/Fl_Button.H>
  11. #include <FL/Fl_Light_Button.H>
  12. #include <FL/Fl_Check_Button.H>
  13. #include <FL/Fl_Radio_Button.H>
  14. #include <FL/Fl_Menu_Item.H>
  15. #include <FL/Fl_Menu_.H>
  16. #include <FL/Fl_Choice.H>
  17. #include <FL/Fl_Input_.H>
  18. #include <FL/Fl_Input.H>
  19. #include <FL/Fl_Float_Input.H>
  20. #include <FL/Fl_Int_Input.H>
  21. #include <FL/Fl_Output.H>
  22. #include <FL/Fl_Secret_Input.H>
  23. #include <FL/Fl_Text_Display.H>
  24. #include <FL/Fl_Text_Editor.H>
  25. #include <FL/Fl_Pack.H>
  26. #include <FL/Fl_Tabs.H>
  27. #include <FL/Flv_List.H>
  28. #include <FL/Flv_Table.H>
  29. #include <FL/Fl_Image.H>
  30. #include <FL/Fl_PNG_Image.H>
  31. #include <FL/Fl_JPEG_Image.H>
  32. #include <squirrel.h>
  33. #include "sqfltk.h"
  34. struct MyFltkUData {
  35. HSQOBJECT self;
  36. HSQOBJECT udata;
  37. HSQUIRRELVM v;
  38. };
  39. #define FLTK_TAG(tag) SQFLTK_##tag##_TYPE_TAG
  40. #define CREATE_TAG(tag) \
  41. static const char* FLTK_TAG(tag) = #tag
  42. CREATE_TAG(Fl);
  43. CREATE_TAG(Fl_Widget);
  44. CREATE_TAG(Fl_Box);
  45. CREATE_TAG(Fl_Button);
  46. CREATE_TAG(Fl_Light_Button);
  47. CREATE_TAG(Fl_Check_Button);
  48. CREATE_TAG(Fl_Radio_Button);
  49. CREATE_TAG(Fl_Menu_);
  50. CREATE_TAG(Fl_Menu_Item);
  51. CREATE_TAG(Fl_Choice);
  52. CREATE_TAG(Fl_Input_);
  53. CREATE_TAG(Fl_Input);
  54. CREATE_TAG(Fl_Float_Input);
  55. CREATE_TAG(Fl_Int_Input);
  56. CREATE_TAG(Fl_Output);
  57. CREATE_TAG(Fl_Secret_Input);
  58. CREATE_TAG(Fl_Group);
  59. CREATE_TAG(Fl_Pack);
  60. CREATE_TAG(Fl_Tabs);
  61. CREATE_TAG(Flv_List);
  62. CREATE_TAG(Flv_Table);
  63. CREATE_TAG(Fl_Text_Display);
  64. CREATE_TAG(Fl_Text_Editor);
  65. CREATE_TAG(Fl_Text_Editor_Buffered);
  66. CREATE_TAG(Fl_Window);
  67. CREATE_TAG(Fl_Double_Window);
  68. CREATE_TAG(Fl_Image);
  69. CREATE_TAG(Fl_PNG_Image);
  70. CREATE_TAG(Fl_JPEG_Image);
  71. static void do_register_object_and_instance(HSQUIRRELVM sqvm, int instance_idx, void *cptr){
  72. sq_pushregistrytable(sqvm);
  73. sq_pushuserpointer(sqvm, cptr);
  74. HSQOBJECT obj; sq_resetobject(&obj);
  75. sq_getstackobj(sqvm, instance_idx, &obj);
  76. sq_pushobject(sqvm, obj);
  77. sq_rawset(sqvm, -3);
  78. sq_pop(sqvm, -1);
  79. }
  80. #define SETUP_FL_KLASS(v, Klass) \
  81. Klass *self = NULL; \
  82. { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(void*)FLTK_TAG(Klass)))) \
  83. return SQ_ERROR; }
  84. #define SETUP_FL_WIDGET(v) SETUP_FL_KLASS(v, Fl_Widget)
  85. #define NOTHING(a)
  86. #define AS_IS(a) a
  87. #define FLTK_CONSTRUCTOR_RELEASE(Klass, RELEASE_HOOK, _release_hook)\
  88. static SQInteger _##Klass##_constructor(HSQUIRRELVM sqvm)\
  89. {\
  90. const SQChar *label;\
  91. SQInteger argc, x,y,w,h;\
  92. Klass *cptr;\
  93. argc = sq_gettop(sqvm);\
  94. if(argc > 5){\
  95. sq_getinteger(sqvm, 2, &x);\
  96. sq_getinteger(sqvm, 3, &y);\
  97. sq_getinteger(sqvm, 4, &w);\
  98. sq_getinteger(sqvm, 5, &h);\
  99. if(argc == 6) sq_getstring(sqvm, 6, &label);\
  100. else label = NULL;\
  101. cptr = new Klass(x,y,w,h,label);\
  102. do_register_object_and_instance(sqvm, 1, cptr);\
  103. } else\
  104. return sq_throwerror(sqvm, _SC("Wrong number of parameters."));\
  105. \
  106. sq_setinstanceup(sqvm, 1, cptr);\
  107. RELEASE_HOOK(sq_setreleasehook(sqvm,1,_release_hook));\
  108. return 1;\
  109. }
  110. #define FLTK_CONSTRUCTOR(Klass) FLTK_CONSTRUCTOR_RELEASE(Klass, NOTHING, a)
  111. #define FL_WIDGET_GETSET_STR(funcNAME) \
  112. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  113. {\
  114. SETUP_FL_WIDGET(sqvm);\
  115. SQInteger argc = sq_gettop(sqvm);\
  116. const SQChar *funcNAME = NULL;\
  117. if(argc > 0){\
  118. sq_getstring(sqvm, 2, &funcNAME);\
  119. self->funcNAME(funcNAME);\
  120. return 0;\
  121. }\
  122. funcNAME = self->funcNAME();\
  123. if(funcNAME) sq_pushstring(sqvm, funcNAME, -1);\
  124. else sq_pushnull(sqvm);\
  125. return 1;\
  126. }
  127. #define FL_WIDGET_GETSET_INT0(funcNAME, typeNAME) \
  128. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  129. {\
  130. SETUP_FL_WIDGET(sqvm);\
  131. SQInteger argc = sq_gettop(sqvm);\
  132. SQInteger funcNAME;\
  133. if(argc > 0){\
  134. sq_getinteger(sqvm, 2, &funcNAME);\
  135. self->funcNAME((typeNAME)funcNAME);\
  136. return 0;\
  137. }\
  138. sq_pushinteger(sqvm, self->funcNAME());\
  139. return 1;\
  140. }
  141. #define FL_WIDGET_GETSET_INT(funcNAME) FL_WIDGET_GETSET_INT0(funcNAME, int)
  142. #define FL_WIDGET_VOID_CALL(funcNAME) \
  143. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  144. {\
  145. SETUP_FL_WIDGET(sqvm);\
  146. self->funcNAME();\
  147. return 0;\
  148. }
  149. #define FL_WIDGET_VOID_CALL_2INT(funcNAME) \
  150. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  151. {\
  152. SETUP_FL_WIDGET(sqvm);\
  153. SQInteger i1, i2;\
  154. sq_getinteger(sqvm, 2, &i1);\
  155. sq_getinteger(sqvm, 3, &i2);\
  156. self->funcNAME(i1,i2);\
  157. return 0;\
  158. }
  159. #define FL_WIDGET_VOID_CALL_4INT(funcNAME) \
  160. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  161. {\
  162. SETUP_FL_WIDGET(sqvm);\
  163. SQInteger i1, i2, i3, i4;\
  164. sq_getinteger(sqvm, 2, &i1);\
  165. sq_getinteger(sqvm, 3, &i2);\
  166. sq_getinteger(sqvm, 4, &i3);\
  167. sq_getinteger(sqvm, 5, &i4);\
  168. self->funcNAME(i1,i2,i3,i4);\
  169. return 0;\
  170. }
  171. #define FL_WIDGET_INT_CALL(funcNAME) \
  172. static SQInteger _flwidget_##funcNAME(HSQUIRRELVM sqvm) \
  173. {\
  174. SETUP_FL_WIDGET(sqvm);\
  175. sq_pushinteger(sqvm, self->funcNAME());\
  176. return 1;\
  177. }
  178. static void sq_call_fl_virtual(void *self, const SQChar *func_name){
  179. HSQUIRRELVM sqvm = (HSQUIRRELVM) Fl::user_data;
  180. //sq_reservestack(sqvm, 20);
  181. SQInteger top = sq_gettop(sqvm);
  182. sq_pushregistrytable(sqvm);
  183. sq_pushuserpointer(sqvm, self);
  184. if(sq_rawget(sqvm, -2) == SQ_OK){
  185. sq_pushstring(sqvm, func_name, -1);
  186. sq_get(sqvm, -2);
  187. SQObjectType toptype = sq_gettype(sqvm, -1);
  188. if(toptype == OT_CLOSURE || toptype == OT_NATIVECLOSURE){
  189. sq_push(sqvm, -2); //this
  190. sq_call(sqvm, 1, SQFalse, SQTrue);
  191. }
  192. }
  193. sq_settop(sqvm, top);
  194. }
  195. typedef struct {
  196. HSQOBJECT callback;
  197. HSQOBJECT callee;
  198. HSQOBJECT udata;
  199. } st_mycb;
  200. //static st_mycb static_cb;
  201. static void free_st_mycb(HSQUIRRELVM sqvm, st_mycb *cb){
  202. sq_release(sqvm, &cb->callback);
  203. sq_release(sqvm, &cb->udata);
  204. sq_free((void*)cb, sizeof(st_mycb));
  205. }
  206. static void At_Widget_Destroy(Fl_Widget *widget){
  207. printf("%d %p At_Widget_Destroy\n", __LINE__, widget);
  208. Fl_Callback_p cb = widget->callback();
  209. if(!cb || cb == Fl_Widget::default_callback) {
  210. //no need to check
  211. return;
  212. }
  213. HSQUIRRELVM sqvm = (HSQUIRRELVM) Fl::user_data;
  214. SQInteger savedTop = sq_gettop(sqvm);
  215. printf("%d %p %d At_Widget_Destroy\n", __LINE__, widget, sq_gettop(sqvm));
  216. sq_pushregistrytable(sqvm);
  217. printf("%d %p %d At_Widget_Destroy\n", __LINE__, widget, sq_gettop(sqvm));
  218. sq_pushuserpointer(sqvm, widget);
  219. printf("%d %p %d At_Widget_Destroy\n", __LINE__, widget, sq_gettop(sqvm));
  220. int rc = sq_deleteslot(sqvm, -2, SQTrue);
  221. printf("%d %p %d At_Widget_Destroy\n", __LINE__, widget, sq_gettop(sqvm));
  222. printf("%d %p %d %s At_Widget_Destroy\n", __LINE__, widget, rc, sq_getlasterror_str(sqvm));
  223. //if(sq_deleteslot(sqvm, -2, SQTrue) == SQ_OK){
  224. if(rc == SQ_OK){
  225. printf("%d %p At_Widget_Destroy\n", __LINE__, widget);
  226. if(sq_gettype(sqvm, -1) != OT_NULL){
  227. //////////////////////////////nota all will have user pointer !!!!!!!!
  228. SQUserPointer ptr;
  229. sq_getuserpointer(sqvm, -1, &ptr);
  230. free_st_mycb(sqvm, (st_mycb*)ptr);
  231. }
  232. }
  233. sq_settop(sqvm, savedTop);
  234. }
  235. static void fltk_calback_hook(Fl_Widget *sender, void* udata){
  236. printf("Sender %p, data %p\n", sender, udata);
  237. HSQUIRRELVM sqvm = (HSQUIRRELVM) Fl::user_data;
  238. SQInteger savedTop = sq_gettop(sqvm);
  239. st_mycb *mycb = (st_mycb *)udata;
  240. sq_pushobject(sqvm, mycb->callback);
  241. sq_pushroottable(sqvm); //’this’ (function environment object)
  242. sq_pushobject(sqvm, mycb->callee);
  243. sq_pushobject(sqvm, mycb->udata);
  244. printf("%d\n", sq_call(sqvm, 3, SQFalse, SQTrue));
  245. sq_settop(sqvm, savedTop);
  246. }
  247. static SQInteger _flwidget_callback(HSQUIRRELVM sqvm)
  248. {
  249. //printf("%d %s\n", __LINE__, __FILE__);
  250. SETUP_FL_WIDGET(sqvm);
  251. SQInteger argc = sq_gettop(sqvm);
  252. Fl_Callback_p cb = self->callback();
  253. if(cb == Fl_Widget::default_callback){
  254. cb = 0;
  255. }
  256. if(argc == 1){
  257. if(cb) sq_pushuserpointer(sqvm, (void*)cb);
  258. else sq_pushnull(sqvm);
  259. return 1;
  260. }
  261. if(argc >= 2){
  262. int ptypecb = sq_gettype(sqvm, 2);
  263. if(cb || ptypecb == OT_NULL) { //not allways the cb was set by us
  264. At_Widget_Destroy(self);
  265. if(ptypecb == OT_NULL) {
  266. self->callback((Fl_Callback*)NULL, (void*)NULL);
  267. return 0;
  268. }
  269. }
  270. st_mycb *mycb = (st_mycb *)sq_malloc(sizeof(st_mycb));
  271. sq_resetobject(&mycb->callback); //initializes the object handle (sets to NULL)
  272. sq_resetobject(&mycb->callee);
  273. sq_resetobject(&mycb->udata);
  274. sq_getstackobj(sqvm, 2, &mycb->callback);//fetches an handle of the function you passed
  275. if(sq_gettop(sqvm) > 2) { //we have user data too
  276. sq_getstackobj(sqvm, 3, &mycb->udata);
  277. sq_addref(sqvm,&mycb->udata);
  278. }
  279. if(sq_type(mycb->callback) == OT_CLOSURE || sq_type(mycb->callback) == OT_NATIVECLOSURE){
  280. sq_addref(sqvm,&mycb->callback);
  281. sq_getcallee(sqvm);
  282. sq_getstackobj(sqvm, -1, &mycb->callee);
  283. self->callback(&fltk_calback_hook, mycb);
  284. //registry for free when widget is destroyed
  285. sq_pushregistrytable(sqvm);
  286. sq_pushuserpointer(sqvm, self);
  287. sq_pushuserpointer(sqvm, mycb);
  288. sq_rawset(sqvm, -2);
  289. printf("Button %p\n", self);
  290. }
  291. }
  292. return 0;
  293. }
  294. FL_WIDGET_GETSET_INT(align);
  295. FL_WIDGET_GETSET_INT(argument);
  296. //FL_WIDGET_GETSET_INT(box);
  297. FL_WIDGET_GETSET_INT(color);
  298. FL_WIDGET_GETSET_INT(selection_color);
  299. FL_WIDGET_GETSET_STR(label);
  300. FL_WIDGET_GETSET_INT(labelcolor);
  301. FL_WIDGET_GETSET_INT(labelfont);
  302. FL_WIDGET_GETSET_INT(labelsize);
  303. //FL_WIDGET_GETSET_INT(labeltype);
  304. FL_WIDGET_GETSET_INT(textfont);
  305. FL_WIDGET_GETSET_INT(textsize);
  306. FL_WIDGET_GETSET_STR(tooltip);
  307. FL_WIDGET_GETSET_INT(when);
  308. FL_WIDGET_GETSET_INT(type);
  309. FL_WIDGET_INT_CALL(x);
  310. FL_WIDGET_INT_CALL(y);
  311. FL_WIDGET_INT_CALL(w);
  312. FL_WIDGET_INT_CALL(h);
  313. FL_WIDGET_VOID_CALL_2INT(position);
  314. FL_WIDGET_VOID_CALL_2INT(size);
  315. FL_WIDGET_VOID_CALL_4INT(resize);
  316. static SQInteger _flwidget_handle(HSQUIRRELVM sqvm)
  317. {
  318. SETUP_FL_WIDGET(sqvm);
  319. SQInteger event;
  320. sq_getinteger(sqvm, 2, &event);
  321. sq_pushinteger(sqvm, self->handle(event));
  322. return 1;
  323. }
  324. FL_WIDGET_VOID_CALL(redraw);
  325. FL_WIDGET_VOID_CALL(redraw_label);
  326. FL_WIDGET_VOID_CALL(hide);
  327. FL_WIDGET_VOID_CALL(show);
  328. #define _DECL_FL_WIDGET_FUNC(name,nparams,pmask) {_SC(#name),_flwidget_##name,nparams,pmask}
  329. static SQRegFunction fl_widget_obj_funcs[]={
  330. _DECL_FL_WIDGET_FUNC(align,-1,_SC("xi")),
  331. _DECL_FL_WIDGET_FUNC(argument,-1,_SC("xi")),
  332. _DECL_FL_WIDGET_FUNC(callback,-1,_SC("xc.")),
  333. _DECL_FL_WIDGET_FUNC(color,-1,_SC("xi")),
  334. _DECL_FL_WIDGET_FUNC(selection_color,1,_SC("xi")),
  335. _DECL_FL_WIDGET_FUNC(label,-1,_SC("xs")),
  336. _DECL_FL_WIDGET_FUNC(labelcolor,-1,_SC("xi")),
  337. _DECL_FL_WIDGET_FUNC(labelfont,-1,_SC("xi")),
  338. _DECL_FL_WIDGET_FUNC(labelsize,-1,_SC("xi")),
  339. //_DECL_FL_WIDGET_FUNC(labeltype,1,_SC("xi")),
  340. _DECL_FL_WIDGET_FUNC(textfont,-1,_SC("xi")),
  341. _DECL_FL_WIDGET_FUNC(textsize,-1,_SC("xi")),
  342. _DECL_FL_WIDGET_FUNC(tooltip,-1,_SC("xs")),
  343. _DECL_FL_WIDGET_FUNC(type,-1,_SC("xi")),
  344. _DECL_FL_WIDGET_FUNC(when,-1,_SC("xi")),
  345. _DECL_FL_WIDGET_FUNC(handle,2,_SC("xi")),
  346. _DECL_FL_WIDGET_FUNC(redraw,1,_SC("x")),
  347. _DECL_FL_WIDGET_FUNC(redraw_label,1,_SC("x")),
  348. _DECL_FL_WIDGET_FUNC(x,1,_SC("x")),
  349. _DECL_FL_WIDGET_FUNC(y,1,_SC("x")),
  350. _DECL_FL_WIDGET_FUNC(w,1,_SC("x")),
  351. _DECL_FL_WIDGET_FUNC(h,1,_SC("x")),
  352. _DECL_FL_WIDGET_FUNC(position,3,_SC("xii")),
  353. _DECL_FL_WIDGET_FUNC(size,3,_SC("xii")),
  354. _DECL_FL_WIDGET_FUNC(resize,5,_SC("xiiii")),
  355. _DECL_FL_WIDGET_FUNC(show,1,_SC("x")),
  356. _DECL_FL_WIDGET_FUNC(hide,1,_SC("x")),
  357. {0,0}
  358. };
  359. class MyFl_Box : public Fl_Box {
  360. public:
  361. MyFl_Box(int X, int Y, int W, int H, const char *L=0):Fl_Box(X,Y,W,H,L){}
  362. void draw(){
  363. sq_call_fl_virtual(this, "draw");
  364. }
  365. };
  366. FLTK_CONSTRUCTOR(MyFl_Box);
  367. static SQInteger _MyFl_Box_draw(HSQUIRRELVM sqvm)
  368. {
  369. SETUP_FL_WIDGET(sqvm);
  370. ((MyFl_Box*)self)->Fl_Box::draw();
  371. return 0;
  372. }
  373. #define _DECL_FL_BOX_FUNC(name,nparams,pmask) {_SC(#name),_MyFl_Box_##name,nparams,pmask}
  374. static SQRegFunction fl_box_obj_funcs[]={
  375. _DECL_FL_BOX_FUNC(constructor,-5,_SC("xiiiis")),
  376. _DECL_FL_BOX_FUNC(draw,1,_SC("x")),
  377. {0,0}
  378. };
  379. FLTK_CONSTRUCTOR(Fl_Button);
  380. #define _DECL_FL_BUTTON_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Button_##name,nparams,pmask}
  381. static SQRegFunction fl_button_obj_funcs[]={
  382. _DECL_FL_BUTTON_FUNC(constructor,-5,_SC("xiiiis")),
  383. {0,0}
  384. };
  385. FLTK_CONSTRUCTOR(Fl_Light_Button);
  386. #define _DECL_FL_LIGHT_BUTTON_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Light_Button_##name,nparams,pmask}
  387. static SQRegFunction fl_light_button_obj_funcs[]={
  388. _DECL_FL_LIGHT_BUTTON_FUNC(constructor,-5,_SC("xiiiis")),
  389. {0,0}
  390. };
  391. FLTK_CONSTRUCTOR(Fl_Check_Button);
  392. #define _DECL_FL_CHECK_BUTTON_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Check_Button_##name,nparams,pmask}
  393. static SQRegFunction fl_check_button_obj_funcs[]={
  394. _DECL_FL_CHECK_BUTTON_FUNC(constructor,-5,_SC("xiiiis")),
  395. {0,0}
  396. };
  397. FLTK_CONSTRUCTOR(Fl_Radio_Button);
  398. #define _DECL_FL_RADIO_BUTTON_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Radio_Button_##name,nparams,pmask}
  399. static SQRegFunction fl_radio_button_obj_funcs[]={
  400. _DECL_FL_RADIO_BUTTON_FUNC(constructor,-5,_SC("xiiiis")),
  401. {0,0}
  402. };
  403. /*
  404. FLTK_CONSTRUCTOR(Fl_Menu_Item);
  405. #define _DECL_FL_MENU_ITEM_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Menu_Item_##name,nparams,pmask}
  406. static SQRegFunction fl_menu_item_obj_funcs[]={
  407. _DECL_FL_MENU_ITEM_FUNC(constructor,-5,_SC("xiiiis")),
  408. {0,0}
  409. };
  410. */
  411. FLTK_CONSTRUCTOR(Fl_Menu_);
  412. #define _DECL_FL_MENU__FUNC(name,nparams,pmask) {_SC(#name),_Fl_Menu__##name,nparams,pmask}
  413. static SQRegFunction fl_menu__obj_funcs[]={
  414. _DECL_FL_MENU__FUNC(constructor,-5,_SC("xiiiis")),
  415. {0,0}
  416. };
  417. FLTK_CONSTRUCTOR(Fl_Choice);
  418. #define _DECL_FL_CHOICE_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Choice_##name,nparams,pmask}
  419. static SQRegFunction fl_choice_obj_funcs[]={
  420. _DECL_FL_CHOICE_FUNC(constructor,-5,_SC("xiiiis")),
  421. {0,0}
  422. };
  423. FLTK_CONSTRUCTOR(Fl_Input_);
  424. #define _DECL_FL_INPUT__FUNC(name,nparams,pmask) {_SC(#name),_Fl_Input__##name,nparams,pmask}
  425. static SQRegFunction fl_input__obj_funcs[]={
  426. _DECL_FL_INPUT__FUNC(constructor,-5,_SC("xiiiis")),
  427. {0,0}
  428. };
  429. FLTK_CONSTRUCTOR(Fl_Input);
  430. #define _DECL_FL_INPUT_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Input_##name,nparams,pmask}
  431. static SQRegFunction fl_input_obj_funcs[]={
  432. _DECL_FL_INPUT_FUNC(constructor,-5,_SC("xiiiis")),
  433. {0,0}
  434. };
  435. FLTK_CONSTRUCTOR(Fl_Float_Input);
  436. #define _DECL_FL_FLOAT_INPUT_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Float_Input_##name,nparams,pmask}
  437. static SQRegFunction fl_float_input_obj_funcs[]={
  438. _DECL_FL_FLOAT_INPUT_FUNC(constructor,-5,_SC("xiiiis")),
  439. {0,0}
  440. };
  441. FLTK_CONSTRUCTOR(Fl_Int_Input);
  442. #define _DECL_FL_INT_INPUT_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Int_Input_##name,nparams,pmask}
  443. static SQRegFunction fl_int_input_obj_funcs[]={
  444. _DECL_FL_INT_INPUT_FUNC(constructor,-5,_SC("xiiiis")),
  445. {0,0}
  446. };
  447. FLTK_CONSTRUCTOR(Fl_Output);
  448. #define _DECL_FL_INT_OUTPUT_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Output_##name,nparams,pmask}
  449. static SQRegFunction fl_output_obj_funcs[]={
  450. _DECL_FL_INT_OUTPUT_FUNC(constructor,-5,_SC("xiiiis")),
  451. {0,0}
  452. };
  453. FLTK_CONSTRUCTOR(Fl_Secret_Input);
  454. #define _DECL_FL_SECRET_INPUT_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Secret_Input_##name,nparams,pmask}
  455. static SQRegFunction fl_secret_input_obj_funcs[]={
  456. _DECL_FL_SECRET_INPUT_FUNC(constructor,-5,_SC("xiiiis")),
  457. {0,0}
  458. };
  459. #define SETUP_FL_GROUP(v) SETUP_FL_KLASS(v, Fl_Group)
  460. FLTK_CONSTRUCTOR(Fl_Group);
  461. static SQInteger _Fl_Group_end(HSQUIRRELVM sqvm)
  462. {
  463. SETUP_FL_GROUP(sqvm);
  464. self->end();
  465. return 0;
  466. }
  467. static SQInteger _Fl_Group_resizable(HSQUIRRELVM sqvm)
  468. {
  469. SETUP_FL_GROUP(sqvm);
  470. if(sq_gettop(sqvm)==1){
  471. sq_pushuserpointer(sqvm, self->resizable());
  472. return 1;
  473. }
  474. SQUserPointer rsz;
  475. sq_getinstanceup(sqvm, -1, &rsz, 0);
  476. self->resizable((Fl_Widget*)rsz);
  477. return 0;
  478. }
  479. #define _DECL_FL_GROUP_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Group_##name,nparams,pmask}
  480. static SQRegFunction fl_group_obj_funcs[]={
  481. _DECL_FL_GROUP_FUNC(constructor,-5,_SC("xiiiis")),
  482. _DECL_FL_GROUP_FUNC(end,1,_SC("x")),
  483. _DECL_FL_GROUP_FUNC(resizable,-1,_SC("xx")),
  484. {0,0}
  485. };
  486. FLTK_CONSTRUCTOR(Fl_Pack);
  487. #define _DECL_FL_PACK_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Pack_##name,nparams,pmask}
  488. static SQRegFunction fl_pack_obj_funcs[]={
  489. _DECL_FL_PACK_FUNC(constructor,-5,_SC("xiiiis")),
  490. {0,0}
  491. };
  492. FLTK_CONSTRUCTOR(Flv_List);
  493. #define _DECL_FLV_LIST_FUNC(name,nparams,pmask) {_SC(#name),_Flv_List_##name,nparams,pmask}
  494. static SQRegFunction flv_list_obj_funcs[]={
  495. _DECL_FLV_LIST_FUNC(constructor,-5,_SC("xiiiis")),
  496. {0,0}
  497. };
  498. FLTK_CONSTRUCTOR(Flv_Table);
  499. #define _DECL_FLV_TABLE_FUNC(name,nparams,pmask) {_SC(#name),_Flv_Table_##name,nparams,pmask}
  500. static SQRegFunction flv_table_obj_funcs[]={
  501. _DECL_FLV_TABLE_FUNC(constructor,-5,_SC("xiiiis")),
  502. {0,0}
  503. };
  504. FLTK_CONSTRUCTOR(Fl_Tabs);
  505. #define _DECL_FL_TABS_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Tabs_##name,nparams,pmask}
  506. static SQRegFunction fl_tabs_obj_funcs[]={
  507. _DECL_FL_TABS_FUNC(constructor,-5,_SC("xiiiis")),
  508. {0,0}
  509. };
  510. FLTK_CONSTRUCTOR(Fl_Text_Display);
  511. #define _DECL_FL_TEXT_DISPLAY_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Text_Display_##name,nparams,pmask}
  512. static SQRegFunction fl_text_display_obj_funcs[]={
  513. _DECL_FL_TEXT_DISPLAY_FUNC(constructor,-5,_SC("xiiiis")),
  514. {0,0}
  515. };
  516. FLTK_CONSTRUCTOR(Fl_Text_Editor);
  517. #define _DECL_FL_TEXT_EDITOR_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Text_Editor_##name,nparams,pmask}
  518. static SQRegFunction fl_text_editor_obj_funcs[]={
  519. _DECL_FL_TEXT_EDITOR_FUNC(constructor,-5,_SC("xiiiis")),
  520. {0,0}
  521. };
  522. FLTK_CONSTRUCTOR(Fl_Text_Editor_Buffered);
  523. #define _DECL_FL_TEXT_EDITOR_BUFFERED_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Text_Editor_Buffered_##name,nparams,pmask}
  524. static SQRegFunction fl_text_editor_buffered_obj_funcs[]={
  525. _DECL_FL_TEXT_EDITOR_BUFFERED_FUNC(constructor,-5,_SC("xiiiis")),
  526. {0,0}
  527. };
  528. static SQInteger _fl_window_releasehook(SQUserPointer p, SQInteger size)
  529. {
  530. Fl_Window *self = ((Fl_Window *)p);
  531. delete self;
  532. //printf("Releasing %p\n", self);
  533. return 1;
  534. }
  535. FLTK_CONSTRUCTOR_RELEASE(Fl_Window, AS_IS, _fl_window_releasehook);
  536. #define _DECL_FL_WINDOW_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Window_##name,nparams,pmask}
  537. static SQRegFunction fl_window_obj_funcs[]={
  538. _DECL_FL_WINDOW_FUNC(constructor,-5,_SC("xiiiis")),
  539. {0,0}
  540. };
  541. static SQInteger _fl_double_window_releasehook(SQUserPointer p, SQInteger size)
  542. {
  543. Fl_Double_Window *self = ((Fl_Double_Window *)p);
  544. delete self;
  545. //printf("Releasing %p\n", self);
  546. return 1;
  547. }
  548. FLTK_CONSTRUCTOR_RELEASE(Fl_Double_Window, AS_IS, _fl_double_window_releasehook);
  549. #define _DECL_FL_DOUBLE_WINDOW_FUNC(name,nparams,pmask) {_SC(#name),_Fl_Double_Window_##name,nparams,pmask}
  550. static SQRegFunction fl_double_window_obj_funcs[]={
  551. _DECL_FL_DOUBLE_WINDOW_FUNC(constructor,-5,_SC("xiiiis")),
  552. {0,0}
  553. };
  554. static void delayedDeleteWindow(void *w){
  555. printf("delayed %p\n", w);
  556. Fl_Widget *win = ((Fl_Widget*)w);
  557. win->hide();
  558. delete win;
  559. }
  560. static void delWindow(Fl_Widget *sender){
  561. Fl_Widget *win = sender->parent_root();
  562. printf("Parent root %p\n", win);
  563. Fl::add_timeout(0.1, &delayedDeleteWindow, win);
  564. }
  565. static Fl_Double_Window *newMyWin(){
  566. Fl_Double_Window *win = new Fl_Double_Window(200,200, "My FLTK Window");
  567. printf("New Window %p\n", win);
  568. Fl_Button *btnNew = new Fl_Button(50,50, 80,25, "New Win");
  569. btnNew->callback((Fl_Callback_p)&newMyWin);
  570. Fl_Button *btnClose = new Fl_Button(50,100, 80,25, "Close Win");
  571. btnClose->callback(&delWindow);
  572. win->end();
  573. win->resizable(win);
  574. win->show();
  575. return win;
  576. }
  577. static SQInteger _fl_show(HSQUIRRELVM sqvm)
  578. {
  579. Fl_Double_Window *win = newMyWin();
  580. sq_pushinteger(sqvm, Fl::run());
  581. //delete win;
  582. return 1;
  583. }
  584. static SQInteger _fl_run(HSQUIRRELVM sqvm)
  585. {
  586. sq_pushinteger(sqvm, Fl::run());
  587. return 1;
  588. }
  589. #define _DECL_FL_FUNC(name,nparams,pmask) {_SC(#name),_fl_##name,nparams,pmask}
  590. static SQRegFunction fl_obj_funcs[]={
  591. _DECL_FL_FUNC(show,-1,_SC("y")),
  592. _DECL_FL_FUNC(run,1,_SC("y")),
  593. {0,0}
  594. };
  595. #undef _DECL_FL_FUNC
  596. static void insertFuncs(HSQUIRRELVM sqvm, SQRegFunction *obj_funcs){
  597. SQInteger i = 0;
  598. while(obj_funcs[i].name != 0) {
  599. SQRegFunction &f = obj_funcs[i];
  600. sq_pushstring(sqvm,f.name,-1);
  601. sq_newclosure(sqvm,f.f,0);
  602. sq_setparamscheck(sqvm,f.nparamscheck,f.typemask);
  603. sq_setnativeclosurename(sqvm,-1,f.name);
  604. sq_newslot(sqvm,-3,SQFalse);
  605. i++;
  606. }
  607. }
  608. #define PUSH_FL_CLASS(klass, parent, method_funcs)\
  609. sq_pushstring(sqvm,_SC(#klass),-1);\
  610. sq_pushstring(sqvm,_SC(#parent),-1);\
  611. if (SQ_FAILED(sq_get(sqvm, -3)))\
  612. return sq_throwerror(sqvm, _SC("Missing base class."));\
  613. sq_newclass(sqvm,SQTrue);\
  614. sq_settypetag(sqvm,-1,(void*)FLTK_TAG(klass));\
  615. insertFuncs(sqvm, method_funcs);\
  616. sq_newslot(sqvm,-3,SQFalse);
  617. SQRESULT sqstd_register_fltklib(HSQUIRRELVM sqvm)
  618. {
  619. Fl::user_data = sqvm;
  620. sq_pushstring(sqvm,_SC("fltk"),-1);
  621. sq_newtable(sqvm);
  622. //Fl class
  623. sq_pushstring(sqvm,_SC("Fl"),-1);
  624. sq_newclass(sqvm,SQFalse);
  625. sq_settypetag(sqvm,-1,(void*)FLTK_TAG(Fl));
  626. insertFuncs(sqvm, fl_obj_funcs);
  627. sq_newslot(sqvm,-3,SQFalse);
  628. //Fl_Widget class
  629. sq_pushstring(sqvm,_SC("Fl_Widget"),-1);
  630. sq_newclass(sqvm,SQFalse);
  631. sq_settypetag(sqvm,-1,(void*)FLTK_TAG(Fl_Widget));
  632. insertFuncs(sqvm, fl_widget_obj_funcs);
  633. sq_newslot(sqvm,-3,SQFalse);
  634. //Fl_Box class
  635. PUSH_FL_CLASS(Fl_Box, Fl_Widget, fl_box_obj_funcs);
  636. //Fl_Button class
  637. PUSH_FL_CLASS(Fl_Button, Fl_Widget, fl_button_obj_funcs);
  638. PUSH_FL_CLASS(Fl_Light_Button, Fl_Button, fl_light_button_obj_funcs);
  639. PUSH_FL_CLASS(Fl_Check_Button, Fl_Light_Button, fl_check_button_obj_funcs);
  640. PUSH_FL_CLASS(Fl_Radio_Button, Fl_Button, fl_radio_button_obj_funcs);
  641. PUSH_FL_CLASS(Fl_Menu_, Fl_Widget, fl_menu__obj_funcs);
  642. PUSH_FL_CLASS(Fl_Choice, Fl_Menu_, fl_choice_obj_funcs);
  643. //Fl_Input_ class
  644. PUSH_FL_CLASS(Fl_Input_, Fl_Widget, fl_input__obj_funcs);
  645. PUSH_FL_CLASS(Fl_Input, Fl_Input_, fl_input_obj_funcs);
  646. PUSH_FL_CLASS(Fl_Float_Input, Fl_Input, fl_float_input_obj_funcs);
  647. PUSH_FL_CLASS(Fl_Int_Input, Fl_Input, fl_int_input_obj_funcs);
  648. PUSH_FL_CLASS(Fl_Output, Fl_Input, fl_output_obj_funcs);
  649. PUSH_FL_CLASS(Fl_Secret_Input, Fl_Input, fl_secret_input_obj_funcs);
  650. //Fl_Group class
  651. PUSH_FL_CLASS(Fl_Group, Fl_Widget, fl_group_obj_funcs);
  652. PUSH_FL_CLASS(Fl_Pack, Fl_Group, fl_pack_obj_funcs);
  653. PUSH_FL_CLASS(Fl_Tabs, Fl_Group, fl_tabs_obj_funcs);
  654. PUSH_FL_CLASS(Fl_Text_Display, Fl_Group, fl_text_display_obj_funcs);
  655. PUSH_FL_CLASS(Fl_Text_Editor, Fl_Text_Display, fl_text_editor_obj_funcs);
  656. PUSH_FL_CLASS(Fl_Text_Editor_Buffered, Fl_Text_Editor, fl_text_editor_buffered_obj_funcs);
  657. PUSH_FL_CLASS(Flv_List, Fl_Group, flv_list_obj_funcs);
  658. PUSH_FL_CLASS(Flv_Table, Flv_List, flv_table_obj_funcs);
  659. //Fl_Window class
  660. PUSH_FL_CLASS(Fl_Window, Fl_Group, fl_window_obj_funcs);
  661. //Fl_Double_Window class
  662. PUSH_FL_CLASS(Fl_Double_Window, Fl_Window, fl_double_window_obj_funcs);
  663. sq_newslot(sqvm,-3,SQFalse); //add fltk table to the root table
  664. sq_poptop(sqvm); //removes fltk table
  665. #define INT_CONST(key) \
  666. sq_pushstring(sqvm, _SC(#key), -1);\
  667. sq_pushinteger(sqvm, key);\
  668. sq_newslot(sqvm, -3, SQFalse);
  669. sq_pushconsttable(sqvm);
  670. INT_CONST(FL_RED);
  671. INT_CONST(FL_YELLOW);
  672. INT_CONST(FL_GREEN);
  673. sq_poptop(sqvm);
  674. //check to see if we need to release resources
  675. Fl::do_at_widget_destroy_ = At_Widget_Destroy;
  676. return SQ_OK;
  677. }
  678. #endif //WITH_FLTK