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
|
.xorg_paths: &xorg_paths
|
||||||
- hw/xfree86/**/*
|
- hw/xfree86/**/*
|
||||||
|
|
||||||
.xwayland_paths: &xwayland_paths
|
|
||||||
- hw/xwayland/**/*
|
|
||||||
|
|
||||||
.all_ddx_paths:
|
.all_ddx_paths:
|
||||||
- hw/**/*
|
- hw/**/*
|
||||||
|
|
||||||
|
@ -178,12 +175,11 @@ meson:
|
||||||
PIGLIT_DIR: /root/piglit
|
PIGLIT_DIR: /root/piglit
|
||||||
LP_NUM_THREADS: 0
|
LP_NUM_THREADS: 0
|
||||||
MESON_DDX_BUILD_ARGS: >
|
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_XEPHYR: true
|
||||||
BUILD_XNEST: true
|
BUILD_XNEST: true
|
||||||
BUILD_XORG: true
|
BUILD_XORG: true
|
||||||
BUILD_XVFB: true
|
BUILD_XVFB: true
|
||||||
BUILD_XWAYLAND: true
|
|
||||||
MESON_EXTRA_ARGS: ${MESON_DDX_BUILD_ARGS}
|
MESON_EXTRA_ARGS: ${MESON_DDX_BUILD_ARGS}
|
||||||
|
|
||||||
meson-noglamor:
|
meson-noglamor:
|
||||||
|
@ -191,15 +187,6 @@ meson-noglamor:
|
||||||
variables:
|
variables:
|
||||||
MESON_EXTRA_ARGS: -Dglamor=false ${MESON_DDX_BUILD_ARGS}
|
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:
|
mingw-cross-build:
|
||||||
extends: .common-build-and-test
|
extends: .common-build-and-test
|
||||||
script:
|
script:
|
||||||
|
@ -374,7 +361,7 @@ xf86-driver-build-test:
|
||||||
variables:
|
variables:
|
||||||
GIT_DEPTH: 1
|
GIT_DEPTH: 1
|
||||||
MESON_ARGS: -Dprefix=/usr/
|
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
|
# 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_XNEST" == true ]] && check_executable "hw/xnest/Xnest"
|
||||||
[[ "$BUILD_XORG" == true ]] && check_executable "hw/xfree86/Xorg"
|
[[ "$BUILD_XORG" == true ]] && check_executable "hw/xfree86/Xorg"
|
||||||
[[ "$BUILD_XVFB" == true ]] && check_executable "hw/vfb/Xvfb"
|
[[ "$BUILD_XVFB" == true ]] && check_executable "hw/vfb/Xvfb"
|
||||||
[[ "$BUILD_XWAYLAND" == true ]] && check_executable "hw/xwayland/Xwayland"
|
|
||||||
|
|
||||||
exit 0
|
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 xephyr-glamor hw/kdrive/ephyr/Xephyr.p/ephyr_glamor.c.o
|
||||||
check_piglit_results xvfb hw/vfb/Xvfb
|
check_piglit_results xvfb hw/vfb/Xvfb
|
||||||
check_piglit_results xwayland hw/xwayland/Xwayland
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ apt-get install -y \
|
||||||
libglx-mesa0 \
|
libglx-mesa0 \
|
||||||
libinput10 \
|
libinput10 \
|
||||||
libinput-dev \
|
libinput-dev \
|
||||||
libnvidia-egl-wayland-dev \
|
|
||||||
libpango1.0-0 \
|
libpango1.0-0 \
|
||||||
libpango1.0-dev \
|
libpango1.0-dev \
|
||||||
libpciaccess-dev \
|
libpciaccess-dev \
|
||||||
|
@ -60,7 +59,6 @@ apt-get install -y \
|
||||||
libtool \
|
libtool \
|
||||||
libudev-dev \
|
libudev-dev \
|
||||||
libunwind-dev \
|
libunwind-dev \
|
||||||
libwayland-dev \
|
|
||||||
libx11-dev \
|
libx11-dev \
|
||||||
libx11-xcb-dev \
|
libx11-xcb-dev \
|
||||||
libxau-dev \
|
libxau-dev \
|
||||||
|
@ -131,7 +129,7 @@ apt-get install -y \
|
||||||
|
|
||||||
cd /root
|
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
|
git clone https://gitlab.freedesktop.org/mesa/drm --depth 1 --branch=libdrm-2.4.121
|
||||||
cd drm
|
cd drm
|
||||||
meson _build
|
meson _build
|
||||||
|
@ -147,7 +145,7 @@ ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
|
||||||
cd ..
|
cd ..
|
||||||
rm -rf libxcvt
|
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
|
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2024.1
|
||||||
pushd xorgproto
|
pushd xorgproto
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
|
@ -155,38 +153,6 @@ make -j${FDO_CI_CONCURRENT:-4} install
|
||||||
popd
|
popd
|
||||||
rm -rf xorgproto
|
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
|
git clone https://gitlab.freedesktop.org/mesa/piglit.git
|
||||||
cd piglit
|
cd piglit
|
||||||
git checkout 265896c86f90cb72e8f218ba6a3617fca8b9a1e3
|
git checkout 265896c86f90cb72e8f218ba6a3617fca8b9a1e3
|
||||||
|
|
|
@ -106,7 +106,6 @@ static struct { const char *name; int id; } reservedExt[] = {
|
||||||
{ "XTEST", EXTENSION_MAJOR_XTEST },
|
{ "XTEST", EXTENSION_MAJOR_XTEST },
|
||||||
{ "XVideo", EXTENSION_MAJOR_XVIDEO },
|
{ "XVideo", EXTENSION_MAJOR_XVIDEO },
|
||||||
{ "XVideo-MotionCompensation", EXTENSION_MAJOR_XVMC },
|
{ "XVideo-MotionCompensation", EXTENSION_MAJOR_XVMC },
|
||||||
{ "XWAYLAND", EXTENSION_MAJOR_XWAYLAND },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int checkReserved(const char* name)
|
static int checkReserved(const char* name)
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#define EXTENSION_MAJOR_XTEST (EXTENSION_BASE + 33)
|
#define EXTENSION_MAJOR_XTEST (EXTENSION_BASE + 33)
|
||||||
#define EXTENSION_MAJOR_XVIDEO (EXTENSION_BASE + 34)
|
#define EXTENSION_MAJOR_XVIDEO (EXTENSION_BASE + 34)
|
||||||
#define EXTENSION_MAJOR_XVMC (EXTENSION_BASE + 35)
|
#define EXTENSION_MAJOR_XVMC (EXTENSION_BASE + 35)
|
||||||
#define EXTENSION_MAJOR_XWAYLAND (EXTENSION_BASE + 36)
|
|
||||||
|
|
||||||
#define RESERVED_EXTENSIONS 38
|
#define RESERVED_EXTENSIONS 38
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* Adam Jackson <ajax@redhat.com>
|
* Adam Jackson <ajax@redhat.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XWAYLAND_GLX_H
|
#ifndef GLAMOR_GLX_PROVIDER_H
|
||||||
#define XWAYLAND_GLX_H
|
#define GLAMOR_GLX_PROVIDER_H
|
||||||
|
|
||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
@ -34,4 +34,4 @@
|
||||||
extern _X_EXPORT __GLXprovider glamor_provider;
|
extern _X_EXPORT __GLXprovider glamor_provider;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* XWAYLAND_GLX_H */
|
#endif /* GLAMOR_GLX_PROVIDER_H */
|
||||||
|
|
|
@ -18,10 +18,6 @@ if build_xquartz
|
||||||
subdir('xquartz')
|
subdir('xquartz')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if build_xwayland
|
|
||||||
subdir('xwayland')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if build_xwin
|
if build_xwin
|
||||||
subdir('xwin')
|
subdir('xwin')
|
||||||
endif
|
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',
|
input : 'xwin-config.h.meson.in',
|
||||||
configuration : xwin_data)
|
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_hdr = []
|
||||||
dtrace_tmpl = files('Xserver.d')
|
dtrace_tmpl = files('Xserver.d')
|
||||||
if with_dtrace
|
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
|
.PP
|
||||||
Server-specific man pages:
|
Server-specific man pages:
|
||||||
.BR Xorg (1),
|
.BR Xorg (1),
|
||||||
.BR Xwayland (1),
|
|
||||||
.BR Xephyr (1),
|
.BR Xephyr (1),
|
||||||
.BR Xnest (1),
|
.BR Xnest (1),
|
||||||
.BR Xvfb (1),
|
.BR Xvfb (1),
|
||||||
|
|
64
meson.build
64
meson.build
|
@ -66,8 +66,6 @@ libdrm_req = '>= 2.4.116'
|
||||||
libselinux_req = '>= 2.0.86'
|
libselinux_req = '>= 2.0.86'
|
||||||
xext_req = '>= 1.0.99.4'
|
xext_req = '>= 1.0.99.4'
|
||||||
xproto_req = '>= 7.0.31'
|
xproto_req = '>= 7.0.31'
|
||||||
wayland_req = '>= 1.21.0'
|
|
||||||
wayland_protocols_req = '>= 1.38'
|
|
||||||
gbm_req = '>= 10.2'
|
gbm_req = '>= 10.2'
|
||||||
xf86dgaproto_req = '>= 2.0.99.1'
|
xf86dgaproto_req = '>= 2.0.99.1'
|
||||||
xshmfence_req = '>= 1.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'])
|
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)
|
applewmproto_dep = dependency('applewmproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'], required: false)
|
||||||
xshmfence_dep = dependency('xshmfence', version: xshmfence_req, 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'))
|
dpmsproto_dep = dependency('dpmsproto', version: '>= 1.2', required: get_option('dpms'))
|
||||||
|
|
||||||
pixman_dep = dependency('pixman-1')
|
pixman_dep = dependency('pixman-1')
|
||||||
|
@ -214,38 +211,6 @@ endif
|
||||||
xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg')
|
xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg')
|
||||||
libxcvt_dep = dependency('libxcvt', fallback: ['libxcvt', 'libxcvt_dep'], required: build_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
|
## configure Xnest - nesting X server
|
||||||
build_xnest = get_option('xnest') != 'false'
|
build_xnest = get_option('xnest') != 'false'
|
||||||
|
|
||||||
|
@ -277,7 +242,6 @@ build_xvfb = get_option('xvfb')
|
||||||
|
|
||||||
summary({
|
summary({
|
||||||
'Xorg': build_xorg,
|
'Xorg': build_xorg,
|
||||||
'Xwayland': build_xwayland,
|
|
||||||
'Xnest': build_xnest,
|
'Xnest': build_xnest,
|
||||||
'Xvfb': build_xvfb,
|
'Xvfb': build_xvfb,
|
||||||
'Xwin': build_xwin,
|
'Xwin': build_xwin,
|
||||||
|
@ -350,7 +314,7 @@ endif
|
||||||
module_dir = join_paths(get_option('libdir'), get_option('module_dir'))
|
module_dir = join_paths(get_option('libdir'), get_option('module_dir'))
|
||||||
|
|
||||||
if glamor_option == 'auto'
|
if glamor_option == 'auto'
|
||||||
build_glamor = build_xorg or build_xwayland
|
build_glamor = build_xorg
|
||||||
else
|
else
|
||||||
build_glamor = glamor_option == 'true'
|
build_glamor = glamor_option == 'true'
|
||||||
endif
|
endif
|
||||||
|
@ -362,32 +326,6 @@ if build_glamor
|
||||||
epoxy_dep = dependency('epoxy', required: false)
|
epoxy_dep = dependency('epoxy', required: false)
|
||||||
endif
|
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 :)
|
# Lots of sha1 options, because Linux is about choice :)
|
||||||
|
|
||||||
# The idea behind the ordering here is that we should first prefer system
|
# 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')
|
description: 'Enable Xorg X Server')
|
||||||
option('xephyr', type: 'boolean', value: false,
|
option('xephyr', type: 'boolean', value: false,
|
||||||
description: 'Enable Xephyr nested X server')
|
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',
|
option('glamor', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||||
description: 'Enable glamor (default yes for Xorg/Xwayland builds)')
|
description: 'Enable glamor (default yes for Xorg builds)')
|
||||||
option('xwayland_ei', type: 'combo', choices: ['socket', 'portal', 'false', 'auto'],
|
|
||||||
value: 'auto', description: 'Enable emulated input support on Xwayland')
|
|
||||||
option('xnest', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
option('xnest', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||||
description: 'Enable Xnest nested X server')
|
description: 'Enable Xnest nested X server')
|
||||||
option('xvfb', type: 'boolean', value: true,
|
option('xvfb', type: 'boolean', value: true,
|
||||||
|
@ -141,10 +137,6 @@ option('xpbproxy', type: 'boolean', value: false,
|
||||||
option('libunwind', type: 'boolean', value: false,
|
option('libunwind', type: 'boolean', value: false,
|
||||||
description: 'Use libunwind for backtrace reporting')
|
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',
|
option('docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||||
description: 'Build documentation')
|
description: 'Build documentation')
|
||||||
option('devel-docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
option('devel-docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||||
|
|
|
@ -10,7 +10,7 @@ hdrs_miext_sync = [
|
||||||
'misyncstr.h',
|
'misyncstr.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
if build_dri3 or build_xwayland
|
if build_dri3
|
||||||
srcs_miext_sync += 'misyncshm.c'
|
srcs_miext_sync += 'misyncshm.c'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -149,19 +149,6 @@ if get_option('xvfb')
|
||||||
endif
|
endif
|
||||||
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('bigreq')
|
||||||
subdir('damage')
|
subdir('damage')
|
||||||
subdir('sync')
|
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