fix bug in QOVERRIDE (adding new function QCALL-DEFAULT); update examples & docu...
[eql:eql.git] / src / ecl_fun.h
1 // copyright (c) 2010-2011 Polos Ruetz\r
2 \r
3 #ifndef ECL_FUN_H\r
4 #define ECL_FUN_H\r
5 \r
6 #include "eql_global.h"\r
7 #include <ecl/ecl.h>\r
8 #include <QList>\r
9 #include <QUiLoader>\r
10 #include <QByteArray>\r
11 #include <QPair>\r
12 #include <QVariant>\r
13 \r
14 #define PRINT(x) cl_print(1, x)\r
15 #define TERPRI() cl_terpri(0)\r
16 \r
17 #define STATIC_SYMBOL(var, name) \\r
18     static cl_object var = cl_intern(1, make_constant_base_string(name));\r
19 \r
20 #define STATIC_SYMBOL_PKG(var, name, pkg) \\r
21     static cl_object var = cl_intern(2, \\r
22                                      make_constant_base_string(name), \\r
23                                      cl_find_package(make_constant_base_string(pkg)));\r
24 \r
25 #define LEN(x) fixint(cl_length(x))\r
26 \r
27 #define  LIST1(a1) \\r
28     CONS(a1,  Cnil)\r
29 #define  LIST2(a1, a2) \\r
30     CONS(a1, LIST1(a2))\r
31 #define  LIST3(a1, a2, a3) \\r
32     CONS(a1, LIST2(a2, a3))\r
33 #define  LIST4(a1, a2, a3, a4) \\r
34     CONS(a1, LIST3(a2, a3, a4))\r
35 #define  LIST5(a1, a2, a3, a4, a5) \\r
36     CONS(a1, LIST4(a2, a3, a4, a5))\r
37 #define  LIST6(a1, a2, a3, a4, a5, a6) \\r
38     CONS(a1, LIST5(a2, a3, a4, a5, a6))\r
39 #define  LIST7(a1, a2, a3, a4, a5, a6, a7) \\r
40     CONS(a1, LIST6(a2, a3, a4, a5, a6, a7))\r
41 #define  LIST8(a1, a2, a3, a4, a5, a6, a7, a8) \\r
42     CONS(a1, LIST7(a2, a3, a4, a5, a6, a7, a8))\r
43 #define  LIST9(a1, a2, a3, a4, a5, a6, a7, a8, a9) \\r
44     CONS(a1, LIST8(a2, a3, a4, a5, a6, a7, a8, a9))\r
45 #define LIST10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \\r
46     CONS(a1, LIST9(a2, a3, a4, a5, a6, a7, a8, a9, a10))\r
47 \r
48 #define TO_QT_TYPE(name) \\r
49     static name to##name(cl_object x) { \\r
50         if(LISTP(x)) { \\r
51             return name(toInt(cl_first(x)), toInt(cl_second(x))); } \\r
52         return name(); }\r
53 \r
54 #define TO_QT_TYPEF(name) \\r
55     TO_QT_TYPE(name) \\r
56     static name##F to##name##F(cl_object x) { \\r
57         if(LISTP(x)) { \\r
58             return name##F(toReal(cl_first(x)), toReal(cl_second(x))); } \\r
59     return name##F(); }\r
60 \r
61 #define TO_QT_TYPE2(name) \\r
62     static name to##name(cl_object x) { \\r
63         if(LISTP(x)) { \\r
64             return name(toInt(cl_first(x)), toInt(cl_second(x)), toInt(cl_third(x)), toInt(cl_fourth(x))); } \\r
65         return name(); }\r
66 \r
67 #define TO_QT_TYPEF2(name) \\r
68     TO_QT_TYPE2(name) \\r
69     static name##F to##name##F(cl_object x) { \\r
70         if(LISTP(x)) { \\r
71             return name##F(toReal(cl_first(x)), toReal(cl_second(x)), toReal(cl_third(x)), toReal(cl_fourth(x))); } \\r
72     return name##F(); }\r
73 \r
74 #define TO_QT_TYPE_PTR(cap_name, name) \\r
75 static cap_name* to##cap_name##Pointer(cl_object x) { \\r
76     cap_name* p = 0; \\r
77     QtObject o = toQtObject(x); \\r
78     if(#cap_name == o.className()) { \\r
79         p = (cap_name*)o.pointer; } \\r
80     return p; } \\r
81 static cl_object from_##name(const cap_name& x) { \\r
82     if(EQL::is_arg_return_value) { \\r
83         return qt_object_from_name(#cap_name, new cap_name(x), 0, true); } \\r
84     return qt_object_from_name(#cap_name, (void*)&x); }\r
85 \r
86 #define TO_QT_TYPE_PTR2(cap_name, name) \\r
87     TO_QT_TYPE_PTR(cap_name, name) \\r
88 static cap_name to##cap_name(cl_object l_x) { \\r
89     cap_name* x = to##cap_name##Pointer(l_x); \\r
90     if(x) { \\r
91         return *x; } \\r
92     return cap_name(); }\r
93 \r
94 #define TO_CL_TYPE(cap_name, name, x1, x2) \\r
95     static cl_object from_##name(const cap_name& q) { \\r
96         return LIST2(MAKE_FIXNUM(q.x1()), MAKE_FIXNUM(q.x2())); }\r
97 \r
98 #define TO_CL_TYPEF(cap_name, name, x1, x2) \\r
99     TO_CL_TYPE(cap_name, name, x1, x2) \\r
100     static cl_object from_##name##f(const cap_name##F& q) { \\r
101         return LIST2(ecl_make_doublefloat(q.x1()), ecl_make_doublefloat(q.x2())); }\r
102 \r
103 #define TO_CL_TYPE2(cap_name, name, x1, x2, x3, x4) \\r
104     static cl_object from_##name(const cap_name& q) { \\r
105         return LIST4(MAKE_FIXNUM(q.x1()), MAKE_FIXNUM(q.x2()), MAKE_FIXNUM(q.x3()), MAKE_FIXNUM(q.x4())); }\r
106 \r
107 #define TO_CL_TYPEF2(cap_name, name, x1, x2, x3, x4) \\r
108     TO_CL_TYPE2(cap_name, name, x1, x2, x3, x4) \\r
109     static cl_object from_##name##f(const cap_name##F& q) { \\r
110         return LIST4(ecl_make_doublefloat(q.x1()), ecl_make_doublefloat(q.x2()), ecl_make_doublefloat(q.x3()), ecl_make_doublefloat(q.x4())); }\r
111 \r
112 #define TO_CL_LIST_PTR(cap_type, type) \\r
113     static cl_object from_##type##list(const QList<cap_type*>& l) { \\r
114         cl_object l_lst = Cnil; \\r
115         Q_FOREACH(cap_type* x, l) { \\r
116             l_lst = CONS(qt_object_from_name(#cap_type, x), l_lst); } \\r
117         return cl_nreverse(l_lst); }\r
118 \r
119 #define TO_CL_LIST_VAL(cap_type, type) \\r
120     static cl_object from_##type##list(const QList<cap_type>& l) { \\r
121         cl_object l_lst = Cnil; \\r
122         Q_FOREACH(cap_type x, l) { \\r
123             l_lst = CONS(from_##type(x), l_lst); } \\r
124         return cl_nreverse(l_lst); }\r
125 \r
126 #define TO_CL_LIST_VAL2(cap_type, fun) \\r
127     static cl_object from_##type##list(const QList<cap_type*>& l) { \\r
128         cl_object l_lst = Cnil; \\r
129         Q_FOREACH(cap_type* x, l) { \\r
130             l_lst = CONS(fun(*x), l_lst); } \\r
131         return cl_nreverse(l_lst); }\r
132 \r
133 #define TO_QT_LIST_PTR(type) \\r
134     static QList<type*> to##type##List(cl_object l_lst) { \\r
135         QList<type*> l; \\r
136         if(LISTP(l_lst)) { \\r
137             cl_object l_el = l_lst; \\r
138             while(l_el != Cnil) { \\r
139                 l << (type*)toQtObject(cl_car(l_el)).pointer; \\r
140                 l_el = cl_cdr(l_el); }} \\r
141         return l; }\r
142 \r
143 #define TO_QT_LIST_VAL(type) \\r
144     static QList<type> to##type##List(cl_object l_lst) { \\r
145         QList<type> l; \\r
146         if(LISTP(l_lst)) { \\r
147             cl_object l_el = l_lst; \\r
148             while(l_el != Cnil) { \\r
149                 l << to##type(cl_car(l_el)); \\r
150                 l_el = cl_cdr(l_el); }} \\r
151         return l; }\r
152 \r
153 #define TO_QT_LIST_VAL2(type, fun) \\r
154     static QList<type> to##fun##List(cl_object l_lst) { \\r
155         QList<type> l; \\r
156         if(LISTP(l_lst)) { \\r
157             cl_object l_el = l_lst; \\r
158             while(l_el != Cnil) { \\r
159                 l << to##fun(cl_car(l_el)); \\r
160                 l_el = cl_cdr(l_el); }} \\r
161         return l; }\r
162 \r
163 #define TO_QT_VECTOR_VAL(type) \\r
164     static QVector<type> to##type##Vector(cl_object l_v) { \\r
165         QVector<type> v; \\r
166         if(cl_simple_vector_p(l_v) == Ct) { \\r
167             for(int i = 0; i < LEN(l_v); ++i) { \\r
168                 v.append(to##type(cl_svref(l_v, MAKE_FIXNUM(i)))); }} \\r
169         return v; }\r
170 \r
171 #define TO_QT_VECTOR_VAL2(type, fun) \\r
172     static QVector<type> to##type##Vector(cl_object l_v) { \\r
173         QVector<type> v; \\r
174         if(cl_simple_vector_p(l_v) == Ct) { \\r
175             for(int i = 0; i < LEN(l_v); ++i) { \\r
176                 v.append(to##fun(cl_svref(l_v, MAKE_FIXNUM(i)))); }} \\r
177         return v; }\r
178 \r
179 #define TO_CL_VECTOR_VAL(cap_type, type) \\r
180     static cl_object from_##type##vector(const QVector<cap_type>& v) { \\r
181         cl_object l_vec = make_vector(); \\r
182         for(int i = 0; i < v.size(); ++i) { \\r
183             cl_vector_push_extend(2, from_##type(v.at(i)), l_vec); } \\r
184         return l_vec; }\r
185 \r
186 #define TO_CL_VECTOR_VAL2(cap_type, type, fun) \\r
187     static cl_object from_##type##vector(const QVector<cap_type>& v) { \\r
188         cl_object l_vec = make_vector(); \\r
189         for(int i = 0; i < v.size(); ++i) { \\r
190             cl_vector_push_extend(2, fun(v.at(i)), l_vec); } \\r
191         return l_vec; }\r
192 \r
193 class QByteArray;\r
194 class QObject;\r
195 class QEvent;\r
196 \r
197 cl_object qadd_event_filter    (cl_object, cl_object, cl_object);\r
198 cl_object qapropos2            (cl_object, cl_object, cl_object);\r
199 cl_object qapp                 ();\r
200 cl_object qcall_default        ();\r
201 cl_object qclear_event_filters ();\r
202 cl_object qconnect2            (cl_object, cl_object, cl_object, cl_object, cl_object);\r
203 cl_object qcopy                (cl_object);\r
204 cl_object qdelete2             (cl_object, cl_object);\r
205 cl_object qenum                (cl_object, cl_object);\r
206 cl_object qescape              (cl_object);\r
207 cl_object qexec                ();\r
208 cl_object qfind_child          (cl_object, cl_object);\r
209 cl_object qfrom_utf8           (cl_object);\r
210 cl_object qid                  (cl_object);\r
211 cl_object qinvoke_method2      (cl_object, cl_object, cl_object, cl_object);\r
212 cl_object qload_ui             (cl_object);\r
213 cl_object qlocal8bit           (cl_object);\r
214 cl_object qmeta_enums          ();\r
215 cl_object qnew_instance2       (cl_object, cl_object);\r
216 cl_object qobject_names2       (cl_object);\r
217 cl_object qok                  ();\r
218 cl_object qoverride            (cl_object, cl_object, cl_object);\r
219 cl_object qprocess_events      ();\r
220 cl_object qproperty            (cl_object, cl_object);\r
221 cl_object qquit                ();\r
222 cl_object qrequire             (cl_object);\r
223 cl_object qsender              ();\r
224 cl_object qset_property        (cl_object, cl_object, cl_object);\r
225 cl_object qsingle_shot         (cl_object, cl_object);\r
226 cl_object qstatic_meta_object  (cl_object);\r
227 cl_object qsuper_class_name    (cl_object);\r
228 cl_object qtranslate           (cl_object, cl_object, cl_object);\r
229 cl_object qt_object_name       (cl_object);\r
230 cl_object qui_class2           (cl_object, cl_object);\r
231 cl_object qui_names            (cl_object);\r
232 cl_object qutf8                (cl_object);\r
233 cl_object qversion             ();\r
234 \r
235 struct EQL_EXPORT QtObject {\r
236     QtObject() : pointer(0), unique(0), id(0) {}\r
237 \r
238     void* pointer;\r
239     uint unique;\r
240     int id;\r
241 \r
242     bool isQObject() const { return (id > 0); }\r
243     bool isStatic() const { return !pointer; }\r
244     QByteArray className() const;\r
245 \r
246     static QByteArray idToClassName(int);\r
247 };\r
248 \r
249 struct QtMetaObject : private QObject {\r
250     // commonly used trick to access staticQtMetaObject\r
251     static const QMetaObject* get() { return &static_cast<QtMetaObject*>(0)->staticQtMetaObject; }\r
252 };\r
253 \r
254 typedef QPair<QByteArray, void*> MetaArg;\r
255 \r
256 void iniCLFunctions();\r
257 void callConnectFun(void*, const QList<QByteArray>&, void**);\r
258 bool callEventFun(void*, QObject*, QEvent*);\r
259 cl_object to_lisp_arg(const MetaArg&);\r
260 QVariant toQVariant(cl_object, const char*, QVariant::Type = QVariant::UserType);\r
261 void error_msg(const char*, cl_object);\r
262 \r
263 EQL_EXPORT QVariant callOverrideFun(void*, int, const void**);\r
264 EQL_EXPORT QtObject toQtObject(cl_object, cl_object = Cnil, bool* = 0);\r
265 EQL_EXPORT cl_object qt_object_from_name(const QByteArray&, void*, uint = 0, bool = false);\r
266 \r
267 #endif\r