From 8339c064c87c6cba2c9281eb35ade5841ba61b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 17 Oct 2020 18:25:53 +0200 Subject: [PATCH] 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: --- cogl/cogl/meson.build | 2 + cogl/cogl/winsys/cogl-onscreen-xlib.c | 331 ++++++++++++++++++ cogl/cogl/winsys/cogl-onscreen-xlib.h | 61 ++++ .../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(-) create mode 100644 cogl/cogl/winsys/cogl-onscreen-xlib.c create mode 100644 cogl/cogl/winsys/cogl-onscreen-xlib.h diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index 9bf5e04fb..e565d74b2 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 000000000..cbc5441c3 --- /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 000000000..41b234b95 --- /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 5b84941f6..7d4218c0d 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 735b43a2a..63871d708 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... */