2006-06-05 Emmanuele Bassi <ebassi@openedhand.com>
authorEmmanuele Bassi <ebassi@openedhand.com>
Mon, 5 Jun 2006 13:38:31 +0000 (13:38 +0000)
committerEmmanuele Bassi <ebassi@openedhand.com>
Mon, 5 Jun 2006 13:38:31 +0000 (13:38 +0000)
* clutter-color.h:
* clutter-color.c: Reimplement ClutterColor as a boxed type;
add convenience API for color handling, like: add, subtract,
shade, HSL color-space conversion, packing and unpacking.

* clutter-private.h: Update ClutterMainContext, and export the
main context pointer here.

* clutter-rectangle.h:
* clutter-rectangle.c: Update the color-related code; make
clutter_rectangle_new() and empty constructor and provide
clutter_rectangle_new_with_color(); provide color setter
and getter API.

* clutter-label.h:
* clutter-label.c: Rename the "font" property to "font-name";
update the color-related code to the new ClutterColor object;
rename clutter_label_new() to clutter_label_new_with_text(),
and add setters and getters for the properties.

* clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers
generators.

* clutter-stage.h:
* clutter-stage.c: Rework the API: provide a default constructor
for a singleton object, named clutter_stage_get_default(), which
supercedes the clutter_stage() function in clutter-main; provide
new events: button-press-event, button-release-event,
key-press-event and key-release-event; update the color-related
code;

(clutter_stage_snapshot): Allow negative width and height when
taking a snapshot (meaning: use full width/height).

(clutter_stage_get_element_at_pos): Rename clutter_stage_pick().

* clutter-element.c (clutter_element_paint): Clean up the
stage and color related code.

* clutter-event.h:
* clutter-event.c: Add generic ClutterAnyEvent type; add
clutter_event_new(), clutter_event_copy() and clutter_event_free();
make ClutterEvent a boxed type.

* clutter-main.h:
* clutter-main.c: Remove clutter_stage(); add clutter_main_quit(),
for cleanly quitting from clutter_main(); add multiple mainloops
support; allocate the ClutterCntx instead of adding it to the
stack; re-work the ClutterEvent dispatching.

* clutter-group.c (clutter_group_add), (clutter_group_remove): Keep
a reference on the element when added to a ClutterGroup.

* examples/rects.py
* examples/test.c:
* examples/test-text.c:
* examples/video-cube.c:
* examples/super-oh.c:
* examples/test-video.c: Update.

39 files changed:
ChangeLog
bindings/ChangeLog
bindings/python/clutter-base-types.defs
bindings/python/clutter-base.defs
bindings/python/clutter.override
clutter/clutter-color.c
clutter/clutter-color.h
clutter/clutter-element.c
clutter/clutter-event.c
clutter/clutter-event.h
clutter/clutter-group.c
clutter/clutter-group.h
clutter/clutter-label.c
clutter/clutter-label.h
clutter/clutter-main.c
clutter/clutter-main.h
clutter/clutter-marshal.list
clutter/clutter-private.h
clutter/clutter-rectangle.c
clutter/clutter-rectangle.h
clutter/clutter-stage.c
clutter/clutter-stage.h
doc/reference/clutter-0.0-sections.txt
doc/reference/tmpl/clutter-0.0-unused.sgml
doc/reference/tmpl/clutter-color.sgml
doc/reference/tmpl/clutter-element.sgml
doc/reference/tmpl/clutter-event.sgml
doc/reference/tmpl/clutter-group.sgml
doc/reference/tmpl/clutter-label.sgml
doc/reference/tmpl/clutter-main.sgml
doc/reference/tmpl/clutter-rectangle.sgml
doc/reference/tmpl/clutter-stage.sgml
doc/reference/tmpl/clutter-timeline.sgml
examples/rects.py
examples/super-oh.c
examples/test-text.c
examples/test-video.c
examples/test.c
examples/video-cube.c

index 69be110..a66d988 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,65 @@
+2006-06-05  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * clutter-color.h:
+       * clutter-color.c: Reimplement ClutterColor as a boxed type;
+       add convenience API for color handling, like: add, subtract,
+       shade, HSL color-space conversion, packing and unpacking.
+
+       * clutter-private.h: Update ClutterMainContext, and export the
+       main context pointer here.
+
+       * clutter-rectangle.h:
+       * clutter-rectangle.c: Update the color-related code; make
+       clutter_rectangle_new() and empty constructor and provide
+       clutter_rectangle_new_with_color(); provide color setter
+       and getter API.
+
+       * clutter-label.h:
+       * clutter-label.c: Rename the "font" property to "font-name";
+       update the color-related code to the new ClutterColor object;
+       rename clutter_label_new() to clutter_label_new_with_text(),
+       and add setters and getters for the properties.
+
+       * clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers
+       generators.
+
+       * clutter-stage.h:
+       * clutter-stage.c: Rework the API: provide a default constructor
+       for a singleton object, named clutter_stage_get_default(), which
+       supercedes the clutter_stage() function in clutter-main; provide
+       new events: button-press-event, button-release-event,
+       key-press-event and key-release-event; update the color-related
+       code;
+
+       (clutter_stage_snapshot): Allow negative width and height when
+       taking a snapshot (meaning: use full width/height).
+
+       (clutter_stage_get_element_at_pos): Rename clutter_stage_pick().
+
+       * clutter-element.c (clutter_element_paint): Clean up the
+       stage and color related code.
+
+       * clutter-event.h:
+       * clutter-event.c: Add generic ClutterAnyEvent type; add
+       clutter_event_new(), clutter_event_copy() and clutter_event_free();
+       make ClutterEvent a boxed type.
+
+       * clutter-main.h:
+       * clutter-main.c: Remove clutter_stage(); add clutter_main_quit(),
+       for cleanly quitting from clutter_main(); add multiple mainloops
+       support; allocate the ClutterCntx instead of adding it to the
+       stack; re-work the ClutterEvent dispatching.
+
+       * clutter-group.c (clutter_group_add), (clutter_group_remove): Keep
+       a reference on the element when added to a ClutterGroup.
+
+       * examples/rects.py
+       * examples/test.c:
+       * examples/test-text.c:
+       * examples/video-cube.c:
+       * examples/super-oh.c:
+       * examples/test-video.c: Update.
+
 2006-06-04  Matthew Allum  <mallum@openedhand.com>
 
        * clutter/clutter-element.c:
@@ -18,8 +80,8 @@
        * clutter/clutter-private.h:
        * clutter/clutter-stage.c:
        * clutter/clutter-stage.h:
-       Rejig GL setup as for stage to support an offscreen property. 
-        Offscreen support is however a little borked.
+       Rejig GL setup as for stage to support an offscreen property.
+       Offscreen support is however a little borked.
 
 2006-06-01  Matthew Allum  <mallum@openedhand.com>
 
index 22062c5..5dc67bb 100644 (file)
@@ -1,3 +1,9 @@
+2006-06-05  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * python/clutter-base-types.defs:
+       * python/clutter-base.defs:
+       * python/clutter.override: Wrap new API and objects.
+
 2006-05-27  Emmanuele Bassi  <ebassi@openedhand.com>
 
        * python/clutter-base.defs: Make static functions appear like
index 94e408d..9a3b5a7 100644 (file)
@@ -5,6 +5,18 @@
 
 ;; Boxed types
 
+(define-boxed Color
+  (in-module "Clutter")
+  (c-name "ClutterColor")
+  (gtype-id "CLUTTER_TYPE_COLOR")
+  (fields
+    '("guint8" "red")
+    '("guint8" "green")
+    '("guint8" "blue")
+    '("guint8" "alpha")
+  )
+)
+
 (define-boxed ElementBox
   (in-module "Clutter")
   (c-name "ClutterElementBox")
   )
 )
 
+(define-boxed Event
+  (in-module "Clutter")
+  (c-name "ClutterEvent")
+  (gtype-id "CLUTTER_TYPE_EVENT")
+  (fields
+    '("ClutterEventType" "type")
+  )
+)
+
 (define-boxed Geometry
   (in-module "Clutter")
   (c-name "ClutterGeometry")
 
 ;; Enumerations and flags ...
 
-(define-flags ElementTransform
-  (in-module "Clutter")
-  (c-name "ClutterElementTransform")
-  (gtype-id "CLUTTER_TYPE_ELEMENT_TRANSFORM")
-  (values
-    '("x" "CLUTTER_ELEMENT_MIRROR_X")
-    '("y" "CLUTTER_ELEMENT_MIRROR_Y")
-  )
-)
-
 (define-flags ElementFlags
   (in-module "Clutter")
   (c-name "ClutterElementFlags")
   )
 )
 
+(define-flags ElementTransform
+  (in-module "Clutter")
+  (c-name "ClutterElementTransform")
+  (gtype-id "CLUTTER_TYPE_ELEMENT_TRANSFORM")
+  (values
+    '("x" "CLUTTER_ELEMENT_MIRROR_X")
+    '("y" "CLUTTER_ELEMENT_MIRROR_Y")
+  )
+)
+
 (define-enum EventType
   (in-module "Clutter")
   (c-name "ClutterEventType")
   (gtype-id "CLUTTER_TYPE_EVENT_TYPE")
   (values
+    '("nothing" "CLUTTER_NOTHING")
     '("key-press" "CLUTTER_KEY_PRESS")
     '("key-release" "CLUTTER_KEY_RELEASE")
     '("motion" "CLUTTER_MOTION")
 
 ;; Objects
 
-(define-object Element
-  (in-module "Clutter")
-  (parent "GObject")
-  (c-name "ClutterElement")
-  (gtype-id "CLUTTER_TYPE_ELEMENT")
-)
-
 (define-object CloneTexture
   (in-module "Clutter")
   (parent "ClutterElement")
   (gtype-id "CLUTTER_TYPE_CLONE_TEXTURE")
 )
 
+(define-object Element
+  (in-module "Clutter")
+  (parent "GObject")
+  (c-name "ClutterElement")
+  (gtype-id "CLUTTER_TYPE_ELEMENT")
+)
+
 (define-object Group
   (in-module "Clutter")
   (parent "ClutterElement")
   (gtype-id "CLUTTER_TYPE_GROUP")
 )
 
+(define-object Label
+  (in-module "Clutter")
+  (parent "ClutterTexture")
+  (c-name "ClutterLabel")
+  (gtype-id "CLUTTER_TYPE_LABEL")
+)
+
 (define-object Rectangle
   (in-module "Clutter")
   (parent "ClutterElement")
   (gtype-id "CLUTTER_TYPE_TEXTURE")
 )
 
-(define-object Label
-  (in-module "Clutter")
-  (parent "ClutterTexture")
-  (c-name "ClutterLabel")
-  (gtype-id "CLUTTER_TYPE_LABEL")
-)
-
 (define-object Timeline
   (in-module "Clutter")
   (parent "GObject")
index 79f5bfb..4acf20e 100644 (file)
   (return-type "none")
 )
 
-(define-function stage
-  (c-name "clutter_stage")
-  (return-type "ClutterGroup*")
+(define-function main_quit
+  (c-name "clutter_main_quit")
+  (return-type "none")
 )
 
 (define-function redraw
 
 ;; From ../../clutter/clutter-event.h
 
+(define-function clutter_event_new
+  (c-name "clutter_event_new")
+  (is-constructor-of "ClutterEvent")
+  (return-type "ClutterEvent*")
+  (parameters
+    '("ClutterEventType" "type")
+  )
+)
+
+(define-method copy
+  (of-object "ClutterEvent")
+  (c-name "clutter_event_copy")
+  (return-type "ClutterEvent*")
+)
+
+(define-method free
+  (of-object "ClutterEvent")
+  (c-name "clutter_event_free")
+  (return-type "none")
+)
+
 (define-method type
   (of-object "ClutterKeyEvent")
   (c-name "clutter_key_event_type")
   (return-type "GType")
 )
 
-(define-function geometry_new
-  (c-name "clutter_geometry_new")
-  (is-constructor-of "ClutterGeometry")
-  (return-type "ClutterGeometry")
-)
+;;(define-function geometry_new
+;;  (c-name "clutter_geometry_new")
+;;  (is-constructor-of "ClutterGeometry")
+;;  (return-type "ClutterGeometry")
+;;)
 
 (define-function clutter_element_box_get_type
   (c-name "clutter_element_box_get_type")
   (return-type "GType")
 )
 
-(define-function element_box_new
-  (c-name "clutter_element_box_new")
-  (is-constructor-of "ClutterElementBox")
-  (return-type "ClutterElementBox")
-)
+;;(define-function element_box_new
+;;  (c-name "clutter_element_box_new")
+;;  (is-constructor-of "ClutterElementBox")
+;;  (return-type "ClutterElementBox")
+;;)
 
 (define-function clutter_element_get_type
   (c-name "clutter_element_get_type")
 
 ;; From ../../clutter/clutter-rectangle.h
 
-(define-function clutter_rectangle_get_type
-  (c-name "clutter_rectangle_get_type")
-  (return-type "GType")
-)
-
 (define-function clutter_rectangle_new
   (c-name "clutter_rectangle_new")
   (is-constructor-of "ClutterRectangle")
   (return-type "ClutterElement*")
+)
+
+(define-function clutter_rectangle_new_with_color
+  (c-name "clutter_rectangle_new_with_color")
+  (is-constructor-of "ClutterRectangle")
+  (return-type "ClutterElement*")
   (properties
-    '("color" (argname "col"))
+    '("color" (argname "color"))
+  )
+)
+
+(define-method get_color
+  (of-object "ClutterRectangle")
+  (c-name "clutter_rectangle_get_color")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "color")
+  )
+)
+
+(define-method set_color
+  (of-object "ClutterRectangle")
+  (c-name "clutter_rectangle_set_color")
+  (return-type "none")
+  (parameters
+    '("const-ClutterColor*" "color")
   )
 )
 
 
 ;; From ../../clutter/clutter-color.h
 
-(define-function clutter_color_new
-  (c-name "clutter_color_new")
-  (return-type "ClutterColor")
+(define-function clutter_color_get_type
+  (c-name "clutter_color_get_type")
+  (return-type "GType")
+)
+
+(define-method add
+  (of-object "ClutterColor")
+  (c-name "clutter_color_add")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "src2")
+    '("ClutterColor*" "dest")
+  )
+)
+
+(define-method subtract
+  (of-object "ClutterColor")
+  (c-name "clutter_color_subtract")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "src2")
+    '("ClutterColor*" "dest")
+  )
+)
+
+(define-method lighten
+  (of-object "ClutterColor")
+  (c-name "clutter_color_lighten")
+  (return-type "none")
   (parameters
-    '("guint8" "r")
-    '("guint8" "g")
-    '("guint8" "b")
-    '("guint8" "a")
+    '("ClutterColor*" "dest")
   )
 )
 
-(define-method set
+(define-method darken
   (of-object "ClutterColor")
-  (c-name "clutter_color_set")
+  (c-name "clutter_color_darken")
   (return-type "none")
   (parameters
-    '("guint8" "r")
-    '("guint8" "g")
-    '("guint8" "b")
-    '("guint8" "a")
+    '("ClutterColor*" "dest")
   )
 )
 
-(define-method get
+(define-method shade
   (of-object "ClutterColor")
-  (c-name "clutter_color_get")
+  (c-name "clutter_color_shade")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "dest")
+    '("gdouble" "shade")
+  )
+)
+
+(define-function color_to_hls
+  (c-name "clutter_color_to_hls")
+  (return-type "none")
+  (parameters
+    '("guint8*" "hue")
+    '("guint8*" "luminance")
+    '("guint8*" "saturation")
+  )
+)
+
+(define-function color_from_hls
+  (c-name "clutter_color_from_hls")
+  (return-type "none")
+  (parameters
+    '("guint8" "hue")
+    '("guint8" "luminance")
+    '("guint8" "saturation")
+  )
+)
+
+(define-function color_to_pixel
+  (c-name "clutter_color_to_pixel")
+  (return-type "guint32")
+  (parameters
+    '("ClutterColor" "src")
+  )
+)
+
+(define-function color_from_pixel
+  (c-name "clutter_color_from_pixel")
   (return-type "none")
   (parameters
-    '("guint8*" "r")
-    '("guint8*" "g")
-    '("guint8*" "b")
-    '("guint8*" "a")
+    '("ClutterColor" "dest")
+    '("guint32" "pixel")
   )
 )
 
 
 
+
 ;; From ../../clutter/clutter-clone-texture.h
 
 (define-function clutter_clone_texture_get_type
   (return-type "GType")
 )
 
-(define-function clutter_label_new_with_text
-  (c-name "clutter_label_new_with_text")
-  (return-type "ClutterElement*")
-  (parameters
-    '("const-gchar*" "font_desc")
-    '("const-gchar*" "text")
-  )
-)
-
 (define-function clutter_label_new
   (c-name "clutter_label_new")
   (is-constructor-of "ClutterLabel")
   (return-type "ClutterElement*")
 )
 
+(define-function clutter_label_new_with_text
+  (c-name "clutter_label_new_with_text")
+  (return-type "ClutterElement*")
+  (is-constructor-of "ClutterLabel")
+  (properties
+    '("font-name" (argname "name") (optional))
+    '("text" (argname "str") (optional))
+  )
+)
+
 (define-method set_text
   (of-object "ClutterLabel")
   (c-name "clutter_label_set_text")
   )
 )
 
-(define-method set_font
+(define-method get_text
   (of-object "ClutterLabel")
-  (c-name "clutter_label_set_font")
+  (c-name "clutter_label_get_text")
+  (return-type "const-gchar*")
+)
+
+(define-method set_font_name
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_set_font_name")
   (return-type "none")
   (parameters
-    '("const-gchar*" "desc")
+    '("const-gchar*" "font_name")
   )
 )
 
+(define-method get_font_name
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_get_font_name")
+  (return-type "const-gchar*")
+)
+
 (define-method set_color
   (of-object "ClutterLabel")
   (c-name "clutter_label_set_color")
   (return-type "none")
   (parameters
-    '("guint32" "pixel")
+    '("const-ClutterColor*" "color")
+  )
+)
+
+(define-method get_color
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_get_color")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "color")
   )
 )
 
   )
 )
 
+(define-method get_text_extents
+  (of-object "ClutterLabel")
+  (c-name "clutter_label_get_text_extents")
+  (return-type "none")
+  (parameters
+    '("gint*" "width")
+    '("gint*" "height")
+  )
+)
+
 
 
 ;; From ../../clutter/clutter-group.h
   (return-type "GType")
 )
 
