Macro tweaks.
[ruby-ecore.git] / src / ecore_evas / rb_ecore_evas.c
1 /*
2  * $Id: rb_ecore_evas.c 40 2004-07-25 13:14:34Z tilman $
3  *
4  * Copyright (C) 2004 Tilman Sauerbeck (tilman at code-monkey de)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <ruby.h>
22
23 #include <Ecore.h>
24 #include <Ecore_Evas.h>
25 #include <rb_evas.h>
26
27 #include "../ecore/rb_ecore.h"
28 #include "rb_ecore_evas_main.h"
29 #include "rb_ecore_evas.h"
30
31 #define CALLBACK_ADD_HANDLER(name) \
32         static void on_##name (Ecore_Evas *ee) \
33         { \
34                 VALUE self = rb_hash_aref (objects, INT2NUM ((long) ee)); \
35                 VALUE hash = rb_hash_aref (callbacks, self); \
36 \
37                 rb_funcall (rb_hash_aref (hash, rb_str_new2 (#name)), \
38                             rb_intern ("call"), 0); \
39         } \
40 \
41         static VALUE c_on_##name (VALUE self) \
42         { \
43                 VALUE hash; \
44 \
45                 GET_OBJ (self, Ecore_Evas *, ee); \
46 \
47                 if (!rb_block_given_p ()) \
48                         return Qnil; \
49 \
50                 if (NIL_P ((hash = rb_hash_aref (callbacks, self)))) { \
51                         hash = rb_hash_new (); \
52 \
53                         rb_global_variable (&hash); \
54                         rb_hash_aset (callbacks, self, hash); \
55                 } \
56 \
57                 rb_hash_aset (hash, rb_str_new2 (#name), rb_block_proc ()); \
58 \
59                 ecore_evas_callback_##name##_set (*ee, on_##name); \
60 \
61                 return Qnil; \
62         }
63
64 #define CALLBACK_ADD(mod, name) \
65         rb_define_method ((mod), "on_"#name, c_on_##name, 0);
66
67 static VALUE evases, callbacks, objects;
68
69 /* called by the child classes */
70 void c_ecore_evas_free (Ecore_Evas **ee)
71 {
72         if (*ee) {
73                 rb_hash_aset (objects, INT2NUM ((long) *ee), Qnil);
74                 ecore_evas_free (*ee);
75         }
76
77         rb_hash_aset (evases, INT2NUM ((long) ee), Qnil);
78
79         ecore_evas_shutdown ();
80         ecore_shutdown ();
81
82         free (ee);
83 }
84
85 static VALUE c_initialize (int argc, VALUE *argv, VALUE self)
86 {
87         Ecore_Evas **ee = NULL;
88
89         Data_Get_Struct (self, Ecore_Evas *, ee);
90
91         rb_hash_aset (objects, INT2NUM ((long) *ee), self);
92
93         return Qnil;
94 }
95
96 static VALUE c_inspect (VALUE self)
97 {
98         INSPECT (self, Ecore_Evas *);
99 }
100
101 static VALUE c_show (VALUE self)
102 {
103         GET_OBJ (self, Ecore_Evas *, ee);
104
105         ecore_evas_show (*ee);
106
107         return Qnil;
108 }
109
110 static VALUE c_hide (VALUE self)
111 {
112         GET_OBJ (self, Ecore_Evas *, ee);
113
114         ecore_evas_hide (*ee);
115
116         return Qnil;
117 }
118
119 static VALUE c_visible_get (VALUE self)
120 {
121         GET_OBJ (self, Ecore_Evas *, ee);
122
123         return ecore_evas_visibility_get (*ee) ? Qtrue : Qfalse;
124 }
125
126 static VALUE c_raise (VALUE self)
127 {
128         GET_OBJ (self, Ecore_Evas *, ee);
129
130         ecore_evas_raise (*ee);
131
132         return Qnil;
133 }
134
135 static VALUE c_lower (VALUE self)
136 {
137         GET_OBJ (self, Ecore_Evas *, ee);
138
139         ecore_evas_lower (*ee);
140
141         return Qnil;
142 }
143
144 static VALUE c_layer_get (VALUE self)
145 {
146         GET_OBJ (self, Ecore_Evas *, ee);
147
148         return INT2FIX (ecore_evas_layer_get (*ee));
149 }
150
151 static VALUE c_layer_set (VALUE self, VALUE val)
152 {
153         GET_OBJ (self, Ecore_Evas *, ee);
154
155         Check_Type (val, T_FIXNUM);
156
157         ecore_evas_layer_set (*ee, FIX2INT (val));
158
159         return Qnil;
160 }
161
162 static VALUE c_evas_get (VALUE self)
163 {
164         VALUE evas;
165
166         GET_OBJ (self, Ecore_Evas *, ee);
167
168         if (NIL_P (evas = rb_hash_aref (evases, INT2NUM ((long) (ee))))) {
169                 evas = TO_EVAS (self, ecore_evas_get (*ee));
170                 rb_hash_aset (evases, INT2NUM ((long) ee), evas);
171         }
172
173         return evas;
174 }
175
176 static VALUE c_geometry_get (VALUE self)
177 {
178         int x = 0, y = 0, w = 0, h = 0;
179
180         GET_OBJ (self, Ecore_Evas *, ee);
181
182         ecore_evas_geometry_get (*ee, &x, &y, &w, &h);
183
184         return rb_ary_new3 (4, INT2FIX (x), INT2FIX (y),
185                             INT2FIX (w), INT2FIX (h));
186 }
187
188 static VALUE c_get_size_min (VALUE self)
189 {
190         int w = 0, h = 0;
191
192         GET_OBJ (self, Ecore_Evas *, ee);
193
194         ecore_evas_size_min_get (*ee, &w, &h);
195
196         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
197 }
198
199 static VALUE c_set_size_min (VALUE self, VALUE w, VALUE h)
200 {
201         GET_OBJ (self, Ecore_Evas *, ee);
202
203         Check_Type (w, T_FIXNUM);
204         Check_Type (h, T_FIXNUM);
205
206         ecore_evas_size_min_set (*ee, FIX2INT (w), FIX2INT (h));
207
208         return Qnil;
209 }
210
211 static VALUE c_get_size_max (VALUE self)
212 {
213         int w = 0, h = 0;
214
215         GET_OBJ (self, Ecore_Evas *, ee);
216
217         ecore_evas_size_max_get (*ee, &w, &h);
218
219         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
220 }
221
222 static VALUE c_set_size_max (VALUE self, VALUE w, VALUE h)
223 {
224         GET_OBJ (self, Ecore_Evas *, ee);
225
226         Check_Type (w, T_FIXNUM);
227         Check_Type (h, T_FIXNUM);
228
229         ecore_evas_size_max_set (*ee, FIX2INT (w), FIX2INT (h));
230
231         return Qnil;
232 }
233
234 static VALUE c_move (VALUE self, VALUE x, VALUE y)
235 {
236         GET_OBJ (self, Ecore_Evas *, ee);
237
238         Check_Type (x, T_FIXNUM);
239         Check_Type (y, T_FIXNUM);
240
241         ecore_evas_move (*ee, FIX2INT (x), FIX2INT (y));
242
243         return Qnil;
244 }
245
246 static VALUE c_resize (VALUE self, VALUE w, VALUE h)
247 {
248         GET_OBJ (self, Ecore_Evas *, ee);
249
250         Check_Type (w, T_FIXNUM);
251         Check_Type (h, T_FIXNUM);
252
253         ecore_evas_resize (*ee, FIX2INT (w), FIX2INT (h));
254
255         return Qnil;
256 }
257
258 static VALUE c_title_get (VALUE self)
259 {
260         const char *tmp;
261
262         GET_OBJ (self, Ecore_Evas *, ee);
263
264         if (!(tmp = ecore_evas_title_get (*ee)))
265                 return Qnil;
266         else
267                 return rb_str_new2 (tmp);
268 }
269
270 static VALUE c_title_set (VALUE self, VALUE val)
271 {
272         GET_OBJ (self, Ecore_Evas *, ee);
273
274         Check_Type (val, T_STRING);
275
276         ecore_evas_title_set (*ee, StringValuePtr (val));
277
278         return Qnil;
279 }
280
281 static VALUE c_borderless_get (VALUE self)
282 {
283         GET_OBJ (self, Ecore_Evas *, ee);
284
285         return ecore_evas_borderless_get (*ee) ? Qtrue : Qfalse;
286 }
287
288 static VALUE c_borderless_set (VALUE self, VALUE val)
289 {
290         GET_OBJ (self, Ecore_Evas *, ee);
291
292         CHECK_BOOL (val);
293
294         ecore_evas_borderless_set (*ee, val == Qtrue ? 1 : 0);
295
296         return Qnil;
297 }
298
299 static VALUE c_shaped_get (VALUE self)
300 {
301         GET_OBJ (self, Ecore_Evas *, ee);
302
303         return ecore_evas_shaped_get (*ee) ? Qtrue : Qfalse;
304 }
305
306 static VALUE c_shaped_set (VALUE self, VALUE val)
307 {
308         GET_OBJ (self, Ecore_Evas *, ee);
309
310         CHECK_BOOL (val);
311
312         ecore_evas_shaped_set (*ee, val == Qtrue ? 1 : 0);
313
314         return Qnil;
315 }
316
317 static VALUE c_sticky_get (VALUE self)
318 {
319         GET_OBJ (self, Ecore_Evas *, ee);
320
321         return ecore_evas_sticky_get (*ee) ? Qtrue : Qfalse;
322 }
323
324 static VALUE c_sticky_set (VALUE self, VALUE val)
325 {
326         GET_OBJ (self, Ecore_Evas *, ee);
327
328         CHECK_BOOL (val);
329
330         ecore_evas_sticky_set (*ee, val == Qtrue ? 1 : 0);
331
332         return Qnil;
333 }
334
335 static VALUE c_rotation_get (VALUE self)
336 {
337         GET_OBJ (self, Ecore_Evas *, ee);
338
339         return INT2FIX (ecore_evas_rotation_get (*ee));
340 }
341
342 static VALUE c_rotation_set (VALUE self, VALUE val)
343 {
344         GET_OBJ (self, Ecore_Evas *, ee);
345
346         Check_Type (val, T_FIXNUM);
347
348         ecore_evas_rotation_set (*ee, FIX2INT (val));
349
350         return Qnil;
351 }
352
353 /* FIXME: this is unsafe! */
354 static VALUE c_delete (VALUE self)
355 {
356         GET_OBJ (self, Ecore_Evas *, ee);
357
358         /* reap our children */
359         rb_gc_start ();
360
361         ecore_evas_free (*ee);
362         rb_hash_aset (objects, INT2NUM ((long) *ee), Qnil);
363         *ee = NULL;
364
365         return Qnil;
366 }
367
368 CALLBACK_ADD_HANDLER (resize);
369 CALLBACK_ADD_HANDLER (move);
370 CALLBACK_ADD_HANDLER (show);
371 CALLBACK_ADD_HANDLER (hide);
372 CALLBACK_ADD_HANDLER (delete_request);
373 CALLBACK_ADD_HANDLER (destroy);
374 CALLBACK_ADD_HANDLER (focus_in);
375 CALLBACK_ADD_HANDLER (focus_out);
376 CALLBACK_ADD_HANDLER (mouse_in);
377 CALLBACK_ADD_HANDLER (mouse_out);
378 CALLBACK_ADD_HANDLER (pre_render);
379 CALLBACK_ADD_HANDLER (post_render);
380
381 void Init_EcoreEvas (void)
382 {
383         cEcoreEvas = rb_define_class_under (mEvas, "EcoreEvas", rb_cObject);
384
385         rb_define_private_method (rb_singleton_class (cEcoreEvas),
386                                   "new", NULL, 0);
387         rb_define_method (cEcoreEvas, "initialize", c_initialize, -1);
388         rb_define_method (cEcoreEvas, "inspect", c_inspect, 0);
389         rb_define_method (cEcoreEvas, "delete", c_delete, 0);
390         rb_define_method (cEcoreEvas, "show", c_show, 0);
391         rb_define_method (cEcoreEvas, "hide", c_hide, 0);
392         rb_define_method (cEcoreEvas, "visible?", c_visible_get, 0);
393         rb_define_method (cEcoreEvas, "raise", c_raise, 0);
394         rb_define_method (cEcoreEvas, "lower", c_lower, 0);
395         rb_define_method (cEcoreEvas, "layer", c_layer_get, 0);
396         rb_define_method (cEcoreEvas, "layer=", c_layer_set, 1);
397         rb_define_method (cEcoreEvas, "evas", c_evas_get, 0);
398         rb_define_method (cEcoreEvas, "geometry", c_geometry_get, 0);
399         rb_define_method (cEcoreEvas, "get_size_min", c_get_size_min, 0);
400         rb_define_method (cEcoreEvas, "set_size_min", c_set_size_min, 2);
401         rb_define_method (cEcoreEvas, "get_size_max", c_get_size_max, 0);
402         rb_define_method (cEcoreEvas, "set_size_max", c_set_size_max, 2);
403         rb_define_method (cEcoreEvas, "move", c_move, 2);
404         rb_define_method (cEcoreEvas, "resize", c_resize, 2);
405         rb_define_method (cEcoreEvas, "title", c_title_get, 0);
406         rb_define_method (cEcoreEvas, "title=", c_title_set, 1);
407         rb_define_method (cEcoreEvas, "borderless?", c_borderless_get, 0);
408         rb_define_method (cEcoreEvas, "borderless=", c_borderless_set, 1);
409         rb_define_method (cEcoreEvas, "shaped?", c_shaped_get, 0);
410         rb_define_method (cEcoreEvas, "shaped=", c_shaped_set, 1);
411         rb_define_method (cEcoreEvas, "sticky?", c_sticky_get, 0);
412         rb_define_method (cEcoreEvas, "sticky=", c_sticky_set, 1);
413         rb_define_method (cEcoreEvas, "rotation", c_rotation_get, 0);
414         rb_define_method (cEcoreEvas, "rotation=", c_rotation_set, 1);
415
416         CALLBACK_ADD (cEcoreEvas, resize);
417         CALLBACK_ADD (cEcoreEvas, move);
418         CALLBACK_ADD (cEcoreEvas, show);
419         CALLBACK_ADD (cEcoreEvas, hide);
420         CALLBACK_ADD (cEcoreEvas, delete_request);
421         CALLBACK_ADD (cEcoreEvas, destroy);
422         CALLBACK_ADD (cEcoreEvas, focus_in);
423         CALLBACK_ADD (cEcoreEvas, focus_out);
424         CALLBACK_ADD (cEcoreEvas, mouse_in);
425         CALLBACK_ADD (cEcoreEvas, mouse_out);
426         CALLBACK_ADD (cEcoreEvas, pre_render);
427         CALLBACK_ADD (cEcoreEvas, post_render);
428
429         evases = rb_hash_new ();
430         rb_global_variable (&evases);
431
432         objects = rb_hash_new ();
433         rb_global_variable (&objects);
434
435         callbacks = rb_hash_new ();
436         rb_global_variable (&callbacks);
437 }