xserver-multidpi/hw/xwayland/xwayland.c

1115 lines
32 KiB
C
Raw Normal View History

/*
* Copyright © 2011-2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include "xwayland.h"
#include <stdio.h>
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
#include <X11/Xatom.h>
#include <selection.h>
#include <micmap.h>
#include <misyncshm.h>
#include <compositeext.h>
#include <compint.h>
#include <glx_extinit.h>
#include <os.h>
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
#include <xserver_poll.h>
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
#include <propertyst.h>
#ifdef XF86VIDMODE
#include <X11/extensions/xf86vmproto.h>
_X_EXPORT Bool noXFree86VidModeExtension;
#endif
void
ddxGiveUp(enum ExitCode error)
{
}
void
AbortDDX(enum ExitCode error)
{
ddxGiveUp(error);
}
void
OsVendorInit(void)
{
if (serverGeneration == 1)
ForceClockId(CLOCK_MONOTONIC);
}
void
OsVendorFatalError(const char *f, va_list args)
{
}
#if defined(DDXBEFORERESET)
void
ddxBeforeReset(void)
{
return;
}
#endif
_X_NORETURN
static void _X_ATTRIBUTE_PRINTF(1, 2)
xwl_give_up(const char *f, ...)
{
va_list args;
va_start(args, f);
VErrorFSigSafe(f, args);
va_end(args);
CloseWellKnownConnections();
OsCleanup(TRUE);
fflush(stderr);
exit(1);
}
void
ddxUseMsg(void)
{
ErrorF("-rootless run rootless, requires wm support\n");
ErrorF("-wm fd create X client for wm on given fd\n");
ErrorF("-listen fd add give fd as a listen socket\n");
}
int
ddxProcessArgument(int argc, char *argv[], int i)
{
if (strcmp(argv[i], "-rootless") == 0) {
return 1;
}
else if (strcmp(argv[i], "-listen") == 0) {
NoListenAll = TRUE;
return 2;
}
else if (strcmp(argv[i], "-wm") == 0) {
return 2;
}
else if (strcmp(argv[i], "-shm") == 0) {
return 1;
}
return 0;
}
static DevPrivateKeyRec xwl_window_private_key;
static DevPrivateKeyRec xwl_screen_private_key;
static DevPrivateKeyRec xwl_pixmap_private_key;
struct xwl_window *
xwl_window_of_top(WindowPtr window)
{
return dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
}
static struct xwl_window *
xwl_window_of_self(WindowPtr window)
{
struct xwl_window *xwl_window = dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
if (xwl_window && xwl_window->window == window)
return xwl_window;
else
return NULL;
}
struct xwl_screen *
xwl_screen_get(ScreenPtr screen)
{
return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
}
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
static void
xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
const char *debug_msg)
{
xwl_window->allow_commits = allow;
DebugF("xwayland: win %d allow_commits = %d (%s)\n",
xwl_window->window->drawable.id, allow, debug_msg);
}
static void
xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
PropertyPtr prop)
{
static Bool warned = FALSE;
CARD32 *propdata;
if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
/* Not properly set, so fall back to safe and glitchy */
xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
if (!warned) {
LogMessage(X_WARNING, "Window manager is misusing property %s.\n",
NameForAtom(prop->propertyName));
warned = TRUE;
}
return;
}
propdata = prop->data;
xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
}
static void
xwl_window_property_allow_commits(struct xwl_window *xwl_window,
PropertyStateRec *propstate)
{
Bool old_allow_commits = xwl_window->allow_commits;
switch (propstate->state) {
case PropertyNewValue:
xwl_window_set_allow_commits_from_property(xwl_window, propstate->prop);
break;
case PropertyDelete:
xwl_window_set_allow_commits(xwl_window, TRUE, "property deleted");
break;
default:
break;
}
/* If allow_commits turned from off to on, discard any frame
* callback we might be waiting for so that a new buffer is posted
* immediately through block_handler() if there is damage to post.
*/
if (!old_allow_commits && xwl_window->allow_commits) {
if (xwl_window->frame_callback) {
wl_callback_destroy(xwl_window->frame_callback);
xwl_window->frame_callback = NULL;
}
}
}
static void
xwl_property_callback(CallbackListPtr *pcbl, void *closure,
void *calldata)
{
ScreenPtr screen = closure;
PropertyStateRec *rec = calldata;
struct xwl_screen *xwl_screen;
struct xwl_window *xwl_window;
if (rec->win->drawable.pScreen != screen)
return;
xwl_window = xwl_window_of_self(rec->win);
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
if (!xwl_window)
return;
xwl_screen = xwl_screen_get(screen);
if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
xwl_window_property_allow_commits(xwl_window, rec);
}
static Bool
xwl_close_screen(ScreenPtr screen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_output *xwl_output, *next_xwl_output;
struct xwl_seat *xwl_seat, *next_xwl_seat;
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen);
xorg_list_for_each_entry_safe(xwl_output, next_xwl_output,
&xwl_screen->output_list, link)
xwl_output_destroy(xwl_output);
xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat,
&xwl_screen->seat_list, link)
xwl_seat_destroy(xwl_seat);
xwl_screen_release_tablet_manager(xwl_screen);
RemoveNotifyFd(xwl_screen->wayland_fd);
wl_display_disconnect(xwl_screen->display);
screen->CloseScreen = xwl_screen->CloseScreen;
free(xwl_screen);
return screen->CloseScreen(screen);
}
static struct xwl_seat *
xwl_screen_get_default_seat(struct xwl_screen *xwl_screen)
{
xwayland: Don't process cursor warping without an xwl_seat Unfortunately, on my machine Xwayland immediately crashes when I try to start it. gdb backtrace: #0 0x00007ffff74f0e79 in wl_proxy_marshal () from target:/lib64/libwayland-client.so.0 #1 0x0000000000413172 in zwp_confined_pointer_v1_destroy (zwp_confined_pointer_v1=0x700000000) at hw/xwayland/Xwayland@exe/pointer-constraints-unstable-v1-client-protocol.h:612 #2 0x0000000000418bc0 in xwl_seat_destroy_confined_pointer (xwl_seat=0x8ba2a0) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2839 #3 0x0000000000418c09 in xwl_seat_unconfine_pointer (xwl_seat=0x8ba2a0) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2849 #4 0x0000000000410d97 in xwl_cursor_confined_to (device=0xa5a000, screen=0x8b9d80, window=0x9bdb70) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland.c:328 #5 0x00000000004a8571 in ConfineCursorToWindow (pDev=0xa5a000, pWin=0x9bdb70, generateEvents=1, confineToScreen=0) at /home/lyudess/Projects/xserver/dix/events.c:900 #6 0x00000000004a94b7 in ScreenRestructured (pScreen=0x8b9d80) at /home/lyudess/Projects/xserver/dix/events.c:1387 #7 0x0000000000502386 in RRScreenSizeNotify (pScreen=0x8b9d80) at /home/lyudess/Projects/xserver/randr/rrscreen.c:160 #8 0x000000000041a83c in update_screen_size (xwl_output=0x8e7670, width=3840, height=2160) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:203 #9 0x000000000041a9f0 in apply_output_change (xwl_output=0x8e7670) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:252 #10 0x000000000041aaeb in xdg_output_handle_done (data=0x8e7670, xdg_output=0x8e7580) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:307 #11 0x00007ffff50e9d1e in ffi_call_unix64 () at ../src/x86/unix64.S:76 #12 0x00007ffff50e968f in ffi_call (cif=<optimized out>, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>) at ../src/x86/ffi64.c:525 #13 0x00007ffff74f3d8b in wl_closure_invoke () from target:/lib64/libwayland-client.so.0 #14 0x00007ffff74f0928 in dispatch_event.isra () from target:/lib64/libwayland-client.so.0 #15 0x00007ffff74f1be4 in wl_display_dispatch_queue_pending () from target:/lib64/libwayland-client.so.0 #16 0x00007ffff74f200b in wl_display_roundtrip_queue () from target:/lib64/libwayland-client.so.0 #17 0x0000000000418cad in InitInput (argc=12, argv=0x7fffffffd9c8) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2867 #18 0x00000000004a20e3 in dix_main (argc=12, argv=0x7fffffffd9c8, envp=0x7fffffffda30) at /home/lyudess/Projects/xserver/dix/main.c:250 #19 0x0000000000420cb2 in main (argc=12, argv=0x7fffffffd9c8, envp=0x7fffffffda30) at /home/lyudess/Projects/xserver/dix/stubmain.c:34 This appears to be the result of xwl_cursor_confined_to() and xwl_screen_get_default_seat(). While not against protocol, mutter ends up sending xdg_output before wl_seat. xwl_screen_get_default_seat() makes the naïve assumption that we always have a valid seat, we end up returning a pointer to the empty list itself instead of an actual seat and causing ourselves to segfault. So, actually return NULL in xwl_screen_get_default_seat() if the seat list is empty, and skip any pointer confinement processing in xwl_cursor_confined_to() when we don't have a seat setup yet. Signed-off-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
2018-02-06 18:41:47 +01:00
if (xorg_list_is_empty(&xwl_screen->seat_list))
return NULL;
return container_of(xwl_screen->seat_list.prev,
struct xwl_seat,
link);
}
static void
xwl_cursor_warped_to(DeviceIntPtr device,
ScreenPtr screen,
ClientPtr client,
WindowPtr window,
SpritePtr sprite,
int x, int y)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_seat *xwl_seat = device->public.devicePrivate;
struct xwl_window *xwl_window;
WindowPtr focus;
if (!xwl_seat)
xwl_seat = xwl_screen_get_default_seat(xwl_screen);
xwl_window = xwl_window_of_top(window);
if (!xwl_window && xwl_seat->focus_window) {
focus = xwl_seat->focus_window->window;
/* Warps on non wl_surface backed Windows are only allowed
* as long as the pointer stays within the focus window.
*/
if (x >= focus->drawable.x &&
y >= focus->drawable.y &&
x < focus->drawable.x + focus->drawable.width &&
y < focus->drawable.y + focus->drawable.height) {
if (!window) {
DebugF("Warp relative to pointer, assuming pointer focus\n");
xwl_window = xwl_seat->focus_window;
} else if (window == screen->root) {
DebugF("Warp on root window, assuming pointer focus\n");
xwl_window = xwl_seat->focus_window;
}
}
}
if (!xwl_window)
return;
xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
}
static void
xwl_cursor_confined_to(DeviceIntPtr device,
ScreenPtr screen,
WindowPtr window)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_seat *xwl_seat = device->public.devicePrivate;
struct xwl_window *xwl_window;
if (!xwl_seat)
xwl_seat = xwl_screen_get_default_seat(xwl_screen);
xwayland: Don't process cursor warping without an xwl_seat Unfortunately, on my machine Xwayland immediately crashes when I try to start it. gdb backtrace: #0 0x00007ffff74f0e79 in wl_proxy_marshal () from target:/lib64/libwayland-client.so.0 #1 0x0000000000413172 in zwp_confined_pointer_v1_destroy (zwp_confined_pointer_v1=0x700000000) at hw/xwayland/Xwayland@exe/pointer-constraints-unstable-v1-client-protocol.h:612 #2 0x0000000000418bc0 in xwl_seat_destroy_confined_pointer (xwl_seat=0x8ba2a0) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2839 #3 0x0000000000418c09 in xwl_seat_unconfine_pointer (xwl_seat=0x8ba2a0) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2849 #4 0x0000000000410d97 in xwl_cursor_confined_to (device=0xa5a000, screen=0x8b9d80, window=0x9bdb70) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland.c:328 #5 0x00000000004a8571 in ConfineCursorToWindow (pDev=0xa5a000, pWin=0x9bdb70, generateEvents=1, confineToScreen=0) at /home/lyudess/Projects/xserver/dix/events.c:900 #6 0x00000000004a94b7 in ScreenRestructured (pScreen=0x8b9d80) at /home/lyudess/Projects/xserver/dix/events.c:1387 #7 0x0000000000502386 in RRScreenSizeNotify (pScreen=0x8b9d80) at /home/lyudess/Projects/xserver/randr/rrscreen.c:160 #8 0x000000000041a83c in update_screen_size (xwl_output=0x8e7670, width=3840, height=2160) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:203 #9 0x000000000041a9f0 in apply_output_change (xwl_output=0x8e7670) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:252 #10 0x000000000041aaeb in xdg_output_handle_done (data=0x8e7670, xdg_output=0x8e7580) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-output.c:307 #11 0x00007ffff50e9d1e in ffi_call_unix64 () at ../src/x86/unix64.S:76 #12 0x00007ffff50e968f in ffi_call (cif=<optimized out>, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>) at ../src/x86/ffi64.c:525 #13 0x00007ffff74f3d8b in wl_closure_invoke () from target:/lib64/libwayland-client.so.0 #14 0x00007ffff74f0928 in dispatch_event.isra () from target:/lib64/libwayland-client.so.0 #15 0x00007ffff74f1be4 in wl_display_dispatch_queue_pending () from target:/lib64/libwayland-client.so.0 #16 0x00007ffff74f200b in wl_display_roundtrip_queue () from target:/lib64/libwayland-client.so.0 #17 0x0000000000418cad in InitInput (argc=12, argv=0x7fffffffd9c8) at /home/lyudess/Projects/xserver/hw/xwayland/xwayland-input.c:2867 #18 0x00000000004a20e3 in dix_main (argc=12, argv=0x7fffffffd9c8, envp=0x7fffffffda30) at /home/lyudess/Projects/xserver/dix/main.c:250 #19 0x0000000000420cb2 in main (argc=12, argv=0x7fffffffd9c8, envp=0x7fffffffda30) at /home/lyudess/Projects/xserver/dix/stubmain.c:34 This appears to be the result of xwl_cursor_confined_to() and xwl_screen_get_default_seat(). While not against protocol, mutter ends up sending xdg_output before wl_seat. xwl_screen_get_default_seat() makes the naïve assumption that we always have a valid seat, we end up returning a pointer to the empty list itself instead of an actual seat and causing ourselves to segfault. So, actually return NULL in xwl_screen_get_default_seat() if the seat list is empty, and skip any pointer confinement processing in xwl_cursor_confined_to() when we don't have a seat setup yet. Signed-off-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
2018-02-06 18:41:47 +01:00
/* xwl_seat hasn't been setup yet, don't do anything just yet */
if (!xwl_seat)
return;
if (window == screen->root) {
xwl_seat_unconfine_pointer(xwl_seat);
return;
}
xwl_window = xwl_window_of_top(window);
if (!xwl_window && xwl_seat->focus_window) {
/* Allow confining on InputOnly windows, but only if the geometry
* is the same than the focus window.
*/
if (window->drawable.class == InputOnly) {
DebugF("Confine on InputOnly window, assuming pointer focus\n");
xwl_window = xwl_seat->focus_window;
}
}
if (!xwl_window)
return;
xwl_seat_confine_pointer(xwl_seat, xwl_window);
}
static void
damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
{
struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
}
static void
damage_destroy(DamagePtr pDamage, void *data)
{
}
static void
shell_surface_ping(void *data,
struct wl_shell_surface *shell_surface, uint32_t serial)
{
wl_shell_surface_pong(shell_surface, serial);
}
static void
shell_surface_configure(void *data,
struct wl_shell_surface *wl_shell_surface,
uint32_t edges, int32_t width, int32_t height)
{
}
static void
shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
{
}
static const struct wl_shell_surface_listener shell_surface_listener = {
shell_surface_ping,
shell_surface_configure,
shell_surface_popup_done
};
void
xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap)
{
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key, xwl_pixmap);
}
struct xwl_pixmap *
xwl_pixmap_get(PixmapPtr pixmap)
{
return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key);
}
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
static void
xwl_window_init_allow_commits(struct xwl_window *xwl_window)
{
PropertyPtr prop = NULL;
int ret;
ret = dixLookupProperty(&prop, xwl_window->window,
xwl_window->xwl_screen->allow_commits_prop,
serverClient, DixReadAccess);
if (ret == Success && prop)
xwl_window_set_allow_commits_from_property(xwl_window, prop);
else
xwl_window_set_allow_commits(xwl_window, TRUE, "no property");
}
static void
send_surface_id_event(struct xwl_window *xwl_window)
{
static const char atom_name[] = "WL_SURFACE_ID";
static Atom type_atom;
DeviceIntPtr dev;
xEvent e;
if (type_atom == None)
type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
e.u.u.type = ClientMessage;
e.u.u.detail = 32;
e.u.clientMessage.window = xwl_window->window->drawable.id;
e.u.clientMessage.u.l.type = type_atom;
e.u.clientMessage.u.l.longs0 =
wl_proxy_get_id((struct wl_proxy *) xwl_window->surface);
e.u.clientMessage.u.l.longs1 = 0;
e.u.clientMessage.u.l.longs2 = 0;
e.u.clientMessage.u.l.longs3 = 0;
e.u.clientMessage.u.l.longs4 = 0;
dev = PickPointer(serverClient);
DeliverEventsToWindow(dev, xwl_window->xwl_screen->screen->root,
&e, 1, SubstructureRedirectMask, NullGrab);
}
static Bool
xwl_realize_window(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
struct xwl_screen *xwl_screen;
struct xwl_window *xwl_window;
struct wl_region *region;
Bool create_xwl_window = TRUE;
Bool ret;
xwl_screen = xwl_screen_get(screen);
screen->RealizeWindow = xwl_screen->RealizeWindow;
ret = (*screen->RealizeWindow) (window);
xwl_screen->RealizeWindow = screen->RealizeWindow;
screen->RealizeWindow = xwl_realize_window;
if (xwl_screen->rootless && !window->parent) {
BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height };
RegionReset(&window->winSize, &box);
RegionNull(&window->clipList);
RegionNull(&window->borderClip);
}
if (xwl_screen->rootless) {
if (window->redirectDraw != RedirectDrawManual)
create_xwl_window = FALSE;
}
else {
if (window->parent)
create_xwl_window = FALSE;
}
if (!create_xwl_window) {
if (window->parent)
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window_of_top(window->parent));
return ret;
}
xwl_window = calloc(1, sizeof *xwl_window);
if (xwl_window == NULL)
return FALSE;
xwl_window->xwl_screen = xwl_screen;
xwl_window->window = window;
xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor);
if (xwl_window->surface == NULL) {
ErrorF("wl_display_create_surface failed\n");
goto err;
}
if (!xwl_screen->rootless) {
xwl_window->shell_surface =
wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface);
if (xwl_window->shell_surface == NULL) {
ErrorF("Failed creating shell surface\n");
goto err_surf;
}
wl_shell_surface_add_listener(xwl_window->shell_surface,
&shell_surface_listener, xwl_window);
wl_shell_surface_set_toplevel(xwl_window->shell_surface);
region = wl_compositor_create_region(xwl_screen->compositor);
if (region == NULL) {
ErrorF("Failed creating region\n");
goto err_surf;
}
wl_region_add(region, 0, 0,
window->drawable.width, window->drawable.height);
wl_surface_set_opaque_region(xwl_window->surface, region);
wl_region_destroy(region);
}
wl_display_flush(xwl_screen->display);
send_surface_id_event(xwl_window);
wl_surface_set_user_data(xwl_window->surface, xwl_window);
xwl_window->damage =
DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
FALSE, screen, xwl_window);
if (xwl_window->damage == NULL) {
ErrorF("Failed creating damage\n");
goto err_surf;
}
compRedirectWindow(serverClient, window, CompositeRedirectManual);
DamageRegister(&window->drawable, xwl_window->damage);
DamageSetReportAfterOp(xwl_window->damage, TRUE);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
xorg_list_init(&xwl_window->link_damage);
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
xwl_window_init_allow_commits(xwl_window);
return ret;
err_surf:
if (xwl_window->shell_surface)
wl_shell_surface_destroy(xwl_window->shell_surface);
wl_surface_destroy(xwl_window->surface);
err:
free(xwl_window);
return FALSE;
}
static Bool
xwl_unrealize_window(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
struct xwl_screen *xwl_screen;
struct xwl_window *xwl_window;
struct xwl_seat *xwl_seat;
Bool ret;
xwl_screen = xwl_screen_get(screen);
xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
if (xwl_seat->focus_window && xwl_seat->focus_window->window == window)
xwl_seat->focus_window = NULL;
if (xwl_seat->tablet_focus_window && xwl_seat->tablet_focus_window->window == window)
xwl_seat->tablet_focus_window = NULL;
if (xwl_seat->last_xwindow == window)
xwl_seat->last_xwindow = NullWindow;
if (xwl_seat->cursor_confinement_window &&
xwl_seat->cursor_confinement_window->window == window)
xwl_seat_unconfine_pointer(xwl_seat);
if (xwl_seat->pointer_warp_emulator &&
xwl_seat->pointer_warp_emulator->locked_window &&
xwl_seat->pointer_warp_emulator->locked_window->window == window)
xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
xwl_seat_clear_touch(xwl_seat, window);
}
compUnredirectWindow(serverClient, window, CompositeRedirectManual);
screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
ret = (*screen->UnrealizeWindow) (window);
xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
screen->UnrealizeWindow = xwl_unrealize_window;
xwl_window = xwl_window_of_self(window);
if (!xwl_window) {
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
return ret;
}
wl_surface_destroy(xwl_window->surface);
xorg_list_del(&xwl_window->link_damage);
DamageUnregister(xwl_window->damage);
DamageDestroy(xwl_window->damage);
if (xwl_window->frame_callback)
wl_callback_destroy(xwl_window->frame_callback);
free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
return ret;
}
static Bool
xwl_save_screen(ScreenPtr pScreen, int on)
{
return TRUE;
}
static void
frame_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
struct xwl_window *xwl_window = data;
wl_callback_destroy (xwl_window->frame_callback);
xwl_window->frame_callback = NULL;
}
static const struct wl_callback_listener frame_listener = {
frame_callback
};
static void
xwl_window_post_damage(struct xwl_window *xwl_window)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
RegionPtr region;
BoxPtr box;
struct wl_buffer *buffer;
PixmapPtr pixmap;
int i;
assert(!xwl_window->frame_callback);
region = DamageRegion(xwl_window->damage);
pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
#ifdef GLAMOR_HAS_GBM
if (xwl_screen->glamor)
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
else
#endif
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
/* Arbitrary limit to try to avoid flooding the Wayland
* connection. If we flood it too much anyway, this could
* abort in libwayland-client.
*/
if (RegionNumRects(region) > 256) {
box = RegionExtents(region);
wl_surface_damage(xwl_window->surface, box->x1, box->y1,
box->x2 - box->x1, box->y2 - box->y1);
} else {
box = RegionRects(region);
for (i = 0; i < RegionNumRects(region); i++, box++)
wl_surface_damage(xwl_window->surface, box->x1, box->y1,
box->x2 - box->x1, box->y2 - box->y1);
}
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
wl_surface_commit(xwl_window->surface);
DamageEmpty(xwl_window->damage);
xorg_list_del(&xwl_window->link_damage);
}
static void
xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{
struct xwl_window *xwl_window, *next_xwl_window;
xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
&xwl_screen->damage_window_list, link_damage) {
/* If we're waiting on a frame callback from the server,
* don't attach a new buffer. */
if (xwl_window->frame_callback)
continue;
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
if (!xwl_window->allow_commits)
continue;
xwl_window_post_damage(xwl_window);
}
}
static void
registry_global(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version)
{
struct xwl_screen *xwl_screen = data;
if (strcmp(interface, "wl_compositor") == 0) {
xwl_screen->compositor =
wl_registry_bind(registry, id, &wl_compositor_interface, 1);
}
else if (strcmp(interface, "wl_shm") == 0) {
xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
}
else if (strcmp(interface, "wl_shell") == 0) {
xwl_screen->shell =
wl_registry_bind(registry, id, &wl_shell_interface, 1);
}
else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
if (xwl_output_create(xwl_screen, id))
xwl_screen->expecting_event++;
}
else if (strcmp(interface, "zxdg_output_manager_v1") == 0) {
xwl_screen->xdg_output_manager =
wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, 1);
xwl_screen_init_xdg_output(xwl_screen);
}
#ifdef GLAMOR_HAS_GBM
else if (xwl_screen->glamor &&
strcmp(interface, "wl_drm") == 0 && version >= 2) {
xwl_screen_set_drm_interface(xwl_screen, id, version);
}
else if (xwl_screen->glamor &&
strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3) {
xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
}
#endif
}
static void
global_remove(void *data, struct wl_registry *registry, uint32_t name)
{
struct xwl_screen *xwl_screen = data;
struct xwl_output *xwl_output, *tmp_xwl_output;
xorg_list_for_each_entry_safe(xwl_output, tmp_xwl_output,
&xwl_screen->output_list, link) {
if (xwl_output->server_output_id == name) {
xwayland: Avoid double free of RRCrtc and RROutput At shutdown, the Xserver will free all its resources which includes the RRCrtc and RROutput created. Xwayland would do the same in its xwl_output_destroy() called from xwl_close_screen(), leading to a double free of existing RRCrtc RROutput: Invalid read of size 4 at 0x4CDA10: RRCrtcDestroy (rrcrtc.c:689) by 0x426E75: xwl_output_destroy (xwayland-output.c:301) by 0x424144: xwl_close_screen (xwayland.c:117) by 0x460E17: CursorCloseScreen (cursor.c:187) by 0x4EB5A3: AnimCurCloseScreen (animcur.c:106) by 0x4EF431: present_close_screen (present_screen.c:64) by 0x556D40: dix_main (main.c:354) by 0x6F0D290: (below main) (in /usr/lib/libc-2.24.so) Address 0xbb1fc30 is 0 bytes inside a block of size 728 free'd at 0x4C2BDB0: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x4CCE5F: RRCrtcDestroyResource (rrcrtc.c:719) by 0x577541: doFreeResource (resource.c:895) by 0x5787B5: FreeClientResources (resource.c:1161) by 0x578862: FreeAllResources (resource.c:1176) by 0x556C54: dix_main (main.c:323) by 0x6F0D290: (below main) (in /usr/lib/libc-2.24.so) Block was alloc'd at at 0x4C2CA6A: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x4CC6DB: RRCrtcCreate (rrcrtc.c:76) by 0x426D1C: xwl_output_create (xwayland-output.c:264) by 0x4232EC: registry_global (xwayland.c:431) by 0x76CB1C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4) by 0x76CAC29: ffi_call (in /usr/lib/libffi.so.6.0.4) by 0x556CEFD: wl_closure_invoke (connection.c:935) by 0x5569CBF: dispatch_event.isra.4 (wayland-client.c:1310) by 0x556AF13: dispatch_queue (wayland-client.c:1456) by 0x556AF13: wl_display_dispatch_queue_pending (wayland-client.c:1698) by 0x556B33A: wl_display_roundtrip_queue (wayland-client.c:1121) by 0x42371C: xwl_screen_init (xwayland.c:631) by 0x552F60: AddScreen (dispatch.c:3864) And: Invalid read of size 4 at 0x522890: RROutputDestroy (rroutput.c:348) by 0x42684E: xwl_output_destroy (xwayland-output.c:302) by 0x423CF4: xwl_close_screen (xwayland.c:118) by 0x4B6377: CursorCloseScreen (cursor.c:187) by 0x539503: AnimCurCloseScreen (animcur.c:106) by 0x53D081: present_close_screen (present_screen.c:64) by 0x43DBF0: dix_main (main.c:354) by 0x7068730: (below main) (libc-start.c:289) Address 0xc403190 is 0 bytes inside a block of size 154 free'd at 0x4C2CD5A: free (vg_replace_malloc.c:530) by 0x521DF3: RROutputDestroyResource (rroutput.c:389) by 0x45DA61: doFreeResource (resource.c:895) by 0x45ECFD: FreeClientResources (resource.c:1161) by 0x45EDC2: FreeAllResources (resource.c:1176) by 0x43DB04: dix_main (main.c:323) by 0x7068730: (below main) (libc-start.c:289) Block was alloc'd at at 0x4C2BBAD: malloc (vg_replace_malloc.c:299) by 0x52206B: RROutputCreate (rroutput.c:84) by 0x426763: xwl_output_create (xwayland-output.c:270) by 0x422EDC: registry_global (xwayland.c:432) by 0x740FC57: ffi_call_unix64 (unix64.S:76) by 0x740F6B9: ffi_call (ffi64.c:525) by 0x5495A9D: wl_closure_invoke (connection.c:949) by 0x549283F: dispatch_event.isra.4 (wayland-client.c:1274) by 0x5493A13: dispatch_queue (wayland-client.c:1420) by 0x5493A13: wl_display_dispatch_queue_pending (wayland-client.c:1662) by 0x5493D2E: wl_display_roundtrip_queue (wayland-client.c:1085) by 0x4232EC: xwl_screen_init (xwayland.c:632) by 0x439F50: AddScreen (dispatch.c:3864) Split xwl_output_destroy() into xwl_output_destroy() which frees the wl_output and the xwl_output structure, and xwl_output_remove() which does the RRCrtcDestroy() and RROutputDestroy() and call the latter only when an output is effectively removed. An additional benefit, on top of avoiding a double free, is to avoid updating the screen size at shutdown. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-08-08 17:57:57 +02:00
xwl_output_remove(xwl_output);
break;
}
}
}
static const struct wl_registry_listener registry_listener = {
registry_global,
global_remove
};
static void
xwl_read_events (struct xwl_screen *xwl_screen)
{
int ret;
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
if (xwl_screen->wait_flush)
return;
ret = wl_display_read_events(xwl_screen->display);
if (ret == -1)
xwl_give_up("failed to read Wayland events: %s\n", strerror(errno));
xwl_screen->prepare_read = 0;
ret = wl_display_dispatch_pending(xwl_screen->display);
if (ret == -1)
xwl_give_up("failed to dispatch Wayland events: %s\n", strerror(errno));
}
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
static int
xwl_display_pollout (struct xwl_screen *xwl_screen, int timeout)
{
struct pollfd poll_fd;
poll_fd.fd = wl_display_get_fd(xwl_screen->display);
poll_fd.events = POLLOUT;
return xserver_poll(&poll_fd, 1, timeout);
}
static void
xwl_dispatch_events (struct xwl_screen *xwl_screen)
{
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
int ret = 0;
int ready;
if (xwl_screen->wait_flush)
goto pollout;
while (xwl_screen->prepare_read == 0 &&
wl_display_prepare_read(xwl_screen->display) == -1) {
ret = wl_display_dispatch_pending(xwl_screen->display);
if (ret == -1)
xwl_give_up("failed to dispatch Wayland events: %s\n",
strerror(errno));
}
xwl_screen->prepare_read = 1;
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
pollout:
ready = xwl_display_pollout(xwl_screen, 5);
if (ready == -1 && errno != EINTR)
xwl_give_up("error polling on XWayland fd: %s\n", strerror(errno));
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
if (ready > 0)
ret = wl_display_flush(xwl_screen->display);
if (ret == -1 && errno != EAGAIN)
xwl_give_up("failed to write to XWayland fd: %s\n", strerror(errno));
xwayland: handle EAGAIN on Wayland fd wl_display_flush() can fail with EAGAIN and Xwayland would make this a fatal error. When this happens, it means that Xwayland has flooded the Wayland file descriptor, either because the Wayland compositor cannot cope or more likely because of a deadlock situation where the Wayland compositor is blocking, waiting for an X reply while Xwayland tries to write data to the Wayland file descriptor. The general consensus to avoid the deadlock is for the Wayland compositor to never issue blocking X11 roundtrips, but in practice blocking rountrips can occur in various places, including Xlib calls themselves so this is not always achievable without major surgery in the Wayland compositor/Window manager. What this patch does is to avoid dispatching to the Wayland file descriptor until it becomes available for writing again, while at the same time continue processing X11 requests to release the deadlock. This is not perfect, as there is still the possibility of another X client hammering the connection and we'll still fail writing to the Wayland connection eventually, but this improves things enough to avoid a 100% repeatable crash with vlc and gtkperf. Also, it is worth considering that window managers and Wayland compositors such as mutter already have a higher priority than other regular X clients thanks to XSyncSetPriority(), mitigating the risk. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1278159 Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=763400 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-09-15 15:59:07 +02:00
xwl_screen->wait_flush = (ready == 0 || ready == -1 || ret == -1);
}
static void
socket_handler(int fd, int ready, void *data)
{
struct xwl_screen *xwl_screen = data;
xwl_read_events (xwl_screen);
}
static void
wakeup_handler(void *data, int err)
{
}
static void
block_handler(void *data, void *timeout)
{
struct xwl_screen *xwl_screen = data;
xwl_screen_post_damage(xwl_screen);
xwl_dispatch_events (xwl_screen);
}
void
xwl_sync_events (struct xwl_screen *xwl_screen)
{
xwl_dispatch_events (xwl_screen);
xwl_read_events (xwl_screen);
}
static CARD32
add_client_fd(OsTimerPtr timer, CARD32 time, void *arg)
{
struct xwl_screen *xwl_screen = arg;
if (!AddClientOnOpenFD(xwl_screen->wm_fd))
FatalError("Failed to add wm client\n");
TimerFree(timer);
return 0;
}
static void
listen_on_fds(struct xwl_screen *xwl_screen)
{
int i;
for (i = 0; i < xwl_screen->listen_fd_count; i++)
ListenOnOpenFD(xwl_screen->listen_fds[i], FALSE);
}
static void
wm_selection_callback(CallbackListPtr *p, void *data, void *arg)
{
SelectionInfoRec *info = arg;
struct xwl_screen *xwl_screen = data;
static const char atom_name[] = "WM_S0";
static Atom atom_wm_s0;
if (atom_wm_s0 == None)
atom_wm_s0 = MakeAtom(atom_name, strlen(atom_name), TRUE);
if (info->selection->selection != atom_wm_s0 ||
info->kind != SelectionSetOwner)
return;
listen_on_fds(xwl_screen);
DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
}
static Bool
xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
{
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
struct xwl_screen *xwl_screen;
Pixel red_mask, blue_mask, green_mask;
int ret, bpc, green_bpc, i;
xwl_screen = calloc(1, sizeof *xwl_screen);
if (xwl_screen == NULL)
return FALSE;
xwl_screen->wm_fd = -1;
if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
return FALSE;
if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
return FALSE;
if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
return FALSE;
dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
xwl_screen->screen = pScreen;
#ifdef GLAMOR_HAS_GBM
xwl_screen->glamor = 1;
#endif
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-rootless") == 0) {
xwl_screen->rootless = 1;
}
else if (strcmp(argv[i], "-wm") == 0) {
xwl_screen->wm_fd = atoi(argv[i + 1]);
i++;
TimerSet(NULL, 0, 1, add_client_fd, xwl_screen);
}
else if (strcmp(argv[i], "-listen") == 0) {
if (xwl_screen->listen_fd_count ==
ARRAY_SIZE(xwl_screen->listen_fds))
FatalError("Too many -listen arguments given, max is %ld\n",
ARRAY_SIZE(xwl_screen->listen_fds));
xwl_screen->listen_fds[xwl_screen->listen_fd_count++] =
atoi(argv[i + 1]);
i++;
}
else if (strcmp(argv[i], "-shm") == 0) {
xwl_screen->glamor = 0;
}
}
/* In rootless mode, we don't have any screen storage, and the only
* rendering should be to redirected mode. */
if (xwl_screen->rootless)
xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY;
else
xwl_screen->root_clip_mode = ROOT_CLIP_FULL;
if (xwl_screen->listen_fd_count > 0) {
if (xwl_screen->wm_fd >= 0)
AddCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
else
listen_on_fds(xwl_screen);
}
xorg_list_init(&xwl_screen->output_list);
xorg_list_init(&xwl_screen->seat_list);
xorg_list_init(&xwl_screen->damage_window_list);
xwl_screen->depth = 24;
xwl_screen->display = wl_display_connect(NULL);
if (xwl_screen->display == NULL) {
ErrorF("could not connect to wayland server\n");
return FALSE;
}
if (!xwl_screen_init_output(xwl_screen))
return FALSE;
xwl_screen->expecting_event = 0;
xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
wl_registry_add_listener(xwl_screen->registry,
&registry_listener, xwl_screen);
ret = wl_display_roundtrip(xwl_screen->display);
if (ret == -1) {
ErrorF("could not connect to wayland server\n");
return FALSE;
}
while (xwl_screen->expecting_event > 0)
wl_display_roundtrip(xwl_screen->display);
bpc = xwl_screen->depth / 3;
green_bpc = xwl_screen->depth - 2 * bpc;
blue_mask = (1 << bpc) - 1;
green_mask = ((1 << green_bpc) - 1) << bpc;
red_mask = blue_mask << (green_bpc + bpc);
miSetVisualTypesAndMasks(xwl_screen->depth,
((1 << TrueColor) | (1 << DirectColor)),
green_bpc, TrueColor,
red_mask, green_mask, blue_mask);
miSetPixmapDepths();
ret = fbScreenInit(pScreen, NULL,
xwl_screen->width, xwl_screen->height,
96, 96, 0,
BitsPerPixel(xwl_screen->depth));
if (!ret)
return FALSE;
fbPictureInit(pScreen, 0, 0);
#ifdef HAVE_XSHMFENCE
if (!miSyncShmScreenInit(pScreen))
return FALSE;
#endif
xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
pScreen->SaveScreen = xwl_save_screen;
pScreen->blackPixel = 0;
pScreen->whitePixel = 1;
ret = fbCreateDefColormap(pScreen);
if (!xwl_screen_init_cursor(xwl_screen))
return FALSE;
#ifdef GLAMOR_HAS_GBM
if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) {
ErrorF("Failed to initialize glamor, falling back to sw\n");
xwl_screen->glamor = 0;
}
#endif
if (!xwl_screen->glamor) {
xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = xwl_shm_create_screen_resources;
pScreen->CreatePixmap = xwl_shm_create_pixmap;
pScreen->DestroyPixmap = xwl_shm_destroy_pixmap;
}
xwl_screen->RealizeWindow = pScreen->RealizeWindow;
pScreen->RealizeWindow = xwl_realize_window;
xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreen->UnrealizeWindow = xwl_unrealize_window;
xwl_screen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_close_screen;
pScreen->CursorWarpedTo = xwl_cursor_warped_to;
pScreen->CursorConfinedTo = xwl_cursor_confined_to;
xwayland: use _XWAYLAND_ALLOW_COMMITS property The X11 window manager (XWM) of a Wayland compositor can use the _XWAYLAND_ALLOW_COMMITS property to control when Xwayland sends wl_surface.commit requests. If the property is not set, the behaviour remains what it was. XWM uses the property to inhibit commits until the window is ready to be shown. This gives XWM time to set up the window decorations and internal state before Xwayland does the first commit. XWM can use this to ensure the first commit carries fully drawn decorations and the window management state is correct when the window becomes visible. Setting the property to zero inhibits further commits, and setting it to non-zero allows commits. Deleting the property allows commits. When the property is changed from zero to non-zero, there will be a commit on next block_handler() call provided that some damage has been recorded. Without this patch (i.e. with the old behaviour) Xwayland can and will commit the surface very soon as the application window has been realized and drawn into. This races with XWM and may cause visible glitches. v3: - introduced a simple setter for xwl_window::allow_commits - split xwl_window_property_allow_commits() out of xwl_property_callback() - check MakeAtom(_XWAYLAND_ALLOW_COMMITS) v2: - use PropertyStateCallback instead of XACE, based on the patch "xwayland: Track per-window support for netwm frame sync" by Adam Jackson - check property type is XA_CARDINAL - drop a useless memcpy() Weston Bug: https://phabricator.freedesktop.org/T7622 Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-11-23 12:30:53 +01:00
xwl_screen->allow_commits_prop = MakeAtom(allow_commits,
strlen(allow_commits),
TRUE);
if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
return FALSE;
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
return ret;
}
_X_NORETURN
static void _X_ATTRIBUTE_PRINTF(1, 0)
xwl_log_handler(const char *format, va_list args)
{
char msg[256];
vsnprintf(msg, sizeof msg, format, args);
FatalError("%s", msg);
}
static const ExtensionModule xwayland_extensions[] = {
#ifdef XF86VIDMODE
{ xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension },
#endif
};
void
InitOutput(ScreenInfo * screen_info, int argc, char **argv)
{
int depths[] = { 1, 4, 8, 15, 16, 24, 32 };
int bpp[] = { 1, 8, 8, 16, 16, 32, 32 };
int i;
for (i = 0; i < ARRAY_SIZE(depths); i++) {
screen_info->formats[i].depth = depths[i];
screen_info->formats[i].bitsPerPixel = bpp[i];
screen_info->formats[i].scanlinePad = BITMAP_SCANLINE_PAD;
}
screen_info->imageByteOrder = IMAGE_BYTE_ORDER;
screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
screen_info->bitmapBitOrder = BITMAP_BIT_ORDER;
screen_info->numPixmapFormats = ARRAY_SIZE(depths);
xwayland: Don't load extension list more than once When running an Xwayland server from the command line, we end up resetting the server every time all of the clients connected to the server leave. This would be fine, except that xwayland makes the mistake of unconditionally calling LoadExtensionList(). This causes us to setup the glxExtension twice in a row which means that when we lose our last client on the second server generation, we end up trying to call the glx destructors twice in a row resulting in a segfault: (EE) (EE) Backtrace: (EE) 0: Xwayland (OsSigHandler+0x3b) [0x4982f9] (EE) 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x70845bf] (EE) 2: /usr/lib64/dri/swrast_dri.so (__driDriverGetExtensions_virtio_gpu+0x32897d) [0x1196e5bd] (EE) 3: /usr/lib64/dri/swrast_dri.so (__driDriverGetExtensions_virtio_gpu+0x328a45) [0x1196e745] (EE) 4: /usr/lib64/dri/swrast_dri.so (__driDriverGetExtensions_virtio_gpu+0x32665f) [0x11969f7f] (EE) 5: Xwayland (__glXDRIscreenDestroy+0x30) [0x54686e] (EE) 6: Xwayland (glxCloseScreen+0x3f) [0x5473db] (EE) 7: Xwayland (glxCloseScreen+0x53) [0x5473ef] (EE) 8: Xwayland (dix_main+0x7b6) [0x44c8c9] (EE) 9: Xwayland (main+0x28) [0x61c503] (EE) 10: /lib64/libc.so.6 (__libc_start_main+0xf1) [0x72b1401] (EE) 11: Xwayland (_start+0x2a) [0x4208fa] (EE) 12: ? (?+0x2a) [0x2a] (EE) (EE) Segmentation fault at address 0x18 (EE) Fatal server error: (EE) Caught signal 11 (Segmentation fault). Server aborting (EE) Easy reproduction recipe: - Start an Xwayland session with the default settings - Open a window - Close that window - Open another window - Close that window - Total annihilation occurs Signed-off-by: Lyude <lyude@redhat.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-30 22:39:49 +02:00
if (serverGeneration == 1)
LoadExtensionList(xwayland_extensions,
ARRAY_SIZE(xwayland_extensions), FALSE);
/* Cast away warning from missing printf annotation for
* wl_log_func_t. Wayland 1.5 will have the annotation, so we can
* remove the cast and require that when it's released. */
wl_log_set_handler_client((void *) xwl_log_handler);
if (AddScreen(xwl_screen_init, argc, argv) == -1) {
FatalError("Couldn't add screen\n");
}
xorgGlxCreateVendor();
LocalAccessScopeUser();
}