+(define-function stage_get_default
+  (c-name "clutter_stage_get_default")
+  (return-type "ClutterElement*")
+)
+
 (define-method get_xwindow
   (of-object "ClutterStage")
   (c-name "clutter_stage_get_xwindow")
   (c-name "clutter_stage_set_color")
   (return-type "none")
   (parameters
-    '("ClutterColor" "color")
+    '("const-ClutterColor*" "color")
   )
 )
 
 (define-method get_color
   (of-object "ClutterStage")
   (c-name "clutter_stage_get_color")
-  (return-type "ClutterColor")
+  (return-type "none")
+  (parameters
+    '("ClutterColor*" "color")
+  )
 )
 
-(define-method pick
+(define-method get_element_at_pos
   (of-object "ClutterStage")
-  (c-name "clutter_stage_pick")
+  (c-name "clutter_stage_get_element_at_pos")
   (return-type "ClutterElement*")
   (parameters
     '("gint" "x")
   )
 )
 
+(define-method snapshot
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_snapshot")
+  (return-type "GdkPixbuf*")
+  (parameters
+    '("gint" "x")
+    '("gint" "y")
+    '("gint" "width")
+    '("gint" "height")
+  )
+)
+
 
 
 ;; From ../../clutter/clutter-enum-types.h
index 19a96d7..4f314c1 100644 (file)
@@ -26,6 +26,7 @@ import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
 %%
 ignore
   clutter_video_texture_error_quark
+  clutter_video_texture_get_metadata
   clutter_group_add_many_valist
   clutter_stage_get_xwindow
   clutter_init
@@ -132,7 +133,7 @@ static PySequenceMethods _wrap_clutter_geometry_tp_as_sequence = {
 %%
 override-attr ClutterGeometry.x
 static int
-_wrap_clutter_geomtry__set_x (PyGBoxed *self, PyObject *value, void *closure)
+_wrap_clutter_geometry__set_x (PyGBoxed *self, PyObject *value, void *closure)
 {
        gint val;
 
@@ -485,6 +486,22 @@ _wrap_clutter_main (PyObject *self)
        return Py_None;
 }
 %%
+override clutter_main_quit
+static PyObject *
+_wrap_clutter_main_quit (PyObject *self, PyObject *args)
+{
+       /* sanity check to make sure we are in a main loop */
+       if (clutter_main_level () == 0) {
+               PyErr_SetString (PyExc_RuntimeError,
+                                "called outside of a mainloop");
+               return NULL;
+       }
+
+       clutter_main_quit ();
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
 override clutter_threads_enter noargs
 static PyObject *
 _wrap_clutter_threads_enter (PyObject *self)
@@ -498,3 +515,487 @@ _wrap_clutter_threads_enter (PyObject *self)
        Py_INCREF(Py_None);
        return Py_None;
 }
+%%
+override clutter_color_new kwargs
+static int
+_wrap_clutter_color_new (PyGBoxed *self,
+                        PyObject *args,
+                        PyObject *kwargs)
+{
+       static char *kwlist[] = { "red", "green", "blue", "alpha", NULL };
+       ClutterColor color = { 0, 0, 0, 0 };
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "|iiii:ClutterColor.__init__",
+                                        kwlist,
+                                        &(color.red),
+                                        &(color.green),
+                                        &(color.blue),
+                                        &(color.alpha)))
+               return -1;
+       
+       self->boxed = g_boxed_copy (CLUTTER_TYPE_COLOR, &color);
+       self->free_on_dealloc = TRUE;
+       self->gtype = CLUTTER_TYPE_COLOR;
+       
+       return 0;
+}
+%%
+override-slot ClutterColor.tp_as_sequence
+static int
+_wrap_clutter_color_length (PyGBoxed *self)
+{
+       return 4;
+}
+static PyObject *
+_wrap_clutter_color_getitem (PyGBoxed *self, int pos)
+{
+       ClutterColor *color;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString (PyExc_IndexError, "index out of range");
+               return NULL;
+       }
+
+       color = pyg_boxed_get (self, ClutterColor);
+       switch (pos) {
+               case 0: return PyInt_FromLong (color->red);
+               case 1: return PyInt_FromLong (color->green);
+               case 2: return PyInt_FromLong (color->blue);
+               case 3: return PyInt_FromLong (color->alpha);
+               default:
+                       g_assert_not_reached();
+                       return NULL;
+       }
+}
+static int
+_wrap_clutter_color_setitem (PyGBoxed *self, int pos, PyObject *value)
+{
+       ClutterColor *color;
+       gint val;
+
+       if (pos < 0)
+               pos += 4;
+       
+       if (pos < 0 || pos >= 4) {
+               PyErr_SetString (PyExc_IndexError, "index out of range");
+               return -1;
+       }
+
+       color = pyg_boxed_get (self, ClutterColor);
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       switch (pos) {
+               case 0: color->red   = val; break;
+               case 1: color->green = val; break;
+               case 2: color->blue  = val; break;
+               case 3: color->alpha = val; break;
+               default:
+                       g_assert_not_reached();
+                       return -1;
+       }
+
+       return 0;
+}
+static PySequenceMethods _wrap_clutter_color_tp_as_sequence = {
+       (inquiry) _wrap_clutter_color_length,
+       (binaryfunc) 0,
+       (intargfunc) 0,
+       (intargfunc) _wrap_clutter_color_getitem,
+       (intintargfunc) 0,
+       (intobjargproc) _wrap_clutter_color_setitem,
+       (intintobjargproc) 0
+};
+%%
+override-attr ClutterColor.red
+static int
+_wrap_clutter_color__set_red (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterColor)->red = val;
+
+       return 0;
+}
+%%
+override-attr ClutterColor.green
+static int
+_wrap_clutter_color__set_green (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+
+       pyg_boxed_get (self, ClutterColor)->green = val;
+
+       return 0;
+}
+%%
+override-attr ClutterColor.blue
+static int
+_wrap_clutter_color__set_blue (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get(self, ClutterColor)->blue = val;
+       
+       return 0;
+}
+%%
+override-attr ClutterColor.alpha
+static int
+_wrap_clutter_color__set_alpha (PyGBoxed *self, PyObject *value, void *closure)
+{
+       gint val;
+
+       val = PyInt_AsLong (value);
+       if (PyErr_Occurred ())
+               return -1;
+       
+       pyg_boxed_get (self, ClutterColor)->alpha = val;
+
+       return 0;
+}
+%%
+override clutter_stage_set_color
+static PyObject *
+_wrap_clutter_stage_set_color (PyGObject *self,
+                              PyObject  *args)
+{
+       ClutterColor color;
+       int len, i;
+
+       if (PyTuple_Size (args) != 4) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 4 integers: (r, g, b, a)");
+               return NULL;
+       }
+
+       for (i = 0; i < 4; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+               
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+               
+               switch (i) {
+                       case 0: color.red   = (guint8) PyInt_AsLong (comp); break;
+                       case 1: color.green = (guint8) PyInt_AsLong (comp); break;
+                       case 2: color.blue  = (guint8) PyInt_AsLong (comp); break;
+                       case 3: color.alpha = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+       
+       clutter_stage_set_color (CLUTTER_STAGE (self->obj), &color);
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
+override clutter_stage_get_color
+static PyObject *
+_wrap_clutter_stage_get_color (PyGObject *self,
+                              PyObject  *args)
+{
+       ClutterColor color;
+
+       clutter_stage_get_color (CLUTTER_STAGE (self->obj), &color);
+       
+       return Py_BuildValue ("(iiii)", color.red,
+                                       color.green,
+                                       color.blue,
+                                       color.alpha);
+}
+%%
+override clutter_color_to_hls
+static PyObject *
+_wrap_clutter_color_to_hls (PyObject *self,
+                           PyObject *args)
+{
+       ClutterColor color;
+       guint8 h, l, s;
+       int i;
+
+       if (PyTuple_Size (args) != 4) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 4 integers: (r, g, b, a)");
+               return NULL;
+       }
+
+       for (i = 0; i < 4; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+
+               switch (i) {
+                       case 0: color.red   = (guint8) PyInt_AsLong (comp); break;
+                       case 1: color.green = (guint8) PyInt_AsLong (comp); break;
+                       case 2: color.blue  = (guint8) PyInt_AsLong (comp); break;
+                       case 3: color.alpha = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+
+       clutter_color_to_hls (&color, &h, &l, &s);
+
+       return Py_BuildValue ("(iii)", (int) h, (int) l, (int) s);
+}
+%%
+override clutter_color_from_hls
+static PyObject *
+_wrap_clutter_color_from_hls (PyObject *self,
+                             PyObject *args)
+{
+       ClutterColor color;
+       guint8 h, l, s;
+       int i;
+
+       if (PyTuple_Size (args) != 3) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 3 integers: (h, l, s)");
+               return NULL;
+       }
+
+       for (i = 0; i < 3; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+
+               switch (i) {
+                       case 0: h = (guint8) PyInt_AsLong (comp); break;
+                       case 1: l = (guint8) PyInt_AsLong (comp); break;
+                       case 2: s = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+
+       clutter_color_from_hls (&color, h, l, s);
+
+       return Py_BuildValue ("(iiii)",
+                             (int) color.red,
+                             (int) color.green,
+                             (int) color.blue,
+                             (int) color.alpha);
+}
+%%
+override clutter_color_to_pixel
+static PyObject *
+_wrap_clutter_color_to_pixel (PyObject *self,
+                             PyObject *args)
+{
+       ClutterColor color;
+       guint32 pixel;
+       int i;
+
+       if (PyTuple_Size (args) != 4) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 4 integers: (r, g, b, a)");
+               return NULL;
+       }
+
+       for (i = 0; i < 4; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+
+               switch (i) {
+                       case 0: color.red   = (guint8) PyInt_AsLong (comp); break;
+                       case 1: color.green = (guint8) PyInt_AsLong (comp); break;
+                       case 2: color.blue  = (guint8) PyInt_AsLong (comp); break;
+                       case 3: color.alpha = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+
+       pixel = clutter_color_to_pixel (&color);
+
+       return PyInt_FromLong (pixel);
+}
+%%
+override clutter_color_from_pixel
+static PyObject *
+_wrap_clutter_color_from_pixel (PyObject *self,
+                               PyObject *args)
+{
+       ClutterColor color;
+       guint32 pixel;
+
+       if (!PyInt_Check (args)) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a 32 bit encoded integer");
+               return NULL;
+       }
+
+       pixel = (guint32) PyInt_AsLong (args);
+
+       clutter_color_from_pixel (&color, pixel);
+
+       return Py_BuildValue ("(iiii)",
+                             (int) color.red,
+                             (int) color.green,
+                             (int) color.blue,
+                             (int) color.alpha);
+}
+%%
+override clutter_label_get_text_extents
+static PyObject *
+_wrap_clutter_label_get_text_extents (PyGObject *self,
+                                     PyObject  *args)
+{
+       gint width, height;
+
+       clutter_label_get_text_extents (CLUTTER_LABEL (self->obj),
+                                       &width,
+                                       &height);
+       
+       return Py_BuildValue ("(ii)", width, height);
+}
+%%
+override clutter_rectangle_set_color
+static PyObject *
+_wrap_clutter_rectangle_set_color (PyGObject *self,
+                                  PyObject  *args)
+{
+       ClutterColor color;
+       int len, i;
+
+       if (PyTuple_Size (args) != 4) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 4 integers: (r, g, b, a)");
+               return NULL;
+       }
+
+       for (i = 0; i < 4; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+               
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+               
+               switch (i) {
+                       case 0: color.red   = (guint8) PyInt_AsLong (comp); break;
+                       case 1: color.green = (guint8) PyInt_AsLong (comp); break;
+                       case 2: color.blue  = (guint8) PyInt_AsLong (comp); break;
+                       case 3: color.alpha = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+       
+       clutter_rectangle_set_color (CLUTTER_RECTANGLE (self->obj), &color);
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
+override clutter_rectangle_get_color
+static PyObject *
+_wrap_clutter_rectangle_get_color (PyGObject *self,
+                                  PyObject  *args)
+{
+       ClutterColor color;
+
+       clutter_rectangle_get_color (CLUTTER_RECTANGLE (self->obj), &color);
+       
+       return Py_BuildValue ("(iiii)", color.red,
+                                       color.green,
+                                       color.blue,
+                                       color.alpha);
+}
+%%
+override clutter_label_set_color
+static PyObject *
+_wrap_clutter_label_set_color (PyGObject *self,
+                              PyObject  *args)
+{
+       ClutterColor color;
+       int len, i;
+
+       if (PyTuple_Size (args) != 4) {
+               PyErr_SetString (PyExc_TypeError,
+                                "requires a tuple of 4 integers: (r, g, b, a)");
+               return NULL;
+       }
+
+       for (i = 0; i < 4; i++) {
+               PyObject *comp = PyTuple_GetItem (args, i);
+               
+               if (!PyInt_Check (comp)) {
+                       PyErr_SetString (PyExc_TypeError,
+                                        "component is not an integer");
+                       return NULL;
+               }
+               
+               switch (i) {
+                       case 0: color.red   = (guint8) PyInt_AsLong (comp); break;
+                       case 1: color.green = (guint8) PyInt_AsLong (comp); break;
+                       case 2: color.blue  = (guint8) PyInt_AsLong (comp); break;
+                       case 3: color.alpha = (guint8) PyInt_AsLong (comp); break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
+       
+       clutter_label_set_color (CLUTTER_LABEL (self->obj), &color);
+
+       Py_INCREF (Py_None);
+       return Py_None;
+}
+%%
+override clutter_label_get_color
+static PyObject *
+_wrap_clutter_label_get_color (PyGObject *self,
+                              PyObject  *args)
+{
+       ClutterColor color;
+
+       clutter_label_get_color (CLUTTER_LABEL (self->obj), &color);
+       
+       return Py_BuildValue ("(iiii)", color.red,
+                                       color.green,
+                                       color.blue,
+                                       color.alpha);
+}
+%%
index 7b29e6e..a0f8c80 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "clutter-color.h"
 
-ClutterColor
-clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a)
+/**
+ * clutter_color_add:
+ * @src1: a #ClutterColor
+ * @src2: a #ClutterColor
+ * @dest: return location for the result
+ *
+ * Adds @src2 to @src1 and saves the resulting color
+ * inside @dest.
+ *
+ * The alpha channel of @dest is as the maximum value
+ * between the alpha channels of @src1 and @src2.
+ */
+void
+clutter_color_add (const ClutterColor *src1,
+                  const ClutterColor *src2,
+                  ClutterColor       *dest)
+{
+  g_return_if_fail (src1 != NULL);
+  g_return_if_fail (src2 != NULL);
+  g_return_if_fail (dest != NULL);
+
+  dest->red   = CLAMP (src1->red   + src2->red,   0, 255);
+  dest->green = CLAMP (src1->green + src2->green, 0, 255);
+  dest->blue  = CLAMP (src1->blue  + src2->blue,  0, 255);
+
+  dest->alpha = MAX (src1->alpha, src2->alpha);
+}
+
+/**
+ * clutter_color_subtract:
+ * @src1: a #ClutterColor
+ * @src2: a #ClutterColor
+ * @dest: return location for the result
+ *
+ * Subtracts @src2 from @src1 and saves the resulting
+ * color inside @dest.
+ *
+ * The alpha channel of @dest is set as the minimum value
+ * between the alpha channels of @src1 and @src2.
+ */
+void
+clutter_color_subtract (const ClutterColor *src1,
+                       const ClutterColor *src2,
+                       ClutterColor       *dest)
+{
+  g_return_if_fail (src1 != NULL);
+  g_return_if_fail (src2 != NULL);
+  g_return_if_fail (dest != NULL);
+
+  dest->red   = CLAMP (src2->red   - src1->red,   0, 255);
+  dest->green = CLAMP (src2->green - src1->green, 0, 255);
+  dest->blue  = CLAMP (src2->blue  - src1->blue,  0, 255);
+
+  dest->alpha = MIN (src1->alpha, src2->alpha);
+}
+
+/**
+ * clutter_color_lighten:
+ * @src: a #ClutterColor
+ * @dest: return location for the lighter color
+ *
+ * Lightens @src by a fixed amount, and saves the changed
+ * color in @dest.
+ */
+void
+clutter_color_lighten (const ClutterColor *src,
+                      ClutterColor       *dest)
+{
+  clutter_color_shade (src, dest, 1.3);
+}
+
+/**
+ * clutter_color_darken:
+ * @src: a #ClutterColor
+ * @dest: return location for the darker color
+ *
+ * Darkens @src by a fixed amount, and saves the changed color
+ * in @dest.
+ */
+void
+clutter_color_darken (const ClutterColor *src,
+                     ClutterColor       *dest)
+{
+  clutter_color_shade (src, dest, 0.7);
+}
+
+/**
+ * clutter_color_to_hls:
+ * @src: a #ClutterColor
+ * @hue: return location for the hue value or %NULL
+ * @luminance: return location for the luminance value or %NULL
+ * @saturation: return location for the saturation value or %NULL
+ *
+ * Converts @src to the HLS format.
+ */
+void
+clutter_color_to_hls (const ClutterColor *src,
+                     guint8             *hue,
+                     guint8             *luminance,
+                     guint8             *saturation)
+{
+  gdouble red, green, blue;
+  gdouble min, max, delta;
+  gdouble h, l, s;
+  
+  g_return_if_fail (src != NULL);
+
+  red = src->red / 255.0;
+  green = src->green / 255.0;
+  blue = src->blue / 255.0;
+
+  if (red > green)
+    {
+      if (red > blue)
+       max = red;
+      else
+       max = blue;
+
+      if (green < blue)
+       min = green;
+      else
+       min = blue;
+    }
+  else
+    {
+      if (green > blue)
+       max = green;
+      else
+       max = blue;
+
+      if (red < blue)
+       min = red;
+      else
+       min = blue;
+    }
+
+  l = (max + min) / 2;
+  s = 0;
+  h = 0;
+
+  if (max != min)
+    {
+      if (l <= 0.5)
+       s = (max - min) / (max + min);
+      else
+       s = (max - min) / (2 - max - min);
+
+      delta = max - min;
+      if (red == max)
+       h = (green - blue) / delta;
+      else if (green == max)
+       h = 2 + (blue - red) / delta;
+      else if (blue == max)
+       h = 4 + (red - green) / delta;
+
+      h *= 60;
+      if (h < 0.0)
+       h += 360;
+    }
+
+  if (hue)
+    *hue = (guint8) (h * 255);
+
+  if (luminance)
+    *luminance = (guint8) (l * 255);
+
+  if (saturation)
+    *saturation = (guint8) (s * 255);
+}
+
+/**
+ * clutter_color_from_hls:
+ * @dest: return location for a #ClutterColor
+ * @hue: hue value (0 .. 255)
+ * @luminance: luminance value (0 .. 255)
+ * @saturation: saturation value (0 .. 255)
+ *
+ * Converts a color expressed in HLS (hue, luminance and saturation)
+ * values into a #ClutterColor.
+ */
+void
+clutter_color_from_hls (ClutterColor *dest,
+                       guint8        hue,
+                       guint8        luminance,
+                       guint8        saturation)
 {
-  return ( a | b << 8 | g << 16  | r << 24 );
+  gdouble h, l, s;
+  gdouble m1, m2;
+  
+  g_return_if_fail (dest != NULL);
+
+  l = (gdouble) luminance / 255.0;
+  s = (gdouble) saturation / 255.0;
+
+  if (l <= 0.5)
+    m2 = l * (1 - s);
+  else
+    m2 = l + s - l * s;
+
+  m1 = 2 * l - m2;
+
+  if (s == 0)
+    {
+      dest->red = (guint8) l * 255;
+      dest->green = (guint8) l * 255;
+      dest->blue = (guint8) l * 255;
+    }
+  else
+    {
+      h = ((gdouble) hue / 255.0) + 120;
+      while (h > 360)
+       h -= 360;
+      while (h < 0)
+       h += 360;
+
+      if (h < 60)
+       dest->red = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
+      else if (h < 180)
+       dest->red = (guint8) m2 * 255;
+      else if (h < 240)
+       dest->red = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+      else
+       dest->red = (guint8) m1 * 255;
+
+      h = (gdouble) hue / 255.0;
+      while (h > 360)
+       h -= 360;
+      while (h < 0)
+       h += 360;
+
+      if (h < 60)
+       dest->green = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
+      else if (h < 180)
+        dest->green = (guint8) m2 * 255;
+      else if (h < 240)
+       dest->green = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+      else
+       dest->green = (guint8) m1 * 255;
+
+      h = ((gdouble) hue / 255.0) - 120;
+      while (h > 360)
+       h -= 360;
+      while (h < 0)
+       h += 360;
+
+      if (h < 60)
+       dest->blue = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
+      else if (h < 180)
+       dest->blue = (guint8) m2 * 255;
+      else if (h < 240)
+       dest->blue = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+      else
+       dest->blue = (guint8) m1 * 255;
+    }
 }
 
+/**
+ * clutter_color_shade:
+ * @src: a #ClutterColor
+ * @dest: return location for the shaded color
+ * @shade: the shade factor to apply
+ * 
+ * Shades @src by the factor of @shade and saves the modified
+ * color into @dest.
+ */
 void
-clutter_color_set (ClutterColor *color, 
-                  guint8        r, 
-                  guint8        g, 
-                  guint8        b, 
-                  guint8        a)
+clutter_color_shade (const ClutterColor *src,
+                    ClutterColor       *dest,
+                    gdouble             shade)
+{
+  guint8 h, l, s;
+  gdouble h1, l1, s1;
+
+  g_return_if_fail (src != NULL);
+  g_return_if_fail (dest != NULL);
+  
+  clutter_color_to_hls (src, &h, &l, &s);
+
+  h1 = (gdouble) h / 255.0;
+  l1 = (gdouble) l / 255.0;
+  s1 = (gdouble) s / 255.0;
+  
+  l1 *= shade;
+  if (l1 > 1.0)
+    l1 = 1.0;
+  else if (l1 < 0.0)
+    l1 = 0.0;
+  
+  s1 *= shade;
+  if (s1 > 1.0)
+    s1 = 1.0;
+  else if (s1 < 0.0)
+    s1 = 0.0;
+
+  h = (guint8) h1 * 255;
+  l = (guint8) l1 * 255;
+  s = (guint8) s1 * 255;
+
+  clutter_color_from_hls (dest, h, l, s);
+}
+
+/**
+ * clutter_color_to_pixel:
+ * @src: a #ClutterColor
+ *
+ * Converts @src into a packed 32 bit integer, containing
+ * all the four 8 bit channels used by #ClutterColor.
+ *
+ * Return value: a packed color
+ */
+guint32
+clutter_color_to_pixel (const ClutterColor *src)
 {
-  *color = ( a | b << 8 | g << 16  | r << 24 );
+  g_return_val_if_fail (src != NULL, 0);
+  
+  return (src->alpha | src->blue << 8 | src->green << 16  | src->red << 24);
 }
 
+/**
+ * clutter_color_from_pixel:
+ * @dest: return location for a #ClutterColor
+ * @pixel: a 32 bit packed integer containing a color
+ *
+ * Converts @pixel from the packed representation of a four 8 bit channel
+ * color to a #ClutterColor.
+ */
 void
-clutter_color_get (ClutterColor  color, 
-                  guint8        *r, 
-                  guint8        *g, 
-                  guint8        *b, 
-                  guint8        *a)
+clutter_color_from_pixel (ClutterColor *dest,
+                         guint32       pixel)
 {
-  if (r)
-    *r = clutter_color_r(color);
-  if (g)
-    *g = clutter_color_g(color);
-  if (b)
-    *b = clutter_color_b(color);
-  if (a)
-    *a = clutter_color_a(color);
+  g_return_if_fail (dest != NULL);
+
+  dest->red = pixel >> 24;
+  dest->green = (pixel >> 16) & 0xff;
+  dest->blue = (pixel >> 8) & 0xff;
+  dest->alpha = pixel % 0xff;
 }
 
+static ClutterColor *
+clutter_color_copy (ClutterColor *color)
+{
+  ClutterColor *result = g_new0 (ClutterColor, 1);
+
+  *result = *color;
+
+  return result;
+}
 
+GType
+clutter_color_get_type (void)
+{
+  static GType our_type = 0;
+  
+  if (!our_type)
+    our_type = g_boxed_type_register_static ("ClutterColor",
+                                            (GBoxedCopyFunc) clutter_color_copy,
+                                            (GBoxedFreeFunc) g_free);
+  return our_type;
+}
index eab24a4..31850ea 100644 (file)
 #ifndef _HAVE_CLUTTER_COLOR_H
 #define _HAVE_CLUTTER_COLOR_H
 
-#include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
-#define clutter_color_r(col) ((col) >> 24)
-#define clutter_color_g(col) (((col) >> 16) & 0xff)
-#define clutter_color_b(col) (((col) >> 8) & 0xff)
-#define clutter_color_a(col) ((col) & 0xff)
+#define CLUTTER_TYPE_COLOR     (clutter_color_get_type ())
 
-#define clutter_color_set_r(col,r) ((col) &= (r)) 
-#define clutter_color_set_g(col,g) ((col) &= (g << 8)) 
-#define clutter_color_set_b(col,b) ((col) &= (b << 16)) 
-#define clutter_color_set_a(col,a) ((col) &= (a << 24)) 
+typedef struct _ClutterColor ClutterColor;
 
-typedef guint32 ClutterColor;
+struct _ClutterColor
+{
+  guint8 red;
+  guint8 green;
+  guint8 blue;
+  
+  guint8 alpha;
+};
 
-ClutterColor
-clutter_color_new (guint8 r, guint8 g, guint8 b, guint8 a);
+GType   clutter_color_get_type   (void) G_GNUC_CONST;
 
-void
-clutter_color_set (ClutterColor *color, 
-                  guint8        r, 
-                  guint8        g, 
-                  guint8        b, 
-                  guint8        a);
+void    clutter_color_add        (const ClutterColor *src1,
+                                 const ClutterColor *src2,
+                                 ClutterColor       *dest);
+void    clutter_color_subtract   (const ClutterColor *src1,
+                                 const ClutterColor *src2,
+                                 ClutterColor       *dest);
 
-void
-clutter_color_get (ClutterColor  color, 
-                  guint8        *r, 
-                  guint8        *g, 
-                  guint8        *b, 
-                  guint8        *a);
+void    clutter_color_lighten    (const ClutterColor *src,
+                                 ClutterColor       *dest);
+void    clutter_color_darken     (const ClutterColor *src,
+                                 ClutterColor       *dest);
+void    clutter_color_shade      (const ClutterColor *src,
+                                 ClutterColor       *dest,
+                                 gdouble             shade);
+
+void    clutter_color_to_hls     (const ClutterColor *src,
+                                 guint8             *hue,
+                                 guint8             *luminance,
+                                 guint8             *saturation);
+void    clutter_color_from_hls   (ClutterColor       *dest,
+                                 guint8              hue,
+                                 guint8              luminance,
+                                 guint8              saturation);
+
+guint32 clutter_color_to_pixel   (const ClutterColor *src);
+void    clutter_color_from_pixel (ClutterColor       *dest,
+                                 guint32             pixel);
 
 G_END_DECLS
 
index 8f612a3..6ee49ce 100644 (file)
@@ -73,8 +73,6 @@ enum
   PROP_NAME,
 };
 
-extern ClutterMainContext ClutterCntx;
-
 static gboolean
 redraw_update_idle (gpointer data)
 {
@@ -225,14 +223,15 @@ clutter_element_paint (ClutterElement *self)
 
   if (self->priv->has_clip)
     {
-      ClutterGeometry *clip = &self->priv->clip;
+      ClutterGeometry *clip = &(self->priv->clip);
       gint             absx, absy;
+      ClutterElement  *stage = clutter_stage_get_default ();
 
       clutter_element_get_abs_position (self, &absx, &absy);
 
       CLUTTER_DBG("clip +%i+%i, %ix%i\n", 
                  absx + clip->x, 
-                 clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())
+                 clutter_element_get_height (stage
                  - (absy + clip->y) - clip->height, 
                  clip->width, 
                  clip->height);
@@ -240,10 +239,12 @@ clutter_element_paint (ClutterElement *self)
       glEnable (GL_SCISSOR_TEST);
 
       glScissor (absx + clip->x, 
-                clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())
+                clutter_element_get_height (stage
                     - (absy + clip->y) - clip->height, 
                 clip->width, 
                 clip->height);
+
+      g_object_unref (stage);
     }
 
   glPushMatrix();
index e552630..85cded4 100644 (file)
@@ -988,3 +988,47 @@ clutter_keysym_to_unicode (guint keyval)
   return 0;
 }
 
+ClutterEvent *
+clutter_event_new (ClutterEventType type)
+{
+  ClutterEvent *new_event;
+
+  new_event = g_new0 (ClutterEvent, 1);
+  new_event->any.type = type;
+
+  return new_event;
+}
+
+ClutterEvent *
+clutter_event_copy (ClutterEvent *event)
+{
+  ClutterEvent *new_event;
+
+  g_return_val_if_fail (event != NULL, NULL);
+
+  new_event = g_new (ClutterEvent, 1);
+  *new_event = *event;
+
+  return new_event;
+}
+
+void
+clutter_event_free (ClutterEvent *event)
+{
+  if (!event)
+    return;
+
+  g_free (event);
+}
+
+GType
+clutter_event_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (!our_type)
+    our_type = g_boxed_type_register_static ("ClutterEvent",
+                                            (GBoxedCopyFunc) clutter_event_copy,
+                                            (GBoxedFreeFunc) clutter_event_free);
+  return our_type;
+}
index 7e0d7da..6b8593f 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef _HAVE_CLUTTER_EVENT_H
 #define _HAVE_CLUTTER_EVENT_H
 
-#include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
@@ -43,6 +43,8 @@ enum
 
 typedef enum 
 {
+  CLUTTER_NOTHING,
+  
   CLUTTER_KEY_PRESS,
   CLUTTER_KEY_RELEASE,
   CLUTTER_MOTION,
@@ -51,14 +53,23 @@ typedef enum
   CLUTTER_BUTTON_RELEASE
 } ClutterEventType;
 
+#define CLUTTER_TYPE_EVENT     (clutter_event_get_type ())
+
 typedef union _ClutterEvent ClutterEvent;
 
+typedef struct _ClutterAnyEvent    ClutterAnyEvent;
 typedef struct _ClutterKeyEvent    ClutterKeyEvent;
 typedef struct _ClutterButtonEvent ClutterButtonEvent;
 typedef struct _ClutterMotionEvent ClutterMotionEvent;
 
 typedef struct _ClutterInputDevice ClutterInputDevice;
 
+struct _ClutterAnyEvent
+{
+  ClutterEventType  type;
+  guint8            send_event : 1;
+};
+
 struct _ClutterKeyEvent
 {
   ClutterEventType type;
@@ -95,11 +106,18 @@ union _ClutterEvent
 {
   ClutterEventType   type;
   
+  ClutterAnyEvent    any;
   ClutterKeyEvent    key_event;
   ClutterButtonEvent button_event;
   ClutterMotionEvent motion_event;
 };
 
+GType clutter_event_get_type (void) G_GNUC_CONST;
+
+ClutterEvent *clutter_event_new  (ClutterEventType  type);
+ClutterEvent *clutter_event_copy (ClutterEvent     *event);
+void          clutter_event_free (ClutterEvent     *event);
+
 ClutterEventType
 clutter_key_event_type (ClutterKeyEvent *keyev);
 
index fab082a..9de908b 100644 (file)
 
 #include "clutter-group.h"
 #include "clutter-main.h"
+#include "clutter-marshal.h"
+#include "clutter-enum-types.h"
+
+enum
+{
+  ADD,
+  REMOVE,
+
+  LAST_SIGNAL
+};
+
+static guint group_signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (ClutterGroup, clutter_group, CLUTTER_TYPE_ELEMENT);
 
@@ -51,7 +63,7 @@ clutter_group_paint (ClutterElement *element)
 
   /* Translate if parent ( i.e not stage window ).
   */
-  if (clutter_element_get_parent(element) != NULL)
+  if (clutter_element_get_parent (element) != NULL)
     {
       ClutterGeometry geom;      
 
@@ -62,6 +74,20 @@ clutter_group_paint (ClutterElement *element)
 
     }
 
+#if 0
+  for (child_item = self->priv->children;
+       child_item != NULL;
+       child_item = child_item->next)
+    {
+      ClutterElement *child = child_item->data;
+
+      g_assert (child != NULL);
+
+      if (CLUTTER_ELEMENT_IS_MAPPED (child))
+       clutter_element_paint (child);
+    }
+#endif
+  
   if (child_item)
     {
       do 
@@ -151,6 +177,17 @@ clutter_group_dispose (GObject *object)
 static void 
 clutter_group_finalize (GObject *object)
 {
+  ClutterGroup *group = CLUTTER_GROUP (object);
+
+  /* XXX - if something survives ::dispose then there's something
+   * wrong; but, at least, we won't leak stuff around.
+   */
+  if (group->priv->children)
+    {
+      g_list_foreach (group->priv->children, (GFunc) g_object_unref, NULL);
+      g_list_free (group->priv->children);
+    }
+  
   G_OBJECT_CLASS (clutter_group_parent_class)->finalize (object);
 }
 
@@ -172,6 +209,26 @@ clutter_group_class_init (ClutterGroupClass *klass)
   object_class->finalize     = clutter_group_finalize;
   object_class->dispose      = clutter_group_dispose;
 
+  group_signals[ADD] =
+    g_signal_new ("add",
+                 G_OBJECT_CLASS_TYPE (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterGroupClass, add),
+                 NULL, NULL,
+                 clutter_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_ELEMENT);
+
+  group_signals[REMOVE] =
+    g_signal_new ("remove",
+                 G_OBJECT_CLASS_TYPE (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterGroupClass, remove),
+                 NULL, NULL,
+                 clutter_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_ELEMENT);
+
   g_type_class_add_private (object_class, sizeof (ClutterGroupPrivate));
 }
 
@@ -283,19 +340,37 @@ clutter_group_hide_all (ClutterGroup *self)
  * @self: A #ClutterGroup
  * @element: A #ClutterElement 
  *
- * Add a new child #ClutterElement to the #ClutterGroup.
+ * Adds a new child #ClutterElement to the #ClutterGroup.
  **/
 void
-clutter_group_add (ClutterGroup *self, ClutterElement *element)
+clutter_group_add (ClutterGroup   *self,
+                  ClutterElement *element)
 {
+  ClutterElement *parent;
+  
   g_return_if_fail (CLUTTER_IS_GROUP (self));
   g_return_if_fail (CLUTTER_IS_ELEMENT (element));
 
+  parent = clutter_element_get_parent (element);
+  if (parent)
+    {
+      g_warning ("Attempting to add element of type `%s' to a "
+                "group of type `%s', but the element has already "
+                "a parent of type `%s'.",
+                g_type_name (G_OBJECT_TYPE (element)),
+                g_type_name (G_OBJECT_TYPE (self)),
+                g_type_name (G_OBJECT_TYPE (parent)));
+      return;
+    }
+
   self->priv->children = g_list_append (self->priv->children, element);
   /* below refs */
   clutter_element_set_parent (element, CLUTTER_ELEMENT(self));
+  g_object_ref (element);
 
   clutter_group_sort_depth_order (self); 
+
+  g_signal_emit (self, group_signals[ADD], 0, element);
 }
 
 /**
@@ -354,14 +429,30 @@ clutter_group_add_many (ClutterGroup   *self,
  * Remove a child #ClutterElement from the #ClutterGroup.
  **/
 void
-clutter_group_remove (ClutterGroup *self, ClutterElement *element)
+clutter_group_remove (ClutterGroup   *self,
+                     ClutterElement *element)
 {
+  ClutterElement *parent;
+  
   g_return_if_fail (CLUTTER_IS_GROUP (self));
   g_return_if_fail (CLUTTER_IS_ELEMENT (element));
 
-  /* FIXME: Check we actually are a child ? */
+  parent = clutter_element_get_parent (element);
+  if (element != CLUTTER_ELEMENT (self))
+    {
+      g_warning ("Attempting to remove element of type `%s' from "
+                "group of class `%s', but the group is not the "
+                "element's parent.",
+                g_type_name (G_OBJECT_TYPE (element)),
+                g_type_name (G_OBJECT_TYPE (self)));
+      return;
+    }
+
   self->priv->children = g_list_remove (self->priv->children, element);
   clutter_element_set_parent (element, NULL);
+  
+  g_signal_emit (self, group_signals[REMOVE], 0, element);
+  g_object_unref (element);
 }
 
 /**
@@ -369,7 +460,7 @@ clutter_group_remove (ClutterGroup *self, ClutterElement *element)
  * @self: A #ClutterGroup
  *
  * Remove all child #ClutterElement from the #ClutterGroup.
- **/
+ */
 void
 clutter_group_remove_all (ClutterGroup *self)
 {
@@ -396,9 +487,10 @@ clutter_group_remove_all (ClutterGroup *self)
  *
  * Finds a child element of a group by its unique ID. Search recurses
  * into any child groups. 
- **/
-ClutterElement*
-clutter_group_find_child_by_id (ClutterGroup *self, guint id)
+ */
+ClutterElement *
+clutter_group_find_child_by_id (ClutterGroup *self,
+                               guint         id)
 {
   ClutterElement *element = NULL, *inner_element;
   GList          *child_item;
@@ -435,8 +527,16 @@ clutter_group_find_child_by_id (ClutterGroup *self, guint id)
   return element;
 }
 
+/**
+ * clutter_group_raise:
+ * @self: a #ClutterGroup
+ * @element: a #ClutterElement
+ * @sibling: a #ClutterElement
+ *
+ * FIXME
+ */
 void
-clutter_group_raise (ClutterGroup     *self,
+clutter_group_raise (ClutterGroup   *self,
                     ClutterElement *element, 
                     ClutterElement *sibling)
 {
@@ -475,8 +575,16 @@ clutter_group_raise (ClutterGroup     *self,
 
 }
 
+/**
+ * clutter_group_lower:
+ * @self: a #ClutterGroup
+ * @element: a #ClutterElement
+ * @sibling: a #ClutterElement
+ *
+ * FIXME
+ */
 void
-clutter_group_lower (ClutterGroup     *self,
+clutter_group_lower (ClutterGroup   *self,
                     ClutterElement *element, 
                     ClutterElement *sibling)
 {
index 4e6be15..0bc0a8a 100644 (file)
@@ -70,6 +70,11 @@ struct _ClutterGroupClass
   /*< private >*/
   ClutterElementClass     parent_class;
 
+  void (*add)    (ClutterGroup   *group,
+                 ClutterElement *child);
+  void (*remove) (ClutterGroup   *group,
+                 ClutterElement *child);
+
   void (*_clutter_group_1) (void);
   void (*_clutter_group_2) (void);
   void (*_clutter_group_3) (void);
@@ -104,7 +109,8 @@ clutter_group_add_many (ClutterGroup   *group,
                        ...) G_GNUC_NULL_TERMINATED;
 
 void
-clutter_group_remove (ClutterGroup *group, ClutterElement *element); 
+clutter_group_remove (ClutterGroup   *group,
+                     ClutterElement *element); 
 
 void
 clutter_group_show_all (ClutterGroup *self);
@@ -112,7 +118,7 @@ clutter_group_show_all (ClutterGroup *self);
 void
 clutter_group_hide_all (ClutterGroup *self);
 
-ClutterElement*
+ClutterElement *
 clutter_group_find_child_by_id (ClutterGroup *self, guint id);
 
 void
index b8fe7f5..c3063c6 100644 (file)
 
 #include <pango/pangoft2.h>
 
+#define DEFAULT_FONT_NAME      "Sans 10"
+
 G_DEFINE_TYPE (ClutterLabel, clutter_label, CLUTTER_TYPE_TEXTURE);
 
 enum
 {
   PROP_0,
-  PROP_FONT,
+  PROP_FONT_NAME,
   PROP_TEXT,
-  PROP_COL
+  PROP_COLOR
 };
 
 #define CLUTTER_LABEL_GET_PRIVATE(obj) \
@@ -50,10 +52,14 @@ struct _ClutterLabelPrivate
   PangoLayout          *layout;
   PangoContext         *context;
   PangoFontDescription *desc;
-  guint32               fgcol;
+  
+  ClutterColor          fgcol;
+  
   gchar                *text;
-  gchar                *font;
-  gint                  extents_width, extents_height;
+  gchar                *font_name;
+  
+  gint                  extents_width;
+  gint                  extents_height;
 };
 
 static void
@@ -120,9 +126,9 @@ clutter_label_make_pixbuf (ClutterLabel *label)
 
       for (bx = 0; bx < ft_bitmap.width; bx++) 
        {
-         *pd++ = clutter_color_r(priv->fgcol);
-         *pd++ = clutter_color_g(priv->fgcol);
-         *pd++ = clutter_color_b(priv->fgcol);
+         *pd++ = priv->fgcol.red;
+         *pd++ = priv->fgcol.green;
+         *pd++ = priv->fgcol.blue;
          *pd++ = *ps++;
        }
     }
@@ -151,14 +157,14 @@ clutter_label_set_property (GObject      *object,
 
   switch (prop_id) 
     {
-    case PROP_FONT:
-      clutter_label_set_font (label, g_value_get_string(value));
+    case PROP_FONT_NAME:
+      clutter_label_set_font_name (label, g_value_get_string (value));
       break;
     case PROP_TEXT:
-      clutter_label_set_text (label, g_value_get_string(value));
+      clutter_label_set_text (label, g_value_get_string (value));
       break;
-    case PROP_COL:
-      clutter_label_set_color (label, g_value_get_uint(value));
+    case PROP_COLOR:
+      clutter_label_set_color (label, g_value_get_boxed (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -174,20 +180,22 @@ clutter_label_get_property (GObject    *object,
 {
   ClutterLabel        *label;
   ClutterLabelPrivate *priv;
+  ClutterColor         color;
 
   label = CLUTTER_LABEL(object);
   priv = label->priv;
 
   switch (prop_id) 
     {
-    case PROP_FONT:
-      g_value_set_string (value, priv->font);
+    case PROP_FONT_NAME:
+      g_value_set_string (value, priv->font_name);
       break;
     case PROP_TEXT:
       g_value_set_string (value, priv->text);
       break;
-    case PROP_COL:
-      g_value_set_uint (value, priv->fgcol);
+    case PROP_COLOR:
+      clutter_label_get_color (label, &color);
+      g_value_set_boxed (value, &color);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -203,37 +211,29 @@ clutter_label_dispose (GObject *object)
   ClutterLabelPrivate  *priv;  
 
   priv = self->priv;
-
-  if (priv)
+  
+  if (priv->layout)
     {
-      if (priv->layout)
-       {
-         g_object_unref (priv->layout);
-         priv->layout = NULL;
-       }
-      if (priv->desc)
-       {
-         pango_font_description_free (priv->desc);    
-         priv->desc = NULL;
-       }
-
-      if (priv->text)
-       {
-         g_free (priv->text);
-         priv->text = NULL;
-       }
+      g_object_unref (priv->layout);
+      priv->layout = NULL;
+    }
+  
+  if (priv->desc)
+    {
+      pango_font_description_free (priv->desc);    
+      priv->desc = NULL;
+    }
 
-      if (priv->font)
-       {
-         g_free (priv->font);
-         priv->font = NULL;
-       }
+  g_free (priv->text);
+  priv->text = NULL;
 
-      if (priv->context)
-       {
-         g_object_unref (priv->context);
-         priv->context = NULL;
-       }
+  g_free (priv->font_name);
+  priv->font_name = NULL;
+      
+  if (priv->context)
+    {
+      g_object_unref (priv->context);
+      priv->context = NULL;
     }
 
   G_OBJECT_CLASS (clutter_label_parent_class)->dispose (object);
@@ -250,7 +250,6 @@ clutter_label_class_init (ClutterLabelClass *klass)
 {
   GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
   ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
-  ClutterTextureClass *texture_class = CLUTTER_TEXTURE_CLASS (klass);
   ClutterElementClass *parent_class = CLUTTER_ELEMENT_CLASS (clutter_label_parent_class);
 
   element_class->paint      = parent_class->paint;
@@ -265,11 +264,11 @@ clutter_label_class_init (ClutterLabelClass *klass)
   gobject_class->get_property = clutter_label_get_property;
 
   g_object_class_install_property
-    (gobject_class, PROP_FONT,
-     g_param_spec_string ("font",
-                         "Font",
+    (gobject_class, PROP_FONT_NAME,
+     g_param_spec_string ("font-name",
+                         "Font Name",
                          "Pango font description",
-                         "sans 10",
+                         NULL,
                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 
   g_object_class_install_property
@@ -277,18 +276,16 @@ clutter_label_class_init (ClutterLabelClass *klass)
      g_param_spec_string ("text",
                          "Text",
                          "Text to render",
-                         "",
+                         NULL,
                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 
   g_object_class_install_property
-    (gobject_class, PROP_COL,
-     g_param_spec_uint ("color",
-                       "Font Colour",
-                       "Font Colour specified as 8 byte RGBA value",
-                       0,
-                       0xffffffff,
-                       0x000000ff,
-                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+    (gobject_class, PROP_COLOR,
+     g_param_spec_boxed ("color",
+                        "Font Colour",
+                        "Font Colour",
+                        CLUTTER_TYPE_COLOR,
+                        G_PARAM_READWRITE));
 
   g_type_class_add_private (gobject_class, sizeof (ClutterLabelPrivate));
 }
@@ -301,10 +298,17 @@ clutter_label_init (ClutterLabel *self)
 
   self->priv = priv = CLUTTER_LABEL_GET_PRIVATE (self);
 
-  font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
+  priv->fgcol.red = 255;
+  priv->fgcol.green = 255;
+  priv->fgcol.blue = 255;
+  priv->fgcol.alpha = 255;
 
+  priv->text = NULL;
+  priv->font_name = g_strdup (DEFAULT_FONT_NAME);
+  priv->desc = pango_font_description_from_string (priv->font_name);
+  
+  font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
   pango_ft2_font_map_set_resolution (font_map, 96.0, 96.0);
-
   priv->context = pango_ft2_font_map_create_context (font_map);
 
   priv->layout  = pango_layout_new (priv->context);
@@ -315,63 +319,140 @@ clutter_label_init (ClutterLabel *self)
   */
 }
 
-ClutterElement*
-clutter_label_new_with_text (const gchar *font_desc, const gchar *text)
+/**
+ * clutter_label_new_with_text:
+ * @font_name: the name (and size) of the font to be used
+ * @text: the text to be displayed
+ *
+ * Creates a new #ClutterLabel displaying @text using @font_name.
+ *
+ * Return value: a #ClutterLabel
+ */
+ClutterElement *
+clutter_label_new_with_text (const gchar *font_name,
+                            const gchar *text)
 {
-  ClutterLabel *label;
-
-  label = g_object_new (CLUTTER_TYPE_LABEL, 
-                       "font", font_desc,
-                       "text", text,
-                       NULL);
-
-  return CLUTTER_ELEMENT(label);
+  return g_object_new (CLUTTER_TYPE_LABEL, 
+                      "font-name", font_name,
+                      "text", text,
+                      NULL);
 }
 
-ClutterElement*
+/**
+ * clutter_label_new:
+ *
+ * Creates a new, empty #ClutterLabel.
+ *
+ * Return: the newly created #ClutterLabel
+ */
+ClutterElement *
 clutter_label_new (void)
 {
-  return CLUTTER_ELEMENT(g_object_new (CLUTTER_TYPE_LABEL, NULL));
+  return g_object_new (CLUTTER_TYPE_LABEL, NULL);
+}
+
+/**
+ * clutter_label_get_text:
+ * @label: a #ClutterLabel
+ *
+ * Retrieves the text displayed by @label
+ *
+ * Return value: the text of the label.  The returned string is
+ *   owned by #ClutterLabel and should not be modified or freed.
+ */
+G_CONST_RETURN gchar *
+clutter_label_get_text (ClutterLabel *label)
+{
+  g_return_val_if_fail (CLUTTER_IS_LABEL (label), NULL);
+
+  return label->priv->text;
 }
 
+/**
+ * clutter_label_set_text:
+ * @label: a #ClutterLabel
+ * @text: the text to be displayed
+ *
+ * Sets @text as the text to be displayed by @label.
+ */
 void
-clutter_label_set_text (ClutterLabel *label, const gchar *text)
+clutter_label_set_text (ClutterLabel *label,
+                       const gchar  *text)
 {
   ClutterLabelPrivate  *priv;  
 
   g_return_if_fail (CLUTTER_IS_LABEL (label));
 
   priv = label->priv;
-
-  if (priv->text)
-    g_free (priv->text);
-
-  priv->text = g_strdup(text);
+  
+  g_free (priv->text);
+  priv->text = g_strdup (text);
 
   clutter_label_make_pixbuf (label);
 
   if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
     clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+
+  g_object_notify (G_OBJECT (label), "text");
 }
 
+/**
+ * clutter_label_get_font_name:
+ * @label: a #ClutterLabel
+ *
+ * Retrieves the font used by @label.
+ *
+ * Return value: a string containing the font name, in a format
+ *   understandable by pango_font_description_from_string().  The
+ *   string is owned by #ClutterLabel and should not be modified
+ *   or freed.
+ */
+G_CONST_RETURN gchar *
+clutter_label_get_font_name (ClutterLabel *label)
+{
+  g_return_val_if_fail (CLUTTER_IS_LABEL (label), NULL);
+  
+  return label->priv->font_name;
+}
+
+/**
+ * clutter_label_set_font_name:
+ * @label: a #ClutterLabel
+ * @font_name: a font name and size, or %NULL for the default font
+ *
+ * Sets @font_name as the font used by @label.
+ *
+ * @font_name must be a string containing the font name and its
+ * size, similarly to what you would feed to the
+ * pango_font_description_from_string() function.
+ */
 void
-clutter_label_set_font (ClutterLabel *label, const gchar *desc)
+clutter_label_set_font_name (ClutterLabel *label,
+                            const gchar  *font_name)
 {
   ClutterLabelPrivate  *priv;  
 
   g_return_if_fail (CLUTTER_IS_LABEL (label));
+  
+  if (!font_name || font_name[0] == '\0')
+    font_name = DEFAULT_FONT_NAME;
 
   priv = label->priv;
 
   if (priv->desc)
-    pango_font_description_free (priv->desc);    
-
-  if (priv->font)
-    g_free(priv->font);
+    pango_font_description_free (priv->desc);
 
-  priv->font = g_strdup(desc);
+  g_free (priv->font_name);
+  priv->font_name = g_strdup (font_name);
 
-  priv->desc = pango_font_description_from_string (desc);
+  priv->desc = pango_font_description_from_string (priv->font_name);
+  if (!priv->desc)
+    {
+      g_warning ("Attempting to create a PangoFontDescription for "
+                "font name `%s', but failed.",
+                priv->font_name);
+      return;
+    }
 
   if (label->priv->text && label->priv->text[0] != '\0')
     {
@@ -380,8 +461,18 @@ clutter_label_set_font (ClutterLabel *label, const gchar *desc)
       if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
        clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
     }
+  
+  g_object_notify (G_OBJECT (label), "font-name");
 }
 
+/**
+ * clutter_label_set_text_extents:
+ * @label: a #ClutterLabel
+ * @width: the width of the text
+ * @height: the height of the text
+ *
+ * Sets the maximum extents of the label's text.
+ */
 void
 clutter_label_set_text_extents (ClutterLabel *label, 
                                gint          width,
@@ -399,21 +490,82 @@ clutter_label_set_text_extents (ClutterLabel *label,
     clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
 }
 
+/**
+ * clutter_label_get_text_extents:
+ * @label: a #ClutterLabel
+ * @width: return location for the width of the extents or %NULL
+ * @height: return location for the height of the extents or %NULL
+ *
+ * Returns the extents of the label.
+ */
 void
-clutter_label_set_color (ClutterLabel *label, ClutterColor pixel)
+clutter_label_get_text_extents (ClutterLabel *label,
+                               gint         *width,
+                               gint         *height)
 {
-  ClutterLabelPrivate  *priv;  
+  g_return_if_fail (CLUTTER_IS_LABEL (label));
 
-  priv = label->priv;
+  if (width)
+    *width = label->priv->extents_width;
 
-  priv->fgcol = pixel;
+  if (height)
+    *height = label->priv->extents_height;
+}
 
-  clutter_element_set_opacity(CLUTTER_ELEMENT(label), priv->fgcol & 0xff);
+/**
+ * clutter_label_set_color:
+ * @label: a #ClutterLabel
+ * @color: a #ClutterColor
+ *
+ * Sets the color of @label.
+ */
+void
+clutter_label_set_color (ClutterLabel       *label,
+                        const ClutterColor *color)
+{
+  ClutterElement *element;
+  ClutterLabelPrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_LABEL (label));
+  g_return_if_fail (color != NULL);
+
+  priv = label->priv;
+  priv->fgcol.red = color->red;
+  priv->fgcol.green = color->green;
+  priv->fgcol.blue = color->blue;
+  priv->fgcol.alpha = color->alpha;
 
   clutter_label_make_pixbuf (label);
+  
+  element = CLUTTER_ELEMENT (label);
+  clutter_element_set_opacity (element, priv->fgcol.alpha);
 
-  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label)))
-    clutter_element_queue_redraw (CLUTTER_ELEMENT(label));
+  if (CLUTTER_ELEMENT_IS_VISIBLE (element))
+    clutter_element_queue_redraw (element);
+
+  g_object_notify (G_OBJECT (label), "color");
 }
 
+/**
+ * clutter_label_get_color:
+ * @label: a #ClutterLabel
+ * @color: return location for a #ClutterColor
+ *
+ * Retrieves the color of @label.
+ */
+void
+clutter_label_get_color (ClutterLabel *label,
+                        ClutterColor *color)
+{
+  ClutterLabelPrivate *priv;
 
+  g_return_if_fail (CLUTTER_IS_LABEL (label));
+  g_return_if_fail (color != NULL);
+
+  priv = label->priv;
+
+  color->red = priv->fgcol.red;
+  color->green = priv->fgcol.green;
+  color->blue = priv->fgcol.blue;
+  color->alpha = priv->fgcol.alpha;
+}
index 356e3c0..855ba46 100644 (file)
@@ -29,6 +29,7 @@
 #include <glib-object.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <clutter/clutter-texture.h>
+#include <clutter/clutter-color.h>
 
 G_BEGIN_DECLS
 
@@ -77,27 +78,28 @@ struct _ClutterLabelClass
   void (*_clutter_label_4) (void);
 }; 
 
-GType clutter_label_get_type (void);
-
-ClutterElement*
-clutter_label_new_with_text (const gchar *font_desc, const gchar *text);
-
-ClutterElement*
-clutter_label_new (void);
-
-void
-clutter_label_set_text (ClutterLabel *label, const gchar *text);
-
-void
-clutter_label_set_font (ClutterLabel *label, const gchar *desc);
-
-void
-clutter_label_set_color (ClutterLabel *label, guint32 pixel);
-
-void
-clutter_label_set_text_extents (ClutterLabel *label, 
-                               gint          width,
-                               gint          height);
+GType clutter_label_get_type (void) G_GNUC_CONST;
+
+ClutterElement *      clutter_label_new              (void);
+ClutterElement *      clutter_label_new_with_text    (const gchar        *font_name,
+                                                     const gchar        *text);
+
+void                  clutter_label_set_text         (ClutterLabel       *label,
+                                                     const gchar        *text);
+G_CONST_RETURN gchar *clutter_label_get_text         (ClutterLabel       *label);
+void                  clutter_label_set_font_name    (ClutterLabel       *label,
+                                                     const gchar        *font_name);
+G_CONST_RETURN gchar *clutter_label_get_font_name    (ClutterLabel       *label);
+void                  clutter_label_set_color        (ClutterLabel       *label,
+                                                     const ClutterColor *color);
+void                  clutter_label_get_color        (ClutterLabel       *label,
+                                                     ClutterColor       *color);
+void                  clutter_label_set_text_extents (ClutterLabel       *label,
+                                                     gint                width,
+                                                     gint                height);
+void                  clutter_label_get_text_extents (ClutterLabel       *label,
+                                                     gint               *width,
+                                                     gint               *height);
 
 G_END_DECLS
 
index 05131da..5e4ceeb 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+#include "config.h"
+
+#include <stdlib.h>
+
 #include "clutter-main.h"
 #include "clutter-element.h"
 #include "clutter-stage.h"
@@ -37,8 +42,6 @@ typedef struct
 } 
 ClutterXEventSource;
 
-ClutterMainContext ClutterCntx;
-
 #define GLX_SAMPLE_BUFFERS_ARB             100000
 #define GLX_SAMPLES_ARB                    100001
 
@@ -47,6 +50,8 @@ typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data);
 static gboolean __clutter_has_debug = FALSE;
 static gboolean __clutter_has_fps   = FALSE;
 
+static ClutterMainContext *ClutterCntx = NULL;
+
 static gboolean  
 x_event_prepare (GSource  *source,
                 gint     *timeout)
@@ -141,12 +146,17 @@ translate_motion_event (ClutterMotionEvent   *event,
   event->modifier_state = xevent->xmotion.state;
 }
 
-void
+static void
 clutter_dispatch_x_event (XEvent  *xevent,
                          gpointer data)
 {
-  ClutterMainContext *ctx = CLUTTER_CONTEXT();
-  ClutterEvent        event;
+  ClutterMainContext *ctx = CLUTTER_CONTEXT ();
+  ClutterEvent       *event;
+  ClutterStage       *stage = ctx->stage;
+  gboolean            emit_input_event = FALSE;
+
+  event = clutter_event_new (CLUTTER_NOTHING);
+  event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
 
   switch (xevent->type)
     {
@@ -163,24 +173,40 @@ clutter_dispatch_x_event (XEvent  *xevent,
        /* FIXME: need to make stage an 'element' so can que
          * a paint direct from there rather than hack here...
        */
-       clutter_element_queue_redraw (CLUTTER_ELEMENT(clutter_stage()));
+       clutter_element_queue_redraw (CLUTTER_ELEMENT (stage));
       }
       break;
     case KeyPress:
+      translate_key_event ((ClutterKeyEvent *) event, xevent);
+      g_signal_emit_by_name (stage, "key-press-event", event);
+      emit_input_event = TRUE;
+      break;
     case KeyRelease:
-      translate_key_event ((ClutterKeyEvent*)&event, xevent);
-      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      translate_key_event ((ClutterKeyEvent *) event, xevent);
+      g_signal_emit_by_name (stage, "key-release-event", event);
+      emit_input_event = TRUE;
       break;
     case ButtonPress:
+      translate_button_event ((ClutterButtonEvent *) event, xevent);
+      g_signal_emit_by_name (stage, "button-press-event", event);
+      emit_input_event = TRUE;
+      break;
     case ButtonRelease:
-      translate_button_event ((ClutterButtonEvent*)&event, xevent);
-      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      translate_button_event ((ClutterButtonEvent *) event, xevent);
+      g_signal_emit_by_name (stage, "button-release-event", event);
+      emit_input_event = TRUE;
       break;
     case MotionNotify:
-      translate_motion_event ((ClutterMotionEvent*)&event, xevent);
-      g_signal_emit_by_name (clutter_stage(), "input-event", &event);
+      translate_motion_event ((ClutterMotionEvent *) event, xevent);
+      g_signal_emit_by_name (stage, "motion-event", event);
+      emit_input_event = TRUE;
       break;
     }
+
+  if (emit_input_event)
+    g_signal_emit_by_name (stage, "input-event", event);
+
+  clutter_event_free (event);
 }
 
 static void
@@ -195,7 +221,7 @@ events_init()
 
   g_main_context_ref (gmain_context);
 
-  connection_number = ConnectionNumber (ClutterCntx.xdpy);
+  connection_number = ConnectionNumber (ClutterCntx->xdpy);
   
   source = g_source_new ((GSourceFuncs *)&x_event_funcs, 
                         sizeof (ClutterXEventSource));
@@ -204,7 +230,7 @@ events_init()
 
   display_source->event_poll_fd.fd     = connection_number;
   display_source->event_poll_fd.events = G_IO_IN;
-  display_source->display              = ClutterCntx.xdpy;
+  display_source->display              = ClutterCntx->xdpy;
   
   g_source_add_poll (source, &display_source->event_poll_fd);
   g_source_set_can_recurse (source, TRUE);
@@ -223,11 +249,16 @@ clutter_want_fps(void)
   return __clutter_has_fps;
 }
 
+/**
+ * clutter_redraw:
+ *
+ * FIXME
+ */
 void
-clutter_redraw ()
+clutter_redraw (void)
 {
   ClutterMainContext *ctx = CLUTTER_CONTEXT();
-  ClutterStage       *stage = CLUTTER_STAGE(clutter_stage());
+  ClutterStage       *stage = ctx->stage;
   ClutterColor        stage_color;
   
   static GTimer      *timer = NULL; 
@@ -238,25 +269,25 @@ clutter_redraw ()
 
   CLUTTER_DBG("@@@ Redraw enter @@@");
 
-  clutter_threads_enter();
+  clutter_threads_enter ();
 
-  if (clutter_want_fps())
+  if (clutter_want_fps ())
     {
       if (!timer)
-       timer = g_timer_new();
+       timer = g_timer_new ();
     }
 
-  stage_color = clutter_stage_get_color (stage);
+  clutter_stage_get_color (stage, &stage_color);
 
-  glClearColor( ( (float)clutter_color_r(stage_color) / 0xff ) * 1.0,
-               ( (float)clutter_color_g(stage_color) / 0xff ) * 1.0,
-               ( (float)clutter_color_b(stage_color) / 0xff ) * 1.0,
-               0.0 );
+  glClearColor(((float) stage_color.red / 0xff * 1.0),
+              ((float) stage_color.green / 0xff * 1.0),
+              ((float) stage_color.blue / 0xff * 1.0),
+              0.0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glDisable(GL_LIGHTING); 
   glDisable(GL_DEPTH_TEST);
 
-  clutter_element_paint(CLUTTER_ELEMENT(stage));
+  clutter_element_paint (CLUTTER_ELEMENT (stage));
 
   if (clutter_stage_get_xwindow (stage))
     {
@@ -275,7 +306,7 @@ clutter_redraw ()
       glFlush();
     }
 
-  if (clutter_want_fps())
+  if (clutter_want_fps ())
     {
       timer_n_frames++;
 
@@ -287,95 +318,221 @@ clutter_redraw ()
        }
     }
 
-  clutter_threads_leave();
+  clutter_threads_leave ();
 
   CLUTTER_DBG("@@@ Redraw leave @@@");
 }
 
-
+/**
+ * clutter_main_quit:
+ *
+ * FIXME
+ */
 void
-clutter_main()
+clutter_main_quit (void)
 {
-  GMainLoop *loop;
+  ClutterMainContext *context = CLUTTER_CONTEXT ();
 
-  loop = g_main_loop_new (g_main_context_default (), TRUE);
+  g_return_if_fail (context->main_loops != NULL);
 
-  g_main_loop_run (loop);
+  g_main_loop_quit (context->main_loops->data);
 }
 
+/**
+ * clutter_main_level:
+ *
+ * FIXME
+ */
+gint
+clutter_main_level (void)
+{
+  ClutterMainContext *context = CLUTTER_CONTEXT ();
+
+  return context->main_loop_level;
+}
+
+/**
+ * clutter_main:
+ *
+ * FIXME
+ */
 void
-clutter_threads_enter(void)
+clutter_main (void)
 {
-  g_mutex_lock(ClutterCntx.gl_lock);
+  ClutterMainContext *context = CLUTTER_CONTEXT ();
+  GMainLoop *loop;
+
+  if (!context->is_initialized)
+    {
+      g_warning ("Called clutter_main() but Clutter wasn't initialised.  "
+                "You must call clutter_init() first.");
+      return;
+    }
+
+  context->main_loop_level++;
+
+  loop = g_main_loop_new (NULL, TRUE);
+  context->main_loops = g_slist_prepend (context->main_loops, loop);
+
+  if (g_main_loop_is_running (context->main_loops->data))
+    {
+      g_main_loop_run (loop);
+    }
+
+  context->main_loops = g_slist_remove (context->main_loops, loop);
+
+  g_main_loop_unref (loop);
+
+  context->main_loop_level--;
+
+  if (context->main_loop_level == 0)
+    {
+      g_object_unref (context->stage);
+      g_free (context);
+    }
 }
 
+/**
+ * clutter_threads_enter:
+ *
+ * FIXME
+ */
 void
-clutter_threads_leave(void)
+clutter_threads_enter(void)
 {
-  g_mutex_unlock(ClutterCntx.gl_lock);
+  ClutterMainContext *context = CLUTTER_CONTEXT ();
+  
+  g_mutex_lock (context->gl_lock);
 }
 
-ClutterGroup*
-clutter_stage(void)
+/**
+ * clutter_threads_leave:
+ *
+ * FIXME
+ */
+void
+clutter_threads_leave (void)
 {
-  return CLUTTER_GROUP(ClutterCntx.stage);
+  ClutterMainContext *context = CLUTTER_CONTEXT ();
+  
+  g_mutex_unlock (context->gl_lock);
 }
 
 Display*
-clutter_xdisplay(void)
+clutter_xdisplay (void)
 {
-  return ClutterCntx.xdpy;
+  return ClutterCntx->xdpy;
 }
 
 int
-clutter_xscreen(void)
+clutter_xscreen (void)
 {
-  return ClutterCntx.xscreen;
+  return ClutterCntx->xscreen;
 }
 
+/**
+ * clutter_root_xwindow:
+ *
+ * FIXME
+ *
+ * Return value: FIXME
+ */
 Window
-clutter_root_xwindow(void)
+clutter_root_xwindow (void)
 {
-  return ClutterCntx.xwin_root;
+  return ClutterCntx->xwin_root;
 }
 
+/**
+ * clutter_xvisual:
+ *
+ * FIXME
+ *
+ * Return value: FIXME
+ */
 XVisualInfo*
-clutter_xvisual(void)
+clutter_xvisual (void)
 {
-  return ClutterCntx.xvinfo;
+  return ClutterCntx->xvinfo;
 }
 
+/**
+ * clutter_want_debug:
+ * 
+ * FIXME
+ *
+ * Return value: FIXME
+ */
 gboolean
-clutter_want_debug(void)
+clutter_want_debug (void)
 {
   return __clutter_has_debug;
 }
 
+/**
+ * clutter_gl_context_set_indirect:
+ * @indirect: FIXME
+ *
+ * FIXME
+ */
 void
 clutter_gl_context_set_indirect (gboolean indirect)
 {
 
 }
 
-int
-clutter_init(int *argc, char ***argv)
+ClutterMainContext *
+clutter_context_get_default (void)
 {
-  int  gl_attributes[] =
+  if (!ClutterCntx)
     {
-      GLX_RGBA, 
-      GLX_DOUBLEBUFFER, 
-      GLX_RED_SIZE, 1,
-      GLX_GREEN_SIZE, 1,
-      GLX_BLUE_SIZE, 1,
-      /* GLX_DEPTH_SIZE, 1, */
-      /* GLX_DEPTH_SIZE, 32, */
-      0
-    };
-
-  if (getenv("CLUTTER_DEBUG"))
+      ClutterMainContext *ctx;
+
+      ctx = g_new0 (ClutterMainContext, 1);
+      ctx->is_initialized = FALSE;
+
+      ClutterCntx = ctx;
+    }
+
+  return ClutterCntx;
+}
+
+/**
+ * clutter_init:
+ * @argc: FIXME
+ * @argv: FIXME
+ *
+ * FIXME
+ *
+ * Return value: FIXME
+ */
+int
+clutter_init (int *argc, char ***argv)
+{
+  ClutterMainContext *context;
+  XVisualInfo  *vinfo;
+  static gboolean is_initialized = FALSE;
+
+  int gl_attributes[] = {
+    GLX_RGBA, 
+    GLX_DOUBLEBUFFER, 
+    GLX_RED_SIZE, 1,
+    GLX_GREEN_SIZE, 1,
+    GLX_BLUE_SIZE, 1,
+    /* GLX_DEPTH_SIZE, 1, */
+    /* GLX_DEPTH_SIZE, 32, */
+    0
+  };
+
+  if (is_initialized)
+    return 1;
+
+  context = clutter_context_get_default ();
+
+  if (g_getenv ("CLUTTER_DEBUG"))
     __clutter_has_debug = TRUE;
 
-  if (getenv("CLUTTER_SHOW_FPS"))
+  if (g_getenv ("CLUTTER_SHOW_FPS"))
     __clutter_has_fps = TRUE;
 
   g_type_init();
@@ -387,36 +544,40 @@ clutter_init(int *argc, char ***argv)
 
   gst_init (argc, argv);
 
-  if ((ClutterCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+  context->main_loops = NULL;
+  context->main_loop_level = 0;
+
+  if ((context->xdpy = XOpenDisplay (g_getenv ("DISPLAY"))) == NULL)
     {
       g_warning("Unable to connect to X DISPLAY.");
       return -1;
     }
 
-  ClutterCntx.xscreen   = DefaultScreen(ClutterCntx.xdpy);
-  ClutterCntx.xwin_root = RootWindow(ClutterCntx.xdpy, ClutterCntx.xscreen);
-
-  if ((ClutterCntx.xvinfo = glXChooseVisual(ClutterCntx.xdpy, 
-                                           ClutterCntx.xscreen,
-                                           gl_attributes)) == NULL)
+  context->xscreen   = DefaultScreen(context->xdpy);
+  context->xwin_root = RootWindow(context->xdpy,
+                                 context->xscreen);
+  context->xvinfo    = glXChooseVisual (context->xdpy,
+                                       context->xscreen,
+                                       gl_attributes);
+  if (!context->xvinfo)
     {
-      g_warning("Unable to find suitable GL visual.");
+      g_warning ("Unable to find suitable GL visual.");
+      
       return -2;
     }
 
-  ClutterCntx.font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
-
-  pango_ft2_font_map_set_resolution (ClutterCntx.font_map, 96.0, 96.0);
-
-  ClutterCntx.gl_lock = g_mutex_new ();
+  context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
+  pango_ft2_font_map_set_resolution (context->font_map, 96.0, 96.0);
 
-  ClutterCntx.stage = g_object_new (CLUTTER_TYPE_STAGE, NULL);
+  context->gl_lock = g_mutex_new ();
 
-  g_return_val_if_fail (ClutterCntx.stage != NULL, -3);
+  context->stage = CLUTTER_STAGE (clutter_stage_get_default ());
+  g_return_val_if_fail (CLUTTER_IS_STAGE (context->stage), -3);
+  clutter_element_realize (CLUTTER_ELEMENT (context->stage));
 
-  clutter_element_realize(CLUTTER_ELEMENT(ClutterCntx.stage));
+  events_init ();
 
-  events_init();
+  context->is_initialized = TRUE;
 
   return 1;
 }
index 7d5ed1e..1afad6a 100644 (file)
@@ -63,10 +63,13 @@ int
 clutter_init (int *argc, char ***argv);
 
 void
-clutter_main(void);
+clutter_main (void);
 
-ClutterGroup*
-clutter_stage(void);
+void
+clutter_main_quit (void);
+
+gint
+clutter_main_level (void);
 
 void
 clutter_redraw ();
index 435c9ac..51c291e 100644 (file)
@@ -1,4 +1,5 @@
 VOID:INT64,INT64,FLOAT,BOOLEAN
 VOID:STRING,BOOLEAN,BOOLEAN
 VOID:INT,INT
-
+VOID:BOXED
+VOID:OBJECT
index 3d93e99..f6a75d8 100644 (file)
 
 #include <pango/pangoft2.h>
 
+typedef struct _ClutterMainContext ClutterMainContext;
 
-typedef struct ClutterMainContext
+struct _ClutterMainContext
 {
-  Display          *xdpy;
-  Window            xwin_root;
-  int               xscreen;
-  GC                xgc;
-  XVisualInfo      *xvinfo;  
+  Display         *xdpy;
+  Window           xwin_root;
+  int              xscreen;
+  XVisualInfo     *xvinfo;
+  
+  GC               xgc;
+  
   PangoFT2FontMap *font_map;
+  
   GMutex          *gl_lock;
   guint            update_idle;
+  
+  guint            main_loop_level;
+  GSList          *main_loops;
+  
   ClutterStage    *stage;
-} 
-ClutterMainContext;
 
-#define CLUTTER_CONTEXT() &ClutterCntx
+  guint            is_initialized : 1;
+};
+
+#define CLUTTER_CONTEXT()      (clutter_context_get_default ())
+ClutterMainContext *clutter_context_get_default (void);
 
 #endif
index 47207dd..c8cc875 100644 (file)
@@ -35,7 +35,7 @@ G_DEFINE_TYPE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ELEMENT);
 enum
 {
   PROP_0,
-  PROP_COL
+  PROP_COLOR
 
   /* FIXME: Add gradient, rounded corner props etc */
 };
@@ -45,7 +45,7 @@ enum
 
 struct _ClutterRectanglePrivate
 {
-  guint32                  col;
+  ClutterColor color;
 };
 
 static void
@@ -65,10 +65,10 @@ clutter_rectangle_paint (ClutterElement *self)
 
   clutter_element_get_geometry (self, &geom);
 
-  glColor4ub(clutter_color_r(priv->col),
-            clutter_color_g(priv->col),
-            clutter_color_b(priv->col)
-            clutter_element_get_opacity(self));
+  glColor4ub(priv->color.red,
+            priv->color.green,
+            priv->color.blue
+            clutter_element_get_opacity (self));
 
   glRecti (geom.x,
           geom.y,
@@ -86,19 +86,12 @@ clutter_rectangle_set_property (GObject      *object,
                                const GValue *value, 
                                GParamSpec   *pspec)
 {
-  ClutterRectangle        *rectangle;
-  ClutterRectanglePrivate *priv;
-
-  rectangle = CLUTTER_RECTANGLE(object);
-  priv = rectangle->priv;
+  ClutterRectangle *rectangle = CLUTTER_RECTANGLE(object);
 
   switch (prop_id) 
     {
-    case PROP_COL:
-      priv->col = g_value_get_uint(value);
-      clutter_element_set_opacity(CLUTTER_ELEMENT(rectangle), 
-                                 priv->col & 0xff);
-      /* FIXME: queue paint */
+    case PROP_COLOR:
+      clutter_rectangle_set_color (rectangle, g_value_get_boxed (value)); 
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -112,16 +105,14 @@ clutter_rectangle_get_property (GObject    *object,
                                GValue     *value, 
                                GParamSpec *pspec)
 {
-  ClutterRectangle        *rectangle;
-  ClutterRectanglePrivate *priv;
-
-  rectangle = CLUTTER_RECTANGLE(object);
-  priv = rectangle->priv;
+  ClutterRectangle *rectangle = CLUTTER_RECTANGLE(object);
+  ClutterColor      color;
 
   switch (prop_id) 
     {
-    case PROP_COL:
-      g_value_set_uint (value, priv->col);
+    case PROP_COLOR:
+      clutter_rectangle_get_color (rectangle, &color);
+      g_value_set_boxed (value, &color);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -157,14 +148,12 @@ clutter_rectangle_class_init (ClutterRectangleClass *klass)
   gobject_class->get_property = clutter_rectangle_get_property;
 
   g_object_class_install_property
-    (gobject_class, PROP_COL,
-     g_param_spec_uint ("color",
-                      "Rectangle Colour",
-                      "Rectangle Colour specified as 8 byte RGBA value",
-                       0,
-                       0xffffffff,
-                       0xff,
-                       G_PARAM_READWRITE));
+    (gobject_class, PROP_COLOR,
+     g_param_spec_boxed ("color",
+                        "Color",
+                        "The color of the rectangle",
+                        CLUTTER_TYPE_COLOR,
+                        G_PARAM_READWRITE));
 
   g_type_class_add_private (gobject_class, sizeof (ClutterRectanglePrivate));
 }
@@ -173,13 +162,95 @@ static void
 clutter_rectangle_init (ClutterRectangle *self)
 {
   self->priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
+
+  self->priv->color.red = 0xff;
+  self->priv->color.green = 0xff;
+  self->priv->color.blue = 0xff;
+  self->priv->color.alpha = 0xff;
 }
 
+/**
+ * clutter_rectangle_new:
+ *
+ * Creates a new #ClutterElement with a rectangular shape.
+ *
+ * Return value: a new #ClutterElement
+ */
 ClutterElement*
-clutter_rectangle_new (guint32 colour)
+clutter_rectangle_new (void)
+{
+  return g_object_new (CLUTTER_TYPE_RECTANGLE, NULL);
+}
+
+/**
+ * clutter_rectangle_new_with_color:
+ * @color: a #ClutterColor
+ *
+ * Creates a new #ClutterElement with a rectangular shape
+ * and with @color.
+ *
+ * Return value: a new #ClutterElement
+ */
+ClutterElement *
+clutter_rectangle_new_with_color (const ClutterColor *color)
 {
   return g_object_new (CLUTTER_TYPE_RECTANGLE,
-                      "color", colour,
+                      "color", color,
                       NULL);
 }
 
+/**
+ * clutter_rectangle_get_color:
+ * @rectangle: a #ClutterRectangle
+ * @color: return location for a #ClutterColor
+ *
+ * Retrieves the color of @rectangle.
+ */
+void
+clutter_rectangle_get_color (ClutterRectangle *rectangle,
+                            ClutterColor     *color)
+{
+  ClutterRectanglePrivate *priv;
+  
+  g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
+  g_return_if_fail (color != NULL);
+
+  priv = rectangle->priv;
+
+  color->red = priv->color.red;
+  color->green = priv->color.green;
+  color->blue = priv->color.blue;
+  color->alpha = priv->color.alpha;
+}
+
+/**
+ * clutter_rectangle_set_color:
+ * @rectangle: a #ClutterRectangle
+ * @color: a #ClutterColor
+ *
+ * Sets the color of @rectangle.
+ */
+void
+clutter_rectangle_set_color (ClutterRectangle   *rectangle,
+                            const ClutterColor *color)
+{
+  ClutterRectanglePrivate *priv;
+  
+  g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
+  g_return_if_fail (color != NULL);
+
+  priv = rectangle->priv;
+
+  priv->color.red = color->red;
+  priv->color.green = color->green;
+  priv->color.blue = color->blue;
+  priv->color.alpha = color->alpha;
+
+  clutter_element_set_opacity (CLUTTER_ELEMENT (rectangle),
+                              priv->color.alpha);
+
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT (rectangle)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT (rectangle));
+
+  g_object_notify (G_OBJECT (rectangle), "color");
+}
index c13a91e..ef2c2dc 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <glib-object.h>
 #include <clutter/clutter-element.h>
+#include <clutter/clutter-color.h>
 
 G_BEGIN_DECLS
 
@@ -61,19 +62,30 @@ struct _ClutterRectangle
 {
   ClutterElement           parent;
 
-  /*< priv >*/
+  /*< private >*/
   ClutterRectanglePrivate *priv;
 }; 
 
 struct _ClutterRectangleClass 
 {
   ClutterElementClass parent_class;
+
+  /* padding for future expansion */
+  void (*_clutter_rectangle1) (void);
+  void (*_clutter_rectangle2) (void);
+  void (*_clutter_rectangle3) (void);
+  void (*_clutter_rectangle4) (void);
 };
 
-GType clutter_rectangle_get_type (void);
+GType clutter_rectangle_get_type (void) G_GNUC_CONST;
+
+ClutterElement *clutter_rectangle_new            (void);
+ClutterElement *clutter_rectangle_new_with_color (const ClutterColor *color);
 
-ClutterElement*
-clutter_rectangle_new (guint32 col);
+void            clutter_rectangle_get_color      (ClutterRectangle   *rectangle,
+                                                 ClutterColor       *color);
+void            clutter_rectangle_set_color      (ClutterRectangle   *rectangle,
+                                                 const ClutterColor *color);
 
 G_END_DECLS
 
index b59f109..4189fb9 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+
 #include "clutter-stage.h"
 #include "clutter-main.h"
 #include "clutter-color.h"
+#include "clutter-marshal.h"
+#include "clutter-enum-types.h"
 #include "clutter-private.h"   /* for DBG */
 
 #include <GL/glx.h>
 #include <GL/gl.h>
 
+/* the stage is a singleton instance */
+static ClutterStage *stage_singleton = NULL;
+
 G_DEFINE_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
 
-static ClutterElementClass *parent_class;
+#define CLUTTER_STAGE_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_STAGE, ClutterStagePrivate))
 
-struct ClutterStagePrivate
+struct _ClutterStagePrivate
 {
-  Window          xwin;  
-  Pixmap          xpixmap;
-  GLXPixmap       glxpixmap;
-  gint            xwin_width, xwin_height; /* FIXME target_width / height */
-  gboolean        want_fullscreen;
-  gboolean        want_offscreen;
-  gboolean        hide_cursor;
-  GLXContext      gl_context;
-  ClutterColor    color;
+  Window        xwin;  
+  Pixmap        xpixmap;
+  gint          xwin_width, xwin_height; /* FIXME target_width / height */
+  
+  GLXPixmap     glxpixmap;
+  GLXContext    gl_context;
+  
+  ClutterColor  color;
+  
+  guint         want_fullscreen : 1;
+  guint         want_offscreen  : 1;
+  guint         hide_cursor     : 1;
 };
 
 enum
 {
   PROP_0,
+  
+  PROP_COLOR,
   PROP_FULLSCREEN,
   PROP_OFFSCREEN,
   PROP_HIDE_CURSOR
@@ -58,11 +71,19 @@ enum
 
 enum
 {
-  SIGNAL_INPUT_EVENT,
+  INPUT_EVENT,
+  BUTTON_PRESS_EVENT,
+  BUTTON_RELEASE_EVENT,
+  KEY_PRESS_EVENT,
+  KEY_RELEASE_EVENT,
+  MOTION_EVENT,
+  
   LAST_SIGNAL
 };
 
-static int stage_signals[LAST_SIGNAL] = { 0 };
+static guint stage_signals[LAST_SIGNAL] = { 0 };
+
+static ClutterElementClass *parent_class = NULL;
 
 static void
 sync_fullscreen (ClutterStage *stage)
@@ -322,7 +343,7 @@ clutter_stage_realize (ClutterElement *element)
 static void
 clutter_stage_paint (ClutterElement *self)
 {
-  parent_class->paint(self);
+  parent_class->paint (self);
 }
 
 static void
@@ -343,8 +364,7 @@ clutter_stage_request_coords (ClutterElement    *self,
   ClutterStagePrivate *priv;
   gint                 new_width, new_height;
 
-  stage = CLUTTER_STAGE(self);
-
+  stage = CLUTTER_STAGE (self);
   priv = stage->priv;
 
   new_width  = ABS(box->x2 - box->x1);
@@ -381,13 +401,10 @@ clutter_stage_request_coords (ClutterElement    *self,
 static void 
 clutter_stage_dispose (GObject *object)
 {
-  ClutterStage *self = CLUTTER_STAGE(object);
+  ClutterStage *self = CLUTTER_STAGE (object);
 
-  if (self->priv)
-    {
-      if (self->priv->xwin)
-       clutter_stage_unrealize (CLUTTER_ELEMENT(self));
-    }
+  if (self->priv->xwin)
+    clutter_stage_unrealize (CLUTTER_ELEMENT (self));
 
   G_OBJECT_CLASS (clutter_stage_parent_class)->dispose (object);
 }
@@ -395,14 +412,6 @@ clutter_stage_dispose (GObject *object)
 static void 
 clutter_stage_finalize (GObject *object)
 {
-  ClutterStage *self = CLUTTER_STAGE(object);
-
-  if (self->priv)
-    {
-      g_free(self->priv);
-      self->priv = NULL;
-    }
-
   G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
 }
 
@@ -421,12 +430,15 @@ clutter_stage_set_property (GObject      *object,
 
   switch (prop_id) 
     {
+    case PROP_COLOR:
+      clutter_stage_set_color (stage, g_value_get_boxed (value));
+      break;
     case PROP_OFFSCREEN:
       if (priv->want_offscreen != g_value_get_boolean (value))
        {
-         clutter_element_unrealize(CLUTTER_ELEMENT(stage));
+         clutter_element_unrealize (CLUTTER_ELEMENT(stage));
          priv->want_offscreen = g_value_get_boolean (value);
-         clutter_element_realize(CLUTTER_ELEMENT(stage));
+         clutter_element_realize (CLUTTER_ELEMENT(stage));
        }
       break;
     case PROP_FULLSCREEN:
@@ -457,12 +469,17 @@ clutter_stage_get_property (GObject    *object,
 {
   ClutterStage        *stage;
   ClutterStagePrivate *priv;
+  ClutterColor         color;
 
   stage = CLUTTER_STAGE(object);
   priv = stage->priv;
 
   switch (prop_id) 
     {
+    case PROP_COLOR:
+      clutter_stage_get_color (stage, &color);
+      g_value_set_boxed (value, &color);
+      break;
     case PROP_OFFSCREEN:
       g_value_set_boolean (value, priv->want_offscreen);
       break;
@@ -481,13 +498,10 @@ clutter_stage_get_property (GObject    *object,
 static void
 clutter_stage_class_init (ClutterStageClass *klass)
 {
-  GObjectClass        *gobject_class;
-  ClutterElementClass *element_class;
-  ClutterGroupClass     *group_class;
+  GObjectClass        *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterElementClass *element_class = CLUTTER_ELEMENT_CLASS (klass);
 
-  gobject_class = (GObjectClass*)klass;
-  element_class = (ClutterElementClass*)klass;
-  group_class     = (ClutterGroupClass*)klass;
+  parent_class = g_type_class_peek_parent (klass);
 
   element_class->realize    = clutter_stage_realize;
   element_class->unrealize  = clutter_stage_unrealize;
@@ -503,15 +517,18 @@ clutter_stage_class_init (ClutterStageClass *klass)
   gobject_class->set_property = clutter_stage_set_property;
   gobject_class->get_property = clutter_stage_get_property;
 
-  parent_class = g_type_class_peek_parent(group_class);
-
+  /**
+   * ClutterStage:fullscreen
+   *
+   * Whether the stage should be fullscreen or not.
+   */
   g_object_class_install_property
     (gobject_class, PROP_FULLSCREEN,
      g_param_spec_boolean ("fullscreen",
                           "Fullscreen",
                           "Make Clutter stage fullscreen",
                           FALSE,
-                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+                          G_PARAM_READWRITE));
 
   g_object_class_install_property
     (gobject_class, PROP_OFFSCREEN,
@@ -519,7 +536,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
                           "Offscreen",
                           "Make Clutter stage offscreen",
                           FALSE,
-                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+                          G_PARAM_READWRITE));
 
 
   g_object_class_install_property
@@ -528,34 +545,129 @@ clutter_stage_class_init (ClutterStageClass *klass)
                           "Hide Cursor",
                           "Make Clutter stage cursor-less",
                           FALSE,
-                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+                          G_PARAM_READWRITE));
 
-  stage_signals[SIGNAL_INPUT_EVENT] =
+  g_object_class_install_property
+    (gobject_class, PROP_COLOR,
+     g_param_spec_boxed ("color",
+                        "Color",
+                        "The color of the stage",
+                        CLUTTER_TYPE_COLOR,
+                        G_PARAM_READWRITE));
+
+  stage_signals[INPUT_EVENT] =
     g_signal_new ("input-event",
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (ClutterStageClass, input_event),
                  NULL, NULL,
-                 g_cclosure_marshal_VOID__POINTER,
-                 G_TYPE_NONE, 
-                 1, G_TYPE_POINTER);
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  stage_signals[BUTTON_PRESS_EVENT] =
+    g_signal_new ("button-press-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, button_press_event),
+                 NULL, NULL,
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  stage_signals[BUTTON_RELEASE_EVENT] =
+    g_signal_new ("button-release-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, button_release_event),
+                 NULL, NULL,
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  stage_signals[BUTTON_PRESS_EVENT] =
+    g_signal_new ("key-press-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, key_press_event),
+                 NULL, NULL,
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  stage_signals[BUTTON_RELEASE_EVENT] =
+    g_signal_new ("key-release-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, key_release_event),
+                 NULL, NULL,
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  stage_signals[MOTION_EVENT] =
+    g_signal_new ("motion-event",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (ClutterStageClass, motion_event),
+                 NULL, NULL,
+                 clutter_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 CLUTTER_TYPE_EVENT);
+  
+  g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
 }
 
 static void
 clutter_stage_init (ClutterStage *self)
 {
   ClutterStagePrivate *priv;
+  
+  self->priv = priv = CLUTTER_STAGE_GET_PRIVATE (self);
 
-  priv        = g_new0 (ClutterStagePrivate, 1);
+  priv->want_offscreen = FALSE;
+  priv->want_fullscreen = FALSE;
+  priv->hide_cursor = FALSE;
 
   priv->xwin_width  = 100;
   priv->xwin_height = 100;
-  priv->color       = 0xffffffff;
-  self->priv  = priv;
 
-  clutter_element_set_size (CLUTTER_ELEMENT(self), 640, 480);
+  priv->color.red   = 0xff;
+  priv->color.green = 0xff;
+  priv->color.blue  = 0xff;
+  priv->color.alpha = 0xff;
+  
+  clutter_element_set_size (CLUTTER_ELEMENT (self), 640, 480);
+}
+
+/**
+ * clutter_stage_get_default:
+ *
+ * Returns the main stage.  #ClutterStage is a singleton, so
+ * the stage will be created the first time this function is
+ * called (typically, inside clutter_init()); all the subsequent
+ * calls to clutter_stage_get_default() will return the same
+ * instance, with its reference count increased.
+ *
+ * Return value: the main #ClutterStage.  Use g_object_unref()
+ *   when finished using it.
+ */
+ClutterElement *
+clutter_stage_get_default (void)
+{
+  ClutterElement *retval = NULL;
+  
+  if (!stage_singleton)
+    {
+      stage_singleton = g_object_new (CLUTTER_TYPE_STAGE, NULL);
+      retval = CLUTTER_ELEMENT (stage_singleton);
+    }
+  else
+    {
+      retval = CLUTTER_ELEMENT (stage_singleton);
+      g_object_ref (retval);
+    }
+
+  return retval;
+  
 }
 
+
 /**
  * clutter_stage_get_xwindow
  * @stage: A #ClutterStage
@@ -578,42 +690,66 @@ clutter_stage_get_xwindow (ClutterStage *stage)
  * Set the stage color.
  **/
 void
-clutter_stage_set_color (ClutterStage *stage,
-                        ClutterColor  color)
+clutter_stage_set_color (ClutterStage       *stage,
+                        const ClutterColor *color)
 {
-  stage->priv->color = color;
+  ClutterStagePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_STAGE (stage));
+  g_return_if_fail (color != NULL);
+  
+  priv = stage->priv;
+  priv->color.red = color->red;
+  priv->color.green = color->green;
+  priv->color.blue = color->blue;
+  priv->color.alpha = color->alpha;
 
-  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(stage)))
-    clutter_element_queue_redraw (CLUTTER_ELEMENT(stage));
+  if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT (stage)))
+    clutter_element_queue_redraw (CLUTTER_ELEMENT (stage));
+  
+  g_object_notify (G_OBJECT (stage), "color");
 }
 
 /**
- * clutter_stage_set_color
+ * clutter_stage_get_color
  * @stage: A #ClutterStage
+ * @color: return location for a #ClutterColor
  * 
  * Request the stage color.
- * 
- * Return Value: The stages #ClutterColor
- **/
-ClutterColor
-clutter_stage_get_color (ClutterStage *stage)
+ */
+void
+clutter_stage_get_color (ClutterStage *stage,
+                        ClutterColor *color)
 {
-  return stage->priv->color;
+  ClutterStagePrivate *priv;
+  
+  g_return_if_fail (CLUTTER_IS_STAGE (stage));
+  g_return_if_fail (color != NULL);
+
+  priv = stage->priv;
+  
+  color->red = priv->color.red;
+  color->green = priv->color.green;
+  color->blue = priv->color.blue;
+  color->alpha = priv->color.alpha;
 }
 
 static void
-snapshot_pixbuf_free(guchar  *pixels, gpointer data)
+snapshot_pixbuf_free (guchar   *pixels,
+                     gpointer  data)
 {
   g_free(pixels);
 }
 
 /**
  * clutter_stage_snapshot
- * @stage A #ClutterStage
- * @x     x  coordinate of the first pixel that is read from stage
- * @y     y  coordinate of the first pixel that is read from stage
- * @width Width dimention of pixels to be read.
- * @height Height dimention of pixels to be read.
+ * @stage: A #ClutterStage
+ * @x: x coordinate of the first pixel that is read from stage
+ * @y: y coordinate of the first pixel that is read from stage
+ * @width: Width dimention of pixels to be read, or -1 for the
+ *   entire stage width
+ * @height: Height dimention of pixels to be read, or -1 for the
+ *   entire stage height
  *
  * Gets a pixel based representation of the current rendered stage.
  *
@@ -623,16 +759,28 @@ GdkPixbuf*
 clutter_stage_snapshot (ClutterStage *stage,
                        gint          x,
                        gint          y,
-                       guint         width,
-                       guint         height)
+                       gint          width,
+                       gint          height)
 {
   guchar    *data;
   GdkPixbuf *pixb, *fpixb;
+  ClutterElement *element;
+
+  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
+  g_return_val_if_fail (x >= 0 && y >= 0, NULL);
 
-  data = g_malloc0(sizeof(guchar)*width*height*3);
+  element = CLUTTER_ELEMENT (stage);
+
+  if (width < 0)
+    width = clutter_element_get_width (element);
+
+  if (height < 0)
+    height = clutter_element_get_height (element);
+
+  data = g_malloc0 (sizeof (guchar) * width * height * 3);
 
   glReadPixels (x, 
-               clutter_element_get_height(CLUTTER_ELEMENT(clutter_stage())
+               clutter_element_get_height (element
                - y - height,
                width, 
                height, GL_RGB, GL_UNSIGNED_BYTE, data);
@@ -657,9 +805,21 @@ clutter_stage_snapshot (ClutterStage *stage,
   return fpixb;
 }
 
-/* FIXME: better name - pos_to_element */
+/**
+ * clutter_stage_get_element_at_pos:
+ * @stage: a #ClutterStage
+ * @x: the x coordinate
+ * @y: the y coordinate
+ *
+ * If found, retrieves the element that the (x, y) coordinates.
+ *
+ * Return value: the #ClutterElement at the desired coordinates,
+ *   or %NULL if no element was found.
+ */
 ClutterElement*
-clutter_stage_pick (ClutterStage *stage, gint x, gint y)
+clutter_stage_get_element_at_pos (ClutterStage *stage,
+                                 gint          x,
+                                 gint          y)
 {
   ClutterElement *found = NULL;
   GLuint          buff[64] = {0};
@@ -686,7 +846,7 @@ clutter_stage_pick (ClutterStage *stage, gint x, gint y)
 
   glMatrixMode(GL_MODELVIEW);
 
-  clutter_element_paint(CLUTTER_ELEMENT(stage));
+  clutter_element_paint (CLUTTER_ELEMENT (stage));
 
   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
@@ -695,14 +855,13 @@ clutter_stage_pick (ClutterStage *stage, gint x, gint y)
 
   if (hits != 0)
     {
-      /*
-      int i;    
-
-      for (i=0; i<hits; i++)
+#if 0
+      gint i
+      for (i = 0; i < hits; i++)
        g_print ("Hit at %i\n", buff[i * 4 + 3]);
-      */
+#endif
   
-      found = clutter_group_find_child_by_id (clutter_stage(), buff[3]);
+      found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage), buff[3]);
     }
   
   sync_gl_viewport (stage);
index 25e189c..94a46df 100644 (file)
@@ -68,13 +68,15 @@ G_BEGIN_DECLS
   (G_TYPE_INSTANCE_GET_CLASS ((obj), \
   CLUTTER_TYPE_STAGE, ClutterStageClass))
 
-typedef struct ClutterStagePrivate ClutterStagePrivate;
-typedef struct _ClutterStage       ClutterStage;
-typedef struct _ClutterStageClass  ClutterStageClass;
+typedef struct _ClutterStagePrivate ClutterStagePrivate;
+typedef struct _ClutterStage        ClutterStage;
+typedef struct _ClutterStageClass   ClutterStageClass;
 
 struct _ClutterStage
 {
   ClutterGroup         parent;
+  
+  /*< private >*/
   ClutterStagePrivate *priv;
 }; 
 
@@ -82,35 +84,50 @@ struct _ClutterStageClass
 {
   ClutterGroupClass parent_class;
 
-  void (*input_event) (ClutterStage *stage,
-                      ClutterEvent *event);
+  void (*input_event)          (ClutterStage       *stage,
+                               ClutterEvent       *event);
+  void (*button_press_event)   (ClutterStage       *stage,
+                               ClutterButtonEvent *event);
+  void (*button_release_event) (ClutterStage       *stage,
+                               ClutterButtonEvent *event);
+  void (*key_press_event)      (ClutterStage       *stage,
+                               ClutterKeyEvent    *event);
+  void (*key_release_event)    (ClutterStage       *stage,
+                               ClutterKeyEvent    *event);
+  void (*motion_event)         (ClutterStage       *stage,
+                               ClutterMotionEvent *event);
+
+  /* padding for future expansion */
+  void (*_clutter_stage1) (void);
+  void (*_clutter_stage2) (void);
+  void (*_clutter_stage3) (void);
+  void (*_clutter_stage4) (void);
+  void (*_clutter_stage5) (void);
+  void (*_clutter_stage6) (void);
 }; 
 
-GType clutter_stage_get_type (void);
+GType           clutter_stage_get_type           (void);
+
+ClutterElement *clutter_stage_get_default        (void);
 
 /* FIXME: no need for below to take stage arg ? 
  *        convert to defines also ?
 */
 
-Window
-clutter_stage_get_xwindow (ClutterStage *stage);
-
-void
-clutter_stage_set_color (ClutterStage *stage,
-                        ClutterColor  color);
-
-ClutterColor
-clutter_stage_get_color (ClutterStage *stage);
-
-GdkPixbuf*
-clutter_stage_snapshot (ClutterStage *stage,
-                       gint          x,
-                       gint          y,
-                       guint         width,
-                       guint         height);
-
-ClutterElement*
-clutter_stage_pick (ClutterStage *stage, gint x, gint y);
+Window          clutter_stage_get_xwindow        (ClutterStage *stage);
+
+void            clutter_stage_set_color          (ClutterStage       *stage,
+                                                 const ClutterColor *color);
+void            clutter_stage_get_color          (ClutterStage       *stage,
+                                                 ClutterColor       *color);
+ClutterElement *clutter_stage_get_element_at_pos (ClutterStage       *stage,
+                                                 gint                x,
+                                                 gint                y);
+GdkPixbuf *     clutter_stage_snapshot           (ClutterStage       *stage,
+                                                 gint                x,
+                                                 gint                y,
+                                                 gint                width,
+                                                 gint                height);
 
 G_END_DECLS
 
index 487e8fc..0383960 100644 (file)
@@ -1,29 +1,30 @@
 <SECTION>
 <FILE>clutter-label</FILE>
+ClutterLabelPrivate
 <TITLE>ClutterLabel</TITLE>
 ClutterLabel
-ClutterLabelClass
-clutter_label_new_with_text
 clutter_label_new
+clutter_label_new_with_text
 clutter_label_set_text
-clutter_label_set_font
+clutter_label_get_text
+clutter_label_set_font_name
+clutter_label_get_font_name
 clutter_label_set_color
+clutter_label_get_color
 clutter_label_set_text_extents
+clutter_label_get_text_extents
 <SUBSECTION Standard>
 CLUTTER_LABEL
 CLUTTER_IS_LABEL
 CLUTTER_TYPE_LABEL
+clutter_label_get_type
 CLUTTER_LABEL_CLASS
 CLUTTER_IS_LABEL_CLASS
 CLUTTER_LABEL_GET_CLASS
-<SUBSECTION Private>
-ClutterLabelPrivate
-clutter_label_get_type
 </SECTION>
 
 <SECTION>
 <FILE>clutter-element</FILE>
-<TITLE>ClutterElement</TITLE>
 CLUTTER_TYPE_GEOMETRY
 CLUTTER_TYPE_ELEMENT_BOX
 CLUTTER_ELEMENT_SET_FLAGS
@@ -32,12 +33,14 @@ CLUTTER_ELEMENT_IS_MAPPED
 CLUTTER_ELEMENT_IS_REALIZED
 CLUTTER_ELEMENT_IS_VISIBLE
 ClutterElementBox
+ClutterElementPrivate
 ClutterGeometry
+ClutterCallback
 ClutterElementTransform
 ClutterElementFlags
 clutter_element_box_get_type
+<TITLE>ClutterElement</TITLE>
 ClutterElement
-ClutterElementClass
 clutter_element_get_type
 clutter_element_show
 clutter_element_hide
@@ -77,12 +80,10 @@ clutter_element_lower_bottom
 CLUTTER_ELEMENT
 CLUTTER_IS_ELEMENT
 CLUTTER_TYPE_ELEMENT
+clutter_geometry_get_type
 CLUTTER_ELEMENT_CLASS
 CLUTTER_IS_ELEMENT_CLASS
 CLUTTER_ELEMENT_GET_CLASS
-<SUBSECTION Private>
-clutter_geometry_get_type
-ClutterElementPrivate
 </SECTION>
 
 <SECTION>
@@ -91,6 +92,8 @@ ClutterGroupPrivate
 <TITLE>ClutterGroup</TITLE>
 ClutterGroup
 clutter_group_new
+clutter_group_get_children
+clutter_group_foreach
 clutter_group_add
 clutter_group_add_many_valist
 clutter_group_add_many
@@ -162,7 +165,7 @@ ClutterStage
 clutter_stage_get_xwindow
 clutter_stage_set_color
 clutter_stage_get_color
-clutter_stage_pick
+clutter_stage_get_element_at_pos
 <SUBSECTION Standard>
 CLUTTER_STAGE
 CLUTTER_IS_STAGE
@@ -174,22 +177,6 @@ CLUTTER_STAGE_GET_CLASS
 </SECTION>
 
 <SECTION>
-<FILE>clutter-rectangle</FILE>
-ClutterRectanglePrivate
-<TITLE>ClutterRectangle</TITLE>
-ClutterRectangle
-clutter_rectangle_new
-<SUBSECTION Standard>
-CLUTTER_RECTANGLE
-CLUTTER_IS_RECTANGLE
-CLUTTER_TYPE_RECTANGLE
-clutter_rectangle_get_type
-CLUTTER_RECTANGLE_CLASS
-CLUTTER_IS_RECTANGLE_CLASS
-CLUTTER_RECTANGLE_GET_CLASS
-</SECTION>
-
-<SECTION>
 <FILE>clutter-video-texture</FILE>
 ClutterVideoTexturePrivate
 CLUTTER_VIDEO_TEXTURE_ERROR
@@ -229,6 +216,25 @@ CLUTTER_VIDEO_TEXTURE_GET_CLASS
 </SECTION>
 
 <SECTION>
+<FILE>clutter-rectangle</FILE>
+ClutterRectanglePrivate
+<TITLE>ClutterRectangle</TITLE>
+ClutterRectangle
+clutter_rectangle_new
+clutter_rectangle_new_with_color
+clutter_rectangle_get_color
+clutter_rectangle_set_color
+<SUBSECTION Standard>
+CLUTTER_RECTANGLE
+CLUTTER_IS_RECTANGLE
+CLUTTER_TYPE_RECTANGLE
+clutter_rectangle_get_type
+CLUTTER_RECTANGLE_CLASS
+CLUTTER_IS_RECTANGLE_CLASS
+CLUTTER_RECTANGLE_GET_CLASS
+</SECTION>
+
+<SECTION>
 <FILE>clutter-timeline</FILE>
 ClutterTimelinePrivate
 <TITLE>ClutterTimeline</TITLE>
@@ -244,6 +250,7 @@ clutter_timeline_skip
 clutter_timeline_advance
 clutter_timeline_get_current_frame
 clutter_timeline_get_n_frames
+clutter_timeline_is_playing
 <SUBSECTION Standard>
 CLUTTER_TIMELINE
 CLUTTER_IS_TIMELINE
@@ -262,18 +269,16 @@ clutter_util_can_create_texture
 
 <SECTION>
 <FILE>clutter-color</FILE>
-clutter_color_r
-clutter_color_g
-clutter_color_b
-clutter_color_a
-clutter_color_set_r
-clutter_color_set_g
-clutter_color_set_b
-clutter_color_set_a
+CLUTTER_TYPE_COLOR
 ClutterColor
-clutter_color_new
-clutter_color_set
-clutter_color_get
+clutter_color_get_type
+clutter_color_add
+clutter_color_subtract
+clutter_color_lighten
+clutter_color_darken
+clutter_color_shade
+clutter_color_to_hls
+clutter_color_from_hls
 </SECTION>
 
 <SECTION>
@@ -1683,7 +1688,3 @@ CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE
 clutter_video_texture_metadata_type_get_type
 </SECTION>
 
-<SECTION>
-<FILE>stamp-clutter-enum-types</FILE>
-</SECTION>
-
index 8f7b8b8..3caf6a8 100644 (file)
@@ -1,12 +1,14 @@
-<!-- ##### STRUCT ClutterElementPrivate ##### -->
+<!-- ##### FUNCTION clutter_gl_context ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### STRUCT ClutterLabelPrivate ##### -->
+<!-- ##### FUNCTION clutter_stage ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
index 84abd7d..1beefbd 100644 (file)
@@ -17,113 +17,98 @@ clutter-color
 <!-- ##### SECTION Stability_Level ##### -->
 
 
-<!-- ##### MACRO clutter_color_r ##### -->
+<!-- ##### MACRO CLUTTER_TYPE_COLOR ##### -->
 <para>
 
 </para>
 
-@col: 
 
 
-<!-- ##### MACRO clutter_color_g ##### -->
+<!-- ##### STRUCT ClutterColor ##### -->
 <para>
 
 </para>
 
-@col: 
+@red: 
+@green: 
+@blue: 
+@alpha: 
 
-
-<!-- ##### MACRO clutter_color_b ##### -->
-<para>
-
-</para>
-
-@col: 
-
-
-<!-- ##### MACRO clutter_color_a ##### -->
+<!-- ##### FUNCTION clutter_color_get_type ##### -->
 <para>
 
 </para>
 
-@col
+@Returns
 
 
-<!-- ##### MACRO clutter_color_set_r ##### -->
+<!-- ##### FUNCTION clutter_color_add ##### -->
 <para>
 
 </para>
 
-@col: 
-@r: 
+@src1: 
+@src2: 
+@dest: 
 
 
-<!-- ##### MACRO clutter_color_set_g ##### -->
+<!-- ##### FUNCTION clutter_color_subtract ##### -->
 <para>
 
 </para>
 
-@col: 
-@g: 
+@src1: 
+@src2: 
+@dest: 
 
 
-<!-- ##### MACRO clutter_color_set_b ##### -->
+<!-- ##### FUNCTION clutter_color_lighten ##### -->
 <para>
 
 </para>
 
-@col
-@b
+@src
+@dest
 
 
-<!-- ##### MACRO clutter_color_set_a ##### -->
+<!-- ##### FUNCTION clutter_color_darken ##### -->
 <para>
 
 </para>
 
-@col
-@a
+@src
+@dest
 
 
-<!-- ##### TYPEDEF ClutterColor ##### -->
+<!-- ##### FUNCTION clutter_color_shade ##### -->
 <para>
 
 </para>
 
-
-<!-- ##### FUNCTION clutter_color_new ##### -->
-<para>
-
-</para>
-
-@r: 
-@g: 
-@b: 
-@a: 
-@Returns: 
+@src: 
+@dest: 
+@shade: 
 
 
-<!-- ##### FUNCTION clutter_color_set ##### -->
+<!-- ##### FUNCTION clutter_color_to_hls ##### -->
 <para>
 
 </para>
 
-@color: 
-@r: 
-@g: 
-@b: 
-@a: 
+@src: 
+@hue: 
+@luminance: 
+@saturation: 
 
 
-<!-- ##### FUNCTION clutter_color_get ##### -->
+<!-- ##### FUNCTION clutter_color_from_hls ##### -->
 <para>
 
 </para>
 
-@color: 
-@r: 
-@g: 
-@b: 
-@a: 
+@dest: 
+@hue: 
+@luminance: 
+@saturation: 
 
 
index 779d565..ed9d546 100644 (file)
@@ -83,6 +83,12 @@ ClutterElement
 @x2: 
 @y2: 
 
+<!-- ##### STRUCT ClutterElementPrivate ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### STRUCT ClutterGeometry ##### -->
 <para>
 
@@ -93,6 +99,15 @@ ClutterElement
 @width: 
 @height: 
 
+<!-- ##### USER_FUNCTION ClutterCallback ##### -->
+<para>
+
+</para>
+
+@element: 
+@data: 
+
+
 <!-- ##### ENUM ClutterElementTransform ##### -->
 <para>
 
@@ -125,25 +140,6 @@ ClutterElement
 @parent: 
 @flags: 
 
-<!-- ##### STRUCT ClutterElementClass ##### -->
-<para>
-
-</para>
-
-@parent_class: 
-@show: 
-@hide: 
-@realize: 
-@unrealize: 
-@paint: 
-@request_coords: 
-@allocate_coords: 
-@set_depth: 
-@get_depth: 
-@show_all: 
-@hide_all: 
-@queue_redraw: 
-
 <!-- ##### FUNCTION clutter_element_get_type ##### -->
 <para>
 
index debc0a6..473b508 100644 (file)
@@ -22,6 +22,7 @@ clutter-event
 
 </para>
 
+@CLUTTER_NOTHING: 
 @CLUTTER_KEY_PRESS: 
 @CLUTTER_KEY_RELEASE: 
 @CLUTTER_MOTION: 
index 71b1d49..eafd55c 100644 (file)
@@ -38,6 +38,25 @@ ClutterGroup
 @Returns: 
 
 
+<!-- ##### FUNCTION clutter_group_get_children ##### -->
+<para>
+
+</para>
+
+@self: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_group_foreach ##### -->
+<para>
+
+</para>
+
+@self: 
+@callback: 
+@user_data: 
+
+
 <!-- ##### FUNCTION clutter_group_add ##### -->
 <para>
 
index 453ffb4..383363a 100644 (file)
@@ -17,6 +17,12 @@ ClutterLabel
 <!-- ##### SECTION Stability_Level ##### -->
 
 
+<!-- ##### STRUCT ClutterLabelPrivate ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### STRUCT ClutterLabel ##### -->
 <para>
 
@@ -24,46 +30,58 @@ ClutterLabel
 
 @parent: 
 
-<!-- ##### STRUCT ClutterLabelClass ##### -->
+<!-- ##### FUNCTION clutter_label_new ##### -->
 <para>
 
 </para>
 
+@Returns: 
+
 
 <!-- ##### FUNCTION clutter_label_new_with_text ##### -->
 <para>
 
 </para>
 
-@font_desc
+@font_name
 @text: 
 @Returns: 
 
 
-<!-- ##### FUNCTION clutter_label_new ##### -->
+<!-- ##### FUNCTION clutter_label_set_text ##### -->
 <para>
 
 </para>
 
+@label: 
+@text: 
+
+
+<!-- ##### FUNCTION clutter_label_get_text ##### -->
+<para>
+
+</para>
+
+@label: 
 @Returns: 
 
 
-<!-- ##### FUNCTION clutter_label_set_text ##### -->
+<!-- ##### FUNCTION clutter_label_set_font_name ##### -->
 <para>
 
 </para>
 
 @label: 
-@text
+@font_name
 
 
-<!-- ##### FUNCTION clutter_label_set_font ##### -->
+<!-- ##### FUNCTION clutter_label_get_font_name ##### -->
 <para>
 
 </para>
 
 @label: 
-@desc
+@Returns
 
 
 <!-- ##### FUNCTION clutter_label_set_color ##### -->
@@ -72,7 +90,16 @@ ClutterLabel
 </para>
 
 @label: 
-@pixel: 
+@color: 
+
+
+<!-- ##### FUNCTION clutter_label_get_color ##### -->
+<para>
+
+</para>
+
+@label: 
+@color: 
 
 
 <!-- ##### FUNCTION clutter_label_set_text_extents ##### -->
@@ -85,3 +112,13 @@ ClutterLabel
 @height: 
 
 
+<!-- ##### FUNCTION clutter_label_get_text_extents ##### -->
+<para>
+
+</para>
+
+@label: 
+@width: 
+@height: 
+
+
index 38ad5c6..b9dbae3 100644 (file)
@@ -33,6 +33,15 @@ clutter-main
 @a...:
 @a...:
 @a...:
+@a...:
+@a...:
+@a...:
+@a...:
+@a...:
+@a...:
+@a...:
+@a...:
+@a...:
 @a...: 
 
 
@@ -67,14 +76,6 @@ clutter-main
 
 
 
-<!-- ##### FUNCTION clutter_stage ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### FUNCTION clutter_redraw ##### -->
 <para>
 
@@ -106,14 +107,6 @@ clutter-main
 @Returns: 
 
 
-<!-- ##### FUNCTION clutter_gl_context ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### FUNCTION clutter_want_debug ##### -->
 <para>
 
index 29e7205..2da2dbf 100644 (file)
@@ -29,14 +29,39 @@ ClutterRectangle
 </para>
 
 @parent: 
-@priv: 
 
 <!-- ##### FUNCTION clutter_rectangle_new ##### -->
 <para>
 
 </para>
 
-@col: 
 @Returns: 
 
 
+<!-- ##### FUNCTION clutter_rectangle_new_with_color ##### -->
+<para>
+
+</para>
+
+@color: 
+@Returns: 
+
+
+<!-- ##### FUNCTION clutter_rectangle_get_color ##### -->
+<para>
+
+</para>
+
+@rectangle: 
+@color: 
+
+
+<!-- ##### FUNCTION clutter_rectangle_set_color ##### -->
+<para>
+
+</para>
+
+@rectangle: 
+@color: 
+
+
index 58ce359..6beacb1 100644 (file)
@@ -31,7 +31,7 @@ ClutterStage
 
 
 
-<!-- ##### TYPEDEF ClutterStagePrivate ##### -->
+<!-- ##### STRUCT ClutterStagePrivate ##### -->
 <para>
 
 </para>
@@ -43,7 +43,6 @@ ClutterStage
 </para>
 
 @parent: 
-@priv: 
 
 <!-- ##### FUNCTION clutter_stage_get_xwindow ##### -->
 <para>
@@ -69,10 +68,10 @@ ClutterStage
 </para>
 
 @stage: 
-@Returns
+@color
 
 
-<!-- ##### FUNCTION clutter_stage_pick ##### -->
+<!-- ##### FUNCTION clutter_stage_get_element_at_pos ##### -->
 <para>
 
 </para>
index 4cb93a1..6876b1f 100644 (file)
@@ -127,3 +127,12 @@ ClutterTimeline
 @Returns: 
 
 
+<!-- ##### FUNCTION clutter_timeline_is_playing ##### -->
+<para>
+
+</para>
+
+@timeline: 
+@Returns: 
+
+
index 4663e40..e0b71cc 100755 (executable)
@@ -2,16 +2,29 @@
 
 import clutter
 
-stage = clutter.stage()
+def on_stage_add (group, element):
+    print 'Adding element:', element
+
+stage = clutter.stage_get_default()
 stage.set_size(800,600)
+stage.set_color(0x6d, 0x6d, 0x70, 0xff)
+stage.connect('button-press-event', clutter.main_quit)
+stage.connect('add', on_stage_add)
+
+print "stage color: ", stage.get_color()
 
+rect = None
 for i in range(1, 10):
-    rect = clutter.Rectangle(0x0000ff33)
+    #rect = clutter.Rectangle(0x0000ff33)
+    rect = clutter.Rectangle()
+    rect.set_color(0x35, 0x99, 0x2a, 0x66)
     rect.set_position((800 - (80 * i)) / 2, (600 - (60 * i)) / 2)
     rect.set_size(80 * i,60 * i)
     stage.add(rect)
     rect.show()
 
+stage.connect('button-press-event', clutter.main_quit)
+
 stage.show()
 
 clutter.main()
index 4937e91..cacc711 100644 (file)
@@ -25,15 +25,29 @@ input_cb (ClutterStage *stage,
 
   if (event->type == CLUTTER_BUTTON_PRESS)
     {
+      ClutterButtonEvent *bev = (ClutterButtonEvent *) event;
       ClutterElement *e;
 
-      e = clutter_stage_pick (stage, 
-                             clutter_button_event_x(event),
-                             clutter_button_event_y(event));
+      g_print ("*** button press event (button:%d) ***\n",
+              bev->button);
+
+      e = clutter_stage_get_element_at_pos (stage, 
+                                           clutter_button_event_x (event),
+                                           clutter_button_event_y (event));
 
       if (e)
        clutter_element_hide(e);
     }
+  else if (event->type == CLUTTER_KEY_PRESS)
+    {
+      ClutterKeyEvent *kev = (ClutterKeyEvent *) event;
+
+      g_print ("*** key press event (key:%c) ***\n",
+              clutter_key_event_symbol (kev));
+      
+      if (clutter_key_event_symbol (kev) == CLUTTER_q)
+       clutter_main_quit ();
+    }
 }
 
 
@@ -43,14 +57,18 @@ frame_cb (ClutterTimeline *timeline,
          gint             frame_num, 
          gpointer         data)
 {
-  SuperOH *oh = (SuperOH *)data;
-  gint     i;
+  SuperOH        *oh = (SuperOH *)data;
+  ClutterElement *stage = clutter_stage_get_default ();
+  gint            i;
 
 #if TRAILS
-  oh->bgpixb = clutter_stage_snapshot (CLUTTER_STAGE(clutter_stage()),
-                                      0, 0, WINWIDTH, WINHEIGHT);
-  clutter_texture_set_pixbuf(CLUTTER_TEXTURE(oh->bgtex), oh->bgpixb);
-  g_object_unref(G_OBJECT(oh->bgpixb));
+  oh->bgpixb = clutter_stage_snapshot (CLUTTER_STAGE (stage),
+                                      0, 0,
+                                      WINWIDTH,
+                                      WINHEIGHT);
+  clutter_texture_set_pixbuf (CLUTTER_TEXTURE (oh->bgtex), oh->bgpixb);
+  g_object_unref (G_OBJECT (oh->bgpixb));
+  g_object_unref (stage);
 #endif
 
   /* Rotate everything clockwise about stage center*/
@@ -78,23 +96,39 @@ int
 main (int argc, char *argv[])
 {
   ClutterTimeline *timeline;
+  ClutterElement  *stage;
+  ClutterColor     stage_color = { 0x61, 0x64, 0x8c, 0xff };
   GdkPixbuf       *pixbuf;
   SuperOH         *oh;
   gint             i;
 
   clutter_init (&argc, &argv);
 
+  stage = clutter_stage_get_default ();
+
   pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
 
   if (!pixbuf)
     g_error("pixbuf load failed");
 
   /* Set our stage (window) size */
-  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()),
-                           WINWIDTH, WINHEIGHT);
+  clutter_element_set_size (stage, WINWIDTH, WINHEIGHT);
 
   /* and its background color */
-  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0x61648cff);
+  g_print ("before clutter_stage_set_color: (%3d, %3d, %3d, %3d)\n",
+          stage_color.red,
+          stage_color.green,
+          stage_color.blue,
+          stage_color.alpha);
+  clutter_stage_set_color (CLUTTER_STAGE (stage),
+                          &stage_color);
+  clutter_stage_get_color (CLUTTER_STAGE (stage),
+                          &stage_color);
+  g_print ("after clutter_stage_get_color:  (%3d, %3d, %3d, %3d)\n",
+          stage_color.red,
+          stage_color.green,
+          stage_color.blue,
+          stage_color.alpha);
 
   oh = g_new(SuperOH, 1);
 
@@ -102,7 +136,7 @@ main (int argc, char *argv[])
   oh->bgtex = clutter_texture_new();
   clutter_element_set_size (oh->bgtex, WINWIDTH, WINHEIGHT);
   clutter_element_set_opacity (oh->bgtex, 0x99);
-  clutter_group_add (clutter_stage(), oh->bgtex);
+  clutter_group_add (CLUTTER_GROUP (stage), oh->bgtex);
 #endif
 
   /* create a new group to hold multiple elements in a group */
@@ -132,15 +166,18 @@ main (int argc, char *argv[])
     }
 
   /* Add the group to the stage */
-  clutter_group_add (clutter_stage(), CLUTTER_ELEMENT(oh->group));
+  clutter_group_add (CLUTTER_GROUP (stage), CLUTTER_ELEMENT(oh->group));
 
   /* Show everying ( and map window ) */
   clutter_group_show_all (oh->group);
-  clutter_group_show_all (clutter_stage());
+  clutter_group_show_all (CLUTTER_GROUP (stage));
 
-  g_signal_connect (clutter_stage(), "input-event",
+  g_signal_connect (stage, "button-press-event",
                    G_CALLBACK (input_cb), 
                    oh);
+  g_signal_connect (stage, "key-release-event",
+                   G_CALLBACK (input_cb),
+                   oh);
 
   /* Create a timeline to manage animation */
   timeline = clutter_timeline_new (360, 60); /* num frames, fps */
@@ -154,5 +191,7 @@ main (int argc, char *argv[])
 
   clutter_main();
 
+  g_object_unref (stage);
+
   return 0;
 }
index b97bae0..c7c95a8 100644 (file)
@@ -4,26 +4,31 @@ int
 main (int argc, char *argv[])
 {
   ClutterElement *label;
+  ClutterElement *stage;
   gchar          *text;
   gsize           size;
+  ClutterColor    stage_color = { 0x00, 0x00, 0x00, 0xff };
+  ClutterColor    label_color = { 0x11, 0xdd, 0x11, 0xaa };
 
   clutter_init (&argc, &argv);
 
+  stage = clutter_stage_get_default ();
+
   if (!g_file_get_contents ("test-text.c", &text, &size, NULL)) 
     g_error("g_file_get_contents() of test-text.c failed");
 
-  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()), 800, 600);
-  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0x00000000);
-
-  label = clutter_label_new_with_text("Mono 8", text);
+  clutter_element_set_size (stage, 800, 600);
+  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
 
+  label = clutter_label_new_with_text ("Mono 8", text);
+  clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
   /* clutter_label_set_text_extents (CLUTTER_LABEL(label), 200, 0); */
 
-  clutter_label_set_color (CLUTTER_LABEL(label), 0xffffffff);
-
-  clutter_group_add(clutter_stage(), label);
-
-  clutter_group_show_all(clutter_stage());
+  clutter_group_add (CLUTTER_GROUP (stage), label);
+  clutter_group_show_all (CLUTTER_GROUP (stage));
+  g_signal_connect (stage, "button-press-event",
+                   G_CALLBACK (clutter_main_quit), NULL);
+  g_object_unref (stage);
 
   clutter_main();
 
index ac05295..e2f2fe1 100644 (file)
@@ -44,11 +44,13 @@ size_change (ClutterTexture *texture,
             gint            height,
             gpointer        user_data)
 {
-  ClutterGeometry stage_geom;
-  gint            vid_width, vid_height, new_y, new_height;
+  ClutterElement  *stage;
+  ClutterGeometry  stage_geom;
+  gint             vid_width, vid_height, new_y, new_height;
 
-  clutter_element_get_geometry (CLUTTER_ELEMENT(clutter_stage()), 
-                               &stage_geom);
+  stage = clutter_stage_get_default ();
+
+  clutter_element_get_geometry (stage, &stage_geom);
 
   clutter_texture_get_base_size (texture, &vid_width, &vid_height);
 
@@ -59,13 +61,13 @@ size_change (ClutterTexture *texture,
   new_height = ( vid_height * stage_geom.width ) / vid_width;
   new_y      = (stage_geom.height - new_height) / 2;
 
-  clutter_element_set_position (CLUTTER_ELEMENT(texture), 0, new_y);
+  clutter_element_set_position (CLUTTER_ELEMENT (texture), 0, new_y);
 
-  clutter_element_set_size (CLUTTER_ELEMENT(texture),
+  clutter_element_set_size (CLUTTER_ELEMENT (texture),
                            stage_geom.width,
                            new_height);
 
-  clutter_element_set_opacity (CLUTTER_ELEMENT(texture), 50);
+  clutter_element_set_opacity (CLUTTER_ELEMENT (texture), 50);
 
   printf("*** Pos set to +%i+%i , %ix%i ***\n", 
         0, new_y, stage_geom.width, new_height);
@@ -95,7 +97,10 @@ tick (ClutterVideoTexture *cvt,
 int
 main (int argc, char *argv[])
 {
-  ClutterElement        *label, *vtexture, *ctexture; 
+  ClutterElement        *label, *vtexture, *ctexture;
+  ClutterElement        *stage;
+  ClutterColor           rect_color = { 0xde, 0xde, 0xdf, 0xaa };
+  ClutterColor           stage_color = { 0xff, 0xff, 0xff, 0x00 };
   GError                *err = NULL;
 
   if (argc < 2)
@@ -105,6 +110,8 @@ main (int argc, char *argv[])
 
   vtexture = clutter_video_texture_new ();
 
+  stage = clutter_stage_get_default ();
+
   /* Broken..
   g_object_set(vtexture, "repeat-x", TRUE, NULL);
   g_object_set(vtexture, "repeat-y", TRUE, NULL);
@@ -121,7 +128,7 @@ main (int argc, char *argv[])
 
   clutter_element_set_position(label, 10, 10);
 
-  rect = clutter_rectangle_new (0xdededfaa);
+  rect = clutter_rectangle_new_with_color (&rect_color);
   clutter_element_set_size(rect, 0, 0);
   clutter_element_set_position(rect, 5, 5);
 
@@ -140,18 +147,18 @@ main (int argc, char *argv[])
                             NULL,
                             NULL);
 
-  clutter_group_add(clutter_stage(), vtexture);
-  clutter_group_add(clutter_stage(), rect);
-  clutter_group_add(clutter_stage(), label);
-  clutter_group_add(clutter_stage(), ctexture);
+  clutter_group_add (CLUTTER_GROUP (stage), vtexture);
+  clutter_group_add (CLUTTER_GROUP (stage), rect);
+  clutter_group_add (CLUTTER_GROUP (stage), label);
+  clutter_group_add (CLUTTER_GROUP (stage), ctexture);
 
-  clutter_stage_set_color (CLUTTER_STAGE(clutter_stage()), 0xFFFFFF00); 
+  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); 
 
-  g_signal_connect (clutter_stage(), "input-event",
+  g_signal_connect (stage, "input-event",
                    G_CALLBACK (input_cb), 
                    vtexture);
 
-  clutter_group_show_all(clutter_stage());
+  clutter_group_show_all (CLUTTER_GROUP (stage));
 
 
   if (!clutter_video_texture_play(CLUTTER_VIDEO_TEXTURE(vtexture), NULL))
@@ -171,5 +178,7 @@ main (int argc, char *argv[])
 
   clutter_main();
 
+  g_object_unref (stage);
+
   return 0;
 }
index c7d4985..53bd7a0 100644 (file)
@@ -68,12 +68,15 @@ frame_cb (ClutterTimeline *timeline,
 int
 main (int argc, char *argv[])
 {
-  ClutterElement *texture, *label;
+  ClutterElement  *texture, *label;
+  ClutterElement  *stage;
   ClutterTimeline *timeline;
-  GdkPixbuf      *pixbuf;
+  GdkPixbuf       *pixbuf;
 
   clutter_init (&argc, &argv);
 
+  stage = clutter_stage_get_default ();
+
   pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
 
   if (!pixbuf)
@@ -90,19 +93,21 @@ main (int argc, char *argv[])
   clutter_element_set_opacity (CLUTTER_ELEMENT(label), 0x99);
   clutter_element_set_position (CLUTTER_ELEMENT(label), 100, 200);
 
-  clutter_group_add(clutter_stage(), texture);
-  clutter_group_add(clutter_stage(), label);
+  clutter_group_add (CLUTTER_GROUP (stage), texture);
+  clutter_group_add (CLUTTER_GROUP (stage), label);
 
-  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage()), 800, 600);
+  clutter_element_set_size (CLUTTER_ELEMENT (stage), 800, 600);
 
-  clutter_group_show_all(clutter_stage());
+  clutter_group_show_all (CLUTTER_GROUP (stage));
 
   timeline = clutter_timeline_new (360, 200);
-  g_object_set(timeline, "loop", TRUE, 0);
-  g_signal_connect(timeline, "new-frame", frame_cb, label);
+  g_object_set (timeline, "loop", TRUE, 0);
+  g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), label);
   clutter_timeline_start (timeline);
 
   clutter_main();
 
+  g_object_unref (stage);
+
   return 0;
 }
index e186e7d..f57f3a4 100644 (file)
@@ -228,6 +228,7 @@ int
 main (int argc, char *argv[])
 {
   ClutterElement      *label, *texture, *vtexture; 
+  ClutterElement      *stage = clutter_stage_get_default ();
   GdkPixbuf           *pixbuf;
   GError              *err = NULL;
 
@@ -241,7 +242,7 @@ main (int argc, char *argv[])
   if (!pixbuf)
     g_error("pixbuf load failed");
 
-  clutter_element_set_size (CLUTTER_ELEMENT(clutter_stage())
+  clutter_element_set_size (stage
                            WINWIDTH, WINHEIGHT);
 
   texture = clutter_texture_new_from_pixbuf (pixbuf);
@@ -258,17 +259,17 @@ main (int argc, char *argv[])
                             NULL,
                             NULL);
 
-  clutter_group_add(clutter_stage(), texture);
-
-  clutter_group_add(clutter_stage(), vtexture);
-  
-  clutter_group_show_all(clutter_stage());
+  clutter_group_add (CLUTTER_GROUP (stage), texture);
+  clutter_group_add (CLUTTER_GROUP (stage), vtexture);
+  clutter_group_show_all (CLUTTER_GROUP (stage));
 
   if (!clutter_video_texture_play(CLUTTER_VIDEO_TEXTURE(vtexture), NULL))
       g_error("failed to play vtexture");
 
   clutter_main();
 
+  g_object_unref (stage);
+
   return 0;
 }