mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 13:22:15 +00:00
[x11 backend] remove data duplicated between backends and stages
Make backends the canonical point of reference for the xdisplay, the xscreen number, the x root window and the xvisinfo for creating foreign stages.
This commit is contained in:
parent
63414ab233
commit
3187e19642
@ -248,16 +248,12 @@ clutter_backend_egl_create_stage (ClutterBackend *backend,
|
||||
|
||||
/* copy backend data into the stage */
|
||||
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
||||
stage_x11->xdpy = backend_x11->xdpy;
|
||||
stage_x11->xwin_root = backend_x11->xwin_root;
|
||||
stage_x11->xscreen = backend_x11->xscreen_num;
|
||||
stage_x11->backend = backend_x11;
|
||||
stage_x11->wrapper = wrapper;
|
||||
|
||||
CLUTTER_NOTE (MISC, "EGLX stage created (display:%p, screen:%d, root:%u)",
|
||||
stage_x11->xdpy,
|
||||
stage_x11->xscreen,
|
||||
(unsigned int) stage_x11->xwin_root);
|
||||
backend_x11->xdpy,
|
||||
backend_x11->xscreen_num,
|
||||
(unsigned int) backend_x11->xwin_root);
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageEGL,
|
||||
static void
|
||||
clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
@ -41,7 +43,7 @@ clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
if (!stage_x11->is_foreign_xwin && stage_x11->xwin != None)
|
||||
{
|
||||
XDestroyWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
XDestroyWindow (backend_x11->xdpy, stage_x11->xwin);
|
||||
stage_x11->xwin = None;
|
||||
}
|
||||
else
|
||||
@ -53,7 +55,7 @@ clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
|
||||
stage_egl->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
XSync (stage_x11->xdpy, False);
|
||||
XSync (backend_x11->xdpy, False);
|
||||
|
||||
clutter_x11_untrap_x_errors ();
|
||||
}
|
||||
@ -149,20 +151,20 @@ clutter_stage_egl_realize (ClutterStageWindow *stage_window)
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
stage_x11->xwin =
|
||||
XCreateSimpleWindow (stage_x11->xdpy,
|
||||
stage_x11->xwin_root,
|
||||
XCreateSimpleWindow (backend_x11->xdpy,
|
||||
backend_x11->xwin_root,
|
||||
0, 0,
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height,
|
||||
0, 0,
|
||||
WhitePixel (stage_x11->xdpy,
|
||||
stage_x11->xscreen));
|
||||
WhitePixel (backend_x11->xdpy,
|
||||
backend_x11->xscreen_num));
|
||||
|
||||
if (clutter_x11_has_event_retrieval ())
|
||||
{
|
||||
if (clutter_x11_has_xinput ())
|
||||
{
|
||||
XSelectInput (stage_x11->xdpy, stage_x11->xwin,
|
||||
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
|
||||
StructureNotifyMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
@ -173,7 +175,7 @@ clutter_stage_egl_realize (ClutterStageWindow *stage_window)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
XSelectInput (stage_x11->xdpy, stage_x11->xwin,
|
||||
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
|
||||
StructureNotifyMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
|
@ -354,10 +354,14 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||
return flags;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_backend_glx_get_fbconfig (ClutterBackendX11 *backend_x11,
|
||||
GLXFBConfig *config)
|
||||
/* It seems the GLX spec never defined an invalid GLXFBConfig that
|
||||
* we could overload as an indication of error, so we have to return
|
||||
* an explicit boolean status. */
|
||||
gboolean
|
||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
|
||||
GLXFBConfig *config)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
|
||||
int attributes[] = {
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
@ -376,6 +380,12 @@ clutter_backend_glx_get_fbconfig (ClutterBackendX11 *backend_x11,
|
||||
if (backend_x11->xdpy == None || backend_x11->xscreen == None)
|
||||
return FALSE;
|
||||
|
||||
if (backend_glx->found_fbconfig)
|
||||
{
|
||||
*config = backend_glx->fbconfig;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"Retrieving GL fbconfig, dpy: %p, xscreen; %p (%d)",
|
||||
backend_x11->xdpy,
|
||||
@ -387,12 +397,13 @@ clutter_backend_glx_get_fbconfig (ClutterBackendX11 *backend_x11,
|
||||
attributes,
|
||||
&n_configs);
|
||||
if (configs)
|
||||
*config = configs[0];
|
||||
|
||||
XFree (configs);
|
||||
|
||||
if (configs)
|
||||
return TRUE;
|
||||
{
|
||||
*config = configs[0];
|
||||
backend_glx->found_fbconfig = TRUE;
|
||||
backend_glx->fbconfig = configs[0];
|
||||
XFree (configs);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@ -400,9 +411,10 @@ clutter_backend_glx_get_fbconfig (ClutterBackendX11 *backend_x11,
|
||||
static XVisualInfo *
|
||||
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend_x11);
|
||||
GLXFBConfig config;
|
||||
|
||||
if (!clutter_backend_glx_get_fbconfig (backend_x11, &config))
|
||||
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
||||
return NULL;
|
||||
|
||||
return glXGetVisualFromFBConfig (backend_x11->xdpy, config);
|
||||
@ -420,7 +432,7 @@ clutter_backend_glx_create_context (ClutterBackend *backend,
|
||||
GLXFBConfig config;
|
||||
gboolean is_direct;
|
||||
|
||||
if (!clutter_backend_glx_get_fbconfig (backend_x11, &config))
|
||||
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
||||
{
|
||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
@ -479,6 +491,7 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||
else
|
||||
{
|
||||
ClutterBackendGLX *backend_glx;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageGLX *stage_glx;
|
||||
ClutterStageX11 *stage_x11;
|
||||
|
||||
@ -491,6 +504,7 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||
stage_glx = CLUTTER_STAGE_GLX (impl);
|
||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
/* no GL context to set */
|
||||
if (backend_glx->gl_context == None)
|
||||
@ -503,9 +517,6 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||
*/
|
||||
if (stage_x11->xwin == None)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
CLUTTER_NOTE (MULTISTAGE,
|
||||
"Received a stale stage, clearing all context");
|
||||
|
||||
@ -515,12 +526,12 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"MakeContextCurrent dpy: %p, window: 0x%x (%s), context: %p",
|
||||
stage_x11->xdpy,
|
||||
backend_x11->xdpy,
|
||||
(int) stage_x11->xwin,
|
||||
stage_x11->is_foreign_xwin ? "foreign" : "native",
|
||||
backend_glx->gl_context);
|
||||
|
||||
glXMakeContextCurrent (stage_x11->xdpy,
|
||||
glXMakeContextCurrent (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
stage_x11->xwin,
|
||||
backend_glx->gl_context);
|
||||
@ -596,6 +607,7 @@ static void
|
||||
clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||
ClutterStage *stage)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageGLX *stage_glx;
|
||||
ClutterStageX11 *stage_x11;
|
||||
ClutterStageWindow *impl;
|
||||
@ -609,6 +621,7 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||
|
||||
g_assert (CLUTTER_IS_STAGE_GLX (impl));
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||
stage_glx = CLUTTER_STAGE_GLX (impl);
|
||||
|
||||
@ -624,9 +637,9 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||
|
||||
/* push on the screen */
|
||||
CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)",
|
||||
stage_x11->xdpy,
|
||||
backend_x11->xdpy,
|
||||
(unsigned long) stage_x11->xwin);
|
||||
glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin);
|
||||
glXSwapBuffers (backend_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -646,18 +659,14 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
||||
|
||||
/* copy backend data into the stage */
|
||||
stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
stage_x11->xdpy = backend_x11->xdpy;
|
||||
stage_x11->xwin_root = backend_x11->xwin_root;
|
||||
stage_x11->xscreen = backend_x11->xscreen_num;
|
||||
stage_x11->backend = backend_x11;
|
||||
stage_x11->wrapper = wrapper;
|
||||
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"GLX stage created[%p] (dpy:%p, screen:%d, root:%u, wrap:%p)",
|
||||
stage_window,
|
||||
stage_x11->xdpy,
|
||||
stage_x11->xscreen,
|
||||
(unsigned int) stage_x11->xwin_root,
|
||||
backend_x11->xdpy,
|
||||
backend_x11->xscreen_num,
|
||||
(unsigned int) backend_x11->xwin_root,
|
||||
wrapper);
|
||||
|
||||
return stage_window;
|
||||
|
@ -63,6 +63,8 @@ struct _ClutterBackendGLX
|
||||
ClutterBackendX11 parent_instance;
|
||||
|
||||
/* Single context for all wins */
|
||||
gboolean found_fbconfig;
|
||||
GLXFBConfig fbconfig;
|
||||
GLXContext gl_context;
|
||||
|
||||
/* Vblank stuff */
|
||||
@ -84,6 +86,10 @@ struct _ClutterBackendGLXClass
|
||||
|
||||
GType clutter_backend_glx_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gboolean
|
||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_x11,
|
||||
GLXFBConfig *config);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_GLX_H__ */
|
||||
|
@ -60,6 +60,8 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX,
|
||||
static void
|
||||
clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
/* Note unrealize should free up any backend stage related resources */
|
||||
@ -69,19 +71,13 @@ clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
if (!stage_x11->is_foreign_xwin && stage_x11->xwin != None)
|
||||
{
|
||||
XDestroyWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
XDestroyWindow (backend_x11->xdpy, stage_x11->xwin);
|
||||
stage_x11->xwin = None;
|
||||
}
|
||||
else
|
||||
stage_x11->xwin = None;
|
||||
|
||||
if (stage_x11->xvisinfo != None)
|
||||
{
|
||||
XFree (stage_x11->xvisinfo);
|
||||
stage_x11->xvisinfo = None;
|
||||
}
|
||||
|
||||
XSync (stage_x11->xdpy, False);
|
||||
XSync (backend_x11->xdpy, False);
|
||||
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
@ -105,47 +101,55 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
|
||||
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
stage_x11->xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
|
||||
|
||||
if (stage_x11->xvisinfo == None)
|
||||
{
|
||||
g_critical ("Unable to find suitable GL visual.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
{
|
||||
XSetWindowAttributes xattr;
|
||||
unsigned long mask;
|
||||
GLXFBConfig config;
|
||||
XVisualInfo *xvisinfo;
|
||||
|
||||
CLUTTER_NOTE (MISC, "Creating stage X window");
|
||||
|
||||
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
||||
{
|
||||
g_critical ("Unable to find suitable FBConfig to realize stage.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xvisinfo = glXGetVisualFromFBConfig (backend_x11->xdpy, config);
|
||||
if (xvisinfo == NULL)
|
||||
{
|
||||
g_critical ("Unable to find suitable GL visual.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
xattr.background_pixel = WhitePixel (stage_x11->xdpy,
|
||||
stage_x11->xscreen);
|
||||
xattr.background_pixel = WhitePixel (backend_x11->xdpy,
|
||||
backend_x11->xscreen_num);
|
||||
xattr.border_pixel = 0;
|
||||
xattr.colormap = XCreateColormap (stage_x11->xdpy,
|
||||
stage_x11->xwin_root,
|
||||
stage_x11->xvisinfo->visual,
|
||||
xattr.colormap = XCreateColormap (backend_x11->xdpy,
|
||||
backend_x11->xwin_root,
|
||||
xvisinfo->visual,
|
||||
AllocNone);
|
||||
mask = CWBorderPixel | CWColormap;
|
||||
stage_x11->xwin = XCreateWindow (stage_x11->xdpy,
|
||||
stage_x11->xwin_root,
|
||||
stage_x11->xwin = XCreateWindow (backend_x11->xdpy,
|
||||
backend_x11->xwin_root,
|
||||
0, 0,
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height,
|
||||
0,
|
||||
stage_x11->xvisinfo->depth,
|
||||
xvisinfo->depth,
|
||||
InputOutput,
|
||||
stage_x11->xvisinfo->visual,
|
||||
xvisinfo->visual,
|
||||
mask, &xattr);
|
||||
XFree (xvisinfo);
|
||||
}
|
||||
|
||||
if (clutter_x11_has_event_retrieval())
|
||||
{
|
||||
if (clutter_x11_has_xinput())
|
||||
{
|
||||
XSelectInput (stage_x11->xdpy, stage_x11->xwin,
|
||||
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
|
||||
StructureNotifyMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
@ -157,7 +161,7 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
XSelectInput (stage_x11->xdpy, stage_x11->xwin,
|
||||
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
|
||||
StructureNotifyMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
|
@ -993,3 +993,4 @@ clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,11 @@ struct _ClutterBackendX11Class
|
||||
{
|
||||
ClutterBackendClass parent_class;
|
||||
|
||||
/*
|
||||
* To support foreign stage windows the we need a way to ask for an
|
||||
* XVisualInfo that may be used by toolkits to create an XWindow, and this
|
||||
* may need to be handled differently for different backends.
|
||||
*/
|
||||
XVisualInfo *(* get_visual_info) (ClutterBackendX11 *backend);
|
||||
};
|
||||
|
||||
|
@ -91,8 +91,13 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
gint new_width,
|
||||
gint new_height)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
gboolean resize;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
|
||||
|
||||
if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin)
|
||||
@ -134,7 +139,7 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
}
|
||||
}
|
||||
|
||||
XSetWMNormalHints (stage_x11->xdpy, stage_x11->xwin, size_hints);
|
||||
XSetWMNormalHints (backend_x11->xdpy, stage_x11->xwin, size_hints);
|
||||
|
||||
XFree(size_hints);
|
||||
}
|
||||
@ -143,23 +148,32 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
void
|
||||
clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
Atom protocols[2];
|
||||
int n = 0;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
protocols[n++] = backend_x11->atom_WM_DELETE_WINDOW;
|
||||
protocols[n++] = backend_x11->atom_NET_WM_PING;
|
||||
|
||||
XSetWMProtocols (stage_x11->xdpy, stage_x11->xwin, protocols, n);
|
||||
XSetWMProtocols (backend_x11->xdpy, stage_x11->xwin, protocols, n);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
|
||||
ClutterGeometry *geometry)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
gboolean is_fullscreen, resize;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
is_fullscreen = FALSE;
|
||||
g_object_get (G_OBJECT (stage_x11->wrapper),
|
||||
"fullscreen-set", &is_fullscreen,
|
||||
@ -167,8 +181,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
|
||||
|
||||
if (is_fullscreen || stage_x11->fullscreen_on_map)
|
||||
{
|
||||
geometry->width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
|
||||
geometry->height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
|
||||
geometry->width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
|
||||
geometry->height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -193,11 +207,16 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
gboolean resize;
|
||||
|
||||
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
/* Should not happen, if this turns up we need to debug it and
|
||||
@ -227,7 +246,7 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
CLUTTER_SET_PRIVATE_FLAGS (stage_x11->wrapper,
|
||||
CLUTTER_STAGE_IN_RESIZE);
|
||||
|
||||
XResizeWindow (stage_x11->xdpy,
|
||||
XResizeWindow (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height);
|
||||
@ -235,35 +254,28 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
|
||||
if (!resize)
|
||||
clutter_stage_x11_fix_window_size (stage_x11, width, height);
|
||||
|
||||
if (stage_x11->xpixmap != None)
|
||||
{
|
||||
/* Need to recreate to resize */
|
||||
_clutter_actor_rerealize (CLUTTER_ACTOR (stage_x11->wrapper),
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_wm_pid (ClutterStageX11 *stage_x11)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
long pid;
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
return;
|
||||
|
||||
/* this will take care of WM_CLIENT_MACHINE and WM_LOCALE_NAME */
|
||||
XSetWMProperties (stage_x11->xdpy, stage_x11->xwin,
|
||||
XSetWMProperties (backend_x11->xdpy, stage_x11->xwin,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, 0,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
pid = getpid();
|
||||
XChangeProperty (stage_x11->xdpy,
|
||||
XChangeProperty (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32,
|
||||
PropModeReplace,
|
||||
@ -273,26 +285,30 @@ set_wm_pid (ClutterStageX11 *stage_x11)
|
||||
static inline void
|
||||
set_wm_title (ClutterStageX11 *stage_x11)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
return;
|
||||
|
||||
if (stage_x11->title == NULL)
|
||||
{
|
||||
XDeleteProperty (stage_x11->xdpy,
|
||||
XDeleteProperty (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
XChangeProperty (stage_x11->xdpy,
|
||||
XChangeProperty (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_NAME,
|
||||
backend_x11->atom_UTF8_STRING,
|
||||
backend_x11->atom_NET_WM_NAME,
|
||||
backend_x11->atom_UTF8_STRING,
|
||||
8,
|
||||
PropModeReplace,
|
||||
(unsigned char *) stage_x11->title,
|
||||
(unsigned char *) stage_x11->title,
|
||||
(int) strlen (stage_x11->title));
|
||||
}
|
||||
}
|
||||
@ -300,6 +316,12 @@ set_wm_title (ClutterStageX11 *stage_x11)
|
||||
static inline void
|
||||
set_cursor_visible (ClutterStageX11 *stage_x11)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
return;
|
||||
|
||||
@ -310,9 +332,9 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
|
||||
if (stage_x11->is_cursor_visible)
|
||||
{
|
||||
#if 0 /* HAVE_XFIXES - seems buggy/unreliable */
|
||||
XFixesShowCursor (stage_x11->xdpy, stage_x11->xwin);
|
||||
XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin);
|
||||
#else
|
||||
XUndefineCursor (stage_x11->xdpy, stage_x11->xwin);
|
||||
XUndefineCursor (backend_x11->xdpy, stage_x11->xwin);
|
||||
#endif /* HAVE_XFIXES */
|
||||
}
|
||||
else
|
||||
@ -320,20 +342,20 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
|
||||
#if 0 /* HAVE_XFIXES - seems buggy/unreliable, check cursor in firefox
|
||||
* loading page after hiding.
|
||||
*/
|
||||
XFixesHideCursor (stage_x11->xdpy, stage_x11->xwin);
|
||||
XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin);
|
||||
#else
|
||||
XColor col;
|
||||
Pixmap pix;
|
||||
Cursor curs;
|
||||
|
||||
pix = XCreatePixmap (stage_x11->xdpy, stage_x11->xwin, 1, 1, 1);
|
||||
pix = XCreatePixmap (backend_x11->xdpy, stage_x11->xwin, 1, 1, 1);
|
||||
memset (&col, 0, sizeof (col));
|
||||
curs = XCreatePixmapCursor (stage_x11->xdpy,
|
||||
curs = XCreatePixmapCursor (backend_x11->xdpy,
|
||||
pix, pix,
|
||||
&col, &col,
|
||||
1, 1);
|
||||
XFreePixmap (stage_x11->xdpy, pix);
|
||||
XDefineCursor (stage_x11->xdpy, stage_x11->xwin, curs);
|
||||
XFreePixmap (backend_x11->xdpy, pix);
|
||||
XDefineCursor (backend_x11->xdpy, stage_x11->xwin, curs);
|
||||
#endif /* HAVE_XFIXES */
|
||||
}
|
||||
}
|
||||
@ -354,10 +376,14 @@ static void
|
||||
clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
gboolean is_fullscreen)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
ClutterStage *stage = stage_x11->wrapper;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
@ -372,8 +398,8 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
but Metacity (at least) will fullscreen to only one of the
|
||||
displays. This will cause the actor to report the wrong size
|
||||
until the ConfigureNotify for the correct size is received */
|
||||
width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
|
||||
height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
|
||||
width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
|
||||
height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);
|
||||
|
||||
/* we force the stage to the screen size here, in order to
|
||||
* get the fullscreen stage size right after the call to
|
||||
@ -397,7 +423,7 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (stage_x11))
|
||||
{
|
||||
/* FIXME: This wont work if we support more states */
|
||||
XChangeProperty (stage_x11->xdpy,
|
||||
XChangeProperty (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeReplace,
|
||||
@ -427,7 +453,7 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (stage_x11))
|
||||
{
|
||||
/* FIXME: This wont work if we support more states */
|
||||
XDeleteProperty (stage_x11->xdpy,
|
||||
XDeleteProperty (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
backend_x11->atom_NET_WM_STATE);
|
||||
}
|
||||
@ -482,15 +508,20 @@ clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window,
|
||||
static void
|
||||
update_wm_hints (ClutterStageX11 *stage_x11)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
XWMHints wm_hints;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage_x11->wm_state & STAGE_X11_WITHDRAWN)
|
||||
return;
|
||||
|
||||
wm_hints.flags = StateHint;
|
||||
wm_hints.initial_state = NormalState;
|
||||
|
||||
XSetWMHints (stage_x11->xdpy, stage_x11->xwin, &wm_hints);
|
||||
XSetWMHints (backend_x11->xdpy, stage_x11->xwin, &wm_hints);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -516,15 +547,20 @@ static void
|
||||
clutter_stage_x11_show (ClutterStageWindow *stage_window,
|
||||
gboolean do_raise)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
if (do_raise)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Raising stage[%lu]",
|
||||
(unsigned long) stage_x11->xwin);
|
||||
XRaiseWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
XRaiseWindow (backend_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
|
||||
if (!STAGE_X11_IS_MAPPED (stage_x11))
|
||||
@ -546,15 +582,20 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
|
||||
|
||||
clutter_actor_map (CLUTTER_ACTOR (stage_x11->wrapper));
|
||||
|
||||
XMapWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||
XMapWindow (backend_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_hide (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
if (STAGE_X11_IS_MAPPED (stage_x11))
|
||||
@ -564,7 +605,7 @@ clutter_stage_x11_hide (ClutterStageWindow *stage_window)
|
||||
|
||||
clutter_actor_unmap (CLUTTER_ACTOR (stage_x11->wrapper));
|
||||
|
||||
XWithdrawWindow (stage_x11->xdpy,
|
||||
XWithdrawWindow (backend_x11->xdpy,
|
||||
stage_x11->xwin,
|
||||
0);
|
||||
}
|
||||
@ -604,14 +645,9 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
||||
static void
|
||||
clutter_stage_x11_init (ClutterStageX11 *stage)
|
||||
{
|
||||
stage->xdpy = NULL;
|
||||
stage->xwin_root = None;
|
||||
stage->xscreen = 0;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
stage->xvisinfo = None;
|
||||
|
||||
stage->wm_state = STAGE_X11_WITHDRAWN;
|
||||
|
||||
@ -645,7 +681,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
* clutter_x11_get_stage_window:
|
||||
* @stage: a #ClutterStage
|
||||
*
|
||||
* Gets the stages X Window.
|
||||
* Gets the stages X Window.
|
||||
*
|
||||
* Return value: An XID for the stage window.
|
||||
*
|
||||
@ -703,34 +739,29 @@ clutter_x11_get_stage_from_window (Window win)
|
||||
* clutter_x11_get_stage_visual:
|
||||
* @stage: a #ClutterStage
|
||||
*
|
||||
* Returns the stage XVisualInfo
|
||||
* Returns an XVisualInfo suitable for creating a foreign window for the given
|
||||
* stage. NOTE: It doesn't do as the name may suggest, which is return the
|
||||
* XVisualInfo that was used to create an existing window for the given stage.
|
||||
*
|
||||
* Return value: The XVisualInfo for the stage.
|
||||
* XXX: It might be best to deprecate this function and replace with something
|
||||
* along the lines of clutter_backend_x11_get_foreign_visual () or perhaps
|
||||
* clutter_stage_x11_get_foreign_visual ()
|
||||
*
|
||||
* Return value: An XVisualInfo suitable for creating a foreign stage.
|
||||
* You should free this using XFree.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
XVisualInfo *
|
||||
clutter_x11_get_stage_visual (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageWindow *impl;
|
||||
ClutterStageX11 *stage_x11;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||
g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend), NULL);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
g_assert (CLUTTER_IS_STAGE_X11 (impl));
|
||||
|
||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||
|
||||
if (stage_x11->xvisinfo == NULL)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
|
||||
stage_x11->xvisinfo =
|
||||
clutter_backend_x11_get_visual_info (backend_x11);
|
||||
}
|
||||
|
||||
return stage_x11->xvisinfo;
|
||||
return clutter_backend_x11_get_visual_info (backend_x11);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -745,6 +776,8 @@ set_foreign_window_callback (ClutterActor *actor,
|
||||
void *data)
|
||||
{
|
||||
ForeignWindowData *fwd = data;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)",
|
||||
(unsigned int) fwd->xwindow);
|
||||
@ -753,7 +786,7 @@ set_foreign_window_callback (ClutterActor *actor,
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Destroying previous window (0x%x)",
|
||||
(unsigned int) fwd->xwindow);
|
||||
XDestroyWindow (fwd->stage_x11->xdpy, fwd->stage_x11->xwin);
|
||||
XDestroyWindow (backend_x11->xdpy, fwd->stage_x11->xwin);
|
||||
}
|
||||
|
||||
fwd->stage_x11->xwin = fwd->xwindow;
|
||||
@ -786,6 +819,8 @@ gboolean
|
||||
clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
Window xwindow)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterStageX11 *stage_x11;
|
||||
ClutterStageWindow *impl;
|
||||
ClutterActor *actor;
|
||||
@ -794,6 +829,10 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
Window root_return;
|
||||
Status status;
|
||||
ForeignWindowData fwd;
|
||||
XVisualInfo *xvisinfo;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend), FALSE);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||
g_return_val_if_fail (xwindow != None, FALSE);
|
||||
@ -803,19 +842,21 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||
|
||||
xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
|
||||
status = XGetGeometry (stage_x11->xdpy, xwindow,
|
||||
status = XGetGeometry (backend_x11->xdpy, xwindow,
|
||||
&root_return,
|
||||
&x, &y,
|
||||
&width, &height,
|
||||
&border,
|
||||
&depth);
|
||||
|
||||
|
||||
if (clutter_x11_untrap_x_errors () ||
|
||||
!status ||
|
||||
width == 0 || height == 0 ||
|
||||
depth != stage_x11->xvisinfo->depth)
|
||||
depth != xvisinfo->depth)
|
||||
{
|
||||
g_warning ("Unable to retrieve the new window geometry");
|
||||
return FALSE;
|
||||
|
@ -54,17 +54,11 @@ struct _ClutterStageX11
|
||||
guint fullscreen_on_map : 1;
|
||||
guint is_cursor_visible : 1;
|
||||
|
||||
Display *xdpy;
|
||||
Window xwin_root;
|
||||
int xscreen;
|
||||
XVisualInfo *xvisinfo;
|
||||
Window xwin;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
Pixmap xpixmap;
|
||||
gchar *title;
|
||||
|
||||
ClutterBackendX11 *backend;
|
||||
ClutterStageState state;
|
||||
|
||||
ClutterStageX11State wm_state;
|
||||
|
Loading…
Reference in New Issue
Block a user