Use ecore_evas_data_set/get to store a pointer to self.
[ruby-ecore.git] / src / ecore_evas / rb_ecore_evas.c
1 /*
2  * $Id: rb_ecore_evas.c 110 2004-09-02 17:06:54Z tilman $
3  *
4  * Copyright (C) 2004 ruby-ecore team (see AUTHORS)
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 #include <stdbool.h>
23
24 #include <Ecore.h>
25 #include <Ecore_Evas.h>
26 #include <evas/rb_evas.h>
27
28 #define __RB_ECORE_EVAS_C
29 #include "../ecore/rb_ecore.h"
30 #include "rb_ecore_evas_main.h"
31 #include "rb_ecore_evas.h"
32
33 #define RUBY_ECORE_EVAS_KEY "__RB_ECORE_EVAS_KEY"
34
35 #define CALLBACK_DEFINE_HANDLER(name) \
36         static void on_##name (Ecore_Evas *real) \
37         { \
38                 VALUE self; \
39                 VALUE cb; \
40 \
41                 self = (VALUE) ecore_evas_data_get (real, \
42                                                     RUBY_ECORE_EVAS_KEY); \
43                 GET_OBJ (self, RbEcoreEvas, ee); \
44 \
45                 cb = rb_hash_aref (ee->callbacks, rb_str_new2 (#name)); \
46                 rb_funcall (cb, rb_intern ("call"), 0); \
47         } \
48
49 #define CALLBACK_REG_HANDLER(name) \
50                 GET_OBJ (self, RbEcoreEvas, ee); \
51 \
52                 if (!rb_block_given_p ()) \
53                         return Qnil; \
54 \
55                 rb_hash_aset (ee->callbacks, rb_str_new2 (#name), \
56                               rb_block_proc ()); \
57 \
58                 ecore_evas_callback_##name##_set (ee->real, on_##name); \
59 \
60                 return Qnil;
61
62 VALUE cEcoreEvas;
63
64 /* called by the child classes */
65 void c_ecore_evas_mark (RbEcoreEvas *ee)
66 {
67         if (!NIL_P (ee->evas))
68                 rb_gc_mark (ee->evas);
69
70         rb_gc_mark (ee->callbacks);
71 }
72
73 void c_ecore_evas_free (RbEcoreEvas *ee, bool free_mem)
74 {
75         if (ee->real)
76                 ecore_evas_free (ee->real);
77
78         ecore_evas_shutdown ();
79         ecore_shutdown ();
80
81         if (free_mem)
82                 free (ee);
83 }
84
85 /* :nodoc: */
86 static VALUE c_init (int argc, VALUE *argv, VALUE self)
87 {
88         GET_OBJ (self, RbEcoreEvas, ee);
89
90         ee->evas = Qnil;
91         ee->callbacks = rb_hash_new ();
92
93         ecore_evas_data_set (ee->real, RUBY_ECORE_EVAS_KEY, (void *) self);
94
95         return Qnil;
96 }
97
98 /* :nodoc: */
99 static VALUE c_inspect (VALUE self)
100 {
101         INSPECT (self, RbEcoreEvas);
102 }
103
104 /*
105  * call-seq:
106  *  ee.show => nil
107  *
108  * Shows <i>ee</i>.
109  */
110 static VALUE c_show (VALUE self)
111 {
112         GET_OBJ (self, RbEcoreEvas, ee);
113
114         ecore_evas_show (ee->real);
115
116         return Qnil;
117 }
118
119 /*
120  * call-seq:
121  *  ee.hide => nil
122  *
123  * Hides <i>ee</i>.
124  */
125 static VALUE c_hide (VALUE self)
126 {
127         GET_OBJ (self, RbEcoreEvas, ee);
128
129         ecore_evas_hide (ee->real);
130
131         return Qnil;
132 }
133
134 /*
135  * call-seq:
136  *  ee.visible? => true or false
137  *
138  * Returns true if <i>ee</i> is visible, else returns false.
139  */
140 static VALUE c_visible_get (VALUE self)
141 {
142         GET_OBJ (self, RbEcoreEvas, ee);
143
144         return ecore_evas_visibility_get (ee->real) ? Qtrue : Qfalse;
145 }
146
147 /*
148  * call-seq:
149  *   ee.raise => nil
150  *
151  * Raises <i>ee</i>.
152  */
153 static VALUE c_raise (VALUE self)
154 {
155         GET_OBJ (self, RbEcoreEvas, ee);
156
157         ecore_evas_raise (ee->real);
158
159         return Qnil;
160 }
161
162 /*
163  * call-seq:
164  *  ee.lower => nil
165  *
166  * Lowers <i>ee</i>.
167  */
168 static VALUE c_lower (VALUE self)
169 {
170         GET_OBJ (self, RbEcoreEvas, ee);
171
172         ecore_evas_lower (ee->real);
173
174         return Qnil;
175 }
176
177 /*
178  * call-seq:
179  *   ee.layer => fixnum
180  *
181  * Returns the layer of <i>ee</i>.
182  */
183 static VALUE c_layer_get (VALUE self)
184 {
185         GET_OBJ (self, RbEcoreEvas, ee);
186
187         return INT2FIX (ecore_evas_layer_get (ee->real));
188 }
189
190 /*
191  * call-seq:
192  *  ee.layer(fixnum) => fixnum
193  *
194  * Sets the layer of <i>ee</i>.
195  */
196 static VALUE c_layer_set (VALUE self, VALUE val)
197 {
198         GET_OBJ (self, RbEcoreEvas, ee);
199
200         Check_Type (val, T_FIXNUM);
201
202         ecore_evas_layer_set (ee->real, FIX2INT (val));
203
204         return Qnil;
205 }
206
207 /*
208  * call-seq:
209  *  ee.evas => evas
210  *
211  * Returns the <code>Evas::Evas</code> object for <i>ee</i>.
212  */
213 static VALUE c_evas_get (VALUE self)
214 {
215         GET_OBJ (self, RbEcoreEvas, ee);
216
217         if (NIL_P (ee->evas))
218                 ee->evas = TO_EVAS (self, ecore_evas_get (ee->real));
219
220         return ee->evas;
221 }
222
223 /*
224  * call-seq:
225  *  ee.geometry => array
226  *
227  * Returns an array containing the geometry of <i>ee</i>.
228  *
229  *  ee.move(150, 300)   #=> nil
230  *  ee.resize(200, 200) #=> nil
231  *  ee.geometry         #=> [150, 300, 200, 200]
232  */
233 static VALUE c_geometry_get (VALUE self)
234 {
235         int x = 0, y = 0, w = 0, h = 0;
236
237         GET_OBJ (self, RbEcoreEvas, ee);
238
239         ecore_evas_geometry_get (ee->real, &x, &y, &w, &h);
240
241         return rb_ary_new3 (4, INT2FIX (x), INT2FIX (y),
242                             INT2FIX (w), INT2FIX (h));
243 }
244
245 /*
246  * call-seq:
247  *  ee.get_size_min => array
248  *
249  * Returns an array containing the minimum size of <i>ee</i>.
250  *
251  *  ee.set_size_min(100, 200) #=> nil
252  *  ee.get_size_min           #=> [100, 200]
253  */
254 static VALUE c_get_size_min (VALUE self)
255 {
256         int w = 0, h = 0;
257
258         GET_OBJ (self, RbEcoreEvas, ee);
259
260         ecore_evas_size_min_get (ee->real, &w, &h);
261
262         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
263 }
264
265 /*
266  * call-seq:
267  *  ee.set_size_min(width, height) => nil
268  *
269  * Sets the minimum size of <i>ee</i>.
270  *
271  *  ee.set_size_min(100, 200) #=> nil
272  */
273 static VALUE c_set_size_min (VALUE self, VALUE w, VALUE h)
274 {
275         GET_OBJ (self, RbEcoreEvas, ee);
276
277         Check_Type (w, T_FIXNUM);
278         Check_Type (h, T_FIXNUM);
279
280         ecore_evas_size_min_set (ee->real, FIX2INT (w), FIX2INT (h));
281
282         return Qnil;
283 }
284
285 /*
286  * call-seq:
287  *  ee.get_size_max => array
288  *
289  * Returns an array containing the maximum size of <i>ee</i>.
290  *
291  *  ee.set_size_max(100, 200) #=> nil
292  *  ee.get_size_max           #=> [100, 200]
293  */
294 static VALUE c_get_size_max (VALUE self)
295 {
296         int w = 0, h = 0;
297
298         GET_OBJ (self, RbEcoreEvas, ee);
299
300         ecore_evas_size_max_get (ee->real, &w, &h);
301
302         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
303 }
304
305 /*
306  * call-seq:
307  *  ee.set_size_max(width, height) => nil
308  *
309  * Sets the maximum size of <i>ee</i>.
310  *
311  *  ee.set_size_max(100, 200) #=> nil
312  */
313 static VALUE c_set_size_max (VALUE self, VALUE w, VALUE h)
314 {
315         GET_OBJ (self, RbEcoreEvas, ee);
316
317         Check_Type (w, T_FIXNUM);
318         Check_Type (h, T_FIXNUM);
319
320         ecore_evas_size_max_set (ee->real, FIX2INT (w), FIX2INT (h));
321
322         return Qnil;
323 }
324
325 /*
326  * call-seq:
327  *  ee.move(x, y) => nil
328  *
329  * Moves <i>ee</i> to the coordinates specified in
330  * <i>x</i> and <i>y</i>.
331  *
332  *  ee.move(100, 200) #=> nil
333  */
334 static VALUE c_move (VALUE self, VALUE x, VALUE y)
335 {
336         GET_OBJ (self, RbEcoreEvas, ee);
337
338         Check_Type (x, T_FIXNUM);
339         Check_Type (y, T_FIXNUM);
340
341         ecore_evas_move (ee->real, FIX2INT (x), FIX2INT (y));
342
343         return Qnil;
344 }
345
346 /*
347  * call-seq:
348  *  ee.resize(width, height) => nil
349  *
350  * Resizes <i>ee</i> to width x height.
351  *
352  *  ee.resize(100, 200) #=> nil
353  */
354 static VALUE c_resize (VALUE self, VALUE w, VALUE h)
355 {
356         GET_OBJ (self, RbEcoreEvas, ee);
357
358         Check_Type (w, T_FIXNUM);
359         Check_Type (h, T_FIXNUM);
360
361         ecore_evas_resize (ee->real, FIX2INT (w), FIX2INT (h));
362
363         return Qnil;
364 }
365
366 /*
367  * call-seq:
368  *  ee.title => string
369  *
370  * Returns the title of <i>ee</i>.
371  */
372 static VALUE c_title_get (VALUE self)
373 {
374         const char *tmp;
375
376         GET_OBJ (self, RbEcoreEvas, ee);
377
378         if (!(tmp = ecore_evas_title_get (ee->real)))
379                 return Qnil;
380         else
381                 return rb_str_new2 (tmp);
382 }
383
384 /*
385  * call-seq:
386  *  ee.title(string)
387  *
388  * Sets the title of <i>ee</i>.
389  */
390 static VALUE c_title_set (VALUE self, VALUE val)
391 {
392         GET_OBJ (self, RbEcoreEvas, ee);
393
394         Check_Type (val, T_STRING);
395
396         ecore_evas_title_set (ee->real, StringValuePtr (val));
397
398         return Qnil;
399 }
400
401 /*
402  * call-seq:
403  *  ee.borderless? => true or false
404  *
405  * Returns true if <i>ee</i> is borderless, else returns false.
406  */
407 static VALUE c_borderless_get (VALUE self)
408 {
409         GET_OBJ (self, RbEcoreEvas, ee);
410
411         return ecore_evas_borderless_get (ee->real) ? Qtrue : Qfalse;
412 }
413
414 /*
415  * call-seq:
416  *  ee.borderless(true or false)
417  *
418  * Sets whether <i>ee</i> is borderless or not.
419  */
420 static VALUE c_borderless_set (VALUE self, VALUE val)
421 {
422         GET_OBJ (self, RbEcoreEvas, ee);
423
424         CHECK_BOOL (val);
425
426         ecore_evas_borderless_set (ee->real, val == Qtrue);
427
428         return Qnil;
429 }
430
431 /*
432  * call-seq:
433  *  ee.shaped? => true or false
434  *
435  * Returns true if <i>ee</i> is shaped, else returns false.
436  */
437 static VALUE c_shaped_get (VALUE self)
438 {
439         GET_OBJ (self, RbEcoreEvas, ee);
440
441         return ecore_evas_shaped_get (ee->real) ? Qtrue : Qfalse;
442 }
443
444 /*
445  * call-seq:
446  *  ee.shaped(true or false)
447  *
448  * Sets whether <i>ee</i> is shaped or not.
449  */
450 static VALUE c_shaped_set (VALUE self, VALUE val)
451 {
452         GET_OBJ (self, RbEcoreEvas, ee);
453
454         CHECK_BOOL (val);
455
456         ecore_evas_shaped_set (ee->real, val == Qtrue);
457
458         return Qnil;
459 }
460
461 /*
462  * call-seq:
463  *  ee.sticky? => true or false
464  *
465  * Returns true if <i>ee</i> is sticky, else returns false.
466  */
467 static VALUE c_sticky_get (VALUE self)
468 {
469         GET_OBJ (self, RbEcoreEvas, ee);
470
471         return ecore_evas_sticky_get (ee->real) ? Qtrue : Qfalse;
472 }
473
474 /*
475  * call-seq:
476  *  ee.sticky(true or false)
477  *
478  * Sets whether <i>ee</i> is sticky or not.
479  */
480 static VALUE c_sticky_set (VALUE self, VALUE val)
481 {
482         GET_OBJ (self, RbEcoreEvas, ee);
483
484         CHECK_BOOL (val);
485
486         ecore_evas_sticky_set (ee->real, val == Qtrue);
487
488         return Qnil;
489 }
490
491 /*
492  * call-seq:
493  *  ee.rotation => fixnum
494  *
495  * Returns the rotation of <i>ee</i>.
496  */
497 static VALUE c_rotation_get (VALUE self)
498 {
499         GET_OBJ (self, RbEcoreEvas, ee);
500
501         return INT2FIX (ecore_evas_rotation_get (ee->real));
502 }
503
504 /*
505  * call-seq:
506  *  ee.rotation(fixnum)
507  *
508  * Sets the rotation of <i>ee</i>.
509  */
510 static VALUE c_rotation_set (VALUE self, VALUE val)
511 {
512         GET_OBJ (self, RbEcoreEvas, ee);
513
514         Check_Type (val, T_FIXNUM);
515
516         ecore_evas_rotation_set (ee->real, FIX2INT (val));
517
518         return Qnil;
519 }
520
521 /* FIXME: this is unsafe!
522  * :nodoc:
523  */
524 static VALUE c_delete (VALUE self)
525 {
526         GET_OBJ (self, RbEcoreEvas, ee);
527
528         /* reap our children */
529         rb_gc_start ();
530
531         ecore_evas_free (ee->real);
532         ee->real = NULL;
533
534         return Qnil;
535 }
536
537 CALLBACK_DEFINE_HANDLER (resize);
538 CALLBACK_DEFINE_HANDLER (move);
539 CALLBACK_DEFINE_HANDLER (show);
540 CALLBACK_DEFINE_HANDLER (hide);
541 CALLBACK_DEFINE_HANDLER (delete_request);
542 CALLBACK_DEFINE_HANDLER (destroy);
543 CALLBACK_DEFINE_HANDLER (focus_in);
544 CALLBACK_DEFINE_HANDLER (focus_out);
545 CALLBACK_DEFINE_HANDLER (mouse_in);
546 CALLBACK_DEFINE_HANDLER (mouse_out);
547 CALLBACK_DEFINE_HANDLER (pre_render);
548 CALLBACK_DEFINE_HANDLER (post_render);
549
550 /*
551  * call-seq:
552  *  ee.on_resize { block } => nil
553  *
554  * Sets the handler for the resize event.
555  */
556 static VALUE c_on_resize (VALUE self)
557 {
558         CALLBACK_REG_HANDLER (resize);
559 }
560
561 /*
562  * call-seq:
563  *  ee.on_move { block } => nil
564  *
565  * Sets the handler for the move event.
566  */
567 static VALUE c_on_move (VALUE self)
568 {
569         CALLBACK_REG_HANDLER (move);
570 }
571
572 /*
573  * call-seq:
574  *  ee.on_show { block } => nil
575  *
576  * Sets the handler for the show event.
577  */
578 static VALUE c_on_show (VALUE self)
579 {
580         CALLBACK_REG_HANDLER (show);
581 }
582
583 /*
584  * call-seq:
585  *  ee.on_hide { block } => nil
586  *
587  * Sets the handler for the hide event.
588  */
589 static VALUE c_on_hide (VALUE self)
590 {
591         CALLBACK_REG_HANDLER (hide);
592 }
593
594 /*
595  * call-seq:
596  *  ee.on_delete_request { block } => nil
597  *
598  * Sets the handler for the delete request event.
599  */
600 static VALUE c_on_delete_request (VALUE self)
601 {
602         CALLBACK_REG_HANDLER (delete_request);
603 }
604
605 /*
606  * call-seq:
607  *  ee.on_destroy { block } => nil
608  *
609  * Sets the handler for the destroy event.
610  */
611 static VALUE c_on_destroy (VALUE self)
612 {
613         CALLBACK_REG_HANDLER (destroy);
614 }
615
616 /*
617  * call-seq:
618  *  ee.on_focus_in { block } => nil
619  *
620  * Sets the handler for the focus in event.
621  */
622 static VALUE c_on_focus_in (VALUE self)
623 {
624         CALLBACK_REG_HANDLER (focus_in);
625 }
626
627 /*
628  * call-seq:
629  *  ee.on_focus_out { block } => nil
630  *
631  * Sets the handler for the focus out event.
632  */
633 static VALUE c_on_focus_out (VALUE self)
634 {
635         CALLBACK_REG_HANDLER (focus_out);
636 }
637
638 /*
639  * call-seq:
640  *  ee.on_mouse_in { block } => nil
641  *
642  * Sets the handler for the mouse in event.
643  */
644 static VALUE c_on_mouse_in (VALUE self)
645 {
646         CALLBACK_REG_HANDLER (mouse_in);
647 }
648
649 /*
650  * call-seq:
651  *  ee.on_mouse_out { block } => nil
652  *
653  * Sets the handler for the mouse out event.
654  */
655 static VALUE c_on_mouse_out (VALUE self)
656 {
657         CALLBACK_REG_HANDLER (mouse_out);
658 }
659
660 /*
661  * call-seq:
662  *  ee.on_pre_render { block } => nil
663  *
664  * Sets the handler for the pre render event.
665  */
666 static VALUE c_on_pre_render (VALUE self)
667 {
668         CALLBACK_REG_HANDLER (pre_render);
669 }
670
671 /*
672  * call-seq:
673  *  ee.on_post_render { block } => nil
674  *
675  * Sets the handler for the post render event.
676  */
677 static VALUE c_on_post_render (VALUE self)
678 {
679         CALLBACK_REG_HANDLER (post_render);
680 }
681
682 void Init_EcoreEvas (void)
683 {
684         cEcoreEvas = rb_define_class_under (mEvas, "EcoreEvas", rb_cObject);
685
686         rb_define_private_method (rb_singleton_class (cEcoreEvas),
687                                   "new", NULL, 0);
688         rb_define_method (cEcoreEvas, "initialize", c_init, -1);
689         rb_define_method (cEcoreEvas, "inspect", c_inspect, 0);
690         rb_define_method (cEcoreEvas, "delete", c_delete, 0);
691         rb_define_method (cEcoreEvas, "show", c_show, 0);
692         rb_define_method (cEcoreEvas, "hide", c_hide, 0);
693         rb_define_method (cEcoreEvas, "visible?", c_visible_get, 0);
694         rb_define_method (cEcoreEvas, "raise", c_raise, 0);
695         rb_define_method (cEcoreEvas, "lower", c_lower, 0);
696         rb_define_method (cEcoreEvas, "layer", c_layer_get, 0);
697         rb_define_method (cEcoreEvas, "layer=", c_layer_set, 1);
698         rb_define_method (cEcoreEvas, "evas", c_evas_get, 0);
699         rb_define_method (cEcoreEvas, "geometry", c_geometry_get, 0);
700         rb_define_method (cEcoreEvas, "get_size_min", c_get_size_min, 0);
701         rb_define_method (cEcoreEvas, "set_size_min", c_set_size_min, 2);
702         rb_define_method (cEcoreEvas, "get_size_max", c_get_size_max, 0);
703         rb_define_method (cEcoreEvas, "set_size_max", c_set_size_max, 2);
704         rb_define_method (cEcoreEvas, "move", c_move, 2);
705         rb_define_method (cEcoreEvas, "resize", c_resize, 2);
706         rb_define_method (cEcoreEvas, "title", c_title_get, 0);
707         rb_define_method (cEcoreEvas, "title=", c_title_set, 1);
708         rb_define_method (cEcoreEvas, "borderless?", c_borderless_get, 0);
709         rb_define_method (cEcoreEvas, "borderless=", c_borderless_set, 1);
710         rb_define_method (cEcoreEvas, "shaped?", c_shaped_get, 0);
711         rb_define_method (cEcoreEvas, "shaped=", c_shaped_set, 1);
712         rb_define_method (cEcoreEvas, "sticky?", c_sticky_get, 0);
713         rb_define_method (cEcoreEvas, "sticky=", c_sticky_set, 1);
714         rb_define_method (cEcoreEvas, "rotation", c_rotation_get, 0);
715         rb_define_method (cEcoreEvas, "rotation=", c_rotation_set, 1);
716
717         rb_define_method (cEcoreEvas, "on_resize", c_on_resize, 0);
718         rb_define_method (cEcoreEvas, "on_move", c_on_move, 0);
719         rb_define_method (cEcoreEvas, "on_show", c_on_show, 0);
720         rb_define_method (cEcoreEvas, "on_hide", c_on_hide, 0);
721         rb_define_method (cEcoreEvas, "on_delete_request", c_on_delete_request, 0);
722         rb_define_method (cEcoreEvas, "on_destroy", c_on_destroy, 0);
723         rb_define_method (cEcoreEvas, "on_focus_in", c_on_focus_in, 0);
724         rb_define_method (cEcoreEvas, "on_focus_out", c_on_focus_out, 0);
725         rb_define_method (cEcoreEvas, "on_mouse_in", c_on_mouse_in, 0);
726         rb_define_method (cEcoreEvas, "on_mouse_out", c_on_mouse_out, 0);
727         rb_define_method (cEcoreEvas, "on_pre_render", c_on_pre_render, 0);
728         rb_define_method (cEcoreEvas, "on_post_render", c_on_post_render, 0);
729 }