drop Xwayland

It always had it's own lifecycle (not been part of Xorg releases),
doesn't make sense to maintain a competing implementation that we
won't use anyways.

Once that's gone, we can also drop few things in core/dix that had
been added just for xwayland only.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-06-16 10:59:01 +02:00 committed by Enrico Weigelt
parent d042e5a667
commit c8b81fdbc5
56 changed files with 10 additions and 19268 deletions

View File

@ -92,9 +92,6 @@ stages:
.xorg_paths: &xorg_paths
- hw/xfree86/**/*
.xwayland_paths: &xwayland_paths
- hw/xwayland/**/*
.all_ddx_paths:
- hw/**/*
@ -178,12 +175,11 @@ meson:
PIGLIT_DIR: /root/piglit
LP_NUM_THREADS: 0
MESON_DDX_BUILD_ARGS: >
-Dxwayland=${BUILD_XWAYLAND} -Dxorg=${BUILD_XORG} -Dxephyr=${BUILD_XEPHYR} -Dxvfb=${BUILD_XVFB} -Dxnest=${BUILD_XNEST}
-Dxorg=${BUILD_XORG} -Dxephyr=${BUILD_XEPHYR} -Dxvfb=${BUILD_XVFB} -Dxnest=${BUILD_XNEST}
BUILD_XEPHYR: true
BUILD_XNEST: true
BUILD_XORG: true
BUILD_XVFB: true
BUILD_XWAYLAND: true
MESON_EXTRA_ARGS: ${MESON_DDX_BUILD_ARGS}
meson-noglamor:
@ -191,15 +187,6 @@ meson-noglamor:
variables:
MESON_EXTRA_ARGS: -Dglamor=false ${MESON_DDX_BUILD_ARGS}
xwayland-nolibdecor:
extends: meson
variables:
BUILD_XEPHYR: false
BUILD_XNEST: false
BUILD_XORG: false
BUILD_XVFB: false
MESON_EXTRA_ARGS: -Dlibdecor=false ${MESON_DDX_BUILD_ARGS}
mingw-cross-build:
extends: .common-build-and-test
script:
@ -374,7 +361,7 @@ xf86-driver-build-test:
variables:
GIT_DEPTH: 1
MESON_ARGS: -Dprefix=/usr/
MESON_EXTRA_ARGS: -Dxwayland=false -Dxnest=false -Dxvfb=false -Dxquartz=false -Ddocs=false
MESON_EXTRA_ARGS: -Dxnest=false -Dxvfb=false -Dxquartz=false -Ddocs=false
#
# Verify that the merge request has the allow-collaboration checkbox ticked

View File

@ -20,6 +20,5 @@ fi
[[ "$BUILD_XNEST" == true ]] && check_executable "hw/xnest/Xnest"
[[ "$BUILD_XORG" == true ]] && check_executable "hw/xfree86/Xorg"
[[ "$BUILD_XVFB" == true ]] && check_executable "hw/vfb/Xvfb"
[[ "$BUILD_XWAYLAND" == true ]] && check_executable "hw/xwayland/Xwayland"
exit 0

View File

@ -27,4 +27,3 @@ check_piglit_results ()
check_piglit_results xephyr-glamor hw/kdrive/ephyr/Xephyr.p/ephyr_glamor.c.o
check_piglit_results xvfb hw/vfb/Xvfb
check_piglit_results xwayland hw/xwayland/Xwayland

View File

@ -49,7 +49,6 @@ apt-get install -y \
libglx-mesa0 \
libinput10 \
libinput-dev \
libnvidia-egl-wayland-dev \
libpango1.0-0 \
libpango1.0-dev \
libpciaccess-dev \
@ -60,7 +59,6 @@ apt-get install -y \
libtool \
libudev-dev \
libunwind-dev \
libwayland-dev \
libx11-dev \
libx11-xcb-dev \
libxau-dev \
@ -131,7 +129,7 @@ apt-get install -y \
cd /root
# Xwayland requires drm 2.4.116 for drmSyncobjEventfd
# drm 2.4.116 for drmSyncobjEventfd
git clone https://gitlab.freedesktop.org/mesa/drm --depth 1 --branch=libdrm-2.4.121
cd drm
meson _build
@ -147,7 +145,7 @@ ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf libxcvt
# xserver requires xorgproto >= 2024.1 for XWAYLAND
# xserver requires xorgproto >= 2024.1
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2024.1
pushd xorgproto
./autogen.sh
@ -155,38 +153,6 @@ make -j${FDO_CI_CONCURRENT:-4} install
popd
rm -rf xorgproto
# wayland-protocols requires wayland-scanner 1.20, but Debian bullseye has 1.18 only
git clone https://gitlab.freedesktop.org/wayland/wayland.git --depth 1 --branch=1.21.0
cd wayland
meson -Dtests=false -Ddocumentation=false -Ddtd_validation=false _build
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf wayland
# Xwayland requires wayland-protocols >= 1.38, but Debian bullseye has 1.20 only
git clone https://gitlab.freedesktop.org/wayland/wayland-protocols.git --depth 1 --branch=1.38
cd wayland-protocols
meson _build
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf wayland-protocols
# Install libdecor for Xwayland
git clone https://gitlab.freedesktop.org/libdecor/libdecor.git --depth 1 --branch=0.1.1
cd libdecor
meson _build -D{demo,install_demo}=false
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf libdecor
# Install libei for Xwayland
git clone https://gitlab.freedesktop.org/libinput/libei.git --depth 1 --branch=1.0.0
cd libei
meson setup _build -Dtests=disabled -Ddocumentation=[] -Dliboeffis=enabled
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf libei
git clone https://gitlab.freedesktop.org/mesa/piglit.git
cd piglit
git checkout 265896c86f90cb72e8f218ba6a3617fca8b9a1e3

View File

@ -106,7 +106,6 @@ static struct { const char *name; int id; } reservedExt[] = {
{ "XTEST", EXTENSION_MAJOR_XTEST },
{ "XVideo", EXTENSION_MAJOR_XVIDEO },
{ "XVideo-MotionCompensation", EXTENSION_MAJOR_XVMC },
{ "XWAYLAND", EXTENSION_MAJOR_XWAYLAND },
};
static int checkReserved(const char* name)

View File

@ -43,7 +43,6 @@
#define EXTENSION_MAJOR_XTEST (EXTENSION_BASE + 33)
#define EXTENSION_MAJOR_XVIDEO (EXTENSION_BASE + 34)
#define EXTENSION_MAJOR_XVMC (EXTENSION_BASE + 35)
#define EXTENSION_MAJOR_XWAYLAND (EXTENSION_BASE + 36)
#define RESERVED_EXTENSIONS 38

View File

@ -24,8 +24,8 @@
* Adam Jackson <ajax@redhat.com>
*/
#ifndef XWAYLAND_GLX_H
#define XWAYLAND_GLX_H
#ifndef GLAMOR_GLX_PROVIDER_H
#define GLAMOR_GLX_PROVIDER_H
#include <dix-config.h>
@ -34,4 +34,4 @@
extern _X_EXPORT __GLXprovider glamor_provider;
#endif
#endif /* XWAYLAND_GLX_H */
#endif /* GLAMOR_GLX_PROVIDER_H */

View File

@ -18,10 +18,6 @@ if build_xquartz
subdir('xquartz')
endif
if build_xwayland
subdir('xwayland')
endif
if build_xwin
subdir('xwin')
endif

View File

@ -1,17 +0,0 @@
Xwayland
drm-client-protocol.h
drm-protocol.c
linux-dmabuf-unstable-v1-client-protocol.h
linux-dmabuf-unstable-v1-protocol.c
pointer-constraints-unstable-v1-client-protocol.h
pointer-constraints-unstable-v1-protocol.c
relative-pointer-unstable-v1-client-protocol.h
relative-pointer-unstable-v1-protocol.c
tablet-unstable-v2-client-protocol.h
tablet-unstable-v2-protocol.c
viewporter-client-protocol.h
viewporter-protocol.c
xdg-output-unstable-v1-client-protocol.h
xdg-output-unstable-v1-protocol.c
xwayland-keyboard-grab-unstable-v1-client-protocol.h
xwayland-keyboard-grab-unstable-v1-protocol.c

View File

@ -1,8 +0,0 @@
[Desktop Entry]
Name=Xwayland
Comment=A rootful instance of the Xwayland X11 server
Terminal=false
Type=Application
Categories=System;
Exec=@XWAYLAND@ @DECORATE@ -displayfd 1
NoDisplay=true

View File

@ -1,185 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="drm">
<copyright>
Copyright © 2008-2011 Kristian Høgsberg
Copyright © 2010-2011 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\n 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.
</copyright>
<!-- drm support. This object is created by the server and published
using the display's global event. -->
<interface name="wl_drm" version="2">
<enum name="error">
<entry name="authenticate_fail" value="0"/>
<entry name="invalid_format" value="1"/>
<entry name="invalid_name" value="2"/>
</enum>
<enum name="format">
<!-- The drm format codes match the #defines in drm_fourcc.h.
The formats actually supported by the compositor will be
reported by the format event. -->
<entry name="c8" value="0x20203843"/>
<entry name="rgb332" value="0x38424752"/>
<entry name="bgr233" value="0x38524742"/>
<entry name="xrgb4444" value="0x32315258"/>
<entry name="xbgr4444" value="0x32314258"/>
<entry name="rgbx4444" value="0x32315852"/>
<entry name="bgrx4444" value="0x32315842"/>
<entry name="argb4444" value="0x32315241"/>
<entry name="abgr4444" value="0x32314241"/>
<entry name="rgba4444" value="0x32314152"/>
<entry name="bgra4444" value="0x32314142"/>
<entry name="xrgb1555" value="0x35315258"/>
<entry name="xbgr1555" value="0x35314258"/>
<entry name="rgbx5551" value="0x35315852"/>
<entry name="bgrx5551" value="0x35315842"/>
<entry name="argb1555" value="0x35315241"/>
<entry name="abgr1555" value="0x35314241"/>
<entry name="rgba5551" value="0x35314152"/>
<entry name="bgra5551" value="0x35314142"/>
<entry name="rgb565" value="0x36314752"/>
<entry name="bgr565" value="0x36314742"/>
<entry name="rgb888" value="0x34324752"/>
<entry name="bgr888" value="0x34324742"/>
<entry name="xrgb8888" value="0x34325258"/>
<entry name="xbgr8888" value="0x34324258"/>
<entry name="rgbx8888" value="0x34325852"/>
<entry name="bgrx8888" value="0x34325842"/>
<entry name="argb8888" value="0x34325241"/>
<entry name="abgr8888" value="0x34324241"/>
<entry name="rgba8888" value="0x34324152"/>
<entry name="bgra8888" value="0x34324142"/>
<entry name="xrgb2101010" value="0x30335258"/>
<entry name="xbgr2101010" value="0x30334258"/>
<entry name="rgbx1010102" value="0x30335852"/>
<entry name="bgrx1010102" value="0x30335842"/>
<entry name="argb2101010" value="0x30335241"/>
<entry name="abgr2101010" value="0x30334241"/>
<entry name="rgba1010102" value="0x30334152"/>
<entry name="bgra1010102" value="0x30334142"/>
<entry name="yuyv" value="0x56595559"/>
<entry name="yvyu" value="0x55595659"/>
<entry name="uyvy" value="0x59565955"/>
<entry name="vyuy" value="0x59555956"/>
<entry name="ayuv" value="0x56555941"/>
<entry name="nv12" value="0x3231564e"/>
<entry name="nv21" value="0x3132564e"/>
<entry name="nv16" value="0x3631564e"/>
<entry name="nv61" value="0x3136564e"/>
<entry name="yuv410" value="0x39565559"/>
<entry name="yvu410" value="0x39555659"/>
<entry name="yuv411" value="0x31315559"/>
<entry name="yvu411" value="0x31315659"/>
<entry name="yuv420" value="0x32315559"/>
<entry name="yvu420" value="0x32315659"/>
<entry name="yuv422" value="0x36315559"/>
<entry name="yvu422" value="0x36315659"/>
<entry name="yuv444" value="0x34325559"/>
<entry name="yvu444" value="0x34325659"/>
</enum>
<!-- Call this request with the magic received from drmGetMagic().
It will be passed on to the drmAuthMagic() or
DRIAuthConnection() call. This authentication must be
completed before create_buffer could be used. -->
<request name="authenticate">
<arg name="id" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="uint"/>
<arg name="format" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_planar_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
<!-- Notification of the path of the drm device which is used by
the server. The client should use this device for creating
local buffers. Only buffers created from this device should
be be passed to the server using this drm object's
create_buffer request. -->
<event name="device">
<arg name="name" type="string"/>
</event>
<event name="format">
<arg name="format" type="uint"/>
</event>
<!-- Raised if the authenticate request succeeded -->
<event name="authenticated"/>
<enum name="capability" since="2">
<description summary="wl_drm capability bitmask">
Bitmask of capabilities.
</description>
<entry name="prime" value="1" summary="wl_drm prime available"/>
</enum>
<event name="capabilities">
<arg name="value" type="uint"/>
</event>
<!-- Version 2 additions -->
<!-- Create a wayland buffer for the prime fd. Use for regular and planar
buffers. Pass 0 for offset and stride for unused planes. -->
<request name="create_prime_buffer" since="2">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="fd"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
</interface>
</protocol>

View File

@ -1,183 +0,0 @@
'\" t
.\"
.\" Copyright 1984 - 1991, 1993, 1994, 1998 The Open Group
.\"
.\" 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.
.\"
.\" 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 OPEN GROUP 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.
.\"
.\" Except as contained in this notice, the name of The Open Group shall
.\" not be used in advertising or otherwise to promote the sale, use or
.\" other dealings in this Software without prior written authorization
.\" from The Open Group.
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH XWAYLAND 1 @xorgversion@
.SH NAME
Xwayland \- an X server for running X clients under Wayland.
.SH SYNOPSIS
.B Xwayland
[option ...]
.SH DESCRIPTION
.I Xwayland
is an X server and a Wayland client. It plays the role of a proxy between
legacy X clients which do not support the Wayland protocols and the Wayland
server.
.PP
Usually, \fIXwayland\fP is spawned automatically by the Wayland server
and runs rootless so that X clients integrate seamlessly with the rest
of the Wayland desktop. It is however possible for a user to launch Xwayland
non-rootless, mainly for testing purposes.
.PP
Like all of the X servers, \fIXwayland\fP accepts the command line options
described in the
.BR Xserver (@miscmansuffix@)
manual page.
The following additional arguments are supported as well.
.TP 8
.B \-decorate
Add decorations to the Xwayland root window when running rootful.
This option has no effect when \fIXwayland\fP is built without libdecor
support (optional).
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-enable-ei-portal
Enable support for the XDG portal for input emulation.
A Wayland compositor running nested should not use that command line
option with Xwayland.
This option has no effect if the compositor doesn't support the relevant
XDG portal or if Xwayland was not compiled with EI and OEFFIS support.
.TP 8
.B \-fullscreen
Set the Xwayland window fullscreen when running rootful.
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-geometry \fIWxH\fP
Sets the geometry of the \fIXwayland\fP window to \fIWxH\fP when running rootful.
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-glamor " [\fIgl|es|off\fP]"
Use given rendering API for Glamor acceleration. Possible options are \fIgl\fP and \fIes\fP.
If \fIXwayland\fP was compiled with Glamor support, this option will instruct \fIXwayland\fP
to use only requested API for Glamor. If this set to \fIoff\fP, effect is equal to \fI-shm\fP option.
Without this option and without \fI-shm\fP option, \fIXwayland\fP tries the OpenGL rendering API first,
and fallback to GL ES if GL version is less than 2.1.
This option is not compatible with \fI-shm\fP option.
.TP 8
.B \-hidpi
Adjust to the scale of the outputs when running rootful in windowing mode.
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-host-grab
Disable host keyboard shorcuts and confine the pointer when running rootful.
This feature relies on the protocol for inhibiting the compositor keyboard
shortcuts and on the protocol for pointer locking and confinement and may
have no effect if the Wayland compositor in use does not support these
protocols.
Use the keys [CTRL]+[SHIFT] simultaneously to release the keyboard and
pointer devices.
This option is not compatible with rootless mode (\fI-rootless\fP).
.TP 8
.B \-initfd \fIfd\fP
Add the given \fIfd\fP as a listen socket for initialization of X clients.
This options is aimed at \fIWayland\fP servers which run \fIXwayland\fP
on-demand, to be able to spawn specific X clients which need to complete
before other regular X clients can connect to \fIXwayland\fP, like \fIxrdb\fP.
.TP 8
.B \-listen \fIfd\fP
deprecated, use \fI\-listenfd\fP instead.
.TP 8
.B \-listenfd \fIfd\\fP
Add given fd as a listen socket. This option is used by the \fIWayland\fP
server to pass \fIXwayland\fP the socket where X clients connect.
.TP 8
.B \-noTouchPointerEmulation
Disable touch pointer emulation. This allows the Wayland compositor to
implement its own pointer emulation mechanism for X11 clients that don't
support touch input.
.TP 8
.B \-force-xrandr-emulation
Force additional non-native modes to be exposed when viewporter is not
supported by the Wayland compositor.
.TP 8
.B \-nokeymap
Instructs \fIXwayland\fP to ignore the keymap set by the Wayland compositor.
By default, \fIXwayland\fP (as any Wayland client) uses the keymap set by the
Wayland compositor using the standard Wayland protocol.
This option is meant for some specific use cases where it may be desirable to
let the X11 clients control the keymap used in Xwayland, ignoring the keymap
specified by the Wayland compositor.
.B \-output \fIname\fP
Specifies on which output \fIXwayland\fP fullscreen rootful should be placed.
The name must match the name of an existing Wayland output (output names can
be found using wayland-info).
If no matching output can be found, the Wayland compositor will decide on which
output the fullscreen rootful \fIXwayland\fP window will be placed.
This option has no effect if \fIXwayland\fP is not running fullscreen rootful.
.TP 8
.B \-rootless
Run \fIXwayland\fP rootless, so that X clients integrate seamlessly with
Wayland clients in a Wayland desktop. That requires the Wayland server
to be an X window manager as well.
.TP 8
.B \-shm
Force the shared memory backend instead of glamor (if available) for passing
buffers to the Wayland server.
This option is not compatible with \fI-glamor\fP option.
.TP 8
.BR \-verbose " [\fIn\fP]"
Sets the verbosity level for information printed on stderr. If the
.I n
value isn't supplied, each occurrence of this option increments the
verbosity level. When the
.I n
value is supplied, the verbosity level is set to that value. The default
verbosity level is 0.
.TP 8
.B \-version
Show the server version and exit.
.TP 8
.B \-wm \fIfd\fP
This option is used by the \fIWayland\fP server to pass \fIXwayland\fP
the socket where the X window manager client connects, when \fIXwayland\fP
is running with \fI-rootless\fP.
.SH ENVIRONMENT
.TP 8
.B WAYLAND_DISPLAY
the name of the display of the Wayland server.
.TP 8
.B XWAYLAND_NO_GLAMOR
disable glamor and DRI3 support in \fIXwayland\fP, for testing purposes.
.SH "SEE ALSO"
General information:
.BR X (@miscmansuffix@),
.BR wayland-info (@miscmansuffix@)

View File

@ -1,220 +0,0 @@
srcs = [
'xwayland.c',
'xwayland-input.c',
'xwayland-input.h',
'xwayland-cursor.c',
'xwayland-cursor.h',
'xwayland-drm-lease.h',
'xwayland-drm-lease.c',
'xwayland-glamor.h',
'xwayland-pixmap.c',
'xwayland-pixmap.h',
'xwayland-present.c',
'xwayland-present.h',
'xwayland-screen.c',
'xwayland-screen.h',
'xwayland-shm.c',
'xwayland-shm.h',
'xwayland-types.h',
'xwayland-output.c',
'xwayland-output.h',
'xwayland-cvt.c',
'xwayland-cvt.h',
'xwayland-vidmode.c',
'xwayland-vidmode.h',
'xwayland-window.c',
'xwayland-window.h',
'xwayland-window-buffers.c',
'xwayland-window-buffers.h',
'../../mi/miinitext.c',
'../../mi/miinitext.h',
]
scanner_dep = dependency('wayland-scanner', native: true)
scanner = find_program(scanner_dep.get_variable(pkgconfig : 'wayland_scanner'))
protocols_dep = dependency('wayland-protocols', version: wayland_protocols_req)
protodir = protocols_dep.get_variable(pkgconfig : 'pkgdatadir')
pointer_xml = join_paths(protodir, 'unstable', 'pointer-constraints', 'pointer-constraints-unstable-v1.xml')
relative_xml = join_paths(protodir, 'unstable', 'relative-pointer', 'relative-pointer-unstable-v1.xml')
gestures_xml = join_paths(protodir, 'unstable', 'pointer-gestures', 'pointer-gestures-unstable-v1.xml')
tablet_xml = join_paths(protodir, 'unstable', 'tablet', 'tablet-unstable-v2.xml')
kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwayland-keyboard-grab-unstable-v1.xml')
xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')
dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
tearing_xml = join_paths(protodir, 'staging', 'tearing-control', 'tearing-control-v1.xml')
fractional_scale_xml = join_paths(protodir, 'staging', 'fractional-scale', 'fractional-scale-v1.xml')
syncobj_xml = join_paths(protodir, 'staging', 'linux-drm-syncobj', 'linux-drm-syncobj-v1.xml')
system_bell_xml = join_paths(protodir, 'staging', 'xdg-system-bell', 'xdg-system-bell-v1.xml')
proto_xml = [
relative_xml,
pointer_xml,
gestures_xml,
tablet_xml,
kbgrab_xml,
xdg_output_xml,
dmabuf_xml,
viewporter_xml,
xdg_shell_xml,
drm_lease_xml,
shortcuts_inhibit_xml,
xwayland_shell_xml,
tearing_xml,
fractional_scale_xml,
syncobj_xml,
system_bell_xml,
]
client_header = generator(scanner,
output : '@BASENAME@-client-protocol.h',
arguments : ['client-header', '@INPUT@', '@OUTPUT@']
)
if scanner_dep.version().version_compare('>= 1.14.91')
scanner_argument = 'private-code'
else
scanner_argument = 'code'
endif
code = generator(scanner,
output : '@BASENAME@-protocol.c',
arguments : [scanner_argument, '@INPUT@', '@OUTPUT@']
)
foreach xml : proto_xml
srcs += client_header.process(xml)
srcs += code.process(xml)
endforeach
if build_ei
xwayland_dep += libei_dep
srcs += [ 'xwayland-xtest.c', 'xwayland-xtest.h' ]
if build_ei_portal
xwayland_dep += liboeffis_dep
endif
endif
xwayland_glamor = []
if build_xwayland_glamor
srcs += [
'xwayland-glamor.c',
'xwayland-dmabuf.h',
'xwayland-dmabuf.c',
'xwayland-glamor-gbm.c',
'xwayland-glamor-gbm.h'
]
if build_xv
srcs += 'xwayland-glamor-xv.c'
endif
srcs += client_header.process('drm.xml')
srcs += code.process('drm.xml')
xwayland_dep += gbm_dep
xwayland_glamor += glamor
endif
wayland_inc = [ inc, ]
if build_glx
wayland_inc += glx_inc
endif
if libdrm_dep.found()
xwayland_dep += libdrm_dep
endif
if have_libdecor
xwayland_dep += libdecor_dep
endif
xwayland_server = executable(
'Xwayland',
srcs,
include_directories: wayland_inc,
dependencies: [
common_dep,
epoll_dep,
xwayland_dep,
xwaylandproto_dep,
],
link_with: [
libxserver_main,
xwayland_glamor,
libxserver_fb,
libxserver,
libxserver_xext_vidmode,
libxserver_xkb_stubs,
libxserver_xi_stubs,
libxserver_glx,
libglxvnd,
],
install: true,
install_dir: xwayland_path
)
xwayland_vars = [
'have_glamor=' + build_glamor.to_string(),
'have_glamor_api=' + build_glamor.to_string(),
'have_eglstream=false',
'have_initfd=true',
'have_listenfd=true',
'have_verbose=true',
'have_terminate_delay=true',
'have_no_touch_pointer_emulation=true',
'have_force_xrandr_emulation=true',
'have_geometry=true',
'have_fullscreen=true',
'have_host_grab=true',
'have_decorate=' + have_libdecor.to_string(),
'have_enable_ei_portal=' + build_ei_portal.to_string(),
'have_byteswappedclients=true',
'have_hidpi=true',
]
pkgconfig = import('pkgconfig')
pkgconfig.generate(
filebase: 'xwayland',
name: 'Xwayland',
description: 'X Server for Wayland',
dataonly: true,
variables: [
'exec_prefix=${prefix}',
'xwayland=' + xwayland_path / xwayland_server.name(),
] + xwayland_vars,
url: 'https://gitlab.freedesktop.org/xorg/xserver/',
)
xwayland_manpage = configure_file(
input: 'man/Xwayland.man',
output: 'Xwayland.1',
configuration: manpage_config,
)
install_man(xwayland_manpage)
desktop_data = configuration_data()
desktop_data.set('XWAYLAND', xwayland_path / xwayland_server.name())
desktop_data.set('DECORATE', have_libdecor ? '-decorate' : '')
desktop_file = configure_file(
input: 'desktop/org.freedesktop.Xwayland.desktop.in',
output: 'org.freedesktop.Xwayland.desktop',
configuration: desktop_data,
)
datadir = join_paths(get_option('prefix'), get_option('datadir'))
desktopdir = join_paths(datadir, 'applications')
install_data(desktop_file, install_dir : desktopdir)
meson.override_find_program('Xwayland', xwayland_server)
meson.override_dependency('xwayland', declare_dependency(
variables: [
'xwayland=' + xwayland_server.full_path(),
] + xwayland_vars,
))

