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