2006-06-02 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-element.h:
        Add missing _depth() declarations

        * clutter/clutter-main.c:
        * clutter/clutter-main.h:
        * 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.
This commit is contained in:
Matthew Allum 2006-06-02 20:24:55 +00:00
parent 6c471cb7e1
commit ba09979db0
8 changed files with 173 additions and 45 deletions

View File

@ -1,3 +1,16 @@
2006-06-02 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-element.h:
Add missing _depth() declarations
* clutter/clutter-main.c:
* clutter/clutter-main.h:
* 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.
2006-06-01 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-element.c:

View File

@ -256,6 +256,14 @@ clutter_element_raise_top (ClutterElement *self);
void
clutter_element_lower_bottom (ClutterElement *self);
void
clutter_element_set_depth (ClutterElement *self,
gint depth);
gint
clutter_element_get_depth (ClutterElement *self);
G_END_DECLS
#endif

View File

@ -233,6 +233,9 @@ clutter_redraw ()
static GTimer *timer = NULL;
static guint timer_n_frames = 0;
/* FIXME: Should move all this into stage...
*/
CLUTTER_DBG("@@@ Redraw enter @@@");
clutter_threads_enter();
@ -255,7 +258,14 @@ clutter_redraw ()
clutter_element_paint(CLUTTER_ELEMENT(stage));
glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));
if (clutter_stage_get_xwindow (stage))
{
glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));
}
else
{
glFlush();
}
if (clutter_want_fps())
{
@ -321,23 +331,27 @@ clutter_root_xwindow(void)
return ClutterCntx.xwin_root;
}
XVisualInfo*
clutter_xvisual(void)
{
return ClutterCntx.xvinfo;
}
gboolean
clutter_want_debug(void)
{
return __clutter_has_debug;
}
GLXContext
clutter_gl_context(void)
void
clutter_gl_context_set_indirect (gboolean indirect)
{
return ClutterCntx.gl_context;
}
int
clutter_init(int *argc, char ***argv)
{
XVisualInfo *vinfo;
int gl_attributes[] =
{
GLX_RGBA,
@ -374,16 +388,14 @@ clutter_init(int *argc, char ***argv)
ClutterCntx.xscreen = DefaultScreen(ClutterCntx.xdpy);
ClutterCntx.xwin_root = RootWindow(ClutterCntx.xdpy, ClutterCntx.xscreen);
if ((vinfo = glXChooseVisual(ClutterCntx.xdpy,
ClutterCntx.xscreen,
gl_attributes)) == NULL)
if ((ClutterCntx.xvinfo = glXChooseVisual(ClutterCntx.xdpy,
ClutterCntx.xscreen,
gl_attributes)) == NULL)
{
g_warning("Unable to find suitable GL visual.");
return -2;
}
ClutterCntx.gl_context = glXCreateContext(ClutterCntx.xdpy, vinfo, 0, True);
ClutterCntx.font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
pango_ft2_font_map_set_resolution (ClutterCntx.font_map, 96.0, 96.0);

View File

@ -80,8 +80,8 @@ clutter_xscreen (void);
Window
clutter_root_xwindow (void);
GLXContext
clutter_gl_context (void);
XVisualInfo*
clutter_xvisual(void);
gboolean
clutter_want_debug (void);

View File

@ -52,8 +52,8 @@ typedef struct ClutterMainContext
Window xwin_root;
int xscreen;
GC xgc;
XVisualInfo *xvinfo;
PangoFT2FontMap *font_map;
GLXContext gl_context;
GMutex *gl_lock;
guint update_idle;
ClutterStage *stage;

View File

@ -38,9 +38,13 @@ static ClutterElementClass *parent_class;
struct ClutterStagePrivate
{
Window xwin;
gint xwin_width, xwin_height;
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;
};
@ -48,6 +52,7 @@ enum
{
PROP_0,
PROP_FULLSCREEN,
PROP_OFFSCREEN,
PROP_HIDE_CURSOR
};
@ -198,15 +203,17 @@ sync_gl_viewport (ClutterStage *stage)
static void
clutter_stage_show (ClutterElement *self)
{
XMapWindow (clutter_xdisplay(),
clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
if (clutter_stage_get_xwindow (CLUTTER_STAGE(self)))
XMapWindow (clutter_xdisplay(),
clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
}
static void
clutter_stage_hide (ClutterElement *self)
{
XUnmapWindow (clutter_xdisplay(),
clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
if (clutter_stage_get_xwindow (CLUTTER_STAGE(self)))
XUnmapWindow (clutter_xdisplay(),
clutter_stage_get_xwindow (CLUTTER_STAGE(self)));
}
static void
@ -218,8 +225,28 @@ clutter_stage_unrealize (ClutterElement *element)
stage = CLUTTER_STAGE(element);
priv = stage->priv;
XDestroyWindow (clutter_xdisplay(), priv->xwin);
priv->xwin = None;
if (priv->want_offscreen)
{
if (priv->glxpixmap)
{
glXDestroyGLXPixmap (clutter_xdisplay(), priv->glxpixmap);
priv->glxpixmap = None;
}
if (priv->xpixmap)
{
XFreePixmap (clutter_xdisplay(), priv->xpixmap);
priv->xpixmap = None;
}
}
else
{
if (clutter_stage_get_xwindow (CLUTTER_STAGE(element)))
{
XDestroyWindow (clutter_xdisplay(), priv->xwin);
priv->xwin = None;
}
}
}
static void
@ -232,28 +259,63 @@ clutter_stage_realize (ClutterElement *element)
priv = stage->priv;
priv->xwin = XCreateSimpleWindow(clutter_xdisplay(),
clutter_root_xwindow(),
0, 0,
priv->xwin_width, priv->xwin_height,
0, 0,
WhitePixel(clutter_xdisplay(),
clutter_xscreen()));
if (priv->want_offscreen)
{
priv->xpixmap = XCreatePixmap (clutter_xdisplay(),
clutter_root_xwindow(),
priv->xwin_width, priv->xwin_height,
clutter_xvisual()->depth);
XSelectInput(clutter_xdisplay(),
priv->xwin,
StructureNotifyMask
|ExposureMask
|KeyPressMask
|KeyReleaseMask
|ButtonPressMask /* FIXME: Make optional ? */
|ButtonReleaseMask
|PropertyChangeMask);
priv->glxpixmap = glXCreateGLXPixmap(clutter_xdisplay(),
clutter_xvisual(),
priv->xpixmap);
sync_fullscreen (stage);
sync_fullscreen (stage);
sync_cursor_visible (stage);
if (priv->gl_context)
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
/* indirect */
priv->gl_context = glXCreateContext (clutter_xdisplay(),
clutter_xvisual(),
0,
False);
glXMakeCurrent(clutter_xdisplay(), priv->glxpixmap, priv->gl_context);
}
else
{
priv->xwin = XCreateSimpleWindow(clutter_xdisplay(),
clutter_root_xwindow(),
0, 0,
priv->xwin_width, priv->xwin_height,
0, 0,
WhitePixel(clutter_xdisplay(),
clutter_xscreen()));
XSelectInput(clutter_xdisplay(),
priv->xwin,
StructureNotifyMask
|ExposureMask
|KeyPressMask
|KeyReleaseMask
|ButtonPressMask
|ButtonReleaseMask
|PropertyChangeMask);
sync_fullscreen (stage);
sync_cursor_visible (stage);
if (priv->gl_context)
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
priv->gl_context = glXCreateContext (clutter_xdisplay(),
clutter_xvisual(),
0,
True);
glXMakeCurrent(clutter_xdisplay(), priv->xwin, priv->gl_context);
}
glXMakeCurrent(clutter_xdisplay(), priv->xwin, clutter_gl_context());
sync_gl_viewport (stage);
}
@ -298,6 +360,14 @@ clutter_stage_request_coords (ClutterElement *self,
priv->xwin,
priv->xwin_width,
priv->xwin_height);
if (priv->xpixmap)
{
/* Need to recreate to resize */
clutter_element_unrealize(self);
clutter_element_realize(self);
}
sync_gl_viewport (stage);
}
@ -351,6 +421,14 @@ clutter_stage_set_property (GObject *object,
switch (prop_id)
{
case PROP_OFFSCREEN:
if (priv->want_offscreen != g_value_get_boolean (value))
{
clutter_element_unrealize(CLUTTER_ELEMENT(stage));
priv->want_offscreen = g_value_get_boolean (value);
clutter_element_realize(CLUTTER_ELEMENT(stage));
}
break;
case PROP_FULLSCREEN:
if (priv->want_fullscreen != g_value_get_boolean (value))
{
@ -385,6 +463,9 @@ clutter_stage_get_property (GObject *object,
switch (prop_id)
{
case PROP_OFFSCREEN:
g_value_set_boolean (value, priv->want_offscreen);
break;
case PROP_FULLSCREEN:
g_value_set_boolean (value, priv->want_fullscreen);
break;
@ -432,6 +513,15 @@ clutter_stage_class_init (ClutterStageClass *klass)
FALSE,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_OFFSCREEN,
g_param_spec_boolean ("offscreen",
"Offscreen",
"Make Clutter stage offscreen",
FALSE,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_HIDE_CURSOR,
g_param_spec_boolean ("hide-cursor",
@ -573,7 +663,7 @@ clutter_stage_pick (ClutterStage *stage, gint x, gint y)
{
ClutterElement *found = NULL;
GLuint buff[64] = {0};
GLint hits, view[4], i;
GLint hits, view[4];
glSelectBuffer(64, buff);
glGetIntegerv(GL_VIEWPORT, view);
@ -606,6 +696,8 @@ clutter_stage_pick (ClutterStage *stage, gint x, gint y)
if (hits != 0)
{
/*
int i;
for (i=0; i<hits; i++)
g_print ("Hit at %i\n", buff[i * 4 + 3]);
*/

View File

@ -102,6 +102,13 @@ clutter_stage_set_color (ClutterStage *stage,
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);

View File

@ -854,9 +854,6 @@ clutter_texture_class_init (ClutterTextureClass *klass)
PIXEL_FORMAT,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
texture_signals[SIGNAL_SIZE_CHANGE] =
g_signal_new ("size-change",
G_TYPE_FROM_CLASS (gobject_class),
@ -876,7 +873,6 @@ clutter_texture_class_init (ClutterTextureClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
}
static void