diff --git a/ChangeLog b/ChangeLog index 69be11049..a66d98843 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +2006-06-05 Emmanuele Bassi + + * 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 * 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 diff --git a/bindings/ChangeLog b/bindings/ChangeLog index 22062c5ef..5dc67bbba 100644 --- a/bindings/ChangeLog +++ b/bindings/ChangeLog @@ -1,3 +1,9 @@ +2006-06-05 Emmanuele Bassi + + * python/clutter-base-types.defs: + * python/clutter-base.defs: + * python/clutter.override: Wrap new API and objects. + 2006-05-27 Emmanuele Bassi * python/clutter-base.defs: Make static functions appear like diff --git a/bindings/python/clutter-base-types.defs b/bindings/python/clutter-base-types.defs index 94e408dfb..9a3b5a72a 100644 --- a/bindings/python/clutter-base-types.defs +++ b/bindings/python/clutter-base-types.defs @@ -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") @@ -17,6 +29,15 @@ ) ) +(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") @@ -31,16 +52,6 @@ ;; 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") @@ -51,11 +62,22 @@ ) ) +(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") @@ -134,13 +156,6 @@ ;; 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") @@ -148,6 +163,13 @@ (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") @@ -155,6 +177,13 @@ (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") @@ -176,13 +205,6 @@ (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") diff --git a/bindings/python/clutter-base.defs b/bindings/python/clutter-base.defs index 79f5bfbb4..4acf20e9d 100644 --- a/bindings/python/clutter-base.defs +++ b/bindings/python/clutter-base.defs @@ -113,9 +113,9 @@ (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 @@ -164,6 +164,27 @@ ;; 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") @@ -217,22 +238,22 @@ (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") @@ -513,17 +534,36 @@ ;; 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") ) ) @@ -634,41 +674,97 @@ ;; 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 - '("guint8" "r") - '("guint8" "g") - '("guint8" "b") - '("guint8" "a") + '("ClutterColor*" "src2") + '("ClutterColor*" "dest") ) ) -(define-method set +(define-method subtract (of-object "ClutterColor") - (c-name "clutter_color_set") + (c-name "clutter_color_subtract") (return-type "none") (parameters - '("guint8" "r") - '("guint8" "g") - '("guint8" "b") - '("guint8" "a") + '("ClutterColor*" "src2") + '("ClutterColor*" "dest") ) ) -(define-method get +(define-method lighten (of-object "ClutterColor") - (c-name "clutter_color_get") + (c-name "clutter_color_lighten") (return-type "none") (parameters - '("guint8*" "r") - '("guint8*" "g") - '("guint8*" "b") - '("guint8*" "a") + '("ClutterColor*" "dest") ) ) +(define-method darken + (of-object "ClutterColor") + (c-name "clutter_color_darken") + (return-type "none") + (parameters + '("ClutterColor*" "dest") + ) +) + +(define-method shade + (of-object "ClutterColor") + (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 + '("ClutterColor" "dest") + '("guint32" "pixel") + ) +) + + ;; From ../../clutter/clutter-clone-texture.h @@ -850,21 +946,22 @@ (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") @@ -874,21 +971,42 @@ ) ) -(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") ) ) @@ -902,6 +1020,16 @@ ) ) +(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 @@ -1005,6 +1133,11 @@ (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") @@ -1016,19 +1149,22 @@ (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") @@ -1036,6 +1172,18 @@ ) ) +(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 diff --git a/bindings/python/clutter.override b/bindings/python/clutter.override index 19a96d783..4f314c169 100644 --- a/bindings/python/clutter.override +++ b/bindings/python/clutter.override @@ -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); +} +%% diff --git a/clutter/clutter-color.c b/clutter/clutter-color.c index 7b29e6e08..a0f8c805e 100644 --- a/clutter/clutter-color.c +++ b/clutter/clutter-color.c @@ -23,39 +23,368 @@ * 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) -{ - return ( a | b << 8 | g << 16 | r << 24 ); -} - +/** + * 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_set (ClutterColor *color, - guint8 r, - guint8 g, - guint8 b, - guint8 a) +clutter_color_add (const ClutterColor *src1, + const ClutterColor *src2, + ClutterColor *dest) { - *color = ( a | b << 8 | g << 16 | r << 24 ); + 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_get (ClutterColor color, - guint8 *r, - guint8 *g, - guint8 *b, - guint8 *a) +clutter_color_subtract (const ClutterColor *src1, + const ClutterColor *src2, + ClutterColor *dest) { - 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 (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) +{ + 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_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) +{ + 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_from_pixel (ClutterColor *dest, + guint32 pixel) +{ + 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; +} diff --git a/clutter/clutter-color.h b/clutter/clutter-color.h index eab24a430..31850ea03 100644 --- a/clutter/clutter-color.h +++ b/clutter/clutter-color.h @@ -26,38 +26,52 @@ #ifndef _HAVE_CLUTTER_COLOR_H #define _HAVE_CLUTTER_COLOR_H -#include +#include 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 diff --git a/clutter/clutter-element.c b/clutter/clutter-element.c index 8f612a3f3..6ee49cef1 100644 --- a/clutter/clutter-element.c +++ b/clutter/clutter-element.c @@ -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(); diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c index e55263090..85cded495 100644 --- a/clutter/clutter-event.c +++ b/clutter/clutter-event.c @@ -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; +} diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h index 7e0d7daaf..6b8593fb8 100644 --- a/clutter/clutter-event.h +++ b/clutter/clutter-event.h @@ -26,7 +26,7 @@ #ifndef _HAVE_CLUTTER_EVENT_H #define _HAVE_CLUTTER_EVENT_H -#include +#include 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); diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index fab082a9c..9de908b99 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -28,6 +28,18 @@ #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) { diff --git a/clutter/clutter-group.h b/clutter/clutter-group.h index 4e6be150a..0bc0a8ad0 100644 --- a/clutter/clutter-group.h +++ b/clutter/clutter-group.h @@ -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 diff --git a/clutter/clutter-label.c b/clutter/clutter-label.c index b8fe7f548..c3063c6ab 100644 --- a/clutter/clutter-label.c +++ b/clutter/clutter-label.c @@ -32,14 +32,16 @@ #include +#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; - } + 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_free (priv->text); + priv->text = NULL; - if (priv->font) - { - g_free (priv->font); - priv->font = 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); + 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); + pango_font_description_free (priv->desc); - if (priv->font) - g_free(priv->font); + g_free (priv->font_name); + priv->font_name = g_strdup (font_name); - priv->font = g_strdup(desc); - - 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)); + + if (width) + *width = label->priv->extents_width; + + if (height) + *height = label->priv->extents_height; +} + +/** + * 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 (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; - priv->fgcol = pixel; - - clutter_element_set_opacity(CLUTTER_ELEMENT(label), priv->fgcol & 0xff); - - clutter_label_make_pixbuf (label); - - if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(label))) - clutter_element_queue_redraw (CLUTTER_ELEMENT(label)); + color->red = priv->fgcol.red; + color->green = priv->fgcol.green; + color->blue = priv->fgcol.blue; + color->alpha = priv->fgcol.alpha; } - - diff --git a/clutter/clutter-label.h b/clutter/clutter-label.h index 356e3c0ba..855ba46d7 100644 --- a/clutter/clutter-label.h +++ b/clutter/clutter-label.h @@ -29,6 +29,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -77,27 +78,28 @@ struct _ClutterLabelClass void (*_clutter_label_4) (void); }; -GType clutter_label_get_type (void); +GType clutter_label_get_type (void) G_GNUC_CONST; -ClutterElement* -clutter_label_new_with_text (const gchar *font_desc, const gchar *text); +ClutterElement * clutter_label_new (void); +ClutterElement * clutter_label_new_with_text (const gchar *font_name, + 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); +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 diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 05131da3d..5e4ceeb9c 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -22,6 +22,11 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ + +#include "config.h" + +#include + #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_main (void) +{ + 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_enter(void) { - g_mutex_lock(ClutterCntx.gl_lock); + ClutterMainContext *context = CLUTTER_CONTEXT (); + + g_mutex_lock (context->gl_lock); } +/** + * clutter_threads_leave: + * + * FIXME + */ void -clutter_threads_leave(void) +clutter_threads_leave (void) { - g_mutex_unlock(ClutterCntx.gl_lock); -} - -ClutterGroup* -clutter_stage(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 - }; + ClutterMainContext *ctx; - if (getenv("CLUTTER_DEBUG")) + 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 ()); + 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); - pango_ft2_font_map_set_resolution (ClutterCntx.font_map, 96.0, 96.0); + context->gl_lock = g_mutex_new (); - ClutterCntx.gl_lock = g_mutex_new (); + 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)); - ClutterCntx.stage = g_object_new (CLUTTER_TYPE_STAGE, NULL); + events_init (); - g_return_val_if_fail (ClutterCntx.stage != NULL, -3); - - clutter_element_realize(CLUTTER_ELEMENT(ClutterCntx.stage)); - - events_init(); + context->is_initialized = TRUE; return 1; } diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index 7d5ed1e42..1afad6ae9 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -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 (); diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list index 435c9acee..51c291eeb 100644 --- a/clutter/clutter-marshal.list +++ b/clutter/clutter-marshal.list @@ -1,4 +1,5 @@ VOID:INT64,INT64,FLOAT,BOOLEAN VOID:STRING,BOOLEAN,BOOLEAN VOID:INT,INT - +VOID:BOXED +VOID:OBJECT diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 3d93e9906..f6a75d8e9 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -45,21 +45,31 @@ #include +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 diff --git a/clutter/clutter-rectangle.c b/clutter/clutter-rectangle.c index 47207dd26..c8cc87563 100644 --- a/clutter/clutter-rectangle.c +++ b/clutter/clutter-rectangle.c @@ -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"); +} diff --git a/clutter/clutter-rectangle.h b/clutter/clutter-rectangle.h index c13a91ea5..ef2c2dc01 100644 --- a/clutter/clutter-rectangle.h +++ b/clutter/clutter-rectangle.h @@ -28,6 +28,7 @@ #include #include +#include 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 (guint32 col); +ClutterElement *clutter_rectangle_new (void); +ClutterElement *clutter_rectangle_new_with_color (const ClutterColor *color); + +void clutter_rectangle_get_color (ClutterRectangle *rectangle, + ClutterColor *color); +void clutter_rectangle_set_color (ClutterRectangle *rectangle, + const ClutterColor *color); G_END_DECLS diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index b59f10960..4189fb9cf 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -23,34 +23,47 @@ * 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 #include +/* 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; - if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(stage))) - clutter_element_queue_redraw (CLUTTER_ELEMENT(stage)); + 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)); + + 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; - data = g_malloc0(sizeof(guchar)*width*height*3); + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); + g_return_val_if_fail (x >= 0 && y >= 0, NULL); + + 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*/ 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); +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); +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 diff --git a/doc/reference/clutter-0.0-sections.txt b/doc/reference/clutter-0.0-sections.txt index 487e8fc46..03839603a 100644 --- a/doc/reference/clutter-0.0-sections.txt +++ b/doc/reference/clutter-0.0-sections.txt @@ -1,29 +1,30 @@
clutter-label +ClutterLabelPrivate ClutterLabel 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 CLUTTER_LABEL CLUTTER_IS_LABEL CLUTTER_TYPE_LABEL +clutter_label_get_type CLUTTER_LABEL_CLASS CLUTTER_IS_LABEL_CLASS CLUTTER_LABEL_GET_CLASS - -ClutterLabelPrivate -clutter_label_get_type
clutter-element -ClutterElement 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 +ClutterElement 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 - -clutter_geometry_get_type -ClutterElementPrivate
@@ -91,6 +92,8 @@ ClutterGroupPrivate ClutterGroup 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 CLUTTER_STAGE CLUTTER_IS_STAGE @@ -173,22 +176,6 @@ CLUTTER_IS_STAGE_CLASS CLUTTER_STAGE_GET_CLASS
-
-clutter-rectangle -ClutterRectanglePrivate -ClutterRectangle -ClutterRectangle -clutter_rectangle_new - -CLUTTER_RECTANGLE -CLUTTER_IS_RECTANGLE -CLUTTER_TYPE_RECTANGLE -clutter_rectangle_get_type -CLUTTER_RECTANGLE_CLASS -CLUTTER_IS_RECTANGLE_CLASS -CLUTTER_RECTANGLE_GET_CLASS -
-
clutter-video-texture ClutterVideoTexturePrivate @@ -228,6 +215,25 @@ CLUTTER_IS_VIDEO_TEXTURE_CLASS CLUTTER_VIDEO_TEXTURE_GET_CLASS
+
+clutter-rectangle +ClutterRectanglePrivate +ClutterRectangle +ClutterRectangle +clutter_rectangle_new +clutter_rectangle_new_with_color +clutter_rectangle_get_color +clutter_rectangle_set_color + +CLUTTER_RECTANGLE +CLUTTER_IS_RECTANGLE +CLUTTER_TYPE_RECTANGLE +clutter_rectangle_get_type +CLUTTER_RECTANGLE_CLASS +CLUTTER_IS_RECTANGLE_CLASS +CLUTTER_RECTANGLE_GET_CLASS +
+
clutter-timeline ClutterTimelinePrivate @@ -244,6 +250,7 @@ clutter_timeline_skip clutter_timeline_advance clutter_timeline_get_current_frame clutter_timeline_get_n_frames +clutter_timeline_is_playing CLUTTER_TIMELINE CLUTTER_IS_TIMELINE @@ -262,18 +269,16 @@ clutter_util_can_create_texture
clutter-color -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
@@ -1683,7 +1688,3 @@ CLUTTER_TYPE_VIDEO_TEXTURE_METADATA_TYPE clutter_video_texture_metadata_type_get_type
-
-stamp-clutter-enum-types -
- diff --git a/doc/reference/tmpl/clutter-0.0-unused.sgml b/doc/reference/tmpl/clutter-0.0-unused.sgml index 8f7b8b8b3..3caf6a8e7 100644 --- a/doc/reference/tmpl/clutter-0.0-unused.sgml +++ b/doc/reference/tmpl/clutter-0.0-unused.sgml @@ -1,12 +1,14 @@ - + +@Returns: - + +@Returns: diff --git a/doc/reference/tmpl/clutter-color.sgml b/doc/reference/tmpl/clutter-color.sgml index 84abd7ddf..1beefbdcd 100644 --- a/doc/reference/tmpl/clutter-color.sgml +++ b/doc/reference/tmpl/clutter-color.sgml @@ -17,113 +17,98 @@ clutter-color - - - - - -@col: - - - - - - - -@col: - - - - - - - -@col: - - - - - - - -@col: - - - - - - - -@col: -@r: - - - - - - - -@col: -@g: - - - - - - - -@col: -@b: - - - - - - - -@col: -@a: - - - + - + + + + + + +@red: +@green: +@blue: +@alpha: + + -@r: -@g: -@b: -@a: @Returns: - + -@color: -@r: -@g: -@b: -@a: +@src1: +@src2: +@dest: - + -@color: -@r: -@g: -@b: -@a: +@src1: +@src2: +@dest: + + + + + + + +@src: +@dest: + + + + + + + +@src: +@dest: + + + + + + + +@src: +@dest: +@shade: + + + + + + + +@src: +@hue: +@luminance: +@saturation: + + + + + + + +@dest: +@hue: +@luminance: +@saturation: diff --git a/doc/reference/tmpl/clutter-element.sgml b/doc/reference/tmpl/clutter-element.sgml index 779d56563..ed9d5462a 100644 --- a/doc/reference/tmpl/clutter-element.sgml +++ b/doc/reference/tmpl/clutter-element.sgml @@ -83,6 +83,12 @@ ClutterElement @x2: @y2: + + + + + + @@ -93,6 +99,15 @@ ClutterElement @width: @height: + + + + + +@element: +@data: + + @@ -125,25 +140,6 @@ ClutterElement @parent: @flags: - - - - - -@parent_class: -@show: -@hide: -@realize: -@unrealize: -@paint: -@request_coords: -@allocate_coords: -@set_depth: -@get_depth: -@show_all: -@hide_all: -@queue_redraw: - diff --git a/doc/reference/tmpl/clutter-event.sgml b/doc/reference/tmpl/clutter-event.sgml index debc0a61f..473b50832 100644 --- a/doc/reference/tmpl/clutter-event.sgml +++ b/doc/reference/tmpl/clutter-event.sgml @@ -22,6 +22,7 @@ clutter-event +@CLUTTER_NOTHING: @CLUTTER_KEY_PRESS: @CLUTTER_KEY_RELEASE: @CLUTTER_MOTION: diff --git a/doc/reference/tmpl/clutter-group.sgml b/doc/reference/tmpl/clutter-group.sgml index 71b1d495a..eafd55ccb 100644 --- a/doc/reference/tmpl/clutter-group.sgml +++ b/doc/reference/tmpl/clutter-group.sgml @@ -38,6 +38,25 @@ ClutterGroup @Returns: + + + + + +@self: +@Returns: + + + + + + + +@self: +@callback: +@user_data: + + diff --git a/doc/reference/tmpl/clutter-label.sgml b/doc/reference/tmpl/clutter-label.sgml index 453ffb42f..383363af9 100644 --- a/doc/reference/tmpl/clutter-label.sgml +++ b/doc/reference/tmpl/clutter-label.sgml @@ -17,6 +17,12 @@ ClutterLabel + + + + + + @@ -24,30 +30,24 @@ ClutterLabel @parent: - + +@Returns: + -@font_desc: +@font_name: @text: @Returns: - - - - - -@Returns: - - @@ -57,13 +57,31 @@ ClutterLabel @text: - + @label: -@desc: +@Returns: + + + + + + + +@label: +@font_name: + + + + + + + +@label: +@Returns: @@ -72,7 +90,16 @@ ClutterLabel @label: -@pixel: +@color: + + + + + + + +@label: +@color: @@ -85,3 +112,13 @@ ClutterLabel @height: + + + + + +@label: +@width: +@height: + + diff --git a/doc/reference/tmpl/clutter-main.sgml b/doc/reference/tmpl/clutter-main.sgml index 38ad5c655..b9dbae34d 100644 --- a/doc/reference/tmpl/clutter-main.sgml +++ b/doc/reference/tmpl/clutter-main.sgml @@ -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 - - - - - -@Returns: - - @@ -106,14 +107,6 @@ clutter-main @Returns: - - - - - -@Returns: - - diff --git a/doc/reference/tmpl/clutter-rectangle.sgml b/doc/reference/tmpl/clutter-rectangle.sgml index 29e7205d6..2da2dbf96 100644 --- a/doc/reference/tmpl/clutter-rectangle.sgml +++ b/doc/reference/tmpl/clutter-rectangle.sgml @@ -29,14 +29,39 @@ ClutterRectangle @parent: -@priv: -@col: @Returns: + + + + + +@color: +@Returns: + + + + + + + +@rectangle: +@color: + + + + + + + +@rectangle: +@color: + + diff --git a/doc/reference/tmpl/clutter-stage.sgml b/doc/reference/tmpl/clutter-stage.sgml index 58ce359d8..6beacb1b1 100644 --- a/doc/reference/tmpl/clutter-stage.sgml +++ b/doc/reference/tmpl/clutter-stage.sgml @@ -31,7 +31,7 @@ ClutterStage - + @@ -43,7 +43,6 @@ ClutterStage @parent: -@priv: @@ -69,10 +68,10 @@ ClutterStage @stage: -@Returns: +@color: - + diff --git a/doc/reference/tmpl/clutter-timeline.sgml b/doc/reference/tmpl/clutter-timeline.sgml index 4cb93a1f2..6876b1f44 100644 --- a/doc/reference/tmpl/clutter-timeline.sgml +++ b/doc/reference/tmpl/clutter-timeline.sgml @@ -127,3 +127,12 @@ ClutterTimeline @Returns: + + + + + +@timeline: +@Returns: + + diff --git a/examples/rects.py b/examples/rects.py index 4663e4058..e0b71cce7 100755 --- a/examples/rects.py +++ b/examples/rects.py @@ -2,16 +2,29 @@ import clutter -stage = clutter.stage() -stage.set_size(800,600) +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() diff --git a/examples/super-oh.c b/examples/super-oh.c index 4937e91d3..cacc711ea 100644 --- a/examples/super-oh.c +++ b/examples/super-oh.c @@ -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; } diff --git a/examples/test-text.c b/examples/test-text.c index b97bae04b..c7c95a8a1 100644 --- a/examples/test-text.c +++ b/examples/test-text.c @@ -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(); diff --git a/examples/test-video.c b/examples/test-video.c index ac0529518..e2f2fe112 100644 --- a/examples/test-video.c +++ b/examples/test-video.c @@ -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; } diff --git a/examples/test.c b/examples/test.c index c7d498514..53bd7a0b9 100644 --- a/examples/test.c +++ b/examples/test.c @@ -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; } diff --git a/examples/video-cube.c b/examples/video-cube.c index e186e7d60..f57f3a448 100644 --- a/examples/video-cube.c +++ b/examples/video-cube.c @@ -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; }