View File

@ -1,440 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2011 Kristian Høgsberg
*
* 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-config.h>
#include "mi/mipointer_priv.h"
#include "scrnintstr.h"
#include "servermd.h"
#include "cursorstr.h"
#include "inputstr.h"
#include "mipointer.h"
#include "xwayland-cursor.h"
#include "xwayland-input.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-shm.h"
#include "xwayland-types.h"
#include "tablet-unstable-v2-client-protocol.h"
#define DELAYED_X_CURSOR_TIMEOUT 5 /* ms */
static void
expand_source_and_mask(CursorPtr cursor, CARD32 *data)
{
CARD32 *p, d, fg, bg;
CursorBitsPtr bits = cursor->bits;
int x, y, stride, i, bit;
p = data;
fg = ((cursor->foreRed & 0xff00) << 8) |
(cursor->foreGreen & 0xff00) |
(cursor->foreBlue >> 8);
bg = ((cursor->backRed & 0xff00) << 8) |
(cursor->backGreen & 0xff00) |
(cursor->backBlue >> 8);
stride = BitmapBytePad(bits->width);
for (y = 0; y < bits->height; y++)
for (x = 0; x < bits->width; x++) {
i = y * stride + x / 8;
bit = 1 << (x & 7);
if (bits->source[i] & bit)
d = fg;
else
d = bg;
if (bits->mask[i] & bit)
d |= 0xff000000;
else
d = 0x00000000;
*p++ = d;
}
}
static Bool
xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
{
return TRUE;
}
static Bool
xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
{
struct xwl_screen *xwl_screen;
struct xwl_seat *xwl_seat;
/* When called from FreeCursor(), device is always NULL */
xwl_screen = xwl_screen_get(screen);
xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
if (cursor == xwl_seat->x_cursor)
xwl_seat->x_cursor = NULL;
}
return TRUE;
}
static void
frame_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
struct xwl_cursor *xwl_cursor = data;
xwl_cursor_clear_frame_cb(xwl_cursor);
if (xwl_cursor->needs_update) {
xwl_cursor->needs_update = FALSE;
xwl_cursor->update_proc(xwl_cursor);
}
}
static const struct wl_callback_listener frame_listener = {
frame_callback
};
static void
xwl_cursor_buffer_release_callback(void *data)
{
/* drop the reference we took in set_cursor */
xwl_shm_destroy_pixmap(data);
}
static void
xwl_cursor_copy_bits_to_pixmap(CursorPtr cursor, PixmapPtr pixmap)
{
int stride;
stride = cursor->bits->width * 4;
if (cursor->bits->argb)
memcpy(pixmap->devPrivate.ptr,
cursor->bits->argb, cursor->bits->height * stride);
else
expand_source_and_mask(cursor, pixmap->devPrivate.ptr);
}
static void
xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
{
struct wl_buffer *buffer;
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
if (!buffer) {
ErrorF("cursor: Error getting buffer\n");
return;
}
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
wl_surface_set_buffer_scale(xwl_cursor->surface, xwl_screen->global_surface_scale);
xwl_surface_damage(xwl_screen, xwl_cursor->surface, 0, 0,
xwl_seat->x_cursor->bits->width,
xwl_seat->x_cursor->bits->height);
xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
/* The pixmap will be destroyed in xwl_cursor_buffer_release_callback()
* once the compositor is done with it.
*/
xwl_pixmap_set_buffer_release_cb(pixmap,
xwl_cursor_buffer_release_callback,
pixmap);
wl_surface_commit(xwl_cursor->surface);
}
Bool
xwl_cursor_clear_frame_cb(struct xwl_cursor *xwl_cursor)
{
if (xwl_cursor->frame_cb) {
wl_callback_destroy(xwl_cursor->frame_cb);
xwl_cursor->frame_cb = NULL;
return TRUE;
}
return FALSE;
}
void
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
{
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
PixmapPtr pixmap;
CursorPtr cursor;
int xhot, yhot;
if (!xwl_seat->wl_pointer)
return;
if (!xwl_seat->x_cursor) {
wl_pointer_set_cursor(xwl_seat->wl_pointer,
xwl_seat->pointer_enter_serial, NULL, 0, 0);
xwl_cursor_clear_frame_cb(xwl_cursor);
xwl_cursor->needs_update = FALSE;
return;
}
if (xwl_cursor->frame_cb) {
xwl_cursor->needs_update = TRUE;
return;
}
cursor = xwl_seat->x_cursor;
pixmap = xwl_shm_create_pixmap(xwl_screen->screen, cursor->bits->width,
cursor->bits->height, 32,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
if (!pixmap)
return;
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
xhot = xwl_seat->x_cursor->bits->xhot / xwl_screen->global_surface_scale;
yhot = xwl_seat->x_cursor->bits->yhot / xwl_screen->global_surface_scale;
wl_pointer_set_cursor(xwl_seat->wl_pointer,
xwl_seat->pointer_enter_serial,
xwl_cursor->surface,
xhot,
yhot);
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
}
void
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
{
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
PixmapPtr pixmap;
CursorPtr cursor;
int xhot, yhot;
if (!xwl_seat->x_cursor) {
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
xwl_tablet_tool->proximity_in_serial,
NULL, 0, 0);
xwl_cursor_clear_frame_cb(xwl_cursor);
xwl_cursor->needs_update = FALSE;
return;
}
if (xwl_cursor->frame_cb) {
xwl_cursor->needs_update = TRUE;
return;
}
cursor = xwl_seat->x_cursor;
pixmap = xwl_shm_create_pixmap(xwl_screen->screen, cursor->bits->width,
cursor->bits->height, 32,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
if (!pixmap)
return;
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
xhot = xwl_seat->x_cursor->bits->xhot / xwl_screen->global_surface_scale;
yhot = xwl_seat->x_cursor->bits->yhot / xwl_screen->global_surface_scale;
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
xwl_tablet_tool->proximity_in_serial,
xwl_cursor->surface,
xhot,
yhot);
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
}
void
xwl_cursor_release(struct xwl_cursor *xwl_cursor)
{
wl_surface_destroy(xwl_cursor->surface);
xwl_cursor_clear_frame_cb(xwl_cursor);
}
static void
xwl_seat_update_all_cursors(struct xwl_seat *xwl_seat)
{
struct xwl_tablet_tool *xwl_tablet_tool;
xwl_seat_set_cursor(xwl_seat);
xorg_list_for_each_entry(xwl_tablet_tool, &xwl_seat->tablet_tools, link) {
if (xwl_tablet_tool->proximity_in_serial != 0)
xwl_tablet_tool_set_cursor(xwl_tablet_tool);
}
/* Clear delayed cursor if any */
xwl_seat->pending_x_cursor = NULL;
}
static void
xwl_seat_update_cursor_visibility(struct xwl_seat *xwl_seat)
{
xwl_seat->x_cursor = xwl_seat->pending_x_cursor;
xwl_seat_cursor_visibility_changed(xwl_seat);
xwl_seat_update_all_cursors(xwl_seat);
}
static void
xwl_set_cursor_free_timer(struct xwl_seat *xwl_seat)
{
if (xwl_seat->x_cursor_timer) {
TimerFree(xwl_seat->x_cursor_timer);
xwl_seat->x_cursor_timer = NULL;
}
}
static CARD32
xwl_set_cursor_timer_callback(OsTimerPtr timer, CARD32 time, void *arg)
{
struct xwl_seat *xwl_seat = arg;
xwl_set_cursor_free_timer(xwl_seat);
xwl_seat_update_cursor_visibility(xwl_seat);
/* Don't re-arm the timer */
return 0;
}
static void
xwl_set_cursor_delayed(struct xwl_seat *xwl_seat, CursorPtr cursor)
{
xwl_seat->pending_x_cursor = cursor;
if (xwl_seat->x_cursor_timer == NULL) {
xwl_seat->x_cursor_timer = TimerSet(xwl_seat->x_cursor_timer,
0, DELAYED_X_CURSOR_TIMEOUT,
&xwl_set_cursor_timer_callback,
xwl_seat);
}
}
static void
xwl_set_cursor(DeviceIntPtr device,
ScreenPtr screen, CursorPtr cursor, int x, int y)
{
struct xwl_seat *xwl_seat;
Bool cursor_visibility_changed;
xwl_seat = device->public.devicePrivate;
if (xwl_seat == NULL)
return;
cursor_visibility_changed = !!xwl_seat->x_cursor ^ !!cursor;
if (!cursor_visibility_changed) {
/* Cursor remains shown or hidden, apply the change immediately */
xwl_set_cursor_free_timer(xwl_seat);
xwl_seat->x_cursor = cursor;
xwl_seat_update_all_cursors(xwl_seat);
return;
}
xwl_seat->pending_x_cursor = cursor;
if (cursor) {
/* Cursor is being shown, delay the change until moved or timed out */
xwl_set_cursor_delayed(xwl_seat, cursor);
} else {
/* Cursor is being hidden, apply the change immediately */
xwl_seat_update_cursor_visibility(xwl_seat);
}
}
static void
xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
{
struct xwl_seat *xwl_seat;
xwl_seat = device->public.devicePrivate;
if (xwl_seat == NULL)
return;
xwl_set_cursor_free_timer(xwl_seat);
if (xwl_seat->pending_x_cursor)
xwl_seat_update_cursor_visibility(xwl_seat);
}
static Bool
xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
{
return TRUE;
}
static void
xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
{
struct xwl_seat *xwl_seat;
xwl_seat = device->public.devicePrivate;
if (xwl_seat)
xwl_set_cursor_free_timer(xwl_seat);
}
static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = {
xwl_realize_cursor,
xwl_unrealize_cursor,
xwl_set_cursor,
xwl_move_cursor,
xwl_device_cursor_initialize,
xwl_device_cursor_cleanup
};
static Bool
xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y)
{
return FALSE;
}
static void
xwl_cross_screen(ScreenPtr pScreen, Bool entering)
{
}
static void
xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
miPointerWarpCursor(pDev, pScreen, x, y);
}
static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
xwl_cursor_off_screen,
xwl_cross_screen,
xwl_pointer_warp_cursor
};
Bool
xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
{
return miPointerInitialize(xwl_screen->screen,
&xwl_pointer_sprite_funcs,
&xwl_pointer_screen_funcs, TRUE);
}

View File

@ -1,40 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2011 Kristian Høgsberg
*
* 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.
*/
#ifndef XWAYLAND_CURSOR_H
#define XWAYLAND_CURSOR_H
#include <xwayland-config.h>
#include <xwayland-types.h>
#include <xwayland-input.h>
Bool xwl_cursor_clear_frame_cb(struct xwl_cursor *xwl_cursor);
void xwl_cursor_release(struct xwl_cursor *xwl_cursor);
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_CURSOR_H */

View File

@ -1,80 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
* Copyright © 2021 Red Hat, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <xwayland-config.h>
#include <string.h>
#include <randrstr.h>
#include <libxcvt/libxcvt.h>
#include "xwayland-cvt.h"
static void
xwayland_modeinfo_from_cvt(xRRModeInfo *modeinfo,
int hdisplay, int vdisplay, float vrefresh,
Bool reduced, Bool interlaced)
{
struct libxcvt_mode_info *libxcvt_mode_info;
libxcvt_mode_info =
libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
modeinfo->width = libxcvt_mode_info->hdisplay;
modeinfo->height = libxcvt_mode_info->vdisplay;
modeinfo->dotClock = libxcvt_mode_info->dot_clock * 1000.0;
modeinfo->hSyncStart = libxcvt_mode_info->hsync_start;
modeinfo->hSyncEnd = libxcvt_mode_info->hsync_end;
modeinfo->hTotal = libxcvt_mode_info->htotal;
modeinfo->vSyncStart = libxcvt_mode_info->vsync_start;
modeinfo->vSyncEnd = libxcvt_mode_info->vsync_end;
modeinfo->vTotal = libxcvt_mode_info->vtotal;
modeinfo->modeFlags = libxcvt_mode_info->mode_flags;
free(libxcvt_mode_info);
}
RRModePtr
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
Bool interlaced)
{
char name[128];
xRRModeInfo modeinfo = { 0, };
xwayland_modeinfo_from_cvt(&modeinfo,
hdisplay, vdisplay, vrefresh, reduced, interlaced);
/* Horizontal granularity in libxcvt is 8, so if our horizontal size is not
* divisible by 8, libxcvt will round it up, and we will advertise a wrong
* size to our XRandR clients.
* Force the width/height (i.e. simply increase blanking which should not
* hurt anything), keeping the rest of the CVT mode timings unchanged.
*/
modeinfo.width = hdisplay;
modeinfo.height = vdisplay;
snprintf(name, sizeof name, "%dx%d",
modeinfo.width, modeinfo.height);
modeinfo.nameLength = strlen(name);
return RRModeGet(&modeinfo, name);
}

View File

@ -1,34 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 XWAYLAND_CVT_H
#define XWAYLAND_CVT_H
#include <xwayland-config.h>
#include <dix.h>
#include <randrstr.h>
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);
#endif /* XWAYLAND_CVT_H */

View File

@ -1,797 +0,0 @@
/*
* 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-config.h>
#include <sys/mman.h>
#include <drm_fourcc.h>
#include <wayland-util.h>
#include "os/log_priv.h"
#include "xwayland-dmabuf.h"
#include "xwayland-glamor-gbm.h"
#include "xwayland-screen.h"
#include "xwayland-types.h"
#include "xwayland-window-buffers.h"
#include "drm-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
void
xwl_device_formats_destroy(struct xwl_device_formats *dev_formats)
{
for (int j = 0; j < dev_formats->num_formats; j++)
free(dev_formats->formats[j].modifiers);
free(dev_formats->formats);
drmFreeDevice(&dev_formats->drm_dev);
}
void
xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback)
{
if (xwl_feedback->dev_formats_len == 0)
return;
for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
struct xwl_device_formats *dev_format = &xwl_feedback->dev_formats[i];
xwl_device_formats_destroy(dev_format);
}
free(xwl_feedback->dev_formats);
xwl_feedback->dev_formats = NULL;
xwl_feedback->dev_formats_len = 0;
}
void
xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback)
{
munmap(xwl_feedback->format_table.entry,
xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
if (xwl_feedback->dmabuf_feedback)
zwp_linux_dmabuf_feedback_v1_destroy(xwl_feedback->dmabuf_feedback);
xwl_feedback->dmabuf_feedback = NULL;
drmFreeDevice(&xwl_feedback->main_dev);
}
static Bool
xwl_glamor_is_modifier_supported_in_formats(struct xwl_format *formats, int num_formats,
uint32_t format, uint64_t modifier)
{
struct xwl_format *xwl_format = NULL;
int i;
for (i = 0; i < num_formats; i++) {
if (formats[i].format == format) {
xwl_format = &formats[i];
break;
}
}
if (xwl_format) {
for (i = 0; i < xwl_format->num_modifiers; i++) {
if (xwl_format->modifiers[i] == modifier) {
return TRUE;
}
}
}
return FALSE;
}
static Bool
xwl_feedback_is_modifier_supported(struct xwl_dmabuf_feedback *xwl_feedback,
uint32_t format, uint64_t modifier,
int supports_scanout)
{
for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
if (supports_scanout && !dev_formats->supports_scanout)
continue;
if (xwl_glamor_is_modifier_supported_in_formats(dev_formats->formats,
dev_formats->num_formats,
format, modifier))
return TRUE;
}
return FALSE;
}
Bool
xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
uint32_t format, uint64_t modifier)
{
struct xwl_window *xwl_window;
/*
* If we are using dmabuf v4, then we need to check in the main
* device and per-window format lists. For older protocol
* versions we can just check the list returned by the dmabuf.modifier
* events in xwl_screen
*/
if (xwl_screen->dmabuf_protocol_version < 4) {
return xwl_glamor_is_modifier_supported_in_formats(xwl_screen->formats,
xwl_screen->num_formats,
format, modifier);
}
if (xwl_feedback_is_modifier_supported(&xwl_screen->default_feedback, format, modifier, FALSE))
return TRUE;
xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) {
if (xwl_feedback_is_modifier_supported(&xwl_window->feedback, format, modifier, FALSE))
return TRUE;
}
return FALSE;
}
uint32_t
wl_drm_format_for_depth(int depth)
{
switch (depth) {
case 15:
return WL_DRM_FORMAT_XRGB1555;
case 16:
return WL_DRM_FORMAT_RGB565;
case 24:
return WL_DRM_FORMAT_XRGB8888;
case 30:
return WL_DRM_FORMAT_ARGB2101010;
default:
ErrorF("unexpected depth: %d\n", depth);
case 32:
return WL_DRM_FORMAT_ARGB8888;
}
}
static Bool
xwl_dmabuf_get_formats(struct xwl_format *format_array, int format_array_len,
CARD32 *num_formats, CARD32 **formats)
{
*num_formats = 0;
*formats = NULL;
if (format_array_len == 0)
return TRUE;
*formats = calloc(format_array_len, sizeof(CARD32));
if (*formats == NULL)
return FALSE;
for (int i = 0; i < format_array_len; i++)
(*formats)[i] = format_array[i].format;
*num_formats = format_array_len;
return TRUE;
}
static Bool
xwl_dmabuf_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, drmDevice *device,
CARD32 *num_formats, CARD32 **formats)
{
CARD32 *ret = NULL;
uint32_t count = 0;
/* go through all matching sets of tranches for the window's device */
for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
if (drmDevicesEqual(xwl_feedback->dev_formats[i].drm_dev, device)) {
struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
/* Append the formats from this tranche to the list */
ret = XNFreallocarray(ret, count + dev_formats->num_formats, sizeof(CARD32));
for (int j = 0; j < dev_formats->num_formats; j++) {
Bool found = FALSE;
/* Check if this format is already present in the list */
for (int k = 0; k < count; k++) {
if (ret[k] == dev_formats->formats[j].format) {
found = TRUE;
break;
}
}
/* If this format has not yet been added, do so now */
if (!found)
ret[count++] = dev_formats->formats[j].format;
}
}
}
*num_formats = count;
*formats = ret;
return TRUE;
}
Bool
xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
/* Explicitly zero the count as the caller may ignore the return value */
*num_formats = 0;
if (!xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->dmabuf_protocol_version >= 4) {
drmDevice *main_dev = xwl_gbm_get_main_device(xwl_screen);
return xwl_dmabuf_get_formats_for_device(&xwl_screen->default_feedback, main_dev,
num_formats, formats);
}
return xwl_dmabuf_get_formats(xwl_screen->formats, xwl_screen->num_formats,
num_formats, formats);
}
static Bool
xwl_dmabuf_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
uint32_t format, uint32_t *num_modifiers,
uint64_t **modifiers)
{
struct xwl_format *xwl_format = NULL;
int i;
*num_modifiers = 0;
*modifiers = NULL;
if (num_formats == 0)
return TRUE;
for (i = 0; i < num_formats; i++) {
if (format_array[i].format == format) {
xwl_format = &format_array[i];
break;
}
}
if (!xwl_format ||
(xwl_format->num_modifiers == 1 &&
xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
return FALSE;
*modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
if (*modifiers == NULL)
return FALSE;
for (i = 0; i < xwl_format->num_modifiers; i++)
(*modifiers)[i] = xwl_format->modifiers[i];
*num_modifiers = xwl_format->num_modifiers;
return TRUE;
}
static Bool
xwl_dmabuf_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback,
drmDevice *device,
uint32_t format, uint32_t *num_modifiers,
uint64_t **modifiers,
Bool *supports_scanout)
{
/* Now try to find a matching set of tranches for the window's device */
for (int i = 0; i < feedback->dev_formats_len; i++) {
struct xwl_device_formats *dev_formats = &feedback->dev_formats[i];
if (drmDevicesEqual(dev_formats->drm_dev, device) &&
xwl_dmabuf_get_modifiers_for_format(dev_formats->formats,
dev_formats->num_formats,
format, num_modifiers, modifiers)) {
if (supports_scanout)
*supports_scanout = !!dev_formats->supports_scanout;
return TRUE;
}
}
return FALSE;
}
Bool
xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
drmDevice *main_dev;
/* Explicitly zero the count as the caller may ignore the return value */
*num_modifiers = 0;
*modifiers = NULL;
if (!xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->dmabuf_protocol_version >= 4) {
main_dev = xwl_gbm_get_main_device(xwl_screen);
return xwl_dmabuf_get_modifiers_for_device(&xwl_screen->default_feedback, main_dev,
format, num_modifiers, modifiers, NULL);
} else {
return xwl_dmabuf_get_modifiers_for_format(xwl_screen->formats, xwl_screen->num_formats,
format, num_modifiers, modifiers);
}
}
Bool
xwl_glamor_get_drawable_modifiers_and_scanout(DrawablePtr drawable,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers,
Bool *supports_scanout)
{
struct xwl_screen *xwl_screen = xwl_screen_get(drawable->pScreen);
struct xwl_window *xwl_window;
drmDevice *main_dev;
*num_modifiers = 0;
*modifiers = NULL;
if (supports_scanout)
*supports_scanout = FALSE;
/* We can only return per-drawable modifiers if the compositor supports feedback */
if (xwl_screen->dmabuf_protocol_version < 4)
return TRUE;
if (drawable->type != DRAWABLE_WINDOW || !xwl_screen->dmabuf)
return FALSE;
xwl_window = xwl_window_from_window((WindowPtr)drawable);
/* couldn't find drawable for window */
if (!xwl_window)
return FALSE;
main_dev = xwl_gbm_get_main_device(xwl_screen);
return xwl_dmabuf_get_modifiers_for_device(&xwl_window->feedback, main_dev,
format, num_modifiers, modifiers,
supports_scanout);
}
Bool
xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers)
{
return xwl_glamor_get_drawable_modifiers_and_scanout(drawable,
format, num_modifiers,
modifiers, NULL);
}
static void
xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format)
{
}
static void
xwl_add_format_and_mod_to_list(struct xwl_format **formats,
uint32_t *num_formats,
uint32_t format,
uint64_t modifier)
{
struct xwl_format *xwl_format = NULL;
int i;
for (i = 0; i < *num_formats; i++) {
if ((*formats)[i].format == format) {
xwl_format = &(*formats)[i];
break;
}
}
if (xwl_format == NULL) {
(*num_formats)++;
*formats = XNFrealloc(*formats, *num_formats * sizeof(*xwl_format));
xwl_format = &(*formats)[*num_formats - 1];
xwl_format->format = format;
xwl_format->num_modifiers = 0;
xwl_format->modifiers = NULL;
}
for (i = 0; i < xwl_format->num_modifiers; i++) {
/* don't add it if the modifier already exists */
if (xwl_format->modifiers[i] == modifier)
return;
}
xwl_format->num_modifiers++;
xwl_format->modifiers = XNFrealloc(xwl_format->modifiers,
xwl_format->num_modifiers * sizeof(uint64_t));
xwl_format->modifiers[xwl_format->num_modifiers - 1] = modifier;
}
static void
xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format, uint32_t modifier_hi,
uint32_t modifier_lo)
{
struct xwl_screen *xwl_screen = data;
xwl_add_format_and_mod_to_list(&xwl_screen->formats, &xwl_screen->num_formats,
format,
((uint64_t)modifier_hi << 32 | (uint64_t)modifier_lo));
}
static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
.format = xwl_dmabuf_handle_format,
.modifier = xwl_dmabuf_handle_modifier
};
/*
* We need to check if the compositor is resending all of the tranche
* information. Each tranche event will call this method to see
* if the existing format info should be cleared before refilling.
*/
static void
xwl_check_reset_tranche_info(struct xwl_dmabuf_feedback *xwl_feedback)
{
if (!xwl_feedback->feedback_done)
return;
xwl_feedback->feedback_done = FALSE;
xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
}
static void
xwl_dmabuf_feedback_main_device(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *dev)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
dev_t devid;
xwl_check_reset_tranche_info(xwl_feedback);
assert(dev->size == sizeof(dev_t));
memcpy(&devid, dev->data, sizeof(dev_t));
drmFreeDevice(&xwl_feedback->main_dev);
if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->main_dev) != 0)
ErrorF("linux_dmabuf_feedback.main_device: Failed to fetch DRM device\n");
}
static void
xwl_dmabuf_feedback_tranche_target_device(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *dev)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
dev_t devid;
xwl_check_reset_tranche_info(xwl_feedback);
assert(dev->size == sizeof(dev_t));
memcpy(&devid, dev->data, sizeof(dev_t));
if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->tmp_tranche.drm_dev) != 0)
ErrorF("linux_dmabuf_feedback.tranche_target_device: Failed to fetch DRM device\n");
}
static void
xwl_dmabuf_feedback_tranche_flags(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
uint32_t flags)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
xwl_check_reset_tranche_info(xwl_feedback);
if (flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT)
xwl_feedback->tmp_tranche.supports_scanout = TRUE;
}
static void
xwl_dmabuf_feedback_tranche_formats(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *indices)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
struct xwl_device_formats *tranche = &xwl_feedback->tmp_tranche;
uint16_t *index;
xwl_check_reset_tranche_info(xwl_feedback);
wl_array_for_each(index, indices) {
if (*index >= xwl_feedback->format_table.len) {
ErrorF("linux_dmabuf_feedback.tranche_formats: Index given to us by the compositor"
" is too large to fit in the format table\n");
continue;
}
/* Look up this format/mod in the format table */
struct xwl_format_table_entry *entry = &xwl_feedback->format_table.entry[*index];
/* Add it to the in-progress tranche */
xwl_add_format_and_mod_to_list(&tranche->formats, &tranche->num_formats,
entry->format,
entry->modifier);
}
}
static void
xwl_append_to_tranche(struct xwl_device_formats *dst, struct xwl_device_formats *src)
{
struct xwl_format *format;
for (int i = 0; i < src->num_formats; i++) {
format = &src->formats[i];
for (int j = 0; j < format->num_modifiers; j++)
xwl_add_format_and_mod_to_list(&dst->formats, &dst->num_formats,
format->format,
format->modifiers[j]);
}
}
static void
xwl_dmabuf_feedback_tranche_done(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
struct xwl_device_formats *tranche;
int appended = FALSE;
/*
* No need to call xwl_check_reset_tranche_info, the other events should have been
* triggered first
*/
if (xwl_feedback->tmp_tranche.drm_dev == NULL) {
xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
goto out;
}
/*
* First check if there is an existing tranche for this device+flags combo. We
* will combine it with this tranche, since we can only send one modifier list
* in DRI3 but the compositor may report multiple tranches per device (KDE
* does this)
*/
for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
tranche = &xwl_feedback->dev_formats[i];
if (tranche->supports_scanout == xwl_feedback->tmp_tranche.supports_scanout &&
drmDevicesEqual(tranche->drm_dev, xwl_feedback->tmp_tranche.drm_dev)) {
appended = TRUE;
/* Add all format/mods to this tranche */
xwl_append_to_tranche(tranche, &xwl_feedback->tmp_tranche);
/* Now free our temp tranche's allocations */
xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
break;
}
}
if (!appended) {
xwl_feedback->dev_formats_len++;
xwl_feedback->dev_formats = XNFrealloc(xwl_feedback->dev_formats,
sizeof(struct xwl_device_formats) *
xwl_feedback->dev_formats_len);
/* copy the temporary tranche into the official array */
memcpy(&xwl_feedback->dev_formats[xwl_feedback->dev_formats_len - 1],
&xwl_feedback->tmp_tranche,
sizeof(struct xwl_device_formats));
}
out:
/* reset the tranche */
memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats));
}
static void
xwl_dmabuf_feedback_done(void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
xwl_feedback->feedback_done = TRUE;
xwl_feedback->unprocessed_feedback_pending = TRUE;
}
static void
xwl_dmabuf_feedback_format_table(void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
int32_t fd, uint32_t size)
{
struct xwl_dmabuf_feedback *xwl_feedback = data;
/* Unmap the old table */
if (xwl_feedback->format_table.entry) {
munmap(xwl_feedback->format_table.entry,
xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
}
assert(size % sizeof(struct xwl_format_table_entry) == 0);
xwl_feedback->format_table.len = size / sizeof(struct xwl_format_table_entry);
xwl_feedback->format_table.entry = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (xwl_feedback->format_table.entry == MAP_FAILED) {
ErrorF("linux_dmabuf_feedback.format_table: Could not map the format"
" table: Compositor bug or out of resources\n");
xwl_feedback->format_table.len = 0;
}
}
static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_dmabuf_feedback_listener = {
.done = xwl_dmabuf_feedback_done,
.format_table = xwl_dmabuf_feedback_format_table,
.main_device = xwl_dmabuf_feedback_main_device,
.tranche_done = xwl_dmabuf_feedback_tranche_done,
.tranche_target_device = xwl_dmabuf_feedback_tranche_target_device,
.tranche_formats = xwl_dmabuf_feedback_tranche_formats,
.tranche_flags = xwl_dmabuf_feedback_tranche_flags,
};
Bool
xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
{
/* We either support versions 3 or 4. 4 is needed for dmabuf feedback */
int supported_version = version >= 4 ? 4 : 3;
if (version < 3)
return FALSE;
xwl_screen->dmabuf =
wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, supported_version);
xwl_screen->dmabuf_protocol_version = supported_version;
zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
/* If the compositor supports it, request the default feedback hints */
if (version >= 4) {
xwl_screen->default_feedback.dmabuf_feedback =
zwp_linux_dmabuf_v1_get_default_feedback(xwl_screen->dmabuf);
if (!xwl_screen->default_feedback.dmabuf_feedback)
return FALSE;
zwp_linux_dmabuf_feedback_v1_add_listener(xwl_screen->default_feedback.dmabuf_feedback,
&xwl_dmabuf_feedback_listener,
&xwl_screen->default_feedback);
}
return TRUE;
}
static void
xwl_window_dmabuf_feedback_main_device(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *dev)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_main_device(&xwl_window->feedback, dmabuf_feedback, dev);
}
static void
xwl_window_dmabuf_feedback_tranche_target_device(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *dev)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_tranche_target_device(&xwl_window->feedback, dmabuf_feedback, dev);
}
static void
xwl_window_dmabuf_feedback_tranche_flags(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
uint32_t flags)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_tranche_flags(&xwl_window->feedback, dmabuf_feedback, flags);
}
static void
xwl_window_dmabuf_feedback_tranche_formats(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
struct wl_array *indices)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_tranche_formats(&xwl_window->feedback, dmabuf_feedback, indices);
}
static void
xwl_window_dmabuf_feedback_tranche_done(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_tranche_done(&xwl_window->feedback, dmabuf_feedback);
}
static void
xwl_window_dmabuf_feedback_done(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
{
struct xwl_window *xwl_window = data;
uint32_t format = wl_drm_format_for_depth(xwl_window->surface_window->drawable.depth);
xwl_dmabuf_feedback_done(&xwl_window->feedback, dmabuf_feedback);
xwl_window->has_implicit_scanout_support =
xwl_feedback_is_modifier_supported(&xwl_window->feedback, format,
DRM_FORMAT_MOD_INVALID, TRUE);
DebugF("XWAYLAND: Window 0x%x can%s get implicit scanout support\n",
xwl_window->surface_window->drawable.id,
xwl_window->has_implicit_scanout_support ? "" : "not");
/* If the linux-dmabuf v4 per-surface feedback changed, make sure the
* window buffers get re-created with appropriate parameters.
*/
xwl_window_buffers_dispose(xwl_window, FALSE);
xwl_window_realloc_pixmap(xwl_window);
}
static void
xwl_window_dmabuf_feedback_format_table(void *data,
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
int32_t fd, uint32_t size)
{
struct xwl_window *xwl_window = data;
xwl_dmabuf_feedback_format_table(&xwl_window->feedback, dmabuf_feedback, fd, size);
}
static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_window_dmabuf_feedback_listener = {
.done = xwl_window_dmabuf_feedback_done,
.format_table = xwl_window_dmabuf_feedback_format_table,
.main_device = xwl_window_dmabuf_feedback_main_device,
.tranche_done = xwl_window_dmabuf_feedback_tranche_done,
.tranche_target_device = xwl_window_dmabuf_feedback_tranche_target_device,
.tranche_formats = xwl_window_dmabuf_feedback_tranche_formats,
.tranche_flags = xwl_window_dmabuf_feedback_tranche_flags,
};
Bool
xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
xwl_window->feedback.dmabuf_feedback =
zwp_linux_dmabuf_v1_get_surface_feedback(xwl_screen->dmabuf, xwl_window->surface);
if (!xwl_window->feedback.dmabuf_feedback)
return FALSE;
zwp_linux_dmabuf_feedback_v1_add_listener(xwl_window->feedback.dmabuf_feedback,
&xwl_window_dmabuf_feedback_listener,
xwl_window);
return TRUE;
}

