mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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>
This commit is contained in:
parent
a057432e3d
commit
8339c064c8
@ -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',
|
||||
]
|
||||
|
331
cogl/cogl/winsys/cogl-onscreen-xlib.c
Normal file
331
cogl/cogl/winsys/cogl-onscreen-xlib.c
Normal file
@ -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;
|
||||
}
|
61
cogl/cogl/winsys/cogl-onscreen-xlib.h
Normal file
61
cogl/cogl/winsys/cogl-onscreen-xlib.h
Normal file
@ -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 */
|
@ -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 */
|
||||
|
@ -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... */
|
||||
|
Loading…
Reference in New Issue
Block a user