[mutter] cogl/xlib: Move EGL XLIB onscreen to separate file



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]