View File

@ -1,115 +0,0 @@
/*
* 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.
*/
#ifndef XWAYLAND_DMABUF_H
#define XWAYLAND_DMABUF_H
#include <xwayland-config.h>
#include <X11/X.h>
#include <dix.h>
#include <xf86drm.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
#include "xwayland-types.h"
struct xwl_format {
uint32_t format;
int num_modifiers;
uint64_t *modifiers;
};
struct xwl_format_table_entry {
uint32_t format;
uint32_t pad;
uint64_t modifier;
};
struct xwl_device_formats {
drmDevice *drm_dev;
uint32_t num_formats;
struct xwl_format *formats;
Bool supports_scanout;
};
struct xwl_format_table {
/* This is mmapped from the fd given to us by the compositor */
int len;
struct xwl_format_table_entry *entry;
};
/*
* Helper struct for sharing dmabuf feedback logic between
* a screen and a window. The screen will get the default
* feedback, and a window will get a per-surface feedback.
*/
struct xwl_dmabuf_feedback {
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
struct xwl_format_table format_table;
drmDevice *main_dev;
/*
* This will be filled in during wl events and copied to
* dev_formats on dmabuf_feedback.tranche_done
*/
struct xwl_device_formats tmp_tranche;
int feedback_done;
int dev_formats_len;
struct xwl_device_formats *dev_formats;
/*
* This flag is used to identify if the feedback
* has been resent. If this is true, then the xwayland
* clients need to be sent PresentCompleteModeSuboptimalCopy
* to tell them to re-request modifiers.
*/
int unprocessed_feedback_pending;
};
void xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback);
void xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback);
void xwl_device_formats_destroy(struct xwl_device_formats *dev_formats);
Bool xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window);
Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
uint32_t format, uint64_t modifier);
uint32_t wl_drm_format_for_depth(int depth);
Bool xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats);
Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers);
Bool xwl_glamor_get_drawable_modifiers_and_scanout(DrawablePtr drawable,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers,
Bool *supports_scanout);
Bool xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers);
#endif /* XWAYLAND_DMABUF_H */

View File

@ -1,487 +0,0 @@
/*
* Copyright © 2020 Drew Devault
* Copyright © 2021 Xaver Hugl
*
* 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-config.h>
#include "os/client_priv.h"
#include "randr/randrstr_priv.h"
#ifdef WITH_LIBDRM
#include <xf86drm.h>
#include <xf86drmMode.h>
#endif
#include "xwayland-drm-lease.h"
#include "xwayland-screen.h"
#include "xwayland-output.h"
static void
xwl_randr_lease_cleanup_outputs(RRLeasePtr rrLease)
{
struct xwl_output *output;
int i;
for (i = 0; i < rrLease->numOutputs; ++i) {
output = rrLease->outputs[i]->devPrivate;
if (output) {
output->lease = NULL;
}
}
}
static void
xwl_randr_lease_free_outputs(RRLeasePtr rrLease)
{
struct xwl_output *xwl_output;
int i;
for (i = 0; i < rrLease->numOutputs; ++i) {
xwl_output = rrLease->outputs[i]->devPrivate;
if (xwl_output && xwl_output->withdrawn_connector) {
rrLease->outputs[i]->devPrivate = NULL;
xwl_output_remove(xwl_output);
}
}
}
static void
drm_lease_handle_lease_fd(void *data,
struct wp_drm_lease_v1 *wp_drm_lease_v1,
int32_t lease_fd)
{
struct xwl_drm_lease *lease = (struct xwl_drm_lease *)data;
lease->fd = lease_fd;
AttendClient(lease->client);
}
static void
drm_lease_handle_finished(void *data,
struct wp_drm_lease_v1 *wp_drm_lease_v1)
{
struct xwl_drm_lease *lease = (struct xwl_drm_lease *)data;
if (lease->fd >= 0) {
RRTerminateLease(lease->rrLease);
} else {
AttendClient(lease->client);
xwl_randr_lease_cleanup_outputs(lease->rrLease);
}
/* Free the xwl_outputs that have been withdrawn while lease-able */
xwl_randr_lease_free_outputs(lease->rrLease);
}
static struct wp_drm_lease_v1_listener drm_lease_listener = {
.lease_fd = drm_lease_handle_lease_fd,
.finished = drm_lease_handle_finished,
};
void
xwl_randr_get_lease(ClientPtr client, ScreenPtr screen, RRLeasePtr *rrLease, int *fd)
{
struct xwl_screen *xwl_screen;
struct xwl_drm_lease *lease;
xwl_screen = xwl_screen_get(screen);
xorg_list_for_each_entry(lease, &xwl_screen->drm_leases, link) {
if (lease->client == client) {
*rrLease = lease->rrLease;
*fd = lease->fd;
if (lease->fd < 0)
xorg_list_del(&lease->link);
return;
}
}
*rrLease = NULL;
*fd = -1;
}
int
xwl_randr_request_lease(ClientPtr client, ScreenPtr screen, RRLeasePtr rrLease)
{
struct xwl_screen *xwl_screen;
struct wp_drm_lease_request_v1 *req;
struct xwl_drm_lease *lease_private;
struct xwl_drm_lease_device *lease_device = NULL;
struct xwl_drm_lease_device *device_data;
struct xwl_output *output;
int i;
xwl_screen = xwl_screen_get(screen);
if (xorg_list_is_empty(&xwl_screen->drm_lease_devices)) {
ErrorF("Attempted to create DRM lease without wp_drm_lease_device_v1\n");
return BadMatch;
}
for (i = 0; i < rrLease->numOutputs; ++i) {
output = rrLease->outputs[i]->devPrivate;
if (!output || !output->lease_connector || output->lease) {
return BadValue;
}
}
xorg_list_for_each_entry(device_data, &xwl_screen->drm_lease_devices, link) {
Bool connectors_of_device = FALSE;
for (i = 0; i < rrLease->numOutputs; ++i) {
output = rrLease->outputs[i]->devPrivate;
if (output->lease_device == device_data) {
connectors_of_device = TRUE;
break;
}
}
if (connectors_of_device) {
if (lease_device != NULL) {
ErrorF("Attempted to create DRM lease from multiple devices\n");
return BadValue;
}
lease_device = device_data;
}
}
req = wp_drm_lease_device_v1_create_lease_request(
lease_device->drm_lease_device);
if (!(lease_private = calloc(1, sizeof(struct xwl_drm_lease))))
return BadAlloc;
for (i = 0; i < rrLease->numOutputs; ++i) {
output = rrLease->outputs[i]->devPrivate;
output->lease = lease_private;
wp_drm_lease_request_v1_request_connector(req, output->lease_connector);
}
lease_private->fd = -1;
lease_private->lease = wp_drm_lease_request_v1_submit(req);
lease_private->rrLease = rrLease;
lease_private->client = client;
rrLease->devPrivate = lease_private;
wp_drm_lease_v1_add_listener(lease_private->lease,
&drm_lease_listener, lease_private);
xorg_list_add(&lease_private->link, &xwl_screen->drm_leases);
ResetCurrentRequest(client);
client->sequence--;
IgnoreClient(client);
return Success;
}
void
xwl_randr_terminate_lease(ScreenPtr screen, RRLeasePtr lease)
{
struct xwl_drm_lease *lease_private = lease->devPrivate;
if (lease_private) {
xwl_randr_lease_cleanup_outputs(lease);
xorg_list_del(&lease_private->link);
if (lease_private->fd >= 0)
close(lease_private->fd);
wp_drm_lease_v1_destroy(lease_private->lease);
free(lease_private);
lease->devPrivate = NULL;
}
RRLeaseTerminated(lease);
}
static void
lease_connector_handle_name(void *data,
struct wp_drm_lease_connector_v1 *wp_drm_lease_connector_v1,
const char *name)
{
struct xwl_output *xwl_output = data;
char rr_output_name[MAX_OUTPUT_NAME] = { 0 };
snprintf(rr_output_name, MAX_OUTPUT_NAME, "lease-%s", name);
xwl_output_set_name(xwl_output, rr_output_name);
}
static void
lease_connector_handle_description(void *data,
struct wp_drm_lease_connector_v1 *wp_drm_lease_connector_v1,
const char *description)
{
/* This space is deliberately left blank */
}
static RRModePtr *
xwl_get_rrmodes_from_connector_id(int drm, int32_t connector_id, int *nmode, int *npref)
{
#ifdef WITH_LIBDRM
drmModeConnectorPtr conn;
drmModeModeInfoPtr kmode;
RRModePtr *rrmodes;
int pref, i;
*nmode = *npref = 0;
conn = drmModeGetConnectorCurrent(drm, connector_id);
if (!conn) {
ErrorF("drmModeGetConnector for connector %d failed\n", connector_id);
return NULL;
}
rrmodes = calloc(conn->count_modes, sizeof(RRModePtr));
if (!rrmodes) {
ErrorF("Failed to allocate connector modes\n");
drmModeFreeConnector(conn);
return NULL;
}
/* This spaghetti brought to you courtesey of xf86RandrR12.c
* It adds preferred modes first, then non-preferred modes */
for (pref = 1; pref >= 0; pref--) {
for (i = 0; i < conn->count_modes; ++i) {
kmode = &conn->modes[i];
if ((pref != 0) == ((kmode->type & DRM_MODE_TYPE_PREFERRED) != 0)) {
xRRModeInfo modeInfo;
RRModePtr rrmode;
modeInfo.nameLength = strlen(kmode->name);
modeInfo.width = kmode->hdisplay;
modeInfo.dotClock = kmode->clock * 1000;
modeInfo.hSyncStart = kmode->hsync_start;
modeInfo.hSyncEnd = kmode->hsync_end;
modeInfo.hTotal = kmode->htotal;
modeInfo.hSkew = kmode->hskew;
modeInfo.height = kmode->vdisplay;
modeInfo.vSyncStart = kmode->vsync_start;
modeInfo.vSyncEnd = kmode->vsync_end;
modeInfo.vTotal = kmode->vtotal;
modeInfo.modeFlags = kmode->flags;
rrmode = RRModeGet(&modeInfo, kmode->name);
if (rrmode) {
rrmodes[*nmode] = rrmode;
*nmode = *nmode + 1;
*npref = *npref + pref;
}
}
}
}
/* workaround: there could be no preferred mode that got added */
if (*nmode > 0 && *npref == 0)
*npref = 1;
drmModeFreeConnector(conn);
return rrmodes;
#else
*nmode = *npref = 0;
return NULL;
#endif
}
static void
lease_connector_handle_connector_id(void *data,
struct wp_drm_lease_connector_v1 *wp_drm_lease_connector_v1,
uint32_t connector_id)
{
struct xwl_output *output;
Atom name;
INT32 value;
int err;
int nmode, npref;
RRModePtr *rrmodes;
value = connector_id;
output = (struct xwl_output *)data;
name = MakeAtom("CONNECTOR_ID", 12, TRUE);
if (name != BAD_RESOURCE) {
err = RRConfigureOutputProperty(output->randr_output, name,
FALSE, FALSE, TRUE,
1, &value);
if (err != 0) {
ErrorF("RRConfigureOutputProperty error, %d\n", err);
return;
}
err = RRChangeOutputProperty(output->randr_output, name,
XA_INTEGER, 32, PropModeReplace, 1,
&value, FALSE, FALSE);
if (err != 0) {
ErrorF("RRChangeOutputProperty error, %d\n", err);
return;
}
}
rrmodes = xwl_get_rrmodes_from_connector_id(output->lease_device->drm_read_only_fd,
connector_id, &nmode, &npref);
if (rrmodes != NULL)
RROutputSetModes(output->randr_output, rrmodes, nmode, npref);
free(rrmodes);
}
static void
lease_connector_handle_done(void *data,
struct wp_drm_lease_connector_v1 *wp_drm_lease_connector_v1)
{
/* This space is deliberately left blank */
}
static void
lease_connector_handle_withdrawn(void *data,
struct wp_drm_lease_connector_v1 *wp_drm_lease_connector_v1)
{
struct xwl_output *xwl_output = data;
xwl_output->withdrawn_connector = TRUE;
/* Not removing the xwl_output if currently leased with Wayland */
if (xwl_output->lease)
return;
xwl_output_remove(xwl_output);
}
static const struct wp_drm_lease_connector_v1_listener lease_connector_listener = {
.name = lease_connector_handle_name,
.description = lease_connector_handle_description,
.connector_id = lease_connector_handle_connector_id,
.withdrawn = lease_connector_handle_withdrawn,
.done = lease_connector_handle_done,
};
static void
drm_lease_device_handle_drm_fd(void *data,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1,
int fd)
{
((struct xwl_drm_lease_device *)data)->drm_read_only_fd = fd;
}
static void
drm_lease_device_handle_connector(void *data,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1,
struct wp_drm_lease_connector_v1 *connector)
{
struct xwl_drm_lease_device *lease_device = data;
struct xwl_screen *xwl_screen = lease_device->xwl_screen;
struct xwl_output *xwl_output;
char name[MAX_OUTPUT_NAME] = { 0 };
xwl_output = calloc(1, sizeof *xwl_output);
if (xwl_output == NULL) {
ErrorF("%s ENOMEM\n", __func__);
return;
}
xwl_output->lease_device = lease_device;
xwl_output->xwl_screen = xwl_screen;
xwl_output->lease_connector = connector;
xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
if (!xwl_output->randr_crtc) {
ErrorF("Failed creating RandR CRTC\n");
goto err;
}
RRCrtcSetRotations(xwl_output->randr_crtc, ALL_ROTATIONS);
xwl_output->randr_output = RROutputCreate(xwl_screen->screen,
name, MAX_OUTPUT_NAME, xwl_output);
snprintf(name, MAX_OUTPUT_NAME, "XWAYLAND%d",
xwl_screen_get_next_output_serial(xwl_screen));
xwl_output_set_name(xwl_output, name);
if (!xwl_output->randr_output) {
ErrorF("Failed creating RandR Output\n");
goto err;
}
RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
RROutputSetConnection(xwl_output->randr_output, RR_Connected);
RROutputSetNonDesktop(xwl_output->randr_output, TRUE);
xwl_output->randr_output->devPrivate = xwl_output;
wp_drm_lease_connector_v1_add_listener(connector,
&lease_connector_listener,
xwl_output);
xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
return;
err:
if (xwl_output->randr_crtc)
RRCrtcDestroy(xwl_output->randr_crtc);
free(xwl_output);
}
static void
drm_lease_device_handle_released(void *data,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1)
{
struct xwl_drm_lease_device *lease_device = data;
xwl_screen_destroy_drm_lease_device(lease_device->xwl_screen, wp_drm_lease_device_v1);
}
static void
drm_lease_device_handle_done(void *data,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1)
{
/* This space is deliberately left blank */
}
static const struct wp_drm_lease_device_v1_listener drm_lease_device_listener = {
.drm_fd = drm_lease_device_handle_drm_fd,
.connector = drm_lease_device_handle_connector,
.released = drm_lease_device_handle_released,
.done = drm_lease_device_handle_done,
};
void
xwl_screen_add_drm_lease_device(struct xwl_screen *xwl_screen, uint32_t id)
{
struct wp_drm_lease_device_v1 *lease_device = wl_registry_bind(
xwl_screen->registry, id, &wp_drm_lease_device_v1_interface, 1);
struct xwl_drm_lease_device *device_data = XNFcallocarray(1, sizeof(struct xwl_drm_lease_device));
device_data->drm_lease_device = lease_device;
device_data->xwl_screen = xwl_screen;
device_data->drm_read_only_fd = -1;
device_data->id = id;
xorg_list_add(&device_data->link, &xwl_screen->drm_lease_devices);
wp_drm_lease_device_v1_add_listener(lease_device,
&drm_lease_device_listener,
device_data);
}
void
xwl_screen_destroy_drm_lease_device(struct xwl_screen *xwl_screen,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1)
{
struct xwl_drm_lease_device *device_data;
xorg_list_for_each_entry(device_data, &xwl_screen->drm_lease_devices, link) {
if (device_data->drm_lease_device == wp_drm_lease_device_v1) {
wp_drm_lease_device_v1_destroy(wp_drm_lease_device_v1);
xorg_list_del(&device_data->link);
if (device_data->drm_read_only_fd >= 0)
close(device_data->drm_read_only_fd);
free(device_data);
return;
}
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright © 2020 Drew Devault
* Copyright © 2021 Xaver Hugl
*
* 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.
*/
#ifndef XWAYLAND_DRM_LEASE_H
#define XWAYLAND_DRM_LEASE_H
#include <X11/Xatom.h>
#include <randrstr.h>
#include "xwayland-types.h"
#include "list.h"
#include "drm-lease-v1-client-protocol.h"
struct xwl_drm_lease_device {
struct xorg_list link;
struct wp_drm_lease_device_v1 *drm_lease_device;
int drm_read_only_fd;
struct xwl_screen *xwl_screen;
uint32_t id;
};
struct xwl_queued_drm_lease_device {
struct xorg_list link;
uint32_t id;
};
struct xwl_drm_lease {
struct xorg_list link;
struct wp_drm_lease_v1 *lease;
RRLeasePtr rrLease;
ClientPtr client;
int fd;
};
int xwl_randr_request_lease(ClientPtr client, ScreenPtr screen, RRLeasePtr rrLease);
void xwl_randr_get_lease(ClientPtr client, ScreenPtr screen, RRLeasePtr *rrLease, int *fd);
void xwl_randr_terminate_lease(ScreenPtr screen, RRLeasePtr lease);
void xwl_screen_add_drm_lease_device(struct xwl_screen *xwl_screen, uint32_t id);
void xwl_screen_destroy_drm_lease_device(struct xwl_screen *xwl_screen,
struct wp_drm_lease_device_v1 *wp_drm_lease_device_v1);
#endif /* XWAYLAND_DRM_LEASE_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
* Copyright © 2024 Red Hat Inc.
*
* 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 (including
* the next paragraph) 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 XWAYLAND_GLAMOR_GBM_H
#define XWAYLAND_GLAMOR_GBM_H
#include <xwayland-config.h>
#include <sys/types.h>
#include <xf86drm.h>
#include "xwayland-types.h"
Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
Bool xwl_glamor_has_wl_drm(struct xwl_screen *xwl_screen);
Bool xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen);
Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen);
drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen);
/* Explicit buffer synchronization points */
Bool xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap);
void xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap);
void xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap);
void xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
PixmapPtr pixmap,
struct xwl_window_buffer *xwl_window_buffer);
#endif /* XWAYLAND_GLAMOR_GBM_H */

