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:
parent
d042e5a667
commit
c8b81fdbc5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -18,10 +18,6 @@ if build_xquartz
|
|||
subdir('xquartz')
|
||||
endif
|
||||
|
||||
if build_xwayland
|
||||
subdir('xwayland')
|
||||
endif
|
||||
|
||||
if build_xwin
|
||||
subdir('xwin')
|
||||
endif
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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@)
|
|
@ -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,
|
||||
))
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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),
|
||||
|
|
64
meson.build
64
meson.build
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -10,7 +10,7 @@ hdrs_miext_sync = [
|
|||
'misyncstr.h',
|
||||
]
|
||||
|
||||
if build_dri3 or build_xwayland
|
||||
if build_dri3
|
||||
srcs_miext_sync += 'misyncshm.c'
|
||||
endif
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue