x11/stage: Use a global Window ↔ Stage relationship

Since we need to find the stage from the X11 Window, it's better to use
a static hashmap that gets updated every time the ClutterStageX11:xwin
member is changed, instead of iterating over every stage handled by the
global ClutterStageManager singleton.
This commit is contained in:
Emmanuele Bassi 2011-01-28 18:05:06 +00:00
parent f4508be4ab
commit 9be4cfe8a9
2 changed files with 37 additions and 19 deletions

View File

@ -506,7 +506,10 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
void void
_clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx, _clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx,
GLXDrawable drawable, GLXDrawable drawable,
int x, int y, int width, int height) int x,
int y,
int width,
int height)
{ {
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx); ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);

View File

@ -54,6 +54,8 @@
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
static GHashTable *clutter_stages_by_xid = NULL;
#define clutter_stage_x11_get_type _clutter_stage_x11_get_type #define clutter_stage_x11_get_type _clutter_stage_x11_get_type
G_DEFINE_TYPE_WITH_CODE (ClutterStageX11, G_DEFINE_TYPE_WITH_CODE (ClutterStageX11,
@ -1131,24 +1133,16 @@ clutter_x11_get_stage_window (ClutterStage *stage)
ClutterStage * ClutterStage *
clutter_x11_get_stage_from_window (Window win) clutter_x11_get_stage_from_window (Window win)
{ {
ClutterStageManager *stage_manager; ClutterStageX11 *stage_x11;
const GSList *stages, *s;
stage_manager = clutter_stage_manager_get_default (); if (clutter_stages_by_xid == NULL)
stages = clutter_stage_manager_peek_stages (stage_manager); return NULL;
/* XXX: might use a hash here for performance resaon */ stage_x11 = g_hash_table_lookup (clutter_stages_by_xid,
for (s = stages; s != NULL; s = s->next) GINT_TO_POINTER (win));
{
ClutterStage *stage = s->data;
ClutterStageWindow *impl;
impl = _clutter_stage_get_window (stage); if (stage_x11 != NULL)
g_assert (CLUTTER_IS_STAGE_X11 (impl)); return stage_x11->wrapper;
if (CLUTTER_STAGE_X11 (impl)->xwin == win)
return stage;
}
return NULL; return NULL;
} }
@ -1216,6 +1210,13 @@ set_foreign_window_callback (ClutterActor *actor,
clutter_actor_set_geometry (actor, &fwd->geom); clutter_actor_set_geometry (actor, &fwd->geom);
if (clutter_stages_by_xid == NULL)
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
g_hash_table_insert (clutter_stages_by_xid,
GINT_TO_POINTER (fwd->stage_x11->xwin),
fwd->stage_x11);
/* calling this with the stage unrealized will unset the stage /* calling this with the stage unrealized will unset the stage
* from the GL context; once the stage is realized the GL context * from the GL context; once the stage is realized the GL context
* will be set again * will be set again
@ -1329,11 +1330,18 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
void void
_clutter_stage_x11_destroy_window_untrapped (ClutterStageX11 *stage_x11) _clutter_stage_x11_destroy_window_untrapped (ClutterStageX11 *stage_x11)
{ {
if (!stage_x11->is_foreign_xwin && stage_x11->xwin != None) Window xwin = stage_x11->xwin;
if (clutter_stages_by_xid != NULL)
g_hash_table_remove (clutter_stages_by_xid, GINT_TO_POINTER (xwin));
if (!stage_x11->is_foreign_xwin && xwin != None)
{ {
ClutterBackendX11 *backend_x11 = stage_x11->backend; ClutterBackendX11 *backend_x11 = stage_x11->backend;
XDestroyWindow (backend_x11->xdpy, stage_x11->xwin); g_assert (clutter_stages_by_xid != NULL);
XDestroyWindow (backend_x11->xdpy, xwin);
stage_x11->xwin = None; stage_x11->xwin = None;
} }
else else
@ -1415,6 +1423,13 @@ _clutter_stage_x11_create_window (ClutterStageX11 *stage_x11)
XFree (xvisinfo); XFree (xvisinfo);
if (clutter_stages_by_xid == NULL)
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
g_hash_table_insert (clutter_stages_by_xid,
GINT_TO_POINTER (stage_x11->xwin),
stage_x11);
return TRUE; return TRUE;
} }