View File

@ -1,416 +0,0 @@
/*
* Copyright (c) 1998-2003 by The XFree86 Project, Inc.
* Copyright © 2013 Red Hat
* Copyright © 2014 Intel Corporation
* Copyright © 2016 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 (including the next
* paragraph) 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.
*
* Authors:
* Olivier Fourdan <ofourdan@redhat.com>
*
* Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv
* implementations
*/
#include <xwayland-config.h>
#include <X11/extensions/Xv.h>
#include "dix/screen_hooks_priv.h"
#include "Xext/xvdix_priv.h"
#include "glamor_priv.h"
#include "xwayland-glamor.h"
#define NUM_FORMATS 3
#define NUM_PORTS 16
#define ADAPTOR_NAME "glamor textured video"
#define ENCODER_NAME "XV_IMAGE"
static DevPrivateKeyRec xwlXvScreenPrivateKeyRec;
#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec)
typedef struct {
XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */
glamor_port_private *port_privates;
} xwlXvScreenRec, *xwlXvScreenPtr;
typedef struct {
char depth;
short class;
} xwlVideoFormatRec, *xwlVideoFormatPtr;
static xwlVideoFormatRec Formats[NUM_FORMATS] = {
{15, TrueColor},
{16, TrueColor},
{24, TrueColor}
};
static int
xwl_glamor_xv_stop_video(XvPortPtr pPort,
DrawablePtr pDraw)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
if (pDraw->type != DRAWABLE_WINDOW)
return BadAlloc;
glamor_xv_stop_video(gpp);
return Success;
}
static int
xwl_glamor_xv_set_port_attribute(XvPortPtr pPort,
Atom attribute,
INT32 value)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
return glamor_xv_set_port_attribute(gpp, attribute, value);
}
static int
xwl_glamor_xv_get_port_attribute(XvPortPtr pPort,
Atom attribute,
INT32 *pValue)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
return glamor_xv_get_port_attribute(gpp, attribute, pValue);
}
static int
xwl_glamor_xv_query_best_size(XvPortPtr pPort,
CARD8 motion,
CARD16 vid_w,
CARD16 vid_h,
CARD16 drw_w,
CARD16 drw_h,
unsigned int *p_w,
unsigned int *p_h)
{
*p_w = drw_w;
*p_h = drw_h;
return Success;
}
static int
xwl_glamor_xv_query_image_attributes(XvPortPtr pPort,
XvImagePtr format,
CARD16 *width,
CARD16 *height,
int *pitches,
int *offsets)
{
return glamor_xv_query_image_attributes(format->id,
width,
height,
pitches,
offsets);
}
static int
xwl_glamor_xv_put_image(DrawablePtr pDrawable,
XvPortPtr pPort,
GCPtr pGC,
INT16 src_x,
INT16 src_y,
CARD16 src_w,
CARD16 src_h,
INT16 drw_x,
INT16 drw_y,
CARD16 drw_w,
CARD16 drw_h,
XvImagePtr format,
unsigned char *data,
Bool sync,
CARD16 width,
CARD16 height)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
RegionRec WinRegion;
RegionRec ClipRegion;
BoxRec WinBox;
int ret = Success;
if (pDrawable->type != DRAWABLE_WINDOW)
return BadWindow;
WinBox.x1 = pDrawable->x + drw_x;
WinBox.y1 = pDrawable->y + drw_y;
WinBox.x2 = WinBox.x1 + drw_w;
WinBox.y2 = WinBox.y1 + drw_h;
RegionInit(&WinRegion, &WinBox, 1);
RegionInit(&ClipRegion, NullBox, 1);
RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
if (RegionNotEmpty(&ClipRegion))
ret = glamor_xv_put_image(gpp,
pDrawable,
src_x,
src_y,
pDrawable->x + drw_x,
pDrawable->y + drw_y,
src_w,
src_h,
drw_w,
drw_h,
format->id,
data,
width,
height,
sync,
&ClipRegion);
RegionUninit(&WinRegion);
RegionUninit(&ClipRegion);
return ret;
}
static Bool
xwl_glamor_xv_add_formats(XvAdaptorPtr pa)
{
ScreenPtr pScreen;
XvFormatPtr pFormat, pf;
VisualPtr pVisual;
int numFormat;
int totFormat;
int numVisuals;
int i;
totFormat = NUM_FORMATS;
pFormat = XNFcallocarray(totFormat, sizeof(XvFormatRec));
pScreen = pa->pScreen;
for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) {
numVisuals = pScreen->numVisuals;
pVisual = pScreen->visuals;
while (numVisuals--) {
if ((pVisual->class == Formats[i].class) &&
(pVisual->nplanes == Formats[i].depth)) {
if (numFormat >= totFormat) {
void *moreSpace;
totFormat *= 2;
moreSpace = XNFreallocarray(pFormat, totFormat,
sizeof(XvFormatRec));
pFormat = moreSpace;
pf = pFormat + numFormat;
}
pf->visual = pVisual->vid;
pf->depth = Formats[i].depth;
pf++;
numFormat++;
}
pVisual++;
}
}
pa->nFormats = numFormat;
pa->pFormats = pFormat;
return numFormat != 0;
}
static Bool
xwl_glamor_xv_add_ports(XvAdaptorPtr pa)
{
XvPortPtr pPorts, pp;
xwlXvScreenPtr xwlXvScreen;
unsigned long PortResource = 0;
int nPorts;
int i;
pPorts = XNFcallocarray(NUM_PORTS, sizeof(XvPortRec));
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->port_privates = XNFcallocarray(NUM_PORTS,
sizeof(glamor_port_private));
PortResource = XvGetRTPort();
for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) {
if (!(pp->id = dixAllocServerXID()))
continue;
pp->pAdaptor = pa;
glamor_xv_init_port(&xwlXvScreen->port_privates[i]);
pp->devPriv.ptr = &xwlXvScreen->port_privates[i];
if (AddResource(pp->id, PortResource, pp)) {
pp++;
nPorts++;
}
}
pa->base_id = pPorts->id;
pa->nPorts = nPorts;
pa->pPorts = pPorts;
return nPorts != 0;
}
static void
xwl_glamor_xv_add_attributes(XvAdaptorPtr pa)
{
int i;
pa->pAttributes = XNFcallocarray(glamor_xv_num_attributes, sizeof(XvAttributeRec));
memcpy(pa->pAttributes, glamor_xv_attributes,
glamor_xv_num_attributes * sizeof(XvAttributeRec));
for (i = 0; i < glamor_xv_num_attributes; i++)
pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name);
pa->nAttributes = glamor_xv_num_attributes;
}
static void
xwl_glamor_xv_add_images(XvAdaptorPtr pa)
{
pa->pImages = XNFcallocarray(glamor_xv_num_images, sizeof(XvImageRec));
memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * sizeof(XvImageRec));
pa->nImages = glamor_xv_num_images;
}
static void
xwl_glamor_xv_add_encodings(XvAdaptorPtr pa)
{
XvEncodingPtr pe;
GLint texsize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize);
pe = XNFcallocarray(1, sizeof(XvEncodingRec));
pe->id = 0;
pe->pScreen = pa->pScreen;
pe->name = strdup(ENCODER_NAME);
pe->width = texsize;
pe->height = texsize;
pe->rate.numerator = 1;
pe->rate.denominator = 1;
pa->pEncodings = pe;
pa->nEncodings = 1;
}
static Bool
xwl_glamor_xv_add_adaptors(ScreenPtr pScreen)
{
DevPrivateKey XvScreenKey;
XvScreenPtr XvScreen;
xwlXvScreenPtr xwlXvScreen;
XvAdaptorPtr pa;
if (XvScreenInit(pScreen) != Success)
return FALSE;
XvScreenKey = XvGetScreenKey();
XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey);
XvScreen->nAdaptors = 0;
XvScreen->pAdaptors = NULL;
pa = XNFcallocarray(1, sizeof(XvAdaptorRec));
pa->pScreen = pScreen;
pa->type = (unsigned char) (XvInputMask | XvImageMask);
pa->ddStopVideo = xwl_glamor_xv_stop_video;
pa->ddPutImage = xwl_glamor_xv_put_image;
pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute;
pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute;
pa->ddQueryBestSize = xwl_glamor_xv_query_best_size;
pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes;
pa->name = strdup(ADAPTOR_NAME);
xwl_glamor_xv_add_encodings(pa);
xwl_glamor_xv_add_images(pa);
xwl_glamor_xv_add_attributes(pa);
if (!xwl_glamor_xv_add_formats(pa))
goto failed;
if (!xwl_glamor_xv_add_ports(pa))
goto failed;
/* We're good now with out Xv adaptor */
XvScreen->nAdaptors = 1;
XvScreen->pAdaptors = pa;
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->glxv_adaptor = pa;
return TRUE;
failed:
XvFreeAdaptor(pa);
free(pa);
return FALSE;
}
static void xwl_glamor_xv_close_screen(CallbackListPtr *pcbl,
ScreenPtr pScreen, void *unused)
{
dixScreenUnhookClose(pScreen, xwl_glamor_xv_close_screen);
xwlXvScreenPtr xwlXvScreen;
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
xwlXvScreenPrivateKey);
if (!xwlXvScreen)
return;
if (xwlXvScreen->glxv_adaptor) {
XvFreeAdaptor(xwlXvScreen->glxv_adaptor);
free(xwlXvScreen->glxv_adaptor);
}
free(xwlXvScreen->port_privates);
dixSetPrivate(&(pScreen)->devPrivates, xwlXvScreenPrivateKey, NULL);
}
Bool
xwl_glamor_xv_init(ScreenPtr pScreen)
{
xwlXvScreenPtr xwlXvScreen;
if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN,
sizeof(xwlXvScreenRec)))
return FALSE;
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->port_privates = NULL;
xwlXvScreen->glxv_adaptor = NULL;
dixScreenHookClose(pScreen, xwl_glamor_xv_close_screen);
glamor_xv_core_init(pScreen);
return xwl_glamor_xv_add_adaptors(pScreen);
}

View File

@ -1,267 +0,0 @@
/*
* 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-config.h>
#include "glamor/glamor_priv.h"
#define MESA_EGL_NO_X11_HEADERS
#define EGL_NO_X11
#include <glamor_egl.h>
#include <glamor.h>
#include <glamor_context.h>
#include <glamor_glx_provider.h>
#ifdef GLXEXT
#include "glx_extinit.h"
#endif
#include "drm-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "linux-drm-syncobj-v1-client-protocol.h"
#include "mi/mi_priv.h"
#include "xwayland-dmabuf.h"
#include "xwayland-glamor.h"
#include "xwayland-glamor-gbm.h"
#include "xwayland-present.h"
#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xwayland-window-buffers.h"
#include <sys/mman.h>
static void
glamor_egl_make_current(struct glamor_context *glamor_ctx)
{
eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglMakeCurrent(glamor_ctx->display,
EGL_NO_SURFACE, EGL_NO_SURFACE,
glamor_ctx->ctx))
FatalError("Failed to make EGL context current\n");
}
void
xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
{
EGLContext ctx = xwl_screen->glamor_ctx->ctx;
if (lastGLContext == ctx)
return;
lastGLContext = ctx;
xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
}
void
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
glamor_set_glvnd_vendor(screen, xwl_screen->glvnd_vendor);
glamor_enable_dri3(screen);
glamor_ctx->ctx = xwl_screen->egl_context;
glamor_ctx->display = xwl_screen->egl_display;
glamor_ctx->make_current = glamor_egl_make_current;
xwl_screen->glamor_ctx = glamor_ctx;
}
Bool
xwl_glamor_check_flip(WindowPtr present_window, PixmapPtr pixmap)
{
ScreenPtr screen = pixmap->drawable.pScreen;
PixmapPtr backing_pixmap = screen->GetWindowPixmap(present_window);
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
WindowPtr surface_window = xwl_window->surface_window;
if (pixmap->drawable.depth != backing_pixmap->drawable.depth) {
if (pixmap->drawable.depth == 32)
return FALSE;
return xwl_present_maybe_redirect_window(present_window);
}
if (surface_window->redirectDraw == RedirectDrawAutomatic &&
surface_window->drawable.depth != 32 &&
surface_window->parent->drawable.depth == 32)
xwl_present_maybe_redirect_window(surface_window);
return TRUE;
}
void
xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry,
uint32_t id, const char *interface,
uint32_t version)
{
if (strcmp(interface, wl_drm_interface.name) == 0)
xwl_screen_set_drm_interface(xwl_screen, id, version);
else if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0)
xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
else if (strcmp(interface, wp_linux_drm_syncobj_manager_v1_interface.name) == 0)
xwl_screen_set_syncobj_interface(xwl_screen, id, version);
}
static Bool
xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen)
{
if (!xwl_glamor_has_wl_drm(xwl_screen) &&
xwl_screen->dmabuf_protocol_version < 4) {
LogMessageVerb(X_INFO, 3, "glamor: 'wl_drm' not supported and linux-dmabuf v4 not supported\n");
return FALSE;
}
return TRUE;
}
static Bool
xwl_glamor_create_screen_resources(ScreenPtr screen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
if (!miCreateScreenResources(screen))
return FALSE;
if (xwl_screen->rootless) {
screen->devPrivate =
fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
}
else {
screen->devPrivate = screen->CreatePixmap(
screen, screen->width, screen->height, screen->rootDepth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
}
SetRootClip(screen, xwl_screen->root_clip_mode);
return screen->devPrivate != NULL;
}
int
glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap,
CARD16 *stride, CARD32 *size)
{
return 0;
}
int
xwl_glamor_get_fence(struct xwl_screen *xwl_screen)
{
EGLint attribs[3];
EGLSyncKHR sync;
int fence_fd = -1;
if (!xwl_screen->glamor)
return -1;
xwl_glamor_egl_make_current(xwl_screen);
attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
attribs[1] = EGL_NO_NATIVE_FENCE_FD_ANDROID;
attribs[2] = EGL_NONE;
sync = eglCreateSyncKHR(xwl_screen->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync != EGL_NO_SYNC_KHR) {
fence_fd = eglDupNativeFenceFDANDROID(xwl_screen->egl_display, sync);
eglDestroySyncKHR(xwl_screen->egl_display, sync);
}
return fence_fd;
}
/* Takes ownership of fence_fd, specifically eglCreateSyncKHR does */
void
xwl_glamor_wait_fence(struct xwl_screen *xwl_screen, int fence_fd)
{
EGLint attribs[3];
EGLSyncKHR sync;
if (!xwl_screen->glamor) {
close(fence_fd);
return;
}
xwl_glamor_egl_make_current(xwl_screen);
attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
attribs[1] = fence_fd;
attribs[2] = EGL_NONE;
sync = eglCreateSyncKHR(xwl_screen->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync != EGL_NO_SYNC_KHR) {
eglWaitSyncKHR(xwl_screen->egl_display, sync, 0);
eglDestroySyncKHR(xwl_screen->egl_display, sync);
}
}
Bool
xwl_glamor_init(struct xwl_screen *xwl_screen)
{
ScreenPtr screen = xwl_screen->screen;
const char *no_glamor_env;
no_glamor_env = getenv("XWAYLAND_NO_GLAMOR");
if (no_glamor_env && *no_glamor_env != '0') {
ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n");
return FALSE;
}
if (!xwl_glamor_has_wl_interfaces(xwl_screen)) {
ErrorF("Xwayland glamor: GBM Wayland interfaces not available\n");
return FALSE;
}
if (!xwl_glamor_gbm_init_egl(xwl_screen)) {
ErrorF("EGL setup failed, disabling glamor\n");
return FALSE;
}
if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
ErrorF("Failed to initialize glamor\n");
return FALSE;
}
if (!xwl_glamor_gbm_init_screen(xwl_screen)) {
ErrorF("EGL backend init_screen() failed, disabling glamor\n");
return FALSE;
}
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
#ifdef XV
if (!xwl_glamor_xv_init(screen))
ErrorF("Failed to initialize glamor Xv extension\n");
#endif
#ifdef GLXEXT
GlxPushProvider(&glamor_provider);
#endif
return TRUE;
}

View File

@ -1,83 +0,0 @@
/*
* 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.
*/
#ifndef XWAYLAND_GLAMOR_H
#define XWAYLAND_GLAMOR_H
#include <xwayland-config.h>
#include <sys/types.h>
#include <wayland-client.h>
#include <xf86drm.h>
#include "xwayland-types.h"
#include "xwayland-glamor-gbm.h"
#include "dri3.h"
typedef enum _xwl_glamor_mode_flags{
XWL_GLAMOR_NONE = 0,
XWL_GLAMOR_GL = (1 << 0),
XWL_GLAMOR_GLES = (1 << 1),
XWL_GLAMOR_DEFAULT = XWL_GLAMOR_GL | XWL_GLAMOR_GLES,
} xwl_glamor_mode_flags;
#ifdef XWL_HAS_GLAMOR
Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
Bool xwl_screen_set_syncobj_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry,
uint32_t id, const char *interface,
uint32_t version);
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
Bool xwl_glamor_check_flip(WindowPtr present_window, PixmapPtr pixmap);
PixmapPtr xwl_glamor_create_pixmap_for_window (struct xwl_window *xwl_window);
Bool xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen);
void xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file);
int xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap);
Bool xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen);
int xwl_glamor_get_fence(struct xwl_screen *screen);
void xwl_glamor_wait_fence(struct xwl_screen *xwl_screen, int fence);
struct dri3_syncobj *xwl_glamor_dri3_syncobj_create(struct xwl_screen *xwl_screen);
void xwl_glamor_dri3_syncobj_passthrough(struct xwl_window *xwl_window,
struct dri3_syncobj *acquire_syncobj,
struct dri3_syncobj *release_syncobj,
uint64_t acquire_point,
uint64_t release_point);
#ifdef XV
/* glamor Xv Adaptor */
Bool xwl_glamor_xv_init(ScreenPtr pScreen);
#endif /* XV */
#endif /* XWL_HAS_GLAMOR */
#endif /* XWAYLAND_GLAMOR_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,215 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2008 Kristian Høgsberg
*
* 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.
*/
#ifndef XWAYLAND_INPUT_H
#define XWAYLAND_INPUT_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include <dix.h>
#include <input.h>
struct xwl_touch {
struct xwl_window *window;
int32_t id;
int x, y;
struct xorg_list link_touch;
};
struct xwl_pointer_warp_emulator {
struct xwl_seat *xwl_seat;
struct xwl_window *locked_window;
struct zwp_locked_pointer_v1 *locked_pointer;
};
struct xwl_cursor {
void (* update_proc) (struct xwl_cursor *);
struct wl_surface *surface;
struct wl_callback *frame_cb;
Bool needs_update;
};
struct xwl_seat {
DeviceIntPtr pointer;
DeviceIntPtr relative_pointer;
DeviceIntPtr pointer_gestures;
DeviceIntPtr keyboard;
DeviceIntPtr touch;
DeviceIntPtr stylus;
DeviceIntPtr eraser;
DeviceIntPtr puck;
struct xwl_screen *xwl_screen;
struct wl_seat *seat;
struct wl_pointer *wl_pointer;
struct zwp_relative_pointer_v1 *wp_relative_pointer;
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
struct wl_keyboard *wl_keyboard;
struct wl_touch *wl_touch;
struct zwp_tablet_seat_v2 *tablet_seat;
struct wl_array keys;
struct xwl_window *focus_window;
struct xwl_window *tablet_focus_window;
uint32_t id;
uint32_t pointer_enter_serial;
struct xorg_list link;
CursorPtr x_cursor;
OsTimerPtr x_cursor_timer;
CursorPtr pending_x_cursor;
struct xwl_cursor cursor;
struct xwl_window *last_focus_window;
uint32_t pointer_gesture_swipe_fingers;
uint32_t pointer_gesture_pinch_fingers;
double pointer_gesture_pinch_last_scale;
struct xorg_list touches;
size_t keymap_size;
char *keymap;
struct wl_surface *keyboard_focus;
struct xorg_list sync_pending;
struct xwl_pointer_warp_emulator *pointer_warp_emulator;
struct xwl_window *cursor_confinement_window;
struct zwp_confined_pointer_v1 *confined_pointer;
struct {
Bool has_absolute;
wl_fixed_t x;
wl_fixed_t y;
Bool has_relative;
double dx;
double dy;
double dx_unaccel;
double dy_unaccel;
wl_fixed_t scroll_dy;
wl_fixed_t scroll_dx;
int32_t scroll_dy_v120;
int32_t scroll_dx_v120;
Bool has_vertical_scroll;
Bool has_horizontal_scroll;
Bool has_vertical_scroll_v120;
Bool has_horizontal_scroll_v120;
} pending_pointer_event;
struct xorg_list tablets;
struct xorg_list tablet_tools;
struct xorg_list tablet_pads;
struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab;
};
struct xwl_tablet {
struct xorg_list link;
struct zwp_tablet_v2 *tablet;
struct xwl_seat *seat;
};
struct xwl_tablet_tool {
struct xorg_list link;
struct zwp_tablet_tool_v2 *tool;
struct xwl_seat *seat;
DeviceIntPtr xdevice;
uint32_t proximity_in_serial;
double x;
double y;
uint32_t pressure;
double tilt_x;
double tilt_y;
double rotation;
double slider;
uint32_t buttons_now,
buttons_prev;
int32_t wheel_clicks;
struct xwl_cursor cursor;
};
struct xwl_tablet_pad_ring {
unsigned int index;
struct xorg_list link;
struct xwl_tablet_pad_group *group;
struct zwp_tablet_pad_ring_v2 *ring;
};
struct xwl_tablet_pad_strip {
unsigned int index;
struct xorg_list link;
struct xwl_tablet_pad_group *group;
struct zwp_tablet_pad_strip_v2 *strip;
};
struct xwl_tablet_pad_group {
struct xorg_list link;
struct xwl_tablet_pad *pad;
struct zwp_tablet_pad_group_v2 *group;
struct xorg_list pad_group_ring_list;
struct xorg_list pad_group_strip_list;
};
struct xwl_tablet_pad {
struct xorg_list link;
struct zwp_tablet_pad_v2 *pad;
struct xwl_seat *seat;
DeviceIntPtr xdevice;
unsigned int nbuttons;
struct xorg_list pad_group_list;
};
void xwl_seat_leave_ptr(struct xwl_seat *xwl_seat, Bool focus_lost);
void xwl_seat_leave_kbd(struct xwl_seat *xwl_seat);
void xwl_seat_destroy(struct xwl_seat *xwl_seat);
void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window);
void xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
struct xwl_window *xwl_window,
SpritePtr sprite,
int x, int y);
void xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat);
void xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat);
void xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
struct xwl_window *xwl_window);
void xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat);
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_INPUT_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,124 +0,0 @@
/*
* 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.
*/
#ifndef XWAYLAND_OUTPUT_H
#define XWAYLAND_OUTPUT_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include <dix.h>
#include <input.h>
#include <randrstr.h>
#include "xwayland-types.h"
#include "xwayland-drm-lease.h"
#define ALL_ROTATIONS (RR_Rotate_0 | \
RR_Rotate_90 | \
RR_Rotate_180 | \
RR_Rotate_270 | \
RR_Reflect_X | \
RR_Reflect_Y)
#define MAX_OUTPUT_NAME 256
struct xwl_output {
struct xorg_list link;
struct xwl_screen *xwl_screen;
RROutputPtr randr_output;
RRCrtcPtr randr_crtc;
RRTransformPtr transform;
/* only for regular outputs */
struct wl_output *output;
struct zxdg_output_v1 *xdg_output;
uint32_t server_output_id;
int32_t x, y, width, height, refresh, scale;
int32_t mode_width, mode_height;
double xscale; /* Effective scale, can be fractional */
Rotation rotation;
Bool wl_output_done;
Bool xdg_output_done;
/* only for lease-able DRM connectors */
struct wp_drm_lease_connector_v1 *lease_connector;
struct xwl_drm_lease *lease;
struct xwl_drm_lease_device *lease_device;
Bool withdrawn_connector;
};
/* Per client per output emulated randr/vidmode resolution info. */
struct xwl_emulated_mode {
uint32_t server_output_id;
int32_t width;
int32_t height;
RRMode id;
Bool from_vidmode;
};
Bool xwl_screen_init_output(struct xwl_screen *xwl_screen);
void xwl_output_set_name(struct xwl_output *xwl_output, const char *name);
Bool xwl_screen_init_randr_fixed(struct xwl_screen *xwl_screen);
void
xwl_output_set_xscale(struct xwl_output *xwl_output, double xscale);
Bool
xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
int current_width, int current_height);
void xwl_output_set_mode_fixed(struct xwl_output *xwl_output,
RRModePtr mode);
struct xwl_output *xwl_output_from_wl_output(struct xwl_screen *xwl_screen,
struct wl_output* wl_output);
struct xwl_output *xwl_output_get_output_from_name(struct xwl_screen *xwl_screen,
const char *name);
struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen,
uint32_t id, Bool connected,
uint32_t version);
void xwl_output_destroy(struct xwl_output *xwl_output);
void xwl_output_remove(struct xwl_output *xwl_output);
struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
struct xwl_output *xwl_output, ClientPtr client);
RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
int32_t width, int32_t height);
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
ClientPtr client, RRModePtr mode,
Bool from_vidmode);
void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
WindowPtr window);
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_OUTPUT_H */

