2008-05-14 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-actor.c: * clutter/clutter-main.c: * clutter/clutter-private.h: Rejid Øyvind's previous commit a little moving more into clutter-main.c and using ClutterContext. Also Refactor clutter_init & clutter_init_with_args to share same core init code.
This commit is contained in:
parent
a1b240d31b
commit
092fdf1d79
4 changed files with 174 additions and 152 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2008-05-14 Matthew Allum <mallum@openedhand.com>
|
||||||
|
|
||||||
|
* clutter/clutter-actor.c:
|
||||||
|
* clutter/clutter-main.c:
|
||||||
|
* clutter/clutter-private.h:
|
||||||
|
Rejid Øyvind's previous commit a little moving more into
|
||||||
|
clutter-main.c and using ClutterContext.
|
||||||
|
Also Refactor clutter_init & clutter_init_with_args to share
|
||||||
|
same core init code.
|
||||||
|
|
||||||
2008-05-13 Øyvind Kolås <pippin@o-hand.com>
|
2008-05-13 Øyvind Kolås <pippin@o-hand.com>
|
||||||
|
|
||||||
Made it possible to do picking when the colors stored in the
|
Made it possible to do picking when the colors stored in the
|
||||||
|
|
|
@ -1211,91 +1211,6 @@ _clutter_actor_apply_modelview_transform_recursive (ClutterActor *self,
|
||||||
_clutter_actor_apply_modelview_transform (self);
|
_clutter_actor_apply_modelview_transform (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint r_available, g_available, b_available;
|
|
||||||
static gint r_used, g_used, b_used;
|
|
||||||
|
|
||||||
static inline void init_bits (void)
|
|
||||||
{
|
|
||||||
static gboolean done = FALSE;
|
|
||||||
if (G_LIKELY (done))
|
|
||||||
return;
|
|
||||||
done = TRUE;
|
|
||||||
cogl_get_bitmasks (&r_available, &g_available, &b_available, NULL);
|
|
||||||
|
|
||||||
r_used = r_available;
|
|
||||||
g_used = g_available;
|
|
||||||
b_used = b_available;
|
|
||||||
|
|
||||||
#ifndef HAVE_CLUTTER_FRUITY
|
|
||||||
/* We always do fuzzy picking for the fruity backend */
|
|
||||||
if (g_getenv ("CLUTTER_FUZZY_PICK")!=NULL)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
r_used--;
|
|
||||||
g_used--;
|
|
||||||
b_used--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
_clutter_id_to_col (guint id,
|
|
||||||
ClutterColor *col)
|
|
||||||
{
|
|
||||||
gint red, green, blue;
|
|
||||||
|
|
||||||
init_bits ();
|
|
||||||
|
|
||||||
/* compute the numbers we'll store in the components */
|
|
||||||
red = (id >> (g_used+b_used)) & (0xff >> (8-r_used));
|
|
||||||
green = (id >> b_used) & (0xff >> (8-g_used));
|
|
||||||
blue = (id) & (0xff >> (8-b_used));
|
|
||||||
|
|
||||||
/* shift left bits a bit and add one, this circumvents
|
|
||||||
* at least some potential rounding errors in GL/GLES
|
|
||||||
* driver / hw implementation.
|
|
||||||
*/
|
|
||||||
if (r_used != r_available)
|
|
||||||
red = red * 2 + 1;
|
|
||||||
if (g_used != g_available)
|
|
||||||
green = green * 2 + 1;
|
|
||||||
if (b_used != b_available)
|
|
||||||
blue = blue * 2 + 1;
|
|
||||||
|
|
||||||
/* shift up to be full 8bit values */
|
|
||||||
red = red << (8-r_available);
|
|
||||||
green = green << (8-g_available);
|
|
||||||
blue = blue << (8-b_available);
|
|
||||||
|
|
||||||
col->red = red;
|
|
||||||
col->green = green;
|
|
||||||
col->blue = blue;
|
|
||||||
col->alpha = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint _clutter_pix_to_id (guchar pixel[4])
|
|
||||||
{
|
|
||||||
gint red, green, blue;
|
|
||||||
guint id;
|
|
||||||
|
|
||||||
/* reduce the pixel components to the number of bits actually used of the
|
|
||||||
* 8bits.
|
|
||||||
*/
|
|
||||||
red = pixel[0] >> (8 - r_available);
|
|
||||||
green = pixel[1] >> (8 - g_available);
|
|
||||||
blue = pixel[2] >> (8 - b_available);
|
|
||||||
|
|
||||||
/* divide by two */
|
|
||||||
red = red >> (r_available-r_used);
|
|
||||||
green = green >> (g_available-g_used);
|
|
||||||
blue = blue >> (b_available-b_used);
|
|
||||||
|
|
||||||
/* combine the correct per component values into the final id */
|
|
||||||
id = blue + (green << b_used) + (red << (b_used + g_used));
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_actor_paint:
|
* clutter_actor_paint:
|
||||||
* @self: A #ClutterActor
|
* @self: A #ClutterActor
|
||||||
|
@ -1343,7 +1258,7 @@ clutter_actor_paint (ClutterActor *self)
|
||||||
{
|
{
|
||||||
ClutterColor col;
|
ClutterColor col;
|
||||||
|
|
||||||
_clutter_id_to_col (clutter_actor_get_gid (self), &col);
|
_clutter_id_to_color (clutter_actor_get_gid (self), &col);
|
||||||
|
|
||||||
/* Actor will then paint silhouette of itself in supplied
|
/* Actor will then paint silhouette of itself in supplied
|
||||||
* color. See clutter_stage_get_actor_at_pos() for where
|
* color. See clutter_stage_get_actor_at_pos() for where
|
||||||
|
|
|
@ -228,6 +228,82 @@ clutter_get_motion_events_enabled (void)
|
||||||
|
|
||||||
guint _clutter_pix_to_id (guchar pixel[4]);
|
guint _clutter_pix_to_id (guchar pixel[4]);
|
||||||
|
|
||||||
|
static inline void init_bits (void)
|
||||||
|
{
|
||||||
|
ClutterMainContext *ctx;
|
||||||
|
|
||||||
|
static gboolean done = FALSE;
|
||||||
|
if (G_LIKELY (done))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx = clutter_context_get_default ();
|
||||||
|
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_id_to_color (guint id, ClutterColor *col)
|
||||||
|
{
|
||||||
|
ClutterMainContext *ctx;
|
||||||
|
gint red, green, blue;
|
||||||
|
ctx = clutter_context_get_default ();
|
||||||
|
|
||||||
|
/* compute the numbers we'll store in the components */
|
||||||
|
red = (id >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used))
|
||||||
|
& (0xff >> (8-ctx->fb_r_mask_used));
|
||||||
|
green = (id >> ctx->fb_b_mask_used) & (0xff >> (8-ctx->fb_g_mask_used));
|
||||||
|
blue = (id) & (0xff >> (8-ctx->fb_b_mask_used));
|
||||||
|
|
||||||
|
/* shift left bits a bit and add one, this circumvents
|
||||||
|
* at least some potential rounding errors in GL/GLES
|
||||||
|
* driver / hw implementation.
|
||||||
|
*/
|
||||||
|
if (ctx->fb_r_mask_used != ctx->fb_r_mask)
|
||||||
|
red = red * 2 + 1;
|
||||||
|
if (ctx->fb_g_mask_used != ctx->fb_g_mask)
|
||||||
|
green = green * 2 + 1;
|
||||||
|
if (ctx->fb_b_mask_used != ctx->fb_b_mask)
|
||||||
|
blue = blue * 2 + 1;
|
||||||
|
|
||||||
|
/* shift up to be full 8bit values */
|
||||||
|
red = red << (8 - ctx->fb_r_mask);
|
||||||
|
green = green << (8 - ctx->fb_g_mask);
|
||||||
|
blue = blue << (8 - ctx->fb_b_mask);
|
||||||
|
|
||||||
|
col->red = red;
|
||||||
|
col->green = green;
|
||||||
|
col->blue = blue;
|
||||||
|
col->alpha = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
_clutter_pixel_to_id (guchar pixel[4])
|
||||||
|
{
|
||||||
|
ClutterMainContext *ctx;
|
||||||
|
gint red, green, blue;
|
||||||
|
guint id;
|
||||||
|
|
||||||
|
ctx = clutter_context_get_default ();
|
||||||
|
|
||||||
|
/* reduce the pixel components to the number of bits actually used of the
|
||||||
|
* 8bits.
|
||||||
|
*/
|
||||||
|
red = pixel[0] >> (8 - ctx->fb_r_mask);
|
||||||
|
green = pixel[1] >> (8 - ctx->fb_g_mask);
|
||||||
|
blue = pixel[2] >> (8 - ctx->fb_b_mask);
|
||||||
|
|
||||||
|
/* divide potentially by two if 'fuzzy' */
|
||||||
|
red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used);
|
||||||
|
green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used);
|
||||||
|
blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used);
|
||||||
|
|
||||||
|
/* combine the correct per component values into the final id */
|
||||||
|
id = blue + (green << ctx->fb_b_mask_used)
|
||||||
|
+ (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used));
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
_clutter_do_pick (ClutterStage *stage,
|
_clutter_do_pick (ClutterStage *stage,
|
||||||
gint x,
|
gint x,
|
||||||
|
@ -266,15 +342,17 @@ _clutter_do_pick (ClutterStage *stage,
|
||||||
* could be nicer.
|
* could be nicer.
|
||||||
*/
|
*/
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
/* glEnable (GL_DITHER); we never enabled this originally, so its
|
/* glEnable (GL_DITHER); we never enabled this originally, so its
|
||||||
probably not safe to then enable it */
|
probably not safe to then enable it */
|
||||||
|
|
||||||
|
/* Read the color of the screen co-ords pixel */
|
||||||
glReadPixels (x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
glReadPixels (x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
||||||
|
|
||||||
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
||||||
return CLUTTER_ACTOR (stage);
|
return CLUTTER_ACTOR (stage);
|
||||||
|
|
||||||
id = _clutter_pix_to_id (pixel);
|
id = _clutter_pixel_to_id (pixel);
|
||||||
|
|
||||||
return clutter_get_actor_by_gid (id);
|
return clutter_get_actor_by_gid (id);
|
||||||
}
|
}
|
||||||
|
@ -1025,6 +1103,76 @@ clutter_init_error_quark (void)
|
||||||
return g_quark_from_static_string ("clutter-init-error-quark");
|
return g_quark_from_static_string ("clutter-init-error-quark");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterInitError
|
||||||
|
clutter_init_real (GError **error)
|
||||||
|
{
|
||||||
|
ClutterMainContext *ctx;
|
||||||
|
ClutterActor *stage;
|
||||||
|
|
||||||
|
/* Note, creates backend if not already existing, though parse args will
|
||||||
|
* have likely created it
|
||||||
|
*/
|
||||||
|
ctx = clutter_context_get_default ();
|
||||||
|
|
||||||
|
/* Stage will give us a GL Context etc */
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
if (!stage)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
|
"Unable to create the default stage");
|
||||||
|
else
|
||||||
|
g_critical ("Unable to create the default stage");
|
||||||
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_realize (stage);
|
||||||
|
|
||||||
|
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
|
"Unable to realize the default stage");
|
||||||
|
else
|
||||||
|
g_critical ("Unable to realize the default stage");
|
||||||
|
|
||||||
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we can safely assume we have a valid GL context and can
|
||||||
|
* start issueing cogl commands
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Figure out framebuffer masks used for pick */
|
||||||
|
cogl_get_bitmasks (&ctx->fb_r_mask, &ctx->fb_g_mask, &ctx->fb_b_mask, NULL);
|
||||||
|
|
||||||
|
ctx->fb_r_mask_used = ctx->fb_r_mask;
|
||||||
|
ctx->fb_g_mask_used = ctx->fb_g_mask;
|
||||||
|
ctx->fb_b_mask_used = ctx->fb_b_mask;
|
||||||
|
|
||||||
|
#ifndef HAVE_CLUTTER_FRUITY
|
||||||
|
/* We always do fuzzy picking for the fruity backend */
|
||||||
|
if (g_getenv ("CLUTTER_FUZZY_PICK") != NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ctx->fb_r_mask_used--;
|
||||||
|
ctx->fb_g_mask_used--;
|
||||||
|
ctx->fb_b_mask_used--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initiate event collection */
|
||||||
|
_clutter_backend_init_events (ctx->backend);
|
||||||
|
|
||||||
|
/* finally features - will call to backend and cogl */
|
||||||
|
_clutter_feature_init ();
|
||||||
|
|
||||||
|
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
||||||
|
|
||||||
|
return CLUTTER_INIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_init_with_args:
|
* clutter_init_with_args:
|
||||||
* @argc: a pointer to the number of command line arguments
|
* @argc: a pointer to the number of command line arguments
|
||||||
|
@ -1061,11 +1209,9 @@ clutter_init_with_args (int *argc,
|
||||||
char *translation_domain,
|
char *translation_domain,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterMainContext *clutter_context;
|
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
GOptionGroup *group;
|
GOptionGroup *group;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
ClutterActor *stage;
|
|
||||||
|
|
||||||
if (clutter_is_initialized)
|
if (clutter_is_initialized)
|
||||||
return CLUTTER_INIT_SUCCESS;
|
return CLUTTER_INIT_SUCCESS;
|
||||||
|
@ -1092,35 +1238,8 @@ clutter_init_with_args (int *argc,
|
||||||
if (!res)
|
if (!res)
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
|
|
||||||
clutter_context = clutter_context_get_default ();
|
/* Do the real work.. */
|
||||||
|
return clutter_init_real (error);
|
||||||
stage = clutter_stage_get_default ();
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_INTERNAL,
|
|
||||||
"Unable to create the default stage");
|
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_actor_realize (stage);
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
|
||||||
{
|
|
||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_INTERNAL,
|
|
||||||
"Unable to realize the default stage");
|
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_clutter_backend_init_events (clutter_context->backend);
|
|
||||||
|
|
||||||
_clutter_feature_init ();
|
|
||||||
|
|
||||||
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
|
||||||
|
|
||||||
return CLUTTER_INIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1172,9 +1291,6 @@ ClutterInitError
|
||||||
clutter_init (int *argc,
|
clutter_init (int *argc,
|
||||||
char ***argv)
|
char ***argv)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context;
|
|
||||||
ClutterActor *stage;
|
|
||||||
|
|
||||||
if (clutter_is_initialized)
|
if (clutter_is_initialized)
|
||||||
return CLUTTER_INIT_SUCCESS;
|
return CLUTTER_INIT_SUCCESS;
|
||||||
|
|
||||||
|
@ -1183,7 +1299,6 @@ clutter_init (int *argc,
|
||||||
if (argc && *argc > 0 && *argv)
|
if (argc && *argc > 0 && *argv)
|
||||||
g_set_prgname ((*argv)[0]);
|
g_set_prgname ((*argv)[0]);
|
||||||
|
|
||||||
|
|
||||||
/* parse_args will trigger backend creation and things like
|
/* parse_args will trigger backend creation and things like
|
||||||
* DISPLAY connection etc.
|
* DISPLAY connection etc.
|
||||||
*/
|
*/
|
||||||
|
@ -1193,36 +1308,7 @@ clutter_init (int *argc,
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note, creates backend if not already existing (though parse args will
|
return clutter_init_real (NULL);
|
||||||
* have likely created it)
|
|
||||||
*/
|
|
||||||
context = clutter_context_get_default ();
|
|
||||||
|
|
||||||
/* Stage will give us a GL Context etc */
|
|
||||||
stage = clutter_stage_get_default ();
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
g_critical ("Unable to create the default stage");
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_actor_realize (stage);
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
|
||||||
{
|
|
||||||
g_critical ("Unable to realize the default stage");
|
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initiate event collection */
|
|
||||||
_clutter_backend_init_events (context->backend);
|
|
||||||
|
|
||||||
/* finally features - will call to backend and cogl */
|
|
||||||
_clutter_feature_init ();
|
|
||||||
|
|
||||||
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
|
||||||
|
|
||||||
return CLUTTER_INIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -105,6 +105,11 @@ or enter/leave events */
|
||||||
GSList *shaders; /* stack of overridden shaders */
|
GSList *shaders; /* stack of overridden shaders */
|
||||||
|
|
||||||
ClutterActor *motion_last_actor;
|
ClutterActor *motion_last_actor;
|
||||||
|
|
||||||
|
/* fb bit masks for col<->id mapping in picking */
|
||||||
|
gint fb_r_mask, fb_g_mask, fb_b_mask;
|
||||||
|
gint fb_r_mask_used, fb_g_mask_used, fb_b_mask_used;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CLUTTER_CONTEXT() (clutter_context_get_default ())
|
#define CLUTTER_CONTEXT() (clutter_context_get_default ())
|
||||||
|
@ -166,11 +171,17 @@ ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
||||||
|
|
||||||
void _clutter_feature_init (void);
|
void _clutter_feature_init (void);
|
||||||
|
|
||||||
|
/* Picking code */
|
||||||
ClutterActor *_clutter_do_pick (ClutterStage *stage,
|
ClutterActor *_clutter_do_pick (ClutterStage *stage,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
ClutterPickMode mode);
|
ClutterPickMode mode);
|
||||||
|
|
||||||
|
guint _clutter_pixel_to_id (guchar pixel[4]);
|
||||||
|
|
||||||
|
void _clutter_id_to_color (guint id, ClutterColor *col);
|
||||||
|
|
||||||
|
|
||||||
/* use this function as the accumulator if you have a signal with
|
/* use this function as the accumulator if you have a signal with
|
||||||
* a G_TYPE_BOOLEAN return value; this will stop the emission as
|
* a G_TYPE_BOOLEAN return value; this will stop the emission as
|
||||||
* soon as one handler returns TRUE
|
* soon as one handler returns TRUE
|
||||||
|
|
Loading…
Add table
Reference in a new issue