From b2482a2069c07546cb5ae03ac5f60d833a29bebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 19 Oct 2020 23:22:21 +0200 Subject: [PATCH] cogl: Add CoglX11Onscreen interface Mutter needs to fetch the X11 Window ID from the onscreen and did that by using an X11 specific API on the CoglOnscreen, where the X11 type was "expanded" (Window -> uint32_t). Change this by introducing an interface called CoglX11Onscreen, implemented by both the Xlib and GLX onscreen implementations, that keeps the right type (Window), while avoiding X11 specific API for CoglOnscreen. Part-of: --- cogl/cogl/cogl-mutter.h | 3 ++ cogl/cogl/cogl-onscreen.c | 14 -------- cogl/cogl/cogl-onscreen.h | 23 ------------ cogl/cogl/cogl-x11-onscreen.c | 40 +++++++++++++++++++++ cogl/cogl/cogl-x11-onscreen.h | 49 ++++++++++++++++++++++++++ cogl/cogl/meson.build | 2 ++ cogl/cogl/winsys/cogl-onscreen-glx.c | 22 +++++++++--- cogl/cogl/winsys/cogl-onscreen-glx.h | 3 -- cogl/cogl/winsys/cogl-onscreen-xlib.c | 22 +++++++++--- cogl/cogl/winsys/cogl-onscreen-xlib.h | 3 -- cogl/cogl/winsys/cogl-winsys-egl-x11.c | 3 -- cogl/cogl/winsys/cogl-winsys-glx.c | 2 -- cogl/cogl/winsys/cogl-winsys-private.h | 3 -- src/backends/x11/meta-stage-x11.c | 3 +- 14 files changed, 130 insertions(+), 62 deletions(-) create mode 100644 cogl/cogl/cogl-x11-onscreen.c create mode 100644 cogl/cogl/cogl-x11-onscreen.h diff --git a/cogl/cogl/cogl-mutter.h b/cogl/cogl/cogl-mutter.h index 1f94d0d99..a8bf45919 100644 --- a/cogl/cogl/cogl-mutter.h +++ b/cogl/cogl/cogl-mutter.h @@ -48,6 +48,9 @@ #if defined (COGL_HAS_XLIB_SUPPORT) #include #endif +#ifdef COGL_HAS_X11 +#include +#endif #include COGL_EXPORT diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index 29df1c067..214e0d9df 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -498,20 +498,6 @@ cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen) return g_queue_pop_head (&priv->pending_frame_infos); } -#ifdef COGL_HAS_X11_SUPPORT -uint32_t -cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - /* This should only be called for x11 onscreens */ - g_return_val_if_fail (winsys->onscreen_x11_get_window_xid != NULL, 0); - - return winsys->onscreen_x11_get_window_xid (onscreen); -} -#endif /* COGL_HAS_X11_SUPPORT */ - CoglFrameClosure * cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, CoglFrameCallback callback, diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index a179d942c..3b761cd3d 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -90,29 +90,6 @@ typedef enum _CoglScanoutError COGL_SCANOUT_ERROR_INHIBITED, } CoglScanoutError; -#ifdef COGL_HAS_X11 -/** - * cogl_x11_onscreen_get_window_xid: - * @onscreen: A #CoglOnscreen framebuffer - * - * Assuming you know the given @onscreen framebuffer is based on an x11 window - * this queries the XID of that window. If - * cogl_x11_onscreen_set_foreign_window_xid() was previously called then it - * will return that same XID otherwise it will be the XID of a window Cogl - * created internally. If the window has not been allocated yet and a foreign - * xid has not been set then it's undefined what value will be returned. - * - * It's undefined what this function does if called when not using an x11 based - * renderer. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT uint32_t -cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen); - -#endif /* COGL_HAS_X11 */ - /** * cogl_onscreen_show: * @onscreen: The onscreen framebuffer to make visible diff --git a/cogl/cogl/cogl-x11-onscreen.c b/cogl/cogl/cogl-x11-onscreen.c new file mode 100644 index 000000000..2a4bf9e3b --- /dev/null +++ b/cogl/cogl/cogl-x11-onscreen.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "cogl-config.h" + +#include "cogl-x11-onscreen.h" + +G_DEFINE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, + G_TYPE_OBJECT) + +Window +cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen) +{ + CoglX11OnscreenInterface *iface = + COGL_X11_ONSCREEN_GET_IFACE (x11_onscreen); + + return iface->get_x11_window (x11_onscreen); +} + +static void +cogl_x11_onscreen_default_init (CoglX11OnscreenInterface *iface) +{ +} diff --git a/cogl/cogl/cogl-x11-onscreen.h b/cogl/cogl/cogl-x11-onscreen.h new file mode 100644 index 000000000..80bec7893 --- /dev/null +++ b/cogl/cogl/cogl-x11-onscreen.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef COGL_X11_ONSCREEN_H +#define COGL_X11_ONSCREEN_H + +#include +#include + +#include "cogl-macros.h" + +#define COGL_TYPE_X11_ONSCREEN (cogl_x11_onscreen_get_type ()) +COGL_EXPORT +G_DECLARE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, + COGL, X11_ONSCREEN, + GObject) + +struct _CoglX11OnscreenInterface +{ + GTypeInterface parent_iface; + + Window (* get_x11_window) (CoglX11Onscreen *x11_onscreen); +}; + +COGL_EXPORT +Window cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen); + +#endif /* COGL_X11_ONSCREEN_H */ diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index 27ad72b2d..f8ae283a8 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -371,6 +371,8 @@ if have_x11 'cogl-xlib.h', ] cogl_sources += [ + 'cogl-x11-onscreen.c', + 'cogl-x11-onscreen.h', 'cogl-x11-renderer-private.h', 'cogl-xlib-private.h', 'cogl-xlib-renderer-private.h', diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c index 7a6f31acf..54e9146f1 100644 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ b/cogl/cogl/winsys/cogl-onscreen-glx.c @@ -33,6 +33,7 @@ #include "cogl-context-private.h" #include "cogl-frame-info-private.h" #include "cogl-renderer-private.h" +#include "cogl-x11-onscreen.h" #include "cogl-xlib-renderer-private.h" #include "winsys/cogl-glx-display-private.h" #include "winsys/cogl-glx-renderer-private.h" @@ -52,8 +53,13 @@ struct _CoglOnscreenGlx uint32_t pending_complete_notify; }; -G_DEFINE_TYPE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL_TYPE_ONSCREEN) +static void +x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (CoglOnscreenGlx, cogl_onscreen_glx, + COGL_TYPE_ONSCREEN, + G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, + x11_onscreen_init_iface)) #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) @@ -942,10 +948,10 @@ cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, set_frame_info_output (onscreen, onscreen_glx->output); } -uint32_t -_cogl_winsys_onscreen_glx_get_window_xid (CoglOnscreen *onscreen) +static Window +cogl_onscreen_glx_get_x11_window (CoglX11Onscreen *x11_onscreen) { - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); + CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (x11_onscreen); return onscreen_glx->xwin; } @@ -1085,6 +1091,12 @@ cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx) { } +static void +x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) +{ + iface->get_x11_window = cogl_onscreen_glx_get_x11_window; +} + static void cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass) { diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.h b/cogl/cogl/winsys/cogl-onscreen-glx.h index 9ae9c7301..81ac7be08 100644 --- a/cogl/cogl/winsys/cogl-onscreen-glx.h +++ b/cogl/cogl/winsys/cogl-onscreen-glx.h @@ -44,9 +44,6 @@ cogl_onscreen_glx_new (CoglContext *context, int _cogl_winsys_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen); -uint32_t -_cogl_winsys_onscreen_glx_get_window_xid (CoglOnscreen *onscreen); - void cogl_onscreen_glx_resize (CoglOnscreen *onscreen, XConfigureEvent *configure_event); diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c index ef14abbbe..9030fd07d 100644 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.c +++ b/cogl/cogl/winsys/cogl-onscreen-xlib.c @@ -30,6 +30,7 @@ #include "cogl-context-private.h" #include "cogl-renderer-private.h" +#include "cogl-x11-onscreen.h" #include "cogl-xlib-renderer-private.h" #include "winsys/cogl-onscreen-egl.h" #include "winsys/cogl-winsys-egl-x11-private.h" @@ -41,8 +42,13 @@ struct _CoglOnscreenXlib Window xwin; }; -G_DEFINE_TYPE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL_TYPE_ONSCREEN_EGL) +static void +x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (CoglOnscreenXlib, cogl_onscreen_xlib, + COGL_TYPE_ONSCREEN_EGL, + G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, + x11_onscreen_init_iface)) #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) @@ -194,10 +200,10 @@ cogl_onscreen_xlib_dispose (GObject *object) } } -uint32_t -_cogl_winsys_onscreen_xlib_get_window_xid (CoglOnscreen *onscreen) +static Window +cogl_onscreen_xlib_get_x11_window (CoglX11Onscreen *x11_onscreen) { - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); + CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (x11_onscreen); return onscreen_xlib->xwin; } @@ -244,6 +250,12 @@ cogl_onscreen_xlib_init (CoglOnscreenXlib *onscreen_xlib) { } +static void +x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) +{ + iface->get_x11_window = cogl_onscreen_xlib_get_x11_window; +} + static void cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *klass) { diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.h b/cogl/cogl/winsys/cogl-onscreen-xlib.h index 4584735f8..07a1ceaa0 100644 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.h +++ b/cogl/cogl/winsys/cogl-onscreen-xlib.h @@ -49,9 +49,6 @@ cogl_onscreen_xlib_new (CoglContext *context, void _cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen); -uint32_t -_cogl_winsys_onscreen_xlib_get_window_xid (CoglOnscreen *onscreen); - gboolean cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, Window window); diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c index fc57e6471..e972bde50 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c @@ -590,9 +590,6 @@ _cogl_winsys_egl_xlib_get_vtable (void) vtable.renderer_connect = _cogl_winsys_renderer_connect; vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect; - vtable.onscreen_x11_get_window_xid = - _cogl_winsys_onscreen_xlib_get_window_xid; - #ifdef EGL_KHR_image_pixmap /* X11 tfp support... */ /* XXX: instead of having a rather monolithic winsys vtable we could diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c index 1a37b951d..df60c1986 100644 --- a/cogl/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/cogl/winsys/cogl-winsys-glx.c @@ -1470,8 +1470,6 @@ static CoglWinsysVtable _cogl_winsys_vtable = .context_deinit = _cogl_winsys_context_deinit, .context_get_clock_time = _cogl_winsys_get_clock_time, .onscreen_get_buffer_age = _cogl_winsys_onscreen_glx_get_buffer_age, - .onscreen_x11_get_window_xid = - _cogl_winsys_onscreen_glx_get_window_xid, /* X11 tfp support... */ /* XXX: instead of having a rather monolithic winsys vtable we could diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index 8621c1fad..dc150752a 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -112,9 +112,6 @@ typedef struct _CoglWinsysVtable int (*onscreen_get_buffer_age) (CoglOnscreen *onscreen); - uint32_t - (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen); - #ifdef COGL_HAS_XLIB_SUPPORT gboolean (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); diff --git a/src/backends/x11/meta-stage-x11.c b/src/backends/x11/meta-stage-x11.c index bc7e53760..938d65cbf 100644 --- a/src/backends/x11/meta-stage-x11.c +++ b/src/backends/x11/meta-stage-x11.c @@ -330,7 +330,8 @@ meta_stage_x11_realize (ClutterStageWindow *stage_window) if (!(clutter_stage_window_parent_iface->realize (stage_window))) return FALSE; - stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_x11->onscreen); + stage_x11->xwin = + cogl_x11_onscreen_get_x11_window (COGL_X11_ONSCREEN (stage_x11->onscreen)); if (clutter_stages_by_xid == NULL) clutter_stages_by_xid = g_hash_table_new (NULL, NULL);