View File

@ -1,141 +0,0 @@
/*
* Copyright © 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-config.h>
#include <X11/X.h>
#include "os.h"
#include "privates.h"
#include "dix.h"
#include "fb.h"
#include "pixmapstr.h"
#ifdef XWL_HAS_GLAMOR
#include "xwayland-glamor.h"
#endif
#include "xwayland-types.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-shm.h"
#include "xwayland-window-buffers.h"
static DevPrivateKeyRec xwl_pixmap_private_key;
static DevPrivateKeyRec xwl_pixmap_cb_private_key;
struct xwl_pixmap_buffer_release_callback {
xwl_buffer_release_cb callback;
void *data;
};
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);
}
struct wl_buffer *
xwl_pixmap_get_wl_buffer(PixmapPtr pixmap)
{
#ifdef XWL_HAS_GLAMOR
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
if (xwl_screen->glamor)
return xwl_glamor_pixmap_get_wl_buffer(pixmap);
else
#endif
return xwl_shm_pixmap_get_wl_buffer(pixmap);
}
Bool
xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
xwl_buffer_release_cb func, void *data)
{
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback == NULL) {
xwl_pixmap_buffer_release_callback =
calloc(1, sizeof (struct xwl_pixmap_buffer_release_callback));
if (xwl_pixmap_buffer_release_callback == NULL) {
ErrorF("Failed to allocate pixmap callback data\n");
return FALSE;
}
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key,
xwl_pixmap_buffer_release_callback);
}
xwl_pixmap_buffer_release_callback->callback = func;
xwl_pixmap_buffer_release_callback->data = data;
return TRUE;
}
void
xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap)
{
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback) {
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key, NULL);
free(xwl_pixmap_buffer_release_callback);
}
}
void
xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer)
{
PixmapPtr pixmap = data;
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback)
(*xwl_pixmap_buffer_release_callback->callback)
(xwl_pixmap_buffer_release_callback->data);
}
Bool
xwl_pixmap_init(void)
{
if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
return FALSE;
if (!dixRegisterPrivateKey(&xwl_pixmap_cb_private_key, PRIVATE_PIXMAP, 0))
return FALSE;
return TRUE;
}

View File

@ -1,56 +0,0 @@
/*
* Copyright © 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.
*/
#ifndef XWAYLAND_PIXMAP_H
#define XWAYLAND_PIXMAP_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include "dix/resource_priv.h"
#include "pixmapstr.h"
/* This is an opaque structure implemented in the different backends */
struct xwl_pixmap;
typedef void (*xwl_buffer_release_cb) (void *data);
void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
struct wl_buffer *xwl_pixmap_get_wl_buffer(PixmapPtr pixmap);
Bool xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
xwl_buffer_release_cb func, void *data);
void xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap);
void xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer);
Bool xwl_pixmap_init(void);
static inline Bool
xwl_is_client_pixmap(PixmapPtr pixmap)
{
return (!dixResouceIsServerOwned(pixmap->drawable.id));
}
#endif /* XWAYLAND_PIXMAP_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
/*
* Copyright © 2018 Roman Gilg
*
* 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.
*/
#ifndef XWAYLAND_PRESENT_H
#define XWAYLAND_PRESENT_H
#include <xwayland-config.h>
#include <dix.h>
#include <present_priv.h>
#include "xwayland-types.h"
struct xwl_present_window {
WindowPtr window;
struct xorg_list frame_callback_list;
uint64_t msc;
uint64_t ust;
OsTimerPtr frame_timer;
/* Timestamp when the current timer was first armed */
CARD32 timer_armed;
struct wl_callback *sync_callback;
struct xorg_list wait_list;
struct xorg_list flip_queue;
struct xorg_list idle_queue;
struct xorg_list blocked_queue;
present_vblank_ptr flip_active;
uint64_t blocking_event;
OsTimerPtr unredirect_timer;
Bool redirected;
Bool redirect_failed;
};
struct xwl_present_event {
present_vblank_rec vblank;
PixmapPtr pixmap;
Bool copy_executed;
uint32_t options;
uint64_t divisor;
uint64_t remainder;
struct xorg_list blocked;
};
Bool xwl_present_entered_for_each_frame_callback(void);
void xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
void iter_func(struct xwl_present_window *));
void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(WindowPtr window);
void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
Bool xwl_present_maybe_redirect_window(WindowPtr window);
Bool xwl_present_maybe_unredirect_window(WindowPtr window);
Bool xwl_present_window_redirected(WindowPtr window);
#endif /* XWAYLAND_PRESENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,183 +0,0 @@
/*
* 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.
*/
#ifndef XWAYLAND_SCREEN_H
#define XWAYLAND_SCREEN_H
#include <xwayland-config.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/X.h>
#include <dix.h>
#include "xwayland-types.h"
#include "xwayland-window.h"
#include "xwayland-output.h"
#include "xwayland-glamor.h"
#include "xwayland-drm-lease.h"
#include "xwayland-dmabuf.h"
#ifdef XWL_HAS_LIBDECOR
#include <libdecor.h>
#endif
struct xwl_screen {
double width;
double height;
int depth;
int global_surface_scale;
int output_name_serial;
ScreenPtr screen;
int wm_client_id;
int expecting_event;
enum RootClipMode root_clip_mode;
Bool active;
int rootless;
xwl_glamor_mode_flags glamor;
int present;
int force_xrandr_emulation;
int fullscreen;
int host_grab;
int has_grab;
int decorate;
int enable_ei_portal;
int nokeymap;
int hidpi;
ClipNotifyProcPtr ClipNotify;
CloseScreenProcPtr CloseScreen;
ConfigNotifyProcPtr ConfigNotify;
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
XYToWindowProcPtr XYToWindow;
SetWindowPixmapProcPtr SetWindowPixmap;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ResizeWindowProcPtr ResizeWindow;
MoveWindowProcPtr MoveWindow;
SourceValidateProcPtr SourceValidate;
SetShapeProcPtr SetShape;
int (*GrabServer) (ClientPtr client);
int (*UngrabServer) (ClientPtr client);
struct xorg_list output_list;
struct xorg_list seat_list;
struct xorg_list damage_window_list;
struct xorg_list window_list;
Bool ignore_damage;
int need_source_validate;
int wayland_fd;
struct wl_display *display;
struct wl_registry *registry;
struct wl_registry *input_registry;
struct wl_compositor *compositor;
struct zwp_tablet_manager_v2 *tablet_manager;
struct wl_shm *shm;
struct xdg_wm_base *xdg_wm_base;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zwp_pointer_gestures_v1 *pointer_gestures;
struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *shortcuts_inhibit_manager;
struct zwp_keyboard_shortcuts_inhibitor_v1 *shortcuts_inhibit;
struct zwp_linux_dmabuf_v1 *dmabuf;
int dmabuf_protocol_version;
struct xwl_dmabuf_feedback default_feedback;
struct zxdg_output_manager_v1 *xdg_output_manager;
struct wp_viewporter *viewporter;
struct xwayland_shell_v1 *xwayland_shell;
struct wp_tearing_control_manager_v1 *tearing_control_manager;
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
struct wp_linux_drm_syncobj_manager_v1 *explicit_sync;
struct xdg_system_bell_v1 *system_bell;
struct xorg_list drm_lease_devices;
struct xorg_list queued_drm_lease_devices;
struct xorg_list drm_leases;
struct xwl_output *fixed_output;
struct xorg_list pending_wl_surface_destroy;
uint64_t surface_association_serial;
uint32_t serial;
#define XWL_FORMAT_ARGB8888 (1 << 0)
#define XWL_FORMAT_XRGB8888 (1 << 1)
#define XWL_FORMAT_RGB565 (1 << 2)
int prepare_read;
int wait_flush;
uint32_t num_formats;
struct xwl_format *formats;
void *egl_display, *egl_context;
struct glamor_context *glamor_ctx;
Atom allow_commits_prop;
/* The preferred GLVND vendor. If NULL, "mesa" is assumed. */
const char *glvnd_vendor;
#ifdef XWL_HAS_LIBDECOR
int libdecor_fd;
struct libdecor *libdecor_context;
#endif
const char *output_name;
uint32_t present_capabilities;
};
/* Apps which use randr/vidmode to change the mode when going fullscreen,
* usually change the mode of only a single monitor, so this should be plenty.
*/
#define XWL_CLIENT_MAX_EMULATED_MODES 16
struct xwl_client {
struct xwl_emulated_mode emulated_modes[XWL_CLIENT_MAX_EMULATED_MODES];
};
struct xwl_client *xwl_client_get(ClientPtr client);
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
Bool xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen);
Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen);
int xwl_screen_get_width(struct xwl_screen *xwl_screen);
int xwl_screen_get_height(struct xwl_screen *xwl_screen);
Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv);
void xwl_sync_events (struct xwl_screen *xwl_screen);
void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
void xwl_surface_damage(struct xwl_screen *xwl_screen,
struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height);
int xwl_screen_get_next_output_serial(struct xwl_screen * xwl_screen);
void xwl_screen_lost_focus(struct xwl_screen *xwl_screen);
Bool xwl_screen_update_global_surface_scale(struct xwl_screen *xwl_screen);
Bool xwl_screen_should_use_fractional_scale(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_SCREEN_H */

View File

@ -1,370 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2012 Collabora, Ltd.
*
* 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-config.h>
#include "os.h"
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "mi/mi_priv.h"
#include "os/osdep.h"
#include "fb.h"
#include "pixmapstr.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-shm.h"
struct xwl_pixmap {
struct wl_buffer *buffer;
void *data;
size_t size;
};
#ifndef HAVE_MKOSTEMP
static int
set_cloexec_or_close(int fd)
{
long flags;
if (fd == -1)
return -1;
flags = fcntl(fd, F_GETFD);
if (flags == -1)
goto err;
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
goto err;
return fd;
err:
close(fd);
return -1;
}
#endif
static int
create_tmpfile_cloexec(char *tmpname)
{
int fd;
#ifdef HAVE_MKOSTEMP
fd = mkostemp(tmpname, O_CLOEXEC);
if (fd >= 0)
unlink(tmpname);
#else
fd = mkstemp(tmpname);
if (fd >= 0) {
fd = set_cloexec_or_close(fd);
unlink(tmpname);
}
#endif
return os_move_fd(fd);
}
/*
* Create a new, unique, anonymous file of the given size, and
* return the file descriptor for it. The file descriptor is set
* CLOEXEC. The file is immediately suitable for mmap()'ing
* the given size at offset zero.
*
* The file should not have a permanent backing store like a disk,
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
*
* The file name is deleted from the file system.
*
* The file is suitable for buffer sharing between processes by
* transmitting the file descriptor over Unix sockets using the
* SCM_RIGHTS methods.
*
* If the C library implements posix_fallocate(), it is used to
* guarantee that disk space is available for the file at the
* given size. If disk space is insufficient, errno is set to ENOSPC.
* If posix_fallocate() is not supported, program may receive
* SIGBUS on accessing mmap()'ed file contents instead.
*
* If the C library implements memfd_create(), it is used to create the
* file purely in memory, without any backing file name on the file
* system, and then sealing off the possibility of shrinking it. This
* can then be checked before accessing mmap()'ed file contents, to
* make sure SIGBUS can't happen. It also avoids requiring
* XDG_RUNTIME_DIR.
*/
static int
os_create_anonymous_file(off_t size)
{
static const char template[] = "/xwayland-shared-XXXXXX";
const char *path;
int fd;
int ret;
#ifdef HAVE_MEMFD_CREATE
fd = memfd_create("xwayland-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd >= 0) {
/* We can add this seal before calling posix_fallocate(), as
* the file is currently zero-sized anyway.
*
* There is also no need to check for the return value, we
* couldn't do anything with it anyway.
*/
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK);
} else
#endif
{
path = getenv("XDG_RUNTIME_DIR");
if (!path) {
errno = ENOENT;
return -1;
}
char *name = calloc(1, strlen(path) + sizeof(template));
if (!name)
return -1;
strcpy(name, path);
strcat(name, template);
fd = create_tmpfile_cloexec(name);
free(name);
if (fd < 0)
return -1;
}
#ifdef HAVE_POSIX_FALLOCATE
/*
* posix_fallocate does an explicit rollback if it gets EINTR.
* Temporarily block signals to allow the call to succeed on
* slow systems where the smart scheduler's SIGALRM prevents
* large allocation attempts from ever succeeding.
*/
OsBlockSignals();
do {
ret = posix_fallocate(fd, 0, size);
} while (ret == EINTR);
OsReleaseSignals();
if (ret != 0) {
close(fd);
errno = ret;
return -1;
}
#else
do {
ret = ftruncate(fd, size);
} while (ret == -1 && errno == EINTR);
if (ret < 0) {
close(fd);
return -1;
}
#endif
return fd;
}
static uint32_t
shm_format_for_depth(int depth)
{
switch (depth) {
case 32:
return WL_SHM_FORMAT_ARGB8888;
case 24:
default:
return WL_SHM_FORMAT_XRGB8888;
#ifdef WL_SHM_FORMAT_RGB565
case 16:
/* XXX: Check run-time protocol version too */
return WL_SHM_FORMAT_RGB565;
#endif
}
}
static Bool
dimensions_match_toplevel_window(ScreenPtr screen, int width, int height)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
WindowPtr toplevel;
if (xwl_screen->rootless)
toplevel = screen->root->firstChild;
else
toplevel = screen->root;
while (toplevel) {
if (width == toplevel->drawable.width &&
height == toplevel->drawable.height)
return TRUE;
toplevel = toplevel->nextSib;
}
return FALSE;
}
static const struct wl_buffer_listener xwl_shm_buffer_listener = {
xwl_pixmap_buffer_release_cb,
};
PixmapPtr
xwl_shm_create_pixmap(ScreenPtr screen,
int width, int height, int depth, unsigned int hint)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_pixmap *xwl_pixmap;
struct wl_shm_pool *pool;
PixmapPtr pixmap;
size_t size, stride;
uint32_t format;
int fd;
if (hint == CREATE_PIXMAP_USAGE_GLYPH_PICTURE ||
(width == 0 && height == 0) || depth < 15 ||
(hint != CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
!dimensions_match_toplevel_window(screen, width, height)))
return fbCreatePixmap(screen, width, height, depth, hint);
stride = PixmapBytePad(width, depth);
size = stride * height;
/* Size in the protocol is an integer, make sure we don't exceed
* INT32_MAX or else the Wayland compositor will raise an error and
* kill the Wayland connection!
*/
if (size > INT32_MAX)
return NULL;
pixmap = fbCreatePixmap(screen, 0, 0, depth, hint);
if (!pixmap)
return NULL;
xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
if (xwl_pixmap == NULL)
goto err_destroy_pixmap;
xwl_pixmap->buffer = NULL;
xwl_pixmap->size = size;
fd = os_create_anonymous_file(size);
if (fd < 0)
goto err_free_xwl_pixmap;
xwl_pixmap->data = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (xwl_pixmap->data == MAP_FAILED)
goto err_close_fd;
if (!(*screen->ModifyPixmapHeader) (pixmap, width, height, depth,
BitsPerPixel(depth),
stride, xwl_pixmap->data))
goto err_munmap;
format = shm_format_for_depth(pixmap->drawable.depth);
pool = wl_shm_create_pool(xwl_screen->shm, fd, xwl_pixmap->size);
xwl_pixmap->buffer = wl_shm_pool_create_buffer(pool, 0,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->devKind, format);
wl_shm_pool_destroy(pool);
close(fd);
wl_buffer_add_listener(xwl_pixmap->buffer,
&xwl_shm_buffer_listener, pixmap);
xwl_pixmap_set_private(pixmap, xwl_pixmap);
return pixmap;
err_munmap:
munmap(xwl_pixmap->data, size);
err_close_fd:
close(fd);
err_free_xwl_pixmap:
free(xwl_pixmap);
err_destroy_pixmap:
fbDestroyPixmap(pixmap);
return NULL;
}
Bool
xwl_shm_destroy_pixmap(PixmapPtr pixmap)
{
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap && pixmap->refcnt == 1) {
xwl_pixmap_del_buffer_release_cb(pixmap);
if (xwl_pixmap->buffer)
wl_buffer_destroy(xwl_pixmap->buffer);
munmap(xwl_pixmap->data, xwl_pixmap->size);
free(xwl_pixmap);
}
return fbDestroyPixmap(pixmap);
}
struct wl_buffer *
xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap)
{
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (!xwl_pixmap)
return NULL;
return xwl_pixmap->buffer;
}
Bool
xwl_shm_create_screen_resources(ScreenPtr screen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
if (!miCreateScreenResources(screen))
return FALSE;
if (xwl_screen->rootless)
screen->devPrivate =
fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
else
screen->devPrivate =
xwl_shm_create_pixmap(screen, screen->width, screen->height,
screen->rootDepth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
SetRootClip(screen, xwl_screen->root_clip_mode);
return screen->devPrivate != NULL;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2012 Collabora, Ltd.
*
* 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.
*/
#ifndef XWAYLAND_SHM_H
#define XWAYLAND_SHM_H
#include <xwayland-config.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
Bool xwl_shm_create_screen_resources(ScreenPtr screen);
PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
int depth, unsigned int hint);
Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
#endif /* XWAYLAND_SHM_H */

View File

@ -1,36 +0,0 @@
/*
* Copyright © 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.
*/
#ifndef XWAYLAND_TYPES_H
#define XWAYLAND_TYPES_H
struct xwl_pixmap;
struct xwl_window;
struct xwl_screen;
struct xwl_drm_lease;
struct xwl_output;
struct xwl_window_buffer;
#endif /* XWAYLAND_TYPES_H */

View File

@ -1,507 +0,0 @@
/*
* Copyright (c) 1999-2003 by The XFree86 Project, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
#include <dix-config.h>
#include <X11/X.h>
#include "dix/dix_priv.h"
#include "misc.h"
#include "os.h"
#ifdef XF86VIDMODE
#include "randrstr.h"
#include "vidmodestr.h"
#include "xwayland-screen.h"
#include "xwayland-vidmode.h"
static DevPrivateKeyRec xwlVidModePrivateKeyRec;
#define xwlVidModePrivateKey (&xwlVidModePrivateKeyRec)
/* Taken from xrandr, h sync frequency in KHz */
static double
mode_hsync(const xRRModeInfo *mode_info)
{
double rate;
if (mode_info->hTotal)
rate = (double) mode_info->dotClock / (double) mode_info->hTotal;
else
rate = 0.0;
return rate / 1000.0;
}
/* Taken from xrandr, v refresh frequency in Hz */
static double
mode_refresh(const xRRModeInfo *mode_info)
{
double rate;
double vTotal = mode_info->vTotal;
if (mode_info->modeFlags & RR_DoubleScan)
vTotal *= 2.0;
if (mode_info->modeFlags & RR_Interlace)
vTotal /= 2.0;
if (mode_info->hTotal > 0.0 && vTotal > 0.0)
rate = ((double) mode_info->dotClock /
((double) mode_info->hTotal * (double) vTotal));
else
rate = 0.0;
return rate;
}
static void
xwlRRModeToDisplayMode(RRModePtr rrmode, DisplayModePtr mode)
{
const xRRModeInfo *mode_info = &rrmode->mode;
mode->next = mode;
mode->prev = mode;
mode->name = "";
mode->VScan = 1;
mode->Private = NULL;
mode->HDisplay = mode_info->width;
mode->HSyncStart = mode_info->hSyncStart;
mode->HSyncEnd = mode_info->hSyncEnd;
mode->HTotal = mode_info->hTotal;
mode->HSkew = mode_info->hSkew;
mode->VDisplay = mode_info->height;
mode->VSyncStart = mode_info->vSyncStart;
mode->VSyncEnd = mode_info->vSyncEnd;
mode->VTotal = mode_info->vTotal;
mode->Flags = mode_info->modeFlags;
mode->Clock = mode_info->dotClock / 1000.0;
mode->VRefresh = mode_refresh(mode_info); /* Or RRVerticalRefresh() */
mode->HSync = mode_hsync(mode_info);
}
static RRModePtr
xwlVidModeGetRRMode(ScreenPtr pScreen, int32_t width, int32_t height)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (!xwl_output)
return NULL;
return xwl_output_find_mode(xwl_output, width, height);
}
static RRModePtr
xwlVidModeGetCurrentRRMode(ScreenPtr pScreen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_emulated_mode *emulated_mode;
struct xwl_output *xwl_output;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (!xwl_output)
return NULL;
emulated_mode =
xwl_output_get_emulated_mode_for_client(xwl_output, GetCurrentClient());
if (emulated_mode) {
return xwl_output_find_mode(xwl_output,
emulated_mode->width,
emulated_mode->height);
} else {
return xwl_output_find_mode(xwl_output, -1, -1);
}
}
static Bool
xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
DisplayModePtr pMod;
RRModePtr rrmode;
pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
if (pMod == NULL)
return FALSE;
rrmode = xwlVidModeGetCurrentRRMode(pScreen);
if (rrmode == NULL)
return FALSE;
xwlRRModeToDisplayMode(rrmode, pMod);
*mode = pMod;
if (dotClock != NULL)
*dotClock = pMod->Clock;
return TRUE;
}
static vidMonitorValue
xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
{
vidMonitorValue ret = { NULL, };
RRModePtr rrmode;
rrmode = xwlVidModeGetCurrentRRMode(pScreen);
if (rrmode == NULL)
return ret;
switch (valtyp) {
case VIDMODE_MON_VENDOR:
ret.ptr = XVENDORNAME;
break;
case VIDMODE_MON_MODEL:
ret.ptr = "XWAYLAND";
break;
case VIDMODE_MON_NHSYNC:
ret.i = 1;
break;
case VIDMODE_MON_NVREFRESH:
ret.i = 1;
break;
case VIDMODE_MON_HSYNC_LO:
case VIDMODE_MON_HSYNC_HI:
ret.f = mode_hsync(&rrmode->mode) * 100.0;
break;
case VIDMODE_MON_VREFRESH_LO:
case VIDMODE_MON_VREFRESH_HI:
ret.f = mode_refresh(&rrmode->mode) * 100.0;
break;
}
return ret;
}
static int
xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
{
return Clock;
}
static int
xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
{
/* We emulate a programmable clock, rather then a fixed set of clocks */
*progClock = TRUE;
return 0;
}
static Bool
xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks)
{
return FALSE; /* Programmable clock, no clock list */
}
/* GetFirstModeline and GetNextModeline are used from Xext/vidmode.c like this:
* if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
* do {
* ...
* if (...)
* break;
* } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
* }
* IOW our caller basically always loops over all the modes. There never is a
* return to the mainloop between GetFirstModeline and NextModeline calls where
* other parts of the server may change our state so we do not need to worry
* about xwl_output->randr_output->modes changing underneath us.
* Thus we can simply implement these two callbacks by storing the enumeration
* index in pVidMode->Next.
*/
static Bool
xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
VidModePtr pVidMode;
DisplayModePtr pMod;
intptr_t index;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (xwl_output == NULL)
return FALSE;
pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
pVidMode = VidModeGetPtr(pScreen);
if (pMod == NULL || pVidMode == NULL)
return FALSE;
index = (intptr_t)pVidMode->Next;
if (index >= xwl_output->randr_output->numModes)
return FALSE;
xwlRRModeToDisplayMode(xwl_output->randr_output->modes[index], pMod);
index++;
pVidMode->Next = (void *)index;
*mode = pMod;
if (dotClock != NULL)
*dotClock = pMod->Clock;
return TRUE;
}
static Bool
xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
VidModePtr pVidMode;
intptr_t index = 0;
pVidMode = VidModeGetPtr(pScreen);
if (pVidMode == NULL)
return FALSE;
pVidMode->Next = (void *)index; /* 0 */
return xwlVidModeGetNextModeline(pScreen, mode, dotClock);
}
static Bool
xwlVidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
{
/* Unsupported */
return FALSE;
}
static Bool
xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom)
{
/* Support only no zoom */
return (zoom == 1);
}
static Bool
xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (xwl_output == NULL)
return FALSE;
/* Support only default viewport */
return (x == xwl_output->x && y == xwl_output->y);
}
static Bool
xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (xwl_output == NULL)
return FALSE;
*x = xwl_output->x;
*y = xwl_output->y;
return TRUE;
}
static Bool
xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
RRModePtr rrmode;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (xwl_output == NULL)
return FALSE;
rrmode = xwl_output_find_mode(xwl_output, mode->HDisplay, mode->VDisplay);
if (rrmode == NULL)
return FALSE;
if (xwl_screen->rootless)
xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), rrmode, TRUE);
else if (xwl_screen->fixed_output)
xwl_output_set_mode_fixed(xwl_screen->fixed_output, rrmode);
return TRUE;
}
static Bool
xwlVidModeLockZoom(ScreenPtr pScreen, Bool lock)
{
/* Unsupported for now, but pretend it works */
return TRUE;
}
static ModeStatus
xwlVidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
{
RRModePtr rrmode;
rrmode = xwlVidModeGetRRMode(pScreen, mode->HDisplay, mode->VDisplay);
if (rrmode == NULL)
return MODE_ERROR;
/* Only support mode with the same HSync/VRefresh as we advertise */
if (mode->HSync == mode_hsync(&rrmode->mode) &&
mode->VRefresh == mode_refresh(&rrmode->mode))
return MODE_OK;
/* All the rest is unsupported - If we want to succeed, return MODE_OK instead */
return MODE_ONE_SIZE;
}
static ModeStatus
xwlVidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
{
RRModePtr rrmode;
rrmode = xwlVidModeGetRRMode(pScreen, mode->HDisplay, mode->VDisplay);
return rrmode ? MODE_OK : MODE_ERROR;
}
static void
xwlVidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
{
/* Unsupported */
return;
}
static Bool
xwlVidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
{
/* Unsupported */
return FALSE;
}
static int
xwlVidModeGetNumOfModes(ScreenPtr pScreen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct xwl_output *xwl_output;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
return xwl_output ? xwl_output->randr_output->numModes : 0;
}
static Bool
xwlVidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
{
/* Unsupported for now, but pretend it works */
return TRUE;
}
static Bool
xwlVidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
{
/* Unsupported for now, but pretend it works */
*red = *green = *blue = 1.0f;
return TRUE;
}
static Bool
xwlVidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
{
/* Unsupported for now */
return FALSE;
}
static Bool
xwlVidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
{
/* Unsupported for now */
return FALSE;
}
static int
xwlVidModeGetGammaRampSize(ScreenPtr pScreen)
{
/* Unsupported for now */
return 0;
}
static Bool
xwlVidModeInit(ScreenPtr pScreen)
{
VidModePtr pVidMode = NULL;
pVidMode = VidModeInit(pScreen);
if (!pVidMode)
return FALSE;
pVidMode->Flags = 0;
pVidMode->Next = NULL;
pVidMode->GetMonitorValue = xwlVidModeGetMonitorValue;
pVidMode->GetCurrentModeline = xwlVidModeGetCurrentModeline;
pVidMode->GetFirstModeline = xwlVidModeGetFirstModeline;
pVidMode->GetNextModeline = xwlVidModeGetNextModeline;
pVidMode->DeleteModeline = xwlVidModeDeleteModeline;
pVidMode->ZoomViewport = xwlVidModeZoomViewport;
pVidMode->GetViewPort = xwlVidModeGetViewPort;
pVidMode->SetViewPort = xwlVidModeSetViewPort;
pVidMode->SwitchMode = xwlVidModeSwitchMode;
pVidMode->LockZoom = xwlVidModeLockZoom;
pVidMode->GetNumOfClocks = xwlVidModeGetNumOfClocks;
pVidMode->GetClocks = xwlVidModeGetClocks;
pVidMode->CheckModeForMonitor = xwlVidModeCheckModeForMonitor;
pVidMode->CheckModeForDriver = xwlVidModeCheckModeForDriver;
pVidMode->SetCrtcForMode = xwlVidModeSetCrtcForMode;
pVidMode->AddModeline = xwlVidModeAddModeline;
pVidMode->GetDotClock = xwlVidModeGetDotClock;
pVidMode->GetNumOfModes = xwlVidModeGetNumOfModes;
pVidMode->SetGamma = xwlVidModeSetGamma;
pVidMode->GetGamma = xwlVidModeGetGamma;
pVidMode->SetGammaRamp = xwlVidModeSetGammaRamp;
pVidMode->GetGammaRamp = xwlVidModeGetGammaRamp;
pVidMode->GetGammaRampSize = xwlVidModeGetGammaRampSize;
return TRUE;
}
void
xwlVidModeExtensionInit(void)
{
int i;
Bool enabled = FALSE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (xwlVidModeInit (screenInfo.screens[i]))
enabled = TRUE;
}
/* This means that the DDX doesn't want the vidmode extension enabled */
if (!enabled)
return;
if (!dixRegisterPrivateKey(xwlVidModePrivateKey, PRIVATE_SCREEN,
sizeof(DisplayModeRec)))
return;
VidModeAddExtension(FALSE);
}
#endif /* XF86VIDMODE */

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 1999-2003 by The XFree86 Project, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
#ifndef XWAYLAND_VIDMODE_H
#define XWAYLAND_VIDMODE_H
#include <xwayland-config.h>
#ifdef XF86VIDMODE
void xwlVidModeExtensionInit(void);
#endif
#endif /* XWAYLAND_VIDMODE_H */

