[mutter] cogl/xlib: Move EGL XLIB onscreen to separate file
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] cogl/xlib: Move EGL XLIB onscreen to separate file
- Date: Sat, 30 Jan 2021 09:39:48 +0000 (UTC)
commit 8339c064c87c6cba2c9281eb35ade5841ba61b28
Author: Jonas Ådahl <jadahl gmail com>
Date: Sat Oct 17 18:25:53 2020 +0200
cogl/xlib: Move EGL XLIB onscreen to separate file
As with the other onscreens, separate it into its own file in
preparation for GObjectification.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
cogl/cogl/meson.build | 2 +
cogl/cogl/winsys/cogl-onscreen-xlib.c | 331 +++++++++++++++++++++++++
cogl/cogl/winsys/cogl-onscreen-xlib.h | 61 +++++
cogl/cogl/winsys/cogl-winsys-egl-x11-private.h | 4 +
cogl/cogl/winsys/cogl-winsys-egl-x11.c | 310 ++---------------------
5 files changed, 416 insertions(+), 292 deletions(-)
---
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index 9bf5e04fb0..e565d74b2a 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -411,6 +411,8 @@ endif
if have_egl_xlib
cogl_sources += [
+ 'winsys/cogl-onscreen-xlib.c',
+ 'winsys/cogl-onscreen-xlib.h',
'winsys/cogl-winsys-egl-x11.c',
'winsys/cogl-winsys-egl-x11-private.h',
]
diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c
new file mode 100644
index 0000000000..cbc5441c3b
--- /dev/null
+++ b/cogl/cogl/winsys/cogl-onscreen-xlib.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2011,2013 Intel Corporation.
+ * Copyrigth (C) 2020 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "cogl-config.h"
+
+#include "winsys/cogl-onscreen-xlib.h"
+
+#include "cogl-context-private.h"
+#include "cogl-renderer-private.h"
+#include "cogl-xlib-renderer-private.h"
+#include "winsys/cogl-onscreen-egl.h"
+#include "winsys/cogl-winsys-egl-x11-private.h"
+
+typedef struct _CoglOnscreenXlib
+{
+ Window xwin;
+
+ gboolean pending_resize_notify;
+} CoglOnscreenXlib;
+
+#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
+
+gboolean
+_cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen *onscreen,
+ EGLConfig egl_config,
+ GError **error)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+ CoglDisplay *display = context->display;
+ CoglRenderer *renderer = display->renderer;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglOnscreenXlib *xlib_onscreen;
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ Window xwin;
+ EGLSurface egl_surface;
+
+ /* FIXME: We need to explicitly Select for ConfigureNotify events.
+ * We need to document that for windows we create then toolkits
+ * must be careful not to clear event mask bits that we select.
+ */
+
+ {
+ int width;
+ int height;
+ CoglXlibTrapState state;
+ XVisualInfo *xvisinfo;
+ XSetWindowAttributes xattr;
+ unsigned long mask;
+ int xerror;
+
+ width = cogl_framebuffer_get_width (framebuffer);
+ height = cogl_framebuffer_get_height (framebuffer);
+
+ _cogl_xlib_renderer_trap_errors (display->renderer, &state);
+
+ xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config);
+ if (xvisinfo == NULL)
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+ "Unable to retrieve the X11 visual of context's "
+ "fbconfig");
+ return FALSE;
+ }
+
+ /* window attributes */
+ xattr.background_pixel =
+ WhitePixel (xlib_renderer->xdpy,
+ DefaultScreen (xlib_renderer->xdpy));
+ xattr.border_pixel = 0;
+ /* XXX: is this an X resource that we are leaking‽... */
+ xattr.colormap =
+ XCreateColormap (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ xvisinfo->visual,
+ AllocNone);
+ xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
+
+ mask = CWBorderPixel | CWColormap | CWEventMask;
+
+ xwin = XCreateWindow (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ 0, 0,
+ width, height,
+ 0,
+ xvisinfo->depth,
+ InputOutput,
+ xvisinfo->visual,
+ mask, &xattr);
+
+ XFree (xvisinfo);
+
+ XSync (xlib_renderer->xdpy, False);
+ xerror =
+ _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
+ if (xerror)
+ {
+ char message[1000];
+ XGetErrorText (xlib_renderer->xdpy, xerror,
+ message, sizeof (message));
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+ "X error while creating Window for CoglOnscreen: %s",
+ message);
+ return FALSE;
+ }
+ }
+
+ xlib_onscreen = g_slice_new (CoglOnscreenXlib);
+ cogl_onscreen_egl_set_platform (egl_onscreen, xlib_onscreen);
+
+ xlib_onscreen->xwin = xwin;
+
+ egl_surface =
+ eglCreateWindowSurface (egl_renderer->edpy,
+ egl_config,
+ (EGLNativeWindowType) xlib_onscreen->xwin,
+ NULL);
+ cogl_onscreen_egl_set_egl_surface (egl_onscreen,
+ egl_surface);
+
+ return TRUE;
+}
+
+void
+_cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+ CoglRenderer *renderer = context->display->renderer;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglXlibTrapState old_state;
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (egl_onscreen);
+
+ _cogl_xlib_renderer_trap_errors (renderer, &old_state);
+
+ if (xlib_onscreen->xwin != None)
+ {
+ XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+ xlib_onscreen->xwin = None;
+ }
+ else
+ xlib_onscreen->xwin = None;
+
+ XSync (xlib_renderer->xdpy, False);
+
+ if (_cogl_xlib_renderer_untrap_errors (renderer,
+ &old_state) != Success)
+ g_warning ("X Error while destroying X window");
+
+ g_slice_free (CoglOnscreenXlib, xlib_onscreen);
+}
+
+void
+_cogl_winsys_onscreen_xlib_set_visibility (CoglOnscreen *onscreen,
+ gboolean visibility)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+ CoglRenderer *renderer = context->display->renderer;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglOnscreenEGL *onscreen_egl = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (onscreen_egl);
+
+ if (visibility)
+ XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+ else
+ XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+}
+
+void
+_cogl_winsys_onscreen_xlib_set_resizable (CoglOnscreen *onscreen,
+ gboolean resizable)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (context->display->renderer);
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (egl_onscreen);
+
+ XSizeHints *size_hints = XAllocSizeHints ();
+
+ if (resizable)
+ {
+ /* TODO: Add cogl_onscreen_request_minimum_size () */
+ size_hints->min_width = 1;
+ size_hints->min_height = 1;
+
+ size_hints->max_width = INT_MAX;
+ size_hints->max_height = INT_MAX;
+ }
+ else
+ {
+ int width = cogl_framebuffer_get_width (framebuffer);
+ int height = cogl_framebuffer_get_height (framebuffer);
+
+ size_hints->min_width = width;
+ size_hints->min_height = height;
+
+ size_hints->max_width = width;
+ size_hints->max_height = height;
+ }
+
+ XSetWMNormalHints (xlib_renderer->xdpy, xlib_onscreen->xwin, size_hints);
+
+ XFree (size_hints);
+}
+
+uint32_t
+_cogl_winsys_onscreen_xlib_get_window_xid (CoglOnscreen *onscreen)
+{
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (egl_onscreen);
+
+ return xlib_onscreen->xwin;
+}
+
+gboolean
+cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen,
+ Window window)
+{
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (egl_onscreen);
+
+ return xlib_onscreen->xwin == window;
+}
+
+static void
+flush_pending_resize_notifications_cb (void *data,
+ void *user_data)
+{
+ CoglFramebuffer *framebuffer = data;
+
+ if (COGL_IS_ONSCREEN (framebuffer))
+ {
+ CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+ CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+ CoglOnscreenXlib *xlib_onscreen =
+ cogl_onscreen_egl_get_platform (egl_onscreen);
+
+ if (xlib_onscreen->pending_resize_notify)
+ {
+ _cogl_onscreen_notify_resize (onscreen);
+ xlib_onscreen->pending_resize_notify = FALSE;
+ }
+ }
+}
+
+static void
+flush_pending_resize_notifications_idle (void *user_data)
+{
+ CoglContext *context = user_data;
+ CoglRenderer *renderer = context->display->renderer;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+
+ /* This needs to be disconnected before invoking the callbacks in
+ * case the callbacks cause it to be queued again */
+ _cogl_closure_disconnect (egl_renderer->resize_notify_idle);
+ egl_renderer->resize_notify_idle = NULL;
+
+ g_list_foreach (context->framebuffers,
+ flush_pending_resize_notifications_cb,
+ NULL);
+}
+
+void
+cogl_onscreen_xlib_resize (CoglOnscreen *onscreen,
+ int width,
+ int height)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+ CoglRenderer *renderer = context->display->renderer;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglOnscreenEGL *egl_onscreen;
+ CoglOnscreenXlib *xlib_onscreen;
+
+ egl_onscreen = cogl_onscreen_get_winsys (onscreen);
+
+ _cogl_framebuffer_winsys_update_size (framebuffer, width, height);
+
+ /* We only want to notify that a resize happened when the
+ * application calls cogl_context_dispatch so instead of immediately
+ * notifying we queue an idle callback */
+ if (!egl_renderer->resize_notify_idle)
+ {
+ egl_renderer->resize_notify_idle =
+ _cogl_poll_renderer_add_idle (renderer,
+ flush_pending_resize_notifications_idle,
+ context,
+ NULL);
+ }
+
+ xlib_onscreen = cogl_onscreen_egl_get_platform (egl_onscreen);
+ xlib_onscreen->pending_resize_notify = TRUE;
+}
diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.h b/cogl/cogl/winsys/cogl-onscreen-xlib.h
new file mode 100644
index 0000000000..41b234b950
--- /dev/null
+++ b/cogl/cogl/winsys/cogl-onscreen-xlib.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011,2013 Intel Corporation.
+ * Copyrigth (C) 2020 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef COGL_ONSCREEN_XLIB_H
+#define COGL_ONSCREEN_XLIB_H
+
+#include "cogl-onscreen.h"
+#include "winsys/cogl-winsys-egl-private.h"
+
+gboolean
+_cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen *onscreen,
+ EGLConfig egl_config,
+ GError **error);
+
+void
+_cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen);
+
+void
+_cogl_winsys_onscreen_xlib_set_visibility (CoglOnscreen *onscreen,
+ gboolean visibility);
+
+void
+_cogl_winsys_onscreen_xlib_set_resizable (CoglOnscreen *onscreen,
+ gboolean resizable);
+
+uint32_t
+_cogl_winsys_onscreen_xlib_get_window_xid (CoglOnscreen *onscreen);
+
+gboolean
+cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen,
+ Window window);
+
+void
+cogl_onscreen_xlib_resize (CoglOnscreen *onscreen,
+ int width,
+ int height);
+
+#endif /* COGL_ONSCREEN_XLIB_H */
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h
index 5b84941f67..7d4218c0d7 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h
+++ b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h
@@ -36,4 +36,8 @@
COGL_EXPORT const CoglWinsysVtable *
_cogl_winsys_egl_xlib_get_vtable (void);
+XVisualInfo *
+cogl_display_xlib_get_visual_info (CoglDisplay *display,
+ EGLConfig egl_config);
+
#endif /* __COGL_WINSYS_EGL_X11_PRIVATE_H */
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
index 735b43a2a7..63871d7085 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
@@ -46,11 +46,10 @@
#include "cogl-texture-2d.h"
#include "cogl-poll-private.h"
#include "winsys/cogl-onscreen-egl.h"
+#include "winsys/cogl-onscreen-xlib.h"
#include "winsys/cogl-winsys-egl-x11-private.h"
#include "winsys/cogl-winsys-egl-private.h"
-#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
-
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
typedef struct _CoglDisplayXlib
@@ -58,13 +57,6 @@ typedef struct _CoglDisplayXlib
Window dummy_xwin;
} CoglDisplayXlib;
-typedef struct _CoglOnscreenXlib
-{
- Window xwin;
-
- gboolean pending_resize_notify;
-} CoglOnscreenXlib;
-
#ifdef EGL_KHR_image_pixmap
typedef struct _CoglTexturePixmapEGL
{
@@ -81,94 +73,32 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
for (l = context->framebuffers; l; l = l->next)
{
CoglFramebuffer *framebuffer = l->data;
- CoglOnscreenEGL *egl_onscreen;
- CoglOnscreenXlib *xlib_onscreen;
+ CoglOnscreen *onscreen;
if (!COGL_IS_ONSCREEN (framebuffer))
continue;
- egl_onscreen = cogl_onscreen_get_winsys (COGL_ONSCREEN (framebuffer));
- xlib_onscreen =
- cogl_onscreen_egl_get_platform (egl_onscreen);
- if (xlib_onscreen->xwin == (Window)xid)
- return COGL_ONSCREEN (framebuffer);
+ onscreen = COGL_ONSCREEN (framebuffer);
+ if (cogl_onscreen_xlib_is_for_window (onscreen, (Window) xid))
+ return onscreen;
}
return NULL;
}
-static void
-flush_pending_resize_notifications_cb (void *data,
- void *user_data)
-{
- CoglFramebuffer *framebuffer = data;
-
- if (COGL_IS_ONSCREEN (framebuffer))
- {
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
- CoglOnscreenXlib *xlib_onscreen =
- cogl_onscreen_egl_get_platform (egl_onscreen);
-
- if (xlib_onscreen->pending_resize_notify)
- {
- _cogl_onscreen_notify_resize (onscreen);
- xlib_onscreen->pending_resize_notify = FALSE;
- }
- }
-}
-
-static void
-flush_pending_resize_notifications_idle (void *user_data)
-{
- CoglContext *context = user_data;
- CoglRenderer *renderer = context->display->renderer;
- CoglRendererEGL *egl_renderer = renderer->winsys;
-
- /* This needs to be disconnected before invoking the callbacks in
- * case the callbacks cause it to be queued again */
- _cogl_closure_disconnect (egl_renderer->resize_notify_idle);
- egl_renderer->resize_notify_idle = NULL;
-
- g_list_foreach (context->framebuffers,
- flush_pending_resize_notifications_cb,
- NULL);
-}
-
static void
notify_resize (CoglContext *context,
Window drawable,
int width,
int height)
{
- CoglRenderer *renderer = context->display->renderer;
- CoglRendererEGL *egl_renderer = renderer->winsys;
- CoglOnscreen *onscreen = find_onscreen_for_xid (context, drawable);
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglOnscreenEGL *egl_onscreen;
- CoglOnscreenXlib *xlib_onscreen;
+ CoglOnscreen *onscreen;
+ onscreen = find_onscreen_for_xid (context, drawable);
if (!onscreen)
return;
- egl_onscreen = cogl_onscreen_get_winsys (onscreen);
-
- _cogl_framebuffer_winsys_update_size (framebuffer, width, height);
-
- /* We only want to notify that a resize happened when the
- * application calls cogl_context_dispatch so instead of immediately
- * notifying we queue an idle callback */
- if (!egl_renderer->resize_notify_idle)
- {
- egl_renderer->resize_notify_idle =
- _cogl_poll_renderer_add_idle (renderer,
- flush_pending_resize_notifications_idle,
- context,
- NULL);
- }
-
- xlib_onscreen = cogl_onscreen_egl_get_platform (egl_onscreen);
- xlib_onscreen->pending_resize_notify = TRUE;
+ cogl_onscreen_xlib_resize (onscreen, width, height);
}
static CoglFilterReturn
@@ -204,8 +134,9 @@ event_filter_cb (XEvent *xevent, void *data)
return COGL_FILTER_CONTINUE;
}
-static XVisualInfo *
-get_visual_info (CoglDisplay *display, EGLConfig egl_config)
+XVisualInfo *
+cogl_display_xlib_get_visual_info (CoglDisplay *display,
+ EGLConfig egl_config)
{
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
@@ -415,212 +346,6 @@ _cogl_winsys_egl_context_deinit (CoglContext *context)
context);
}
-static gboolean
-_cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
- EGLConfig egl_config,
- GError **error)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *context = cogl_framebuffer_get_context (framebuffer);
- CoglDisplay *display = context->display;
- CoglRenderer *renderer = display->renderer;
- CoglRendererEGL *egl_renderer = renderer->winsys;
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglOnscreenXlib *xlib_onscreen;
- CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
- Window xwin;
- EGLSurface egl_surface;
-
- /* FIXME: We need to explicitly Select for ConfigureNotify events.
- * We need to document that for windows we create then toolkits
- * must be careful not to clear event mask bits that we select.
- */
-
- {
- int width;
- int height;
- CoglXlibTrapState state;
- XVisualInfo *xvisinfo;
- XSetWindowAttributes xattr;
- unsigned long mask;
- int xerror;
-
- width = cogl_framebuffer_get_width (framebuffer);
- height = cogl_framebuffer_get_height (framebuffer);
-
- _cogl_xlib_renderer_trap_errors (display->renderer, &state);
-
- xvisinfo = get_visual_info (display, egl_config);
- if (xvisinfo == NULL)
- {
- g_set_error (error, COGL_WINSYS_ERROR,
- COGL_WINSYS_ERROR_CREATE_ONSCREEN,
- "Unable to retrieve the X11 visual of context's "
- "fbconfig");
- return FALSE;
- }
-
- /* window attributes */
- xattr.background_pixel =
- WhitePixel (xlib_renderer->xdpy,
- DefaultScreen (xlib_renderer->xdpy));
- xattr.border_pixel = 0;
- /* XXX: is this an X resource that we are leaking‽... */
- xattr.colormap =
- XCreateColormap (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- xvisinfo->visual,
- AllocNone);
- xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
-
- mask = CWBorderPixel | CWColormap | CWEventMask;
-
- xwin = XCreateWindow (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- 0, 0,
- width, height,
- 0,
- xvisinfo->depth,
- InputOutput,
- xvisinfo->visual,
- mask, &xattr);
-
- XFree (xvisinfo);
-
- XSync (xlib_renderer->xdpy, False);
- xerror =
- _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
- if (xerror)
- {
- char message[1000];
- XGetErrorText (xlib_renderer->xdpy, xerror,
- message, sizeof (message));
- g_set_error (error, COGL_WINSYS_ERROR,
- COGL_WINSYS_ERROR_CREATE_ONSCREEN,
- "X error while creating Window for CoglOnscreen: %s",
- message);
- return FALSE;
- }
- }
-
- xlib_onscreen = g_slice_new (CoglOnscreenXlib);
- cogl_onscreen_egl_set_platform (egl_onscreen, xlib_onscreen);
-
- xlib_onscreen->xwin = xwin;
-
- egl_surface =
- eglCreateWindowSurface (egl_renderer->edpy,
- egl_config,
- (EGLNativeWindowType) xlib_onscreen->xwin,
- NULL);
- cogl_onscreen_egl_set_egl_surface (egl_onscreen,
- egl_surface);
-
- return TRUE;
-}
-
-static void
-_cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *context = cogl_framebuffer_get_context (framebuffer);
- CoglRenderer *renderer = context->display->renderer;
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglXlibTrapState old_state;
- CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
- CoglOnscreenXlib *xlib_onscreen =
- cogl_onscreen_egl_get_platform (egl_onscreen);
-
- _cogl_xlib_renderer_trap_errors (renderer, &old_state);
-
- if (xlib_onscreen->xwin != None)
- {
- XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
- xlib_onscreen->xwin = None;
- }
- else
- xlib_onscreen->xwin = None;
-
- XSync (xlib_renderer->xdpy, False);
-
- if (_cogl_xlib_renderer_untrap_errors (renderer,
- &old_state) != Success)
- g_warning ("X Error while destroying X window");
-
- g_slice_free (CoglOnscreenXlib, xlib_onscreen);
-}
-
-static void
-_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
- gboolean visibility)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *context = cogl_framebuffer_get_context (framebuffer);
- CoglRenderer *renderer = context->display->renderer;
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglOnscreenEGL *onscreen_egl = cogl_onscreen_get_winsys (onscreen);
- CoglOnscreenXlib *xlib_onscreen =
- cogl_onscreen_egl_get_platform (onscreen_egl);
-
- if (visibility)
- XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
- else
- XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
-}
-
-static void
-_cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
- gboolean resizable)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *context = cogl_framebuffer_get_context (framebuffer);
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (context->display->renderer);
- CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
- CoglOnscreenXlib *xlib_onscreen =
- cogl_onscreen_egl_get_platform (egl_onscreen);
-
- XSizeHints *size_hints = XAllocSizeHints ();
-
- if (resizable)
- {
- /* TODO: Add cogl_onscreen_request_minimum_size () */
- size_hints->min_width = 1;
- size_hints->min_height = 1;
-
- size_hints->max_width = INT_MAX;
- size_hints->max_height = INT_MAX;
- }
- else
- {
- int width = cogl_framebuffer_get_width (framebuffer);
- int height = cogl_framebuffer_get_height (framebuffer);
-
- size_hints->min_width = width;
- size_hints->min_height = height;
-
- size_hints->max_width = width;
- size_hints->max_height = height;
- }
-
- XSetWMNormalHints (xlib_renderer->xdpy, xlib_onscreen->xwin, size_hints);
-
- XFree (size_hints);
-}
-
-static uint32_t
-_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
-{
- CoglOnscreenEGL *egl_onscreen = cogl_onscreen_get_winsys (onscreen);
- CoglOnscreenXlib *xlib_onscreen =
- cogl_onscreen_egl_get_platform (egl_onscreen);
-
- return xlib_onscreen->xwin;
-}
-
static gboolean
_cogl_winsys_egl_context_created (CoglDisplay *display,
GError **error)
@@ -635,7 +360,8 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
XSetWindowAttributes attrs;
const char *error_message;
- xvisinfo = get_visual_info (display, egl_display->egl_config);
+ xvisinfo = cogl_display_xlib_get_visual_info (display,
+ egl_display->egl_config);
if (xvisinfo == NULL)
{
error_message = "Unable to find suitable X visual";
@@ -841,8 +567,8 @@ _cogl_winsys_egl_vtable =
.cleanup_context = _cogl_winsys_egl_cleanup_context,
.context_init = _cogl_winsys_egl_context_init,
.context_deinit = _cogl_winsys_egl_context_deinit,
- .onscreen_init = _cogl_winsys_egl_onscreen_init,
- .onscreen_deinit = _cogl_winsys_egl_onscreen_deinit
+ .onscreen_init = _cogl_winsys_egl_onscreen_xlib_init,
+ .onscreen_deinit = _cogl_winsys_egl_onscreen_xlib_deinit
};
COGL_EXPORT const CoglWinsysVtable *
@@ -867,12 +593,12 @@ _cogl_winsys_egl_xlib_get_vtable (void)
vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
vtable.onscreen_set_visibility =
- _cogl_winsys_onscreen_set_visibility;
+ _cogl_winsys_onscreen_xlib_set_visibility;
vtable.onscreen_set_resizable =
- _cogl_winsys_onscreen_set_resizable;
+ _cogl_winsys_onscreen_xlib_set_resizable;
vtable.onscreen_x11_get_window_xid =
- _cogl_winsys_onscreen_x11_get_window_xid;
+ _cogl_winsys_onscreen_xlib_get_window_xid;
#ifdef EGL_KHR_image_pixmap
/* X11 tfp support... */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]