View File

@ -1,473 +0,0 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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 (including the next
* paragraph) 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.
*
* Authors:
* Olivier Fourdan <ofourdan@redhat.com>
*/
#include <xwayland-config.h>
#include "gcstruct.h"
#include "xwayland-window.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-glamor-gbm.h"
#include "xwayland-window-buffers.h"
#ifdef XWL_HAS_GLAMOR
#include "glamor.h"
#endif
#include "dri3.h"
#include <poll.h>
#ifdef DRI3
#include <sys/eventfd.h>
#endif
#include "linux-drm-syncobj-v1-client-protocol.h"
#define BUFFER_TIMEOUT 1 * 1000 /* ms */
struct xwl_window_buffer {
struct xwl_window *xwl_window;
PixmapPtr pixmap;
RegionPtr damage_region;
int refcnt;
uint32_t time;
struct xorg_list link_buffer;
};
static void
copy_pixmap_area(PixmapPtr src_pixmap, PixmapPtr dst_pixmap,
int x, int y, int width, int height)
{
GCPtr pGC;
pGC = GetScratchGC(dst_pixmap->drawable.depth,
dst_pixmap->drawable.pScreen);
if (!pGC)
FatalError("GetScratchGC failed for depth %d", dst_pixmap->drawable.depth);
ValidateGC(&dst_pixmap->drawable, pGC);
(void) (*pGC->ops->CopyArea) (&src_pixmap->drawable,
&dst_pixmap->drawable,
pGC,
x, y,
width, height,
x, y);
FreeScratchGC(pGC);
}
static struct xwl_window_buffer *
xwl_window_buffer_new(struct xwl_window *xwl_window)
{
struct xwl_window_buffer *xwl_window_buffer;
xwl_window_buffer = calloc (1, sizeof(struct xwl_window_buffer));
if (!xwl_window_buffer)
return NULL;
xwl_window_buffer->xwl_window = xwl_window;
xwl_window_buffer->damage_region = RegionCreate(NullBox, 1);
xwl_window_buffer->pixmap = NullPixmap;
xwl_window_buffer->refcnt = 1;
xorg_list_init(&xwl_window_buffer->link_buffer);
return xwl_window_buffer;
}
static void
xwl_window_buffer_destroy_pixmap(struct xwl_window_buffer *xwl_window_buffer)
{
xwl_pixmap_del_buffer_release_cb(xwl_window_buffer->pixmap);
dixDestroyPixmap(xwl_window_buffer->pixmap, 0);
xwl_window_buffer->pixmap = NullPixmap;
}
static void
xwl_window_buffer_dispose(struct xwl_window_buffer *xwl_window_buffer)
{
RegionDestroy(xwl_window_buffer->damage_region);
if (xwl_window_buffer->pixmap) {
#ifdef XWL_HAS_GLAMOR
xwl_glamor_gbm_dispose_syncpts(xwl_window_buffer->pixmap);
#endif /* XWL_HAS_GLAMOR */
xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
}
xorg_list_del(&xwl_window_buffer->link_buffer);
free(xwl_window_buffer);
}
static Bool
xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
{
assert(xwl_window_buffer->refcnt > 0);
if (--xwl_window_buffer->refcnt)
return FALSE;
xwl_window_buffer_dispose(xwl_window_buffer);
return TRUE;
}
void
xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window)
{
RegionPtr region = xwl_window_get_damage_region(xwl_window);
struct xwl_window_buffer *xwl_window_buffer;
/* Add damage region to all buffers */
xorg_list_for_each_entry(xwl_window_buffer,
&xwl_window->window_buffers_available,
link_buffer) {
RegionUnion(xwl_window_buffer->damage_region,
xwl_window_buffer->damage_region,
region);
}
xorg_list_for_each_entry(xwl_window_buffer,
&xwl_window->window_buffers_unavailable,
link_buffer) {
RegionUnion(xwl_window_buffer->damage_region,
xwl_window_buffer->damage_region,
region);
}
}
static struct xwl_window_buffer *
xwl_window_buffer_get_available(struct xwl_window *xwl_window)
{
if (xorg_list_is_empty(&xwl_window->window_buffers_available))
return NULL;
return xorg_list_last_entry(&xwl_window->window_buffers_available,
struct xwl_window_buffer,
link_buffer);
}
static CARD32
xwl_window_buffer_timer_callback(OsTimerPtr timer, CARD32 time, void *arg)
{
struct xwl_window *xwl_window = arg;
struct xwl_window_buffer *xwl_window_buffer, *tmp;
/* Dispose older available buffers */
xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
&xwl_window->window_buffers_available,
link_buffer) {
if ((int64_t)(time - xwl_window_buffer->time) >= BUFFER_TIMEOUT)
xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
/* If there are still available buffers, re-arm the timer */
if (!xorg_list_is_empty(&xwl_window->window_buffers_available)) {
struct xwl_window_buffer *oldest_available_buffer =
xorg_list_first_entry(&xwl_window->window_buffers_available,
struct xwl_window_buffer,
link_buffer);
return oldest_available_buffer->time + BUFFER_TIMEOUT - time;
}
/* Don't re-arm the timer */
return 0;
}
static void
xwl_window_buffer_release_callback(void *data)
{
struct xwl_window_buffer *xwl_window_buffer = data;
struct xwl_window *xwl_window = xwl_window_buffer->xwl_window;
struct xwl_window_buffer *oldest_available_buffer;
/* Drop the reference on the buffer we took in get_pixmap. If that
* frees the window buffer, we're done.
*/
if (xwl_window_buffer_maybe_dispose(xwl_window_buffer))
return;
/* We append the buffers to the end of the list, as we pick the last
* entry again when looking for new available buffers, that means the
* least used buffers will remain at the beginning of the list so that
* they can be garbage collected automatically after some time unused.
*/
xorg_list_del(&xwl_window_buffer->link_buffer);
xorg_list_append(&xwl_window_buffer->link_buffer,
&xwl_window->window_buffers_available);
xwl_window_buffer->time = (uint32_t) GetTimeInMillis();
oldest_available_buffer =
xorg_list_first_entry(&xwl_window->window_buffers_available,
struct xwl_window_buffer,
link_buffer);
/* Schedule next timer based on time of the oldest buffer */
xwl_window->window_buffers_timer =
TimerSet(xwl_window->window_buffers_timer,
TimerAbsolute,
oldest_available_buffer->time + BUFFER_TIMEOUT,
&xwl_window_buffer_timer_callback,
xwl_window);
}
void
xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer)
{
xwl_window_buffer_release_callback(xwl_window_buffer);
}
void
xwl_window_buffers_init(struct xwl_window *xwl_window)
{
xorg_list_init(&xwl_window->window_buffers_available);
xorg_list_init(&xwl_window->window_buffers_unavailable);
}
static void
xwl_window_buffer_disposal(struct xwl_window_buffer *xwl_window_buffer, Bool force)
{
if (force)
xwl_window_buffer_dispose(xwl_window_buffer);
else
xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
void
xwl_window_buffers_dispose(struct xwl_window *xwl_window, Bool force)
{
struct xwl_window_buffer *xwl_window_buffer, *tmp;
/* This is called prior to free the xwl_window, make sure to untie
* the buffers from the xwl_window so that we don't point at freed
* memory if we get a release buffer later.
*/
xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
&xwl_window->window_buffers_available,
link_buffer) {
xorg_list_del(&xwl_window_buffer->link_buffer);
xwl_window_buffer_disposal(xwl_window_buffer, force);
}
xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
&xwl_window->window_buffers_unavailable,
link_buffer) {
xorg_list_del(&xwl_window_buffer->link_buffer);
xwl_window_buffer_disposal(xwl_window_buffer, force);
}
if (xwl_window->window_buffers_timer)
TimerCancel(xwl_window->window_buffers_timer);
}
struct pixmap_visit {
PixmapPtr old;
PixmapPtr new;
};
static int
xwl_set_pixmap_visit_window(WindowPtr window, void *data)
{
ScreenPtr screen = window->drawable.pScreen;
struct pixmap_visit *visit = data;
if (screen->GetWindowPixmap(window) == visit->old) {
screen->SetWindowPixmap(window, visit->new);
return WT_WALKCHILDREN;
}
return WT_DONTWALKCHILDREN;
}
static void
xwl_window_set_pixmap(WindowPtr window, PixmapPtr pixmap)
{
ScreenPtr screen = window->drawable.pScreen;
struct pixmap_visit visit;
visit.old = screen->GetWindowPixmap(window);
visit.new = pixmap;
pixmap->screen_x = visit.old->screen_x;
pixmap->screen_y = visit.old->screen_y;
TraverseTree(window, xwl_set_pixmap_visit_window, &visit);
if (window == screen->root &&
screen->GetScreenPixmap(screen) == visit.old)
screen->SetScreenPixmap(pixmap);
}
static PixmapPtr
xwl_window_allocate_pixmap(struct xwl_window *xwl_window)
{
ScreenPtr screen = xwl_window->xwl_screen->screen;
PixmapPtr window_pixmap;
#ifdef XWL_HAS_GLAMOR
/* Try the xwayland/glamor direct hook first */
window_pixmap = xwl_glamor_create_pixmap_for_window(xwl_window);
if (window_pixmap)
return window_pixmap;
#endif /* XWL_HAS_GLAMOR */
window_pixmap = screen->GetWindowPixmap(xwl_window->surface_window);
return screen->CreatePixmap(screen,
window_pixmap->drawable.width,
window_pixmap->drawable.height,
window_pixmap->drawable.depth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
}
void
xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
{
PixmapPtr window_pixmap, new_window_pixmap;
WindowPtr window;
ScreenPtr screen;
new_window_pixmap = xwl_window_allocate_pixmap(xwl_window);
if (!new_window_pixmap)
return;
window = xwl_window->surface_window;
screen = window->drawable.pScreen;
window_pixmap = screen->GetWindowPixmap(window);
copy_pixmap_area(window_pixmap,
new_window_pixmap,
0, 0,
window_pixmap->drawable.width,
window_pixmap->drawable.height);
xwl_window_set_pixmap(xwl_window->surface_window, new_window_pixmap);
dixDestroyPixmap(window_pixmap, 0);
}
static Bool
xwl_window_handle_pixmap_sync(struct xwl_window *xwl_window,
PixmapPtr pixmap,
struct xwl_window_buffer *xwl_window_buffer)
{
Bool implicit_sync = TRUE;
#ifdef XWL_HAS_GLAMOR
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, pixmap)) {
implicit_sync = FALSE;
/* wait until the release fence is available before re-using this buffer */
xwl_glamor_gbm_wait_release_fence(xwl_window, pixmap, xwl_window_buffer);
} else {
/* If glamor does not support implicit sync and we can't use
* explicit sync, wait for the GPU to be idle before presenting.
* Note that buffer re-use will still be unsynchronized :(
*/
glamor_finish(xwl_screen->screen);
}
}
#endif /* XWL_HAS_GLAMOR */
return implicit_sync;
}
PixmapPtr
xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
WindowPtr surface_window = xwl_window->surface_window;
struct xwl_window_buffer *xwl_window_buffer;
PixmapPtr window_pixmap;
window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (surface_window);
xwl_window_buffer_add_damage_region(xwl_window);
xwl_window_buffer = xwl_window_buffer_get_available(xwl_window);
if (xwl_window_buffer) {
RegionPtr full_damage = xwl_window_buffer->damage_region;
BoxPtr pBox = RegionRects(full_damage);
int nBox = RegionNumRects(full_damage);
#ifdef XWL_HAS_GLAMOR
xwl_glamor_gbm_wait_syncpts(xwl_window_buffer->pixmap);
#endif /* XWL_HAS_GLAMOR */
while (nBox--) {
copy_pixmap_area(window_pixmap,
xwl_window_buffer->pixmap,
pBox->x1 + surface_window->borderWidth,
pBox->y1 + surface_window->borderWidth,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1);
pBox++;
}
RegionEmpty(xwl_window_buffer->damage_region);
xorg_list_del(&xwl_window_buffer->link_buffer);
xwl_window_set_pixmap(surface_window, xwl_window_buffer->pixmap);
/* Can't re-use client pixmap as a window buffer */
if (xwl_is_client_pixmap(window_pixmap)) {
xwl_window_buffer->pixmap = NULL;
xwl_window_buffer_maybe_dispose(xwl_window_buffer);
if (handle_sync)
xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, NULL);
return window_pixmap;
}
} else {
/* Can't re-use client pixmap as a window buffer */
if (!xwl_is_client_pixmap(window_pixmap))
xwl_window_buffer = xwl_window_buffer_new(xwl_window);
window_pixmap->refcnt++;
xwl_window_realloc_pixmap(xwl_window);
if (!xwl_window_buffer) {
if (handle_sync)
xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, NULL);
return window_pixmap;
}
}
xwl_window_buffer->pixmap = window_pixmap;
/* Hold a reference on the buffer until it's released by the compositor */
xwl_window_buffer->refcnt++;
if (handle_sync &&
xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, xwl_window_buffer)) {
xwl_pixmap_set_buffer_release_cb(xwl_window_buffer->pixmap,
xwl_window_buffer_release_callback,
xwl_window_buffer);
if (xwl_window->surface_sync) {
wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
xwl_window->surface_sync = NULL;
}
}
xorg_list_append(&xwl_window_buffer->link_buffer,
&xwl_window->window_buffers_unavailable);
if (xorg_list_is_empty(&xwl_window->window_buffers_available))
TimerCancel(xwl_window->window_buffers_timer);
return xwl_window_buffer->pixmap;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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 (including the next
* paragraph) 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.
*
* Authors:
* Olivier Fourdan <ofourdan@redhat.com>
*/
#ifndef XWAYLAND_WINDOW_BUFFERS_H
#define XWAYLAND_WINDOW_BUFFERS_H
#include <xwayland-config.h>
#include "xwayland-types.h"
void xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window);
void xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer);
void xwl_window_buffers_init(struct xwl_window *xwl_window);
void xwl_window_buffers_dispose(struct xwl_window *xwl_window, Bool force);
void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
PixmapPtr xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync);
#endif /* XWAYLAND_WINDOW_BUFFERS_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +0,0 @@
/*
* 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.
*/
#ifndef XWAYLAND_WINDOW_H
#define XWAYLAND_WINDOW_H
#include <xwayland-config.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/X.h>
#include "dix/property_priv.h"
#include <dix.h>
#include <propertyst.h>
#include <validate.h>
#include <wayland-util.h>
#include <xf86drm.h>
#include "xwayland-types.h"
#include "xwayland-dmabuf.h"
struct xwl_wl_surface {
OsTimerPtr wl_surface_destroy_timer;
struct wl_surface *wl_surface;
struct xorg_list link;
};
struct xwl_window_output {
struct xorg_list link;
struct xwl_output *xwl_output;
};
struct xwl_window {
struct xwl_screen *xwl_screen;
struct wl_surface *surface;
struct wp_viewport *viewport;
float viewport_scale_x, viewport_scale_y;
int surface_scale;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
/* Top-level window for the Wayland surface:
* - With rootful, the root window itself
* - With rootless, a direct child of the root window
* Mainly useful when the top-level window is needed, can also be used for
* the X dimensions of the Wayland surface though.
*/
WindowPtr toplevel;
/* The window associated with the Wayland surface:
* - If the top-level window has descendants which:
* - Cover it completely
* - Have no alpha channel
* - Use a different window pixmap than their parent for storage
* then the surface window is the lowest-level such descendant.
* - Otherwise it's the top-level window itself.
* Mainly useful for code dealing with (buffers for) the Wayland surface,
* can also be used for the X dimensions of the Wayland surface though.
*/
WindowPtr surface_window;
RegionPtr surface_window_damage;
struct xorg_list link_damage;
struct xorg_list link_window;
struct wl_callback *frame_callback;
Bool allow_commits;
struct xorg_list window_buffers_available;
struct xorg_list window_buffers_unavailable;
OsTimerPtr window_buffers_timer;
struct wl_output *wl_output;
struct wl_output *wl_output_fullscreen;
struct xorg_list xwl_output_list;
struct xorg_list frame_callback_list;
#ifdef XWL_HAS_LIBDECOR
struct libdecor_frame *libdecor_frame;
#endif
struct xwayland_surface_v1 *xwayland_surface;
struct xwl_dmabuf_feedback feedback;
/* If TRUE, the window buffer format supports scanout with implicit modifier */
Bool has_implicit_scanout_support;
struct wp_tearing_control_v1 *tearing_control;
struct wp_fractional_scale_v1 *fractional_scale;
int fractional_scale_numerator;
struct wp_linux_drm_syncobj_surface_v1 *surface_sync;
};
struct xwl_window *xwl_window_get(WindowPtr window);
RegionPtr xwl_window_get_damage_region(struct xwl_window *xwl_window);
struct xwl_window *xwl_window_from_window(WindowPtr window);
Bool is_surface_from_xwl_window(struct wl_surface *surface);
void xwl_window_update_property(struct xwl_window *xwl_window,
PropertyStateRec *propstate);
Bool xwl_window_is_toplevel(WindowPtr window);
void xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window);
void xwl_window_rootful_update_title(struct xwl_window *xwl_window);
void xwl_window_rootful_update_fullscreen(struct xwl_window *xwl_window,
struct xwl_output *xwl_output);
void xwl_window_set_window_pixmap(WindowPtr window, PixmapPtr pixmap);
void xwl_window_update_surface_window(struct xwl_window *xwl_window);
void xwl_window_leave_output(struct xwl_window *xwl_window,
struct xwl_output *xwl_output);
int xwl_window_get_max_output_scale(struct xwl_window *xwl_window);
Bool xwl_realize_window(WindowPtr window);
Bool xwl_unrealize_window(WindowPtr window);
Bool xwl_change_window_attributes(WindowPtr window, unsigned long mask);
void xwl_clip_notify(WindowPtr window, int dx, int dy);
int xwl_config_notify(WindowPtr window,
int x, int y,
int width, int height, int bw,
WindowPtr sib);
void xwl_resize_window(WindowPtr window,
int x, int y,
unsigned int width, unsigned int height,
WindowPtr sib);
void xwl_move_window(WindowPtr window,
int x, int y,
WindowPtr next_sib,
VTKind kind);
void xwl_window_destroy(CallbackListPtr *pcbl, ScreenPtr pScreen, WindowPtr window);
void xwl_window_post_damage(struct xwl_window *xwl_window);
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
void xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface);
void xwl_window_set_input_region(struct xwl_window *xwl_window, RegionPtr input_shape);
Bool xwl_window_init(void);
#endif /* XWAYLAND_WINDOW_H */

View File

@ -1,966 +0,0 @@
/*
* Copyright © 2020 Red Hat
*
* 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-config.h>
#include <errno.h>
#include <unistd.h>
#include <libgen.h>
#include <libei.h>
#include "dix/dix_priv.h"
#include "dix/input_priv.h"
#include "os/client_priv.h"
#include "os/log_priv.h"
#include <inputstr.h>
#include <inpututils.h>
#ifdef XWL_HAS_EI_PORTAL
#include "liboeffis.h"
#endif
#include "xwayland-screen.h"
#include "xwayland-xtest.h"
#define debug_ei(...) DebugF("[xwayland ei] " __VA_ARGS__)
#define error_ei(...) ErrorF("[xwayland ei] " __VA_ARGS__)
#define SCROLL_STEP 120 /* libei's definition of a logical scroll step */
static struct xorg_list clients_for_reuse;
static DevPrivateKeyRec xwl_ei_private_key;
static DevPrivateKeyRec xwl_device_data_private_key;
struct xwl_device_data {
DeviceSendEventsProc sendEventsProc;
};
struct xwl_emulated_event {
DeviceIntPtr dev;
int type;
int detail;
int flags;
ValuatorMask mask;
struct xorg_list link;
};
struct xwl_abs_device {
struct xorg_list link;
struct ei_device *device;
};
struct xwl_ei_client {
struct xorg_list link; /* in clients_for_reuse */
ClientPtr client; /* can be NULL if the X11 client is gone */
char *cmdline;
bool accept_pointer, accept_keyboard, accept_abs;
struct ei *ei;
int ei_fd;
#ifdef XWL_HAS_EI_PORTAL
struct oeffis *oeffis;
int oeffis_fd;
#endif
struct ei_seat *ei_seat;
struct ei_device *ei_pointer;
struct ei_device *ei_keyboard;
struct xorg_list abs_devices;
struct xorg_list pending_emulated_events;
OsTimerPtr disconnect_timer;
};
static void xwl_handle_ei_event(int fd, int ready, void *data);
static bool xwl_dequeue_emulated_events(struct xwl_ei_client *xwl_ei_client);
static struct xwl_device_data *
xwl_device_data_get(DeviceIntPtr dev)
{
return dixLookupPrivate(&dev->devPrivates, &xwl_device_data_private_key);
}
static struct xwl_ei_client *
get_xwl_ei_client(ClientPtr client)
{
return dixLookupPrivate(&client->devPrivates, &xwl_ei_private_key);
}
static void
xwl_queue_emulated_event(struct xwl_ei_client *xwl_ei_client, DeviceIntPtr dev,
int type, int detail, int flags, const ValuatorMask *mask)
{
struct xwl_emulated_event *xwl_emulated_event;
xwl_emulated_event = calloc(1, sizeof *xwl_emulated_event);
if (!xwl_emulated_event) {
error_ei("OOM, cannot queue event\n");
return;
}
xwl_emulated_event->dev = dev;
xwl_emulated_event->type = type;
xwl_emulated_event->detail = detail;
xwl_emulated_event->flags = flags;
valuator_mask_copy(&xwl_emulated_event->mask, mask);
xorg_list_append(&xwl_emulated_event->link,
&xwl_ei_client->pending_emulated_events);
}
static void
xwl_clear_emulated_events(struct xwl_ei_client *xwl_ei_client)
{
struct xwl_emulated_event *xwl_emulated_event, *next_xwl_emulated_event;
xorg_list_for_each_entry_safe(xwl_emulated_event, next_xwl_emulated_event,
&xwl_ei_client->pending_emulated_events, link) {
xorg_list_del(&xwl_emulated_event->link);
free(xwl_emulated_event);
}
}
static void
add_ei_device(struct xwl_ei_client *xwl_ei_client, struct ei_device *device)
{
bool used = true;
/* Note: pointers in libei are split across four capabilities:
pointer/pointer-absolute/button/scroll. We expect any decent
compositor to give pointers the button + scroll interfaces too,
if that's not the case we can look into *why* and fix this as needed.
Meanwhile, we ignore any device that doesn't have button + scroll
in addition to pointer caps.
*/
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER) &&
ei_device_has_capability(device, EI_DEVICE_CAP_BUTTON) &&
ei_device_has_capability(device, EI_DEVICE_CAP_SCROLL) &&
xwl_ei_client->ei_pointer == NULL) {
xwl_ei_client->ei_pointer = ei_device_ref(device);
used = true;
}
if (ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) &&
xwl_ei_client->ei_keyboard == NULL) {
xwl_ei_client->ei_keyboard = ei_device_ref(device);
used = true;
}
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE) &&
ei_device_has_capability(device, EI_DEVICE_CAP_BUTTON) &&
ei_device_has_capability(device, EI_DEVICE_CAP_SCROLL)) {
struct xwl_abs_device *abs = calloc(1, sizeof(*abs));
if (abs) {
xorg_list_add(&abs->link, &xwl_ei_client->abs_devices);
abs->device = ei_device_ref(device);
used = true;
}
}
if (!used)
ei_device_close(device);
}
static void
free_oeffis(struct xwl_ei_client *xwl_ei_client)
{
#ifdef XWL_HAS_EI_PORTAL
if (xwl_ei_client->oeffis) {
debug_ei("Removing OEFFIS fd=%d\n", xwl_ei_client->oeffis_fd);
if (xwl_ei_client->oeffis_fd >= 0)
RemoveNotifyFd(xwl_ei_client->oeffis_fd);
xwl_ei_client->oeffis = oeffis_unref(xwl_ei_client->oeffis);
}
#endif
}
static void
free_ei(struct xwl_ei_client *xwl_ei_client)
{
struct ei *ei = xwl_ei_client->ei;
struct xwl_abs_device *abs, *tmp;
ClientPtr client = xwl_ei_client->client;
TimerCancel(xwl_ei_client->disconnect_timer);
xorg_list_del(&xwl_ei_client->link);
debug_ei("Removing EI fd=%d\n", xwl_ei_client->ei_fd);
if (xwl_ei_client->ei_fd >= 0)
RemoveNotifyFd(xwl_ei_client->ei_fd);
ei_device_unref(xwl_ei_client->ei_pointer);
ei_device_unref(xwl_ei_client->ei_keyboard);
xorg_list_for_each_entry_safe(abs, tmp, &xwl_ei_client->abs_devices, link) {
xorg_list_del(&abs->link);
ei_device_unref(abs->device);
free(abs);
}
xwl_clear_emulated_events(xwl_ei_client);
if (client)
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, NULL);
free_oeffis(xwl_ei_client);
ei_seat_unref(xwl_ei_client->ei_seat);
ei_unref(ei);
free(xwl_ei_client->cmdline);
free(xwl_ei_client);
}
#ifdef XWL_HAS_EI_PORTAL
static void
setup_ei_from_oeffis(struct xwl_ei_client *xwl_ei_client)
{
struct oeffis *oeffis = xwl_ei_client->oeffis;
xwl_ei_client->ei_fd = oeffis_get_eis_fd(oeffis);
if (xwl_ei_client->ei_fd < 0) {
error_ei("Failed to setup EI file descriptor from oeffis\n");
return;
}
ei_setup_backend_fd(xwl_ei_client->ei, xwl_ei_client->ei_fd);
SetNotifyFd(xwl_ei_client->ei_fd, xwl_handle_ei_event,
X_NOTIFY_READ, xwl_ei_client);
}
static void
xwl_handle_oeffis_event(int fd, int ready, void *data)
{
struct xwl_ei_client *xwl_ei_client = data;
struct oeffis *oeffis = xwl_ei_client->oeffis;
enum oeffis_event_type event_type;
bool done = false;
oeffis_dispatch(oeffis);
do {
event_type = oeffis_get_event(oeffis);
switch (event_type) {
case OEFFIS_EVENT_NONE:
debug_ei("OEFFIS event none\n");
done = true;
break;
case OEFFIS_EVENT_CONNECTED_TO_EIS:
debug_ei("OEFFIS connected to EIS\n");
setup_ei_from_oeffis(xwl_ei_client);
break;
case OEFFIS_EVENT_DISCONNECTED:
debug_ei("OEFFIS disconnected: %s\n",
oeffis_get_error_message(oeffis));
xwl_dequeue_emulated_events(xwl_ei_client);
free_ei(xwl_ei_client);
done = true;
break;
case OEFFIS_EVENT_CLOSED:
debug_ei("OEFFIS closed\n");
free_ei(xwl_ei_client);
done = true;
break;
}
}
while (!done);
}
#endif
static bool
setup_oeffis(struct xwl_ei_client *xwl_ei_client)
{
#ifdef XWL_HAS_EI_PORTAL
xwl_ei_client->oeffis_fd = -1;
xwl_ei_client->oeffis = oeffis_new(NULL);
if (!xwl_ei_client->oeffis)
return false;
xwl_ei_client->oeffis_fd = oeffis_get_fd(xwl_ei_client->oeffis);
if (xwl_ei_client->oeffis_fd < 0) {
error_ei("Failed to setup OEFFIS file descriptor\n");
return false;
}
SetNotifyFd(xwl_ei_client->oeffis_fd, xwl_handle_oeffis_event,
X_NOTIFY_READ, xwl_ei_client);
oeffis_create_session(xwl_ei_client->oeffis,
OEFFIS_DEVICE_KEYBOARD | OEFFIS_DEVICE_POINTER);
return true;
#else
return false;
#endif
}
static bool
setup_ei_from_socket(struct xwl_ei_client *xwl_ei_client)
{
int rc;
rc = ei_setup_backend_socket(xwl_ei_client->ei, NULL);
if (rc != 0) {
error_ei("Setup failed: %s\n", strerror(-rc));
return false;
}
xwl_ei_client->ei_fd = ei_get_fd(xwl_ei_client->ei);
if (xwl_ei_client->ei_fd < 0) {
error_ei("Failed to setup EI file descriptor from socket\n");
return false;
}
SetNotifyFd(xwl_ei_client->ei_fd, xwl_handle_ei_event,
X_NOTIFY_READ, xwl_ei_client);
return true;
}
static struct xwl_ei_client *
setup_ei(ClientPtr client)
{
ScreenPtr pScreen = screenInfo.screens[0];
struct xwl_ei_client *xwl_ei_client = NULL;
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
struct ei *ei = NULL;
char buffer[PATH_MAX];
const char *cmdname;
char *client_name = NULL;
bool status = false;
cmdname = GetClientCmdName(client);
if (cmdname) {
snprintf(buffer, sizeof(buffer) - 1, "%s", cmdname);
client_name = basename(buffer);
}
if (!client_name) {
error_ei("Failed to retrieve the client command line name\n");
goto out;
}
xwl_ei_client = calloc(1, sizeof *xwl_ei_client);
if (!xwl_ei_client) {
error_ei("OOM, cannot setup EI\n");
goto out;
}
xwl_ei_client->cmdline = Xstrdup(cmdname);
xorg_list_init(&xwl_ei_client->link);
ei = ei_new(NULL);
ei_configure_name(ei, basename(client_name));
/* We can't send events to EIS until we have a device and the device
* is resumed.
*/
xwl_ei_client->accept_pointer = false;
xwl_ei_client->accept_keyboard = false;
xwl_ei_client->accept_abs = false;
xwl_ei_client->ei = ei;
xwl_ei_client->ei_fd = -1;
xwl_ei_client->client = client;
xorg_list_init(&xwl_ei_client->pending_emulated_events);
xorg_list_init(&xwl_ei_client->abs_devices);
if (xwl_screen->enable_ei_portal)
status = setup_oeffis(xwl_ei_client);
if (!status)
status = setup_ei_from_socket(xwl_ei_client);
if (!status) {
free(xwl_ei_client);
xwl_ei_client = NULL;
ei_unref(ei);
error_ei("EI setup failed\n");
/* We failed to setup EI using either backends, give up on EI. */
xwayland_restore_xtest();
}
out:
return xwl_ei_client;
}
static CARD32
disconnect_timer_cb(OsTimerPtr timer, CARD32 time, void *arg)
{
struct xwl_ei_client *xwl_ei_client = arg;
free_ei(xwl_ei_client);
return 0;
}
static void
xwl_ei_start_emulating(struct xwl_ei_client *xwl_ei_client)
{
static uint32_t sequence = 0;
struct xwl_abs_device *abs;
sequence++;
if (xwl_ei_client->ei_pointer)
ei_device_start_emulating(xwl_ei_client->ei_pointer, sequence);
if (xwl_ei_client->ei_keyboard)
ei_device_start_emulating(xwl_ei_client->ei_keyboard, sequence);
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
ei_device_start_emulating(abs->device, sequence);
}
}
static void
xwl_ei_stop_emulating(struct xwl_ei_client *xwl_ei_client)
{
struct xwl_abs_device *abs;
if (xwl_ei_client->ei_pointer)
ei_device_stop_emulating(xwl_ei_client->ei_pointer);
if (xwl_ei_client->ei_keyboard)
ei_device_stop_emulating(xwl_ei_client->ei_keyboard);
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
ei_device_stop_emulating(abs->device);
}
}
static void
xwl_ei_handle_client_gone(struct xwl_ei_client *xwl_ei_client)
{
ClientPtr client = xwl_ei_client->client;
/* Make this EI client struct re-usable. xdotool only exists for a
* fraction of a second, so let's make it re-use the same client every
* time - this makes it easier to e.g. pause it */
xorg_list_add(&xwl_ei_client->link, &clients_for_reuse);
if (xorg_list_is_empty(&xwl_ei_client->pending_emulated_events))
xwl_ei_stop_emulating(xwl_ei_client);
debug_ei("Client %s is now reusable\n", xwl_ei_client->cmdline);
/* Otherwise, we keep the EI part but break up with the X11 client */
assert(client);
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, NULL);
xwl_ei_client->client = NULL;
/* Set a timer for 10 minutes. If the same client doesn't reconnect,
* free it properly */
xwl_ei_client->disconnect_timer =
TimerSet(xwl_ei_client->disconnect_timer, 0,
10 * 60 * 1000, disconnect_timer_cb, xwl_ei_client);
}
static void
xwl_ei_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr client = clientinfo->client;
struct xwl_ei_client *xwl_ei_client = get_xwl_ei_client(client);
switch (client->clientState) {
case ClientStateGone:
case ClientStateRetained:
if (xwl_ei_client)
xwl_ei_handle_client_gone(xwl_ei_client);
break;
default:
break;
}
}
static inline unsigned int
buttonmap(unsigned int b)
{
unsigned int button;
switch (b) {
case 0:
button = 0;
break;
case 1:
button = 0x110; /* BTN_LEFT */
break;
case 2:
button = 0x112; /* BTN_MIDDLE */
break;
case 3:
button = 0x111; /* BTN_RIGHT */
break;
default:
button = b - 8 + 0x113; /* BTN_SIDE */
break;
}
return button;
}
static void
xwl_send_abs_event_to_ei(struct xwl_ei_client *xwl_ei_client, int sx, int sy)
{
struct xwl_abs_device *abs;
struct ei *ei = xwl_ei_client->ei;
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
struct ei_region *r;
size_t idx = 0;
while ((r = ei_device_get_region(abs->device, idx++))) {
double x = sx, y = sy;
if (ei_region_contains(r, x, y)) {
ei_device_pointer_motion_absolute(abs->device, sx, sy);
ei_device_frame(abs->device, ei_now(ei));
return;
}
}
}
}
static bool
xwl_send_event_to_ei(struct xwl_ei_client *xwl_ei_client,
int type, int detail, int flags, const ValuatorMask *mask)
{
struct ei *ei = xwl_ei_client->ei;
struct ei_device *ei_device = NULL;
int x = 0, y = 0;
debug_ei("Sending event type %d to EIS\n", type);
switch (type) {
case MotionNotify:
valuator_mask_fetch(mask, 0, &x);
valuator_mask_fetch(mask, 1, &y);
if (flags & POINTER_ABSOLUTE) {
if (!xwl_ei_client->accept_abs)
return false;
xwl_send_abs_event_to_ei(xwl_ei_client, x, y);
}
else if (x || y) {
if (!xwl_ei_client->accept_pointer)
return false;
ei_device = xwl_ei_client->ei_pointer;
ei_device_pointer_motion(ei_device, x, y);
ei_device_frame(ei_device, ei_now(ei));
}
break;
case ButtonPress:
case ButtonRelease:
if (!xwl_ei_client->accept_pointer)
return false;
ei_device = xwl_ei_client->ei_pointer;
if (detail < 4 || detail > 7) {
ei_device_button_button(ei_device,
buttonmap(detail), type == ButtonPress);
ei_device_frame(ei_device, ei_now(ei));
/* Scroll only on release */
} else if (type == ButtonRelease) {
if (detail == 4) {
ei_device_scroll_discrete(ei_device, 0, -SCROLL_STEP);
} else if (detail == 5) {
ei_device_scroll_discrete(ei_device, 0, SCROLL_STEP);
} else if (detail == 6) {
ei_device_scroll_discrete(ei_device, -SCROLL_STEP, 0);
} else if (detail == 7) {
ei_device_scroll_discrete(ei_device, SCROLL_STEP, 0);
}
ei_device_frame(ei_device, ei_now(ei));
}
break;
case KeyPress:
case KeyRelease:
if (!xwl_ei_client->accept_keyboard)
return false;
ei_device = xwl_ei_client->ei_keyboard;
ei_device_keyboard_key(ei_device, detail - 8, type == KeyPress);
ei_device_frame(ei_device, ei_now(ei));
break;
default:
error_ei("XTEST event type %d is not implemented\n", type);
break;
}
return true;
}
static struct xwl_ei_client *
reuse_client(ClientPtr client)
{
struct xwl_ei_client *xwl_ei_client = NULL;
const char *cmdname = GetClientCmdName(client);
if (!cmdname)
return NULL;
debug_ei("Client maybe up for re-use: %s\n", cmdname);
xorg_list_for_each_entry(xwl_ei_client, &clients_for_reuse, link) {
debug_ei("Checking if we can re-use %s\n", xwl_ei_client->cmdline);
if (xwl_ei_client->cmdline &&
strcmp(xwl_ei_client->cmdline, cmdname) == 0) {
debug_ei("Re-using client for %s\n", cmdname);
xorg_list_del(&xwl_ei_client->link);
xorg_list_init(&xwl_ei_client->link);
TimerCancel(xwl_ei_client->disconnect_timer);
xwl_ei_start_emulating(xwl_ei_client);
return xwl_ei_client;
}
}
return NULL;
}
static void
xwayland_xtest_fallback(DeviceIntPtr dev,
int type, int detail, int flags, const ValuatorMask *mask)
{
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
if (xwl_device_data->sendEventsProc != NULL) {
debug_ei("EI failed, using XTEST as fallback for sending events\n");
(xwl_device_data->sendEventsProc)(dev, type, detail, flags, mask);
}
}
static void
xwayland_xtest_send_events(DeviceIntPtr dev,
int type, int detail, int flags, const ValuatorMask *mask)
{
ClientPtr client;
struct xwl_ei_client *xwl_ei_client;
bool accept = false;
if (!IsXTestDevice(dev, NULL))
return;
client = GetCurrentClient();
xwl_ei_client = get_xwl_ei_client(client);
if (!xwl_ei_client) {
xwl_ei_client = reuse_client(client);
if (xwl_ei_client)
xwl_ei_client->client = client;
}
if (!xwl_ei_client) {
if (!(xwl_ei_client = setup_ei(client))) {
xwayland_xtest_fallback(dev, type, detail, flags, mask);
return;
}
}
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, xwl_ei_client);
switch (type) {
case MotionNotify:
if (flags & POINTER_ABSOLUTE)
accept = xwl_ei_client->accept_abs;
else
accept = xwl_ei_client->accept_pointer;
break;
case ButtonPress:
case ButtonRelease:
accept = xwl_ei_client->accept_pointer;
break;
case KeyPress:
case KeyRelease:
accept = xwl_ei_client->accept_keyboard;
break;
default:
return;
}
if (accept) {
xwl_send_event_to_ei(xwl_ei_client, type, detail, flags, mask);
}
else {
debug_ei("Not yet connected to EIS, queueing events\n");
xwl_queue_emulated_event(xwl_ei_client, dev, type, detail, flags, mask);
}
}
static bool
xwl_dequeue_emulated_events(struct xwl_ei_client *xwl_ei_client)
{
struct xwl_emulated_event *xwl_emulated_event, *next_xwl_emulated_event;
bool sent;
xorg_list_for_each_entry_safe(xwl_emulated_event, next_xwl_emulated_event,
&xwl_ei_client->pending_emulated_events, link) {
sent = xwl_send_event_to_ei(xwl_ei_client,
xwl_emulated_event->type,
xwl_emulated_event->detail,
xwl_emulated_event->flags,
&xwl_emulated_event->mask);
if (!sent)
xwayland_xtest_fallback(xwl_emulated_event->dev,
xwl_emulated_event->type,
xwl_emulated_event->detail,
xwl_emulated_event->flags,
&xwl_emulated_event->mask);
xorg_list_del(&xwl_emulated_event->link);
free(xwl_emulated_event);
}
return true;
}
static void
xwl_ei_update_caps(struct xwl_ei_client *xwl_ei_client,
struct ei_device *ei_device)
{
struct xwl_abs_device *abs;
if (ei_device == xwl_ei_client->ei_pointer)
xwl_ei_client->accept_pointer = true;
if (ei_device == xwl_ei_client->ei_keyboard)
xwl_ei_client->accept_keyboard = true;
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
if (ei_device == abs->device)
xwl_ei_client->accept_abs = true;
}
}
static bool
xwl_ei_devices_are_ready(struct xwl_ei_client *xwl_ei_client)
{
if ((xwl_ei_client->accept_keyboard ||
!ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_KEYBOARD)) &&
(xwl_ei_client->accept_pointer ||
!ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_POINTER)) &&
(xwl_ei_client->accept_abs ||
!ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_POINTER_ABSOLUTE)))
return true;
return false;
}
static void
xwl_handle_ei_event(int fd, int ready, void *data)
{
struct xwl_ei_client *xwl_ei_client = data;
struct ei *ei;
bool done = false;
ei = xwl_ei_client->ei;
ei_dispatch(ei);
do {
enum ei_event_type type;
struct ei_event *e = ei_get_event(ei);
struct ei_device *ei_device;
if (!e)
break;
ei_device = ei_event_get_device(e);
type = ei_event_get_type(e);
switch (type) {
case EI_EVENT_CONNECT:
debug_ei("Connected\n");
break;
case EI_EVENT_SEAT_ADDED:
/* We take the first seat that comes along and
* add our device there */
if (!xwl_ei_client->ei_seat) {
struct ei_seat *seat = ei_event_get_seat(e);
xwl_ei_client->ei_seat = ei_seat_ref(seat);
debug_ei("Using seat: %s (caps: %s%s%s%s%s)\n",
ei_seat_get_name(seat), ei_seat_has_capability(seat,
EI_DEVICE_CAP_KEYBOARD) ? "k" : "",
ei_seat_has_capability(seat,
EI_DEVICE_CAP_POINTER) ? "p" : "",
ei_seat_has_capability(seat,
EI_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "",
ei_seat_has_capability(seat,
EI_DEVICE_CAP_BUTTON) ? "b" : "",
ei_seat_has_capability(seat,
EI_DEVICE_CAP_SCROLL) ? "s" : "");
ei_seat_bind_capabilities(seat,
EI_DEVICE_CAP_POINTER,
EI_DEVICE_CAP_POINTER_ABSOLUTE,
EI_DEVICE_CAP_BUTTON,
EI_DEVICE_CAP_SCROLL,
EI_DEVICE_CAP_KEYBOARD, NULL);
}
break;
case EI_EVENT_SEAT_REMOVED:
if (ei_event_get_seat(e) == xwl_ei_client->ei_seat) {
debug_ei("Seat was removed\n");
xwl_ei_client->ei_seat =
ei_seat_unref(xwl_ei_client->ei_seat);
}
break;
case EI_EVENT_DEVICE_ADDED:
debug_ei("New device: %s\n", ei_device_get_name(ei_device));
add_ei_device(xwl_ei_client, ei_device);
break;
case EI_EVENT_DEVICE_REMOVED:
debug_ei("Device removed: %s\n", ei_device_get_name(ei_device));
{
struct xwl_abs_device *abs, *tmp;
xorg_list_for_each_entry_safe(abs, tmp,
&xwl_ei_client->abs_devices, link) {
if (abs->device != ei_device)
continue;
ei_device_unref(abs->device);
xorg_list_del(&abs->link);
free(abs);
}
}
if (xwl_ei_client->ei_pointer == ei_device)
xwl_ei_client->ei_pointer =
ei_device_unref(xwl_ei_client->ei_pointer);
if (xwl_ei_client->ei_keyboard == ei_device)
xwl_ei_client->ei_keyboard =
ei_device_unref(xwl_ei_client->ei_keyboard);
break;
case EI_EVENT_DISCONNECT:
debug_ei("Disconnected\n");
free_ei(xwl_ei_client);
done = true;
break;
case EI_EVENT_DEVICE_PAUSED:
debug_ei("Device paused\n");
if (ei_device == xwl_ei_client->ei_pointer)
xwl_ei_client->accept_pointer = false;
if (ei_device == xwl_ei_client->ei_keyboard)
xwl_ei_client->accept_keyboard = false;
{
struct xwl_abs_device *abs;
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices,
link) {
if (ei_device == abs->device)
xwl_ei_client->accept_abs = false;
}
}
break;
case EI_EVENT_DEVICE_RESUMED:
debug_ei("Device resumed\n");
xwl_ei_update_caps(xwl_ei_client, ei_device);
/* Server has accepted our device (or resumed them),
* we can now start sending events */
/* FIXME: Maybe add a timestamp and discard old events? */
if (xwl_ei_devices_are_ready(xwl_ei_client)) {
xwl_ei_start_emulating(xwl_ei_client);
xwl_dequeue_emulated_events(xwl_ei_client);
}
if (!xwl_ei_client->client &&
xorg_list_is_empty(&xwl_ei_client->pending_emulated_events))
/* All events dequeued and client has disconnected in the meantime */
xwl_ei_stop_emulating(xwl_ei_client);
break;
case EI_EVENT_KEYBOARD_MODIFIERS:
debug_ei("Ignored event %s (%d)\n", ei_event_type_to_string(type), type);
/* Don't care */
break;
default:
error_ei("Unhandled event %s (%d)\n", ei_event_type_to_string(type), type);
break;
}
ei_event_unref(e);
} while (!done);
}
Bool
xwayland_ei_init(void)
{
xorg_list_init(&clients_for_reuse);
if (!dixRegisterPrivateKey(&xwl_ei_private_key, PRIVATE_CLIENT, 0)) {
ErrorF("Failed to register EI private key\n");
return FALSE;
}
if (!AddCallback(&ClientStateCallback, xwl_ei_state_client_callback, NULL)) {
ErrorF("Failed to add client state callback\n");
return FALSE;
}
if (!dixRegisterPrivateKey(&xwl_device_data_private_key, PRIVATE_DEVICE,
sizeof(struct xwl_device_data))) {
ErrorF("Failed to register private key for XTEST override\n");
return FALSE;
}
return TRUE;
}
static void
xwayland_override_events_proc(DeviceIntPtr dev)
{
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
if (xwl_device_data->sendEventsProc != NULL)
return;
/* Save original sendEventsProc handler in case */
xwl_device_data->sendEventsProc = dev->sendEventsProc;
/* Set up our own sendEventsProc to forward events to EI */
debug_ei("Overriding XTEST for %s\n", dev->name);
dev->sendEventsProc = xwayland_xtest_send_events;
}
static void
xwayland_restore_events_proc(DeviceIntPtr dev)
{
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
if (xwl_device_data->sendEventsProc == NULL)
return;
/* Restore original sendEventsProc handler */
debug_ei("Restoring XTEST for %s\n", dev->name);
dev->sendEventsProc = xwl_device_data->sendEventsProc;
xwl_device_data->sendEventsProc = NULL;
}
void
xwayland_override_xtest(void)
{
DeviceIntPtr d;
nt_list_for_each_entry(d, inputInfo.devices, next) {
xwayland_override_events_proc(d);
}
}
void
xwayland_restore_xtest(void)
{
DeviceIntPtr d;
nt_list_for_each_entry(d, inputInfo.devices, next) {
xwayland_restore_events_proc(d);
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright © 2020 Red Hat
*
* 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.
*/
#ifndef XWAYLAND_XTEST_H
#define XWAYLAND_XTEST_H
#include <xwayland-config.h>
Bool xwayland_ei_init(void);
void xwayland_override_xtest(void);
void xwayland_restore_xtest(void);
#endif

View File

@ -1,476 +0,0 @@
/*
* 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-config.h>
#if !defined(WIN32)
#include <sys/resource.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <X11/Xatom.h>
#include <X11/Xfuncproto.h>
#include "dix/dix_priv.h"
#include "dix/screenint_priv.h"
#include "dix/selection_priv.h"
#include "os/auth.h"
#include "os/cmdline.h"
#include "os/client_priv.h"
#include "os/ddx_priv.h"
#include "os/fmt.h"
#include "os/log_priv.h"
#include "os/osdep.h"
#include "os/xserver_poll.h"
#include <micmap.h>
#include <misyncshm.h>
#include <compositeext.h>
#include <compint.h>
#include <glx_extinit.h>
#include <opaque.h>
#include <os.h>
#include <propertyst.h>
#include <version-config.h>
#include "extinit.h"
#include "xwayland-screen.h"
#include "xwayland-vidmode.h"
#ifdef XF86VIDMODE
#include <X11/extensions/xf86vmproto.h>
Bool noXFree86VidModeExtension = FALSE;
#endif
void
ddxGiveUp(enum ExitCode 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
#if INPUTTHREAD
/** This function is called in Xserver/os/inputthread.c when starting
the input thread. */
void
ddxInputThreadInit(void)
{
}
#endif
void
ddxUseMsg(void)
{
ErrorF("-rootless run rootless, requires wm support\n");
ErrorF("-fullscreen run fullscreen when rootful\n");
ErrorF("-geometry WxH set Xwayland window size when rootful\n");
ErrorF("-hidpi adjust to output scale when rootful\n");
ErrorF("-host-grab disable host keyboard shortcuts when rootful\n");
ErrorF("-nokeymap ignore keymap from the Wayland compositor\n");
ErrorF("-output specify which output to use for fullscreen when rootful\n");
ErrorF("-wm fd create X client for wm on given fd\n");
ErrorF("-initfd fd add given fd as a listen socket for initialization clients\n");
ErrorF("-listenfd fd add given fd as a listen socket\n");
ErrorF("-listen fd deprecated, use \"-listenfd\" instead\n");
ErrorF("-shm use shared memory for passing buffers\n");
#ifdef XWL_HAS_GLAMOR
ErrorF("-glamor [gl|es|off] use given API for Glamor acceleration. Incompatible with -shm option\n");
#endif
ErrorF("-verbose [n] verbose startup messages\n");
ErrorF("-version show the server version and exit\n");
ErrorF("-noTouchPointerEmulation disable touch pointer emulation\n");
ErrorF("-force-xrandr-emulation force non-native modes to be exposed when viewporter is not exposed by the compositor\n");
#ifdef XWL_HAS_LIBDECOR
ErrorF("-decorate add decorations to Xwayland when rootful\n");
#endif
#ifdef XWL_HAS_EI_PORTAL
ErrorF("-enable-ei-portal use the XDG portal for input emulation\n");
#endif
}
static int init_fd = -1;
static int wm_fd = -1;
static int listen_fds[5] = { -1, -1, -1, -1, -1 };
static int listen_fd_count = 0;
static int verbosity = 0;
static void
xwl_show_version(void)
{
ErrorF("%s Xwayland %s (%d)\n", VENDOR_NAME, VENDOR_MAN_VERSION, VENDOR_RELEASE);
ErrorF("X Protocol Version %d, Revision %d\n", X_PROTOCOL, X_PROTOCOL_REVISION);
#if defined(BUILDERSTRING)
if (strlen(BUILDERSTRING))
ErrorF("%s\n", BUILDERSTRING);
#endif
}
static void
try_raising_nofile_limit(void)
{
#ifdef RLIMIT_NOFILE
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
ErrorF("Failed to get the current nofile limit: %s\n", strerror(errno));
return;
}
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
ErrorF("Failed to set the current nofile limit: %s\n", strerror(errno));
return;
}
LogMessageVerb(X_INFO, 3, "Raising the file descriptors limit to %llu\n",
(long long unsigned int) rlim.rlim_max);
#endif /* RLIMIT_NOFILE */
}
static void
xwl_add_listen_fd(int argc, char *argv[], int i)
{
NoListenAll = TRUE;
if (listen_fd_count == ARRAY_SIZE(listen_fds))
FatalError("Too many -listen arguments given, max is %zu\n",
ARRAY_SIZE(listen_fds));
listen_fds[listen_fd_count++] = atoi(argv[i + 1]);
}
int
ddxProcessArgument(int argc, char *argv[], int i)
{
if (strcmp(argv[i], "-rootless") == 0) {
return 1;
}
else if (strcmp(argv[i], "-listen") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
/* Not an FD */
if (!isdigit(*argv[i + 1]))
return 0;
LogMessageVerb(X_WARNING, 0, "Option \"-listen\" for file descriptors is deprecated\n"
"Please use \"-listenfd\" instead.\n");
xwl_add_listen_fd (argc, argv, i);
return 2;
}
else if (strcmp(argv[i], "-listenfd") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
xwl_add_listen_fd (argc, argv, i);
return 2;
}
else if (strcmp(argv[i], "-wm") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
wm_fd = atoi(argv[i + 1]);
return 2;
}
else if (strcmp(argv[i], "-initfd") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
init_fd = atoi(argv[i + 1]);
return 2;
}
else if (strcmp(argv[i], "-shm") == 0) {
return 1;
}
#ifdef XWL_HAS_GLAMOR
else if (strcmp(argv[i], "-glamor") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
/* Only check here, actual work inside xwayland-screen.c */
return 2;
}
#endif
else if (strcmp(argv[i], "-verbose") == 0) {
if (++i < argc && argv[i]) {
char *end;
long val;
val = strtol(argv[i], &end, 0);
if (*end == '\0') {
verbosity = val;
xorgLogVerbosity = verbosity;
return 2;
}
}
xorgLogVerbosity = ++verbosity;
return 1;
}
else if (strcmp(argv[i], "-version") == 0) {
xwl_show_version();
exit(0);
}
else if (strcmp(argv[i], "-noTouchPointerEmulation") == 0) {
touchEmulatePointer = FALSE;
return 1;
}
else if (strcmp(argv[i], "-force-xrandr-emulation") == 0) {
return 1;
}
else if (strcmp(argv[i], "-geometry") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
return 2;
}
else if (strcmp(argv[i], "-fullscreen") == 0) {
return 1;
}
else if (strcmp(argv[i], "-host-grab") == 0) {
return 1;
}
else if (strcmp(argv[i], "-decorate") == 0) {
return 1;
}
else if (strcmp(argv[i], "-enable-ei-portal") == 0) {
return 1;
}
else if (strcmp(argv[i], "-output") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
return 2;
}
else if (strcmp(argv[i], "-nokeymap") == 0) {
return 1;
}
else if (strcmp(argv[i], "-hidpi") == 0) {
return 1;
}
return 0;
}
static CARD32
add_client_fd(OsTimerPtr timer, CARD32 time, void *arg)
{
if (!AddClientOnOpenFD(wm_fd))
FatalError("Failed to add wm client\n");
TimerFree(timer);
return 0;
}
static void
listen_on_fds(void)
{
int i;
for (i = 0; i < listen_fd_count; i++)
ListenOnOpenFD(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();
DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
}
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);
ErrorF("XWAYLAND: %s", msg);
}
#ifdef XWL_HAS_XWAYLAND_EXTENSION
#include <X11/extensions/xwaylandproto.h>
Bool noXwaylandExtension = FALSE;
static int
ProcXwlQueryVersion(ClientPtr client)
{
xXwlQueryVersionReply reply;
int major, minor;
REQUEST(xXwlQueryVersionReq);
REQUEST_SIZE_MATCH(xXwlQueryVersionReq);
if (version_compare(stuff->majorVersion, stuff->minorVersion,
XWAYLAND_EXTENSION_MAJOR,
XWAYLAND_EXTENSION_MINOR) < 0) {
major = stuff->majorVersion;
minor = stuff->minorVersion;
} else {
major = XWAYLAND_EXTENSION_MAJOR;
minor = XWAYLAND_EXTENSION_MINOR;
}
reply = (xXwlQueryVersionReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.majorVersion = major,
.minorVersion = minor,
};
if (client->swapped) {
swaps(&reply.sequenceNumber);
swapl(&reply.length);
swaps(&reply.majorVersion);
swaps(&reply.minorVersion);
}
WriteToClient(client, sizeof(reply), &reply);
return Success;
}
static int _X_COLD
SProcXwlQueryVersion(ClientPtr client)
{
REQUEST(xXwlQueryVersionReq);
REQUEST_AT_LEAST_SIZE(xXwlQueryVersionReq);
swaps(&stuff->majorVersion);
swaps(&stuff->minorVersion);
return ProcXwlQueryVersion(client);
}
static int
ProcXwaylandDispatch(ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data) {
case X_XwlQueryVersion:
return ProcXwlQueryVersion(client);
}
return BadRequest;
}
static int
SProcXwaylandDispatch(ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data) {
case X_XwlQueryVersion:
return SProcXwlQueryVersion(client);
}
return BadRequest;
}
static void
xwlExtensionInit(void)
{
AddExtension(XWAYLAND_EXTENSION_NAME,
XwlNumberEvents, XwlNumberErrors,
ProcXwaylandDispatch, SProcXwaylandDispatch,
NULL, StandardMinorOpcode);
}
#endif
static const ExtensionModule xwayland_extensions[] = {
#ifdef XF86VIDMODE
{ xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension },
#endif
#ifdef XWL_HAS_XWAYLAND_EXTENSION
{ xwlExtensionInit, XWAYLAND_EXTENSION_NAME, &noXwaylandExtension },
#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);
if (serverGeneration == 1) {
try_raising_nofile_limit();
LoadExtensionList(xwayland_extensions,
ARRAY_SIZE(xwayland_extensions), FALSE);
}
wl_log_set_handler_client(xwl_log_handler);
if (AddScreen(xwl_screen_init, argc, argv) == -1) {
FatalError("Couldn't add screen\n");
}
xorgGlxCreateVendor();
LocalAccessScopeUser();
if (wm_fd >= 0 || init_fd >= 0) {
if (wm_fd >= 0)
TimerSet(NULL, 0, 1, add_client_fd, NULL);
if (init_fd >= 0)
ListenOnOpenFD(init_fd, FALSE);
AddCallback(&SelectionCallback, wm_selection_callback, NULL);
}
else if (listen_fd_count > 0) {
listen_on_fds();
}
}

View File

@ -404,19 +404,6 @@ configure_file(output : 'xwin-config.h',
input : 'xwin-config.h.meson.in',
configuration : xwin_data)
build_xwayland_glamor = build_glamor and gbm_dep.found()
xwayland_data = configuration_data()
xwayland_data.set('XWL_HAS_GLAMOR', build_xwayland_glamor ? '1' : false)
xwayland_data.set('XWL_HAS_LIBDECOR', have_libdecor ? '1' : false)
xwayland_data.set('XWL_HAS_XWAYLAND_EXTENSION', xwaylandproto_dep.found() ? '1' : false)
xwayland_data.set('XWL_HAS_EI', build_ei)
xwayland_data.set('XWL_HAS_EI_PORTAL', build_ei_portal)
configure_file(output : 'xwayland-config.h',
input : 'xwayland-config.h.meson.in',
configuration : xwayland_data)
dtrace_hdr = []
dtrace_tmpl = files('Xserver.d')
if with_dtrace

View File

@ -1,20 +0,0 @@
/* xwayland-config.h.meson.in: not at all generated */
#pragma once
#include <dix-config.h>
/* Build glamor support for Xwayland */
#mesondefine XWL_HAS_GLAMOR
/* Build Xwayland with libdecor support*/
#mesondefine XWL_HAS_LIBDECOR
/* Build Xwayland with XWAYLAND extension */
#mesondefine XWL_HAS_XWAYLAND_EXTENSION
/* Enable EI */
#mesondefine XWL_HAS_EI
/* Enable XDG portal integration */
#mesondefine XWL_HAS_EI_PORTAL

View File

@ -638,7 +638,6 @@ Controlling the server once started:
.PP
Server-specific man pages:
.BR Xorg (1),
.BR Xwayland (1),
.BR Xephyr (1),
.BR Xnest (1),
.BR Xvfb (1),

View File

@ -66,8 +66,6 @@ libdrm_req = '>= 2.4.116'
libselinux_req = '>= 2.0.86'
xext_req = '>= 1.0.99.4'
xproto_req = '>= 7.0.31'
wayland_req = '>= 1.21.0'
wayland_protocols_req = '>= 1.38'
gbm_req = '>= 10.2'
xf86dgaproto_req = '>= 2.0.99.1'
xshmfence_req = '>= 1.1'
@ -100,7 +98,6 @@ xf86bigfontproto_dep = dependency('xf86bigfontproto', version: '>= 1.2.0', fallb
xf86vidmodeproto_dep = dependency('xf86vidmodeproto', version: '>= 2.2.99.1', fallback: ['xorgproto', 'ext_xorgproto'])
applewmproto_dep = dependency('applewmproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'], required: false)
xshmfence_dep = dependency('xshmfence', version: xshmfence_req, required: false)
xwaylandproto_dep = dependency('xwaylandproto', version: '>= 1.0', fallback: ['xorgproto', 'ext_xorgproto'], required: false)
dpmsproto_dep = dependency('dpmsproto', version: '>= 1.2', required: get_option('dpms'))
pixman_dep = dependency('pixman-1')
@ -214,38 +211,6 @@ endif
xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg')
libxcvt_dep = dependency('libxcvt', fallback: ['libxcvt', 'libxcvt_dep'], required: build_xorg)
build_xwayland = false
if (host_machine.system() != 'darwin' and
host_machine.system() != 'windows' and
get_option('xwayland') != 'false')
xwayland_required = get_option('xwayland') == 'true'
build_glamor = glamor_option == 'true' or glamor_option == 'auto'
xwayland_path = get_option('xwayland-path')
if (xwayland_path == '')
xwayland_path = join_paths(get_option('prefix'), get_option('bindir'))
endif
xwayland_dep = [
dependency('wayland-client', version: wayland_req, required: xwayland_required),
dependency('wayland-protocols', version: wayland_protocols_req, required: xwayland_required),
dependency('libxcvt', fallback: ['libxcvt', 'libxcvt_dep'], required: xwayland_required),
]
if build_glamor
xwayland_dep += dependency('xshmfence', version: xshmfence_req, required: xwayland_required)
xwayland_dep += dependency('libdrm', version: libdrm_req, required: xwayland_required)
xwayland_dep += dependency('epoxy', required: xwayland_required)
endif
build_xwayland = true
# check for all the deps being found, to handle 'auto' mode.
foreach d: xwayland_dep
if not d.found()
build_xwayland = false
endif
endforeach
endif
## configure Xnest - nesting X server
build_xnest = get_option('xnest') != 'false'
@ -277,7 +242,6 @@ build_xvfb = get_option('xvfb')
summary({
'Xorg': build_xorg,
'Xwayland': build_xwayland,
'Xnest': build_xnest,
'Xvfb': build_xvfb,
'Xwin': build_xwin,
@ -350,7 +314,7 @@ endif
module_dir = join_paths(get_option('libdir'), get_option('module_dir'))
if glamor_option == 'auto'
build_glamor = build_xorg or build_xwayland
build_glamor = build_xorg
else
build_glamor = glamor_option == 'true'
endif
@ -362,32 +326,6 @@ if build_glamor
epoxy_dep = dependency('epoxy', required: false)
endif
if build_xwayland
libdecor_dep = dependency('libdecor-0', required: false)
libdecor_option = get_option('libdecor')
if libdecor_option == 'auto'
have_libdecor = libdecor_dep.found()
else
have_libdecor = libdecor_option == 'true'
if have_libdecor and not libdecor_dep.found()
error('libdecor support requested but not found')
endif
endif
else
have_libdecor = false
endif
if build_xwayland
libei_dep = dependency('libei-1.0', version: '>= 1.0.0', required: get_option('xwayland_ei') in ['portal', 'socket'])
liboeffis_dep = dependency('liboeffis-1.0', version: '>= 1.0.0', required: get_option('xwayland_ei') == 'portal')
build_ei = libei_dep.found() and get_option('xwayland_ei') != 'false'
build_ei_portal = liboeffis_dep.found() and get_option('xwayland_ei') in ['portal', 'auto']
else
build_ei = false
build_ei_portal = false
endif
# Lots of sha1 options, because Linux is about choice :)
# The idea behind the ordering here is that we should first prefer system

View File

@ -2,12 +2,8 @@ option('xorg', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable Xorg X Server')
option('xephyr', type: 'boolean', value: false,
description: 'Enable Xephyr nested X server')
option('xwayland', type: 'combo', choices: ['true', 'false', 'auto'], value: 'false',
description: 'Enable Xwayland X server')
option('glamor', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable glamor (default yes for Xorg/Xwayland builds)')
option('xwayland_ei', type: 'combo', choices: ['socket', 'portal', 'false', 'auto'],
value: 'auto', description: 'Enable emulated input support on Xwayland')
description: 'Enable glamor (default yes for Xorg builds)')
option('xnest', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable Xnest nested X server')
option('xvfb', type: 'boolean', value: true,
@ -141,10 +137,6 @@ option('xpbproxy', type: 'boolean', value: false,
option('libunwind', type: 'boolean', value: false,
description: 'Use libunwind for backtrace reporting')
option('xwayland-path', type: 'string', description: 'Directory containing Xwayland executable')
option('libdecor', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Whether Xwayland should use libdecor when running rootful.')
option('docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Build documentation')
option('devel-docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',

View File

@ -10,7 +10,7 @@ hdrs_miext_sync = [
'misyncstr.h',
]
if build_dri3 or build_xwayland
if build_dri3
srcs_miext_sync += 'misyncshm.c'
endif

View File

@ -149,19 +149,6 @@ if get_option('xvfb')
endif
endif
if build_xwayland
xwayland_args = [
xwayland_server.full_path(),
]
test('XTS',
find_program('scripts/xwayland-piglit.sh'),
env: piglit_env,
timeout: 1200,
suite: 'xwayland'
)
endif
subdir('bigreq')
subdir('damage')
subdir('sync')

View File

@ -1,62 +0,0 @@
#!/bin/bash -e
if test "x$XTEST_DIR" = "x"; then
echo "XTEST_DIR must be set to the directory of the xtest repository."
# Exit as a "skip" so make check works even without xtest.
exit 77
fi
if test "x$PIGLIT_DIR" = "x"; then
echo "PIGLIT_DIR must be set to the directory of the piglit repository."
# Exit as a "skip" so make check works even without piglit.
exit 77
fi
# this times out on Travis, because the tests take too long.
if test "x$TRAVIS_BUILD_DIR" != "x"; then
exit 77
fi
# Weston requires XDG_RUNTIME_DIR
if test "x$XDG_RUNTIME_DIR" = "x"; then
export XDG_RUNTIME_DIR=$(mktemp -d)
fi
# Skip if weston isn't available
weston --version >/dev/null || exit 77
weston --no-config --backend=headless-backend.so --socket=wayland-$$ &
WESTON_PID=$!
export WAYLAND_DISPLAY=wayland-$$
# Need to kill weston before exiting, or meson will time out waiting for it to terminate
# We rely on bash's behaviour, which executes the EXIT trap handler even if the shell is
# terminated due to receiving a signal
trap 'kill $WESTON_PID' EXIT
# Wait for weston to initialize before starting Xwayland
if ! timeout 5s bash -c "while ! $XSERVER_BUILDDIR/hw/xwayland/Xwayland -pogo -displayfd 1 &>/dev/null; do sleep 1; done"; then
# Try running Xwayland one more time, so we can propagate its stdout/stderr
# output and exit status
$XSERVER_BUILDDIR/hw/xwayland/Xwayland -pogo -displayfd 1
fi
# Start an Xwayland server
export PIGLIT_RESULTS_DIR=$XSERVER_BUILDDIR/test/piglit-results/xwayland
export SERVER_COMMAND="$XSERVER_BUILDDIR/hw/xwayland/Xwayland -noreset"
# Make sure glamor doesn't use HW acceleration
export GBM_ALWAYS_SOFTWARE=1
# Tests that currently fail on llvmpipe on CI
PIGLIT_ARGS="$PIGLIT_ARGS -x xcleararea@6"
PIGLIT_ARGS="$PIGLIT_ARGS -x xcleararea@7"
PIGLIT_ARGS="$PIGLIT_ARGS -x xclearwindow@4"
PIGLIT_ARGS="$PIGLIT_ARGS -x xclearwindow@5"
PIGLIT_ARGS="$PIGLIT_ARGS -x xcopyarea@1"
PIGLIT_ARGS="$PIGLIT_ARGS -x xsetfontpath@1"
PIGLIT_ARGS="$PIGLIT_ARGS -x xsetfontpath@2"
export PIGLIT_ARGS
$XSERVER_DIR/test/scripts/run-piglit.sh