diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7cb3a8937..837715619 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -21,7 +21,7 @@ variables:
REPO_URL_XORGPROTO: 'https://gitlab.freedesktop.org/xorg/proto/xorgproto.git'
XORG_DEBIAN_VERSION: 'bookworm-slim'
XORG_DEBIAN_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh'
- XORG_DEBIAN_TAG: '2026-03-16-image-update'
+ XORG_DEBIAN_TAG: '2026-03-29-drop-xwayland'
XORG_FREEBSD_VERSION: '14.2'
XORG_FREEBSD_EXEC: ''
XORG_FREEBSD_TAG: '2025-02-18-vm-image'
@@ -92,9 +92,6 @@ stages:
.xorg_paths: &xorg_paths
- hw/xfree86/**/*
-.xwayland_paths: &xwayland_paths
- - hw/xwayland/**/*
-
.all_ddx_paths:
- hw/**/*
@@ -178,12 +175,11 @@ meson:
PIGLIT_DIR: /root/piglit
LP_NUM_THREADS: 0
MESON_DDX_BUILD_ARGS: >
- -Dxwayland=${BUILD_XWAYLAND} -Dxorg=${BUILD_XORG} -Dxephyr=${BUILD_XEPHYR} -Dxvfb=${BUILD_XVFB} -Dxnest=${BUILD_XNEST}
+ -Dxorg=${BUILD_XORG} -Dxephyr=${BUILD_XEPHYR} -Dxvfb=${BUILD_XVFB} -Dxnest=${BUILD_XNEST}
BUILD_XEPHYR: true
BUILD_XNEST: true
BUILD_XORG: true
BUILD_XVFB: true
- BUILD_XWAYLAND: true
MESON_EXTRA_ARGS: ${MESON_DDX_BUILD_ARGS}
meson-enable-options:
@@ -201,15 +197,6 @@ meson-noglamor:
variables:
MESON_EXTRA_ARGS: -Dglamor=false ${MESON_DDX_BUILD_ARGS}
-xwayland-nolibdecor:
- extends: meson
- variables:
- BUILD_XEPHYR: false
- BUILD_XNEST: false
- BUILD_XORG: false
- BUILD_XVFB: false
- MESON_EXTRA_ARGS: -Dlibdecor=false ${MESON_DDX_BUILD_ARGS}
-
mingw-cross-build:
extends: .common-build-and-test
script:
@@ -306,7 +293,7 @@ xf86-driver-build-test:
variables:
GIT_DEPTH: 1
MESON_ARGS: -Dprefix=/usr/
- MESON_EXTRA_ARGS: -Dxwayland=false -Dxnest=false -Dxvfb=false -Dxquartz=false -Ddocs=false
+ MESON_EXTRA_ARGS: -Dxnest=false -Dxvfb=false -Dxquartz=false -Ddocs=false
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
changes:
@@ -334,13 +321,6 @@ check-commits:
junit: results.xml
allow_failure: true
-check-whitespace:
- extends:
- - .fdo.ci-fairy
- stage: test
- script:
- - .gitlab-ci/whitespace-check.py $(git ls-files hw/xwayland)
-
#
# Workflow rules needed due to:
# https://gitlab.freedesktop.org/freedesktop/freedesktop/-/issues/438
diff --git a/.gitlab-ci/check-ddx-build.sh b/.gitlab-ci/check-ddx-build.sh
index df6f0c029..3b3a65f38 100755
--- a/.gitlab-ci/check-ddx-build.sh
+++ b/.gitlab-ci/check-ddx-build.sh
@@ -20,6 +20,5 @@ fi
[[ "$BUILD_XNEST" == true ]] && check_executable "hw/xnest/Xnest"
[[ "$BUILD_XORG" == true ]] && check_executable "hw/xfree86/Xorg"
[[ "$BUILD_XVFB" == true ]] && check_executable "hw/vfb/Xvfb"
-[[ "$BUILD_XWAYLAND" == true ]] && check_executable "hw/xwayland/Xwayland"
exit 0
diff --git a/.gitlab-ci/check-piglit-results.sh b/.gitlab-ci/check-piglit-results.sh
index 182579ed2..e8294b0ce 100755
--- a/.gitlab-ci/check-piglit-results.sh
+++ b/.gitlab-ci/check-piglit-results.sh
@@ -27,4 +27,3 @@ check_piglit_results ()
check_piglit_results xephyr-glamor hw/kdrive/ephyr/Xephyr.p/ephyr_glamor.c.o
check_piglit_results xvfb hw/vfb/Xvfb
-check_piglit_results xwayland hw/xwayland/Xwayland
diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh
index a2498f943..e6f7fcaa2 100644
--- a/.gitlab-ci/debian-install.sh
+++ b/.gitlab-ci/debian-install.sh
@@ -30,7 +30,6 @@ apt-get install -y \
libcairo2 \
libcairo2-dev \
libdbus-1-dev \
- libdecor-0-dev \
libdrm-dev \
libegl1-mesa-dev \
libepoxy-dev \
@@ -55,7 +54,6 @@ apt-get install -y \
libtool \
libudev-dev \
libunwind-dev \
- libwayland-dev \
libx11-dev \
libx11-xcb-dev \
libxau-dev \
@@ -127,15 +125,6 @@ apt-get install -y \
cd /root
-# Xwayland requires drm 2.4.116 for drmSyncobjEventfd
-# but Debian bookworm has only 2.4.114
-git clone https://gitlab.freedesktop.org/mesa/drm --depth 1 --branch=libdrm-2.4.116
-cd drm
-meson _build
-ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
-cd ..
-rm -rf drm
-
# xserver requires xorgproto >= 2024.1 for XWAYLAND
# but Debian bookworm has only 2022.1
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2024.1
@@ -154,31 +143,6 @@ make -j${FDO_CI_CONCURRENT:-4} install
popd
rm -rf libxtrans
-# wayland-protocols 1.38 requires either wayland-scanner 1.23 or a build with
-# dtd_validation=false, but Debian bookworm has only 1.21 w/ dtd_validation=true
-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 bookworm has 1.31 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 libei for Xwayland, as Debian didn't add until trixie
-git clone https://gitlab.freedesktop.org/libinput/libei.git --depth 1 --branch=1.0.0
-cd libei
-meson setup _build -Dtests=disabled -Ddocumentation=[] -Dliboeffis=enabled
-ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
-cd ..
-rm -rf libei
-
git clone https://gitlab.freedesktop.org/mesa/piglit.git
cd piglit
git checkout 265896c86f90cb72e8f218ba6a3617fca8b9a1e3
diff --git a/hw/meson.build b/hw/meson.build
index f9605a5b7..fb9e5d431 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -18,10 +18,6 @@ if build_xquartz
subdir('xquartz')
endif
-if build_xwayland
- subdir('xwayland')
-endif
-
if build_xwin
subdir('xwin')
endif
diff --git a/hw/xwayland/.gitignore b/hw/xwayland/.gitignore
deleted file mode 100644
index 2fe460529..000000000
--- a/hw/xwayland/.gitignore
+++ /dev/null
@@ -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
diff --git a/hw/xwayland/desktop/org.freedesktop.Xwayland.desktop.in b/hw/xwayland/desktop/org.freedesktop.Xwayland.desktop.in
deleted file mode 100644
index 106c8bc76..000000000
--- a/hw/xwayland/desktop/org.freedesktop.Xwayland.desktop.in
+++ /dev/null
@@ -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
diff --git a/hw/xwayland/drm.xml b/hw/xwayland/drm.xml
deleted file mode 100644
index 5e64622df..000000000
--- a/hw/xwayland/drm.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Bitmask of capabilities.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hw/xwayland/man/Xwayland.man b/hw/xwayland/man/Xwayland.man
deleted file mode 100644
index ef2db0e85..000000000
--- a/hw/xwayland/man/Xwayland.man
+++ /dev/null
@@ -1,174 +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 shortcuts 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
-.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@)
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
deleted file mode 100644
index 469b61ad0..000000000
--- a/hw/xwayland/meson.build
+++ /dev/null
@@ -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, install_tag : 'runtime')
-
-meson.override_find_program('Xwayland', xwayland_server)
-meson.override_dependency('xwayland', declare_dependency(
- variables: [
- 'xwayland=' + xwayland_server.full_path(),
- ] + xwayland_vars,
-))
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
deleted file mode 100644
index fa77f6daa..000000000
--- a/hw/xwayland/xwayland-cursor.c
+++ /dev/null
@@ -1,438 +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
-
-#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);
-}
diff --git a/hw/xwayland/xwayland-cursor.h b/hw/xwayland/xwayland-cursor.h
deleted file mode 100644
index 76b5b49b6..000000000
--- a/hw/xwayland/xwayland-cursor.h
+++ /dev/null
@@ -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
-#include
-#include
-
-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 */
diff --git a/hw/xwayland/xwayland-cvt.c b/hw/xwayland/xwayland-cvt.c
deleted file mode 100644
index 4248d3869..000000000
--- a/hw/xwayland/xwayland-cvt.c
+++ /dev/null
@@ -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
-
-#include
-#include
-#include
-
-#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);
-}
diff --git a/hw/xwayland/xwayland-cvt.h b/hw/xwayland/xwayland-cvt.h
deleted file mode 100644
index 64ff41e35..000000000
--- a/hw/xwayland/xwayland-cvt.h
+++ /dev/null
@@ -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
-
-#include
-#include
-
-RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
- float VRefresh, Bool Reduced, Bool Interlaced);
-
-#endif /* XWAYLAND_CVT_H */
diff --git a/hw/xwayland/xwayland-dmabuf.c b/hw/xwayland/xwayland-dmabuf.c
deleted file mode 100644
index 1676a82da..000000000
--- a/hw/xwayland/xwayland-dmabuf.c
+++ /dev/null
@@ -1,795 +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
-
-#include
-
-#include
-#include
-
-#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;
-}
diff --git a/hw/xwayland/xwayland-dmabuf.h b/hw/xwayland/xwayland-dmabuf.h
deleted file mode 100644
index ca0dcd706..000000000
--- a/hw/xwayland/xwayland-dmabuf.h
+++ /dev/null
@@ -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
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-drm-lease.c b/hw/xwayland/xwayland-drm-lease.c
deleted file mode 100644
index b636f4942..000000000
--- a/hw/xwayland/xwayland-drm-lease.c
+++ /dev/null
@@ -1,484 +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
-
-#ifdef WITH_LIBDRM
-#include
-#include
-#endif
-
-#include "randrstr_priv.h"
-#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);
- lease_private = calloc(1, sizeof(struct xwl_drm_lease));
- 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 = xallocarray(conn->count_modes, sizeof(RRModePtr));
- if (!rrmodes) {
- ErrorF("Failed to allocate connector modes\n");
- drmModeFreeConnector(conn);
- return NULL;
- }
-
- /* This spaghetti brought to you courtesy 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 = malloc(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;
- }
- }
-}
diff --git a/hw/xwayland/xwayland-drm-lease.h b/hw/xwayland/xwayland-drm-lease.h
deleted file mode 100644
index aa5aed63c..000000000
--- a/hw/xwayland/xwayland-drm-lease.h
+++ /dev/null
@@ -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
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
deleted file mode 100644
index f7f78560c..000000000
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ /dev/null
@@ -1,1880 +0,0 @@
-/*
- * Copyright © 2011-2014 Intel Corporation
- * Copyright © 2017 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:
- * Lyude Paul
- *
- */
-
-#include
-
-#include
-#include
-#include
-#ifdef DRI3
-#include
-#endif /* DRI3 */
-#include
-#include
-#include
-#if defined(__linux__)
-#include
-#include
-#include
-#endif
-
-#define MESA_EGL_NO_X11_HEADERS
-#define EGL_NO_X11
-#include
-#include
-
-#include
-#include
-#include
-#include "drm-client-protocol.h"
-
-#include "xwayland-glamor.h"
-#include "xwayland-glamor-gbm.h"
-#include "xwayland-pixmap.h"
-#include "xwayland-screen.h"
-#include "xwayland-window-buffers.h"
-
-#include "linux-dmabuf-unstable-v1-client-protocol.h"
-#include "linux-drm-syncobj-v1-client-protocol.h"
-
-struct xwl_gbm_private {
- drmDevice *device;
- char *device_name;
- struct gbm_device *gbm;
- int drm_fd;
- Bool fd_render_node;
- Bool drm_authenticated;
- Bool dmabuf_capable;
- Bool glamor_gles;
- Bool implicit_sync;
- Bool supports_syncobjs;
-
- /* Set if wl_drm is available */
- struct wl_drm *drm;
- uint32_t capabilities;
-};
-
-struct xwl_pixmap {
- struct wl_buffer *buffer;
- EGLImage image;
- unsigned int texture;
- struct gbm_bo *bo;
- Bool implicit_modifier;
-#ifdef DRI3
- struct dri3_syncobj *syncobj;
- uint64_t timeline_point;
- int efd;
- struct xwl_window_buffer *xwl_window_buffer;
-#endif /* DRI3 */
-};
-
-static DevPrivateKeyRec xwl_gbm_private_key;
-static DevPrivateKeyRec xwl_auth_state_private_key;
-
-static inline struct xwl_gbm_private *
-xwl_gbm_get(struct xwl_screen *xwl_screen)
-{
- return dixLookupPrivate(&xwl_screen->screen->devPrivates,
- &xwl_gbm_private_key);
-}
-
-Bool
-xwl_glamor_has_wl_drm(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- return !!(xwl_gbm->drm != NULL);
-}
-
-/* There is a workaround for Mesa behaviour, which will cause black windows
- * when RGBX formats is using. Why exactly? There is an explanation:
- * 1. We create GL_RGBA texture with GL_UNSIGNED_BYTE type, all allowed by ES.
- * 2 .We export these texture to GBM bo with GBM_FORMAT_XRGB8888, and Mesa sets internal
- * format of these textures as GL_RGB8 (mesa/mesa!5034 (merged))
- * 3. We import these BO at some point, and use glTexSubImage on it with GL_RGBA format
- * and with GL_UNSIGNED_BYTE type, as we creates. Mesa checks its internalformat
- * in glTexSubImage2D and fails due to GLES internal format limitation
- * (see https://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf, section 3.7.1).
- */
-static uint32_t
-gbm_format_for_depth(int depth, int gles)
-{
- switch (depth) {
- case 15:
- return GBM_FORMAT_ARGB1555;
- case 16:
- return GBM_FORMAT_RGB565;
- case 24:
- if (gles)
- return GBM_FORMAT_ARGB8888;
- return GBM_FORMAT_XRGB8888;
- case 30:
- return GBM_FORMAT_ARGB2101010;
- default:
- ErrorF("unexpected depth: %d\n", depth);
- case 32:
- return GBM_FORMAT_ARGB8888;
- }
-}
-
-static char
-is_device_path_render_node (const char *device_path)
-{
- char is_render_node;
- int fd;
-
- fd = open(device_path, O_RDWR | O_CLOEXEC);
- if (fd < 0)
- return 0;
-
- is_render_node = (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER);
- close(fd);
-
- return is_render_node;
-}
-
-static PixmapPtr
-xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
- int depth,
- Bool implicit_modifier)
-{
- PixmapPtr pixmap;
- struct xwl_pixmap *xwl_pixmap;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-#ifdef GBM_BO_FD_FOR_PLANE
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- uint64_t modifier = gbm_bo_get_modifier(bo);
- const int num_planes = gbm_bo_get_plane_count(bo);
- int fds[GBM_MAX_PLANES];
- int plane;
- int attr_num = 0;
- EGLint img_attrs[64] = {0};
- enum PlaneAttrs {
- PLANE_FD,
- PLANE_OFFSET,
- PLANE_PITCH,
- PLANE_MODIFIER_LO,
- PLANE_MODIFIER_HI,
- NUM_PLANE_ATTRS
- };
- static const EGLint planeAttrs[][NUM_PLANE_ATTRS] = {
- {
- EGL_DMA_BUF_PLANE0_FD_EXT,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT,
- EGL_DMA_BUF_PLANE0_PITCH_EXT,
- EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
- EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
- },
- {
- EGL_DMA_BUF_PLANE1_FD_EXT,
- EGL_DMA_BUF_PLANE1_OFFSET_EXT,
- EGL_DMA_BUF_PLANE1_PITCH_EXT,
- EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
- EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
- },
- {
- EGL_DMA_BUF_PLANE2_FD_EXT,
- EGL_DMA_BUF_PLANE2_OFFSET_EXT,
- EGL_DMA_BUF_PLANE2_PITCH_EXT,
- EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
- EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
- },
- {
- EGL_DMA_BUF_PLANE3_FD_EXT,
- EGL_DMA_BUF_PLANE3_OFFSET_EXT,
- EGL_DMA_BUF_PLANE3_PITCH_EXT,
- EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
- EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
- },
- };
-
- for (plane = 0; plane < num_planes; plane++) fds[plane] = -1;
-#endif
-
- xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
- if (xwl_pixmap == NULL)
- return NULL;
-
- pixmap = glamor_create_pixmap(screen,
- gbm_bo_get_width(bo),
- gbm_bo_get_height(bo),
- depth,
- GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
- if (!pixmap) {
- free(xwl_pixmap);
- return NULL;
- }
-
- xwl_glamor_egl_make_current(xwl_screen);
- xwl_pixmap->bo = bo;
- xwl_pixmap->buffer = NULL;
- xwl_pixmap->implicit_modifier = implicit_modifier;
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
- xwl_pixmap->efd = -1;
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
-
-#ifdef GBM_BO_FD_FOR_PLANE
- if (xwl_gbm->dmabuf_capable) {
-#define ADD_ATTR(attrs, num, attr) \
- do { \
- assert(((num) + 1) < (sizeof(attrs) / sizeof((attrs)[0]))); \
- (attrs)[(num)++] = (attr); \
- } while (0)
- ADD_ATTR(img_attrs, attr_num, EGL_WIDTH);
- ADD_ATTR(img_attrs, attr_num, gbm_bo_get_width(bo));
- ADD_ATTR(img_attrs, attr_num, EGL_HEIGHT);
- ADD_ATTR(img_attrs, attr_num, gbm_bo_get_height(bo));
- ADD_ATTR(img_attrs, attr_num, EGL_LINUX_DRM_FOURCC_EXT);
- ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo));
-
- for (plane = 0; plane < num_planes; plane++) {
- fds[plane] = gbm_bo_get_fd_for_plane(bo, plane);
- ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]);
- ADD_ATTR(img_attrs, attr_num, fds[plane]);
- ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]);
- ADD_ATTR(img_attrs, attr_num, gbm_bo_get_offset(bo, plane));
- ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_PITCH]);
- ADD_ATTR(img_attrs, attr_num, gbm_bo_get_stride_for_plane(bo, plane));
- ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_LO]);
- ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier & 0xFFFFFFFFULL));
- ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_HI]);
- ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier >> 32ULL));
- }
- ADD_ATTR(img_attrs, attr_num, EGL_NONE);
-#undef ADD_ATTR
-
- xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
- EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT,
- NULL,
- img_attrs);
-
- for (plane = 0; plane < num_planes; plane++) {
- close(fds[plane]);
- fds[plane] = -1;
- }
- }
- else
-#endif
- {
- xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
- EGL_NO_CONTEXT,
- EGL_NATIVE_PIXMAP_KHR,
- xwl_pixmap->bo, NULL);
- }
-
- if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
- goto error;
-
- glGenTextures(1, &xwl_pixmap->texture);
- glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
- if (eglGetError() != EGL_SUCCESS)
- goto error;
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- if (!glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture))
- goto error;
-
- glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
- xwl_pixmap_set_private(pixmap, xwl_pixmap);
-
- return pixmap;
-
-error:
- if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
- eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
- if (pixmap)
- glamor_destroy_pixmap(pixmap);
- free(xwl_pixmap);
-
- return NULL;
-}
-
-static PixmapPtr
-xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
- DrawablePtr drawable,
- int width, int height, int depth,
- unsigned int hint,
- Bool implicit_scanout)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- struct gbm_bo *bo = NULL;
- PixmapPtr pixmap = NULL;
- uint32_t num_modifiers = 0;
- uint64_t *modifiers = NULL;
-
- if (width > 0 && height > 0 && depth >= 15 &&
- (hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
- hint == CREATE_PIXMAP_USAGE_SHARED ||
- (xwl_screen->rootless && hint == 0))) {
- uint32_t format = gbm_format_for_depth(depth, xwl_gbm->glamor_gles);
- Bool implicit = FALSE;
-
-#ifdef GBM_BO_WITH_MODIFIERS
- if (xwl_gbm->dmabuf_capable) {
- Bool supports_scanout = FALSE;
-
- if (drawable) {
- xwl_glamor_get_drawable_modifiers_and_scanout(drawable,
- format,
- &num_modifiers,
- &modifiers,
- &supports_scanout);
- }
-
- if (num_modifiers == 0) {
- xwl_glamor_get_modifiers(xwl_screen->screen, format,
- &num_modifiers, &modifiers);
- }
-
- if (num_modifiers > 0) {
-#ifdef GBM_BO_WITH_MODIFIERS2
- uint32_t usage = GBM_BO_USE_RENDERING;
- if (supports_scanout)
- usage |= GBM_BO_USE_SCANOUT;
- bo = gbm_bo_create_with_modifiers2(xwl_gbm->gbm, width, height,
- format, modifiers, num_modifiers,
- usage);
-#else
- bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
- format, modifiers, num_modifiers);
-#endif
- }
- }
-#endif
- if (bo == NULL) {
- uint32_t usage = GBM_BO_USE_RENDERING;
- implicit = TRUE;
- if (implicit_scanout)
- usage |= GBM_BO_USE_SCANOUT;
-
- if (num_modifiers > 0) {
- Bool has_mod_invalid = FALSE, has_mod_linear = FALSE;
- int i;
-
- for (i = 0; i < num_modifiers; i++) {
- if (modifiers[i] == DRM_FORMAT_MOD_INVALID)
- has_mod_invalid = TRUE;
- else if (modifiers[i] == DRM_FORMAT_MOD_LINEAR)
- has_mod_linear = TRUE;
- }
-
- if (!has_mod_invalid && has_mod_linear)
- usage |= GBM_BO_USE_LINEAR;
- }
-
- bo = gbm_bo_create(xwl_gbm->gbm, width, height, format, usage);
- }
-
- if (bo) {
- pixmap = xwl_glamor_gbm_create_pixmap_for_bo(xwl_screen->screen, bo, depth, implicit);
-
- if (!pixmap) {
- gbm_bo_destroy(bo);
- }
- else if (xwl_screen->rootless && hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) {
- glamor_clear_pixmap(pixmap);
- }
- }
- }
-
- if (!pixmap)
- pixmap = glamor_create_pixmap(xwl_screen->screen, width, height, depth, hint);
-
- free(modifiers);
- return pixmap;
-}
-
-static PixmapPtr
-xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
- int width, int height, int depth,
- unsigned int hint)
-{
- return xwl_glamor_gbm_create_pixmap_internal(xwl_screen_get(screen), NULL,
- width, height, depth, hint, FALSE);
-}
-
-PixmapPtr
-xwl_glamor_create_pixmap_for_window(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- WindowPtr window = xwl_window->surface_window;
- unsigned border_width = 2 * window->borderWidth;
-
- if (!xwl_screen->glamor)
- return NullPixmap;
-
- return xwl_glamor_gbm_create_pixmap_internal(xwl_screen,
- &window->drawable,
- window->drawable.width + border_width,
- window->drawable.height + border_width,
- window->drawable.depth,
- CREATE_PIXMAP_USAGE_BACKING_PIXMAP,
- xwl_window->has_implicit_scanout_support);
-}
-
-static Bool
-xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
- 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);
-
- eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
- if (xwl_pixmap->bo)
- gbm_bo_destroy(xwl_pixmap->bo);
- xwl_glamor_gbm_dispose_syncpts(pixmap);
- free(xwl_pixmap);
- }
-
- return glamor_destroy_pixmap(pixmap);
-}
-
-static const struct wl_buffer_listener xwl_glamor_gbm_buffer_listener = {
- xwl_pixmap_buffer_release_cb,
-};
-
-#ifdef GBM_BO_WITH_MODIFIERS
-static Bool
-init_buffer_params_with_modifiers(struct xwl_pixmap *xwl_pixmap,
- uint64_t *modifier,
- int *num_planes,
- int *prime_fds,
- uint32_t *strides,
- uint32_t *offsets)
-{
-#ifndef GBM_BO_FD_FOR_PLANE
- int32_t first_handle;
-#endif
- int i;
-
- *num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
- *modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
-
- for (i = 0; i < *num_planes; i++) {
-#ifdef GBM_BO_FD_FOR_PLANE
- prime_fds[i] = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, i);
-#else
- union gbm_bo_handle plane_handle;
-
- plane_handle = gbm_bo_get_handle_for_plane(xwl_pixmap->bo, i);
- if (i == 0)
- first_handle = plane_handle.s32;
-
- /* If all planes point to the same object as the first plane, i.e. they
- * all have the same handle, we can fall back to the non-planar
- * gbm_bo_get_fd without losing information. If they point to different
- * objects we are out of luck and need to give up.
- */
- if (first_handle == plane_handle.s32)
- prime_fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
- else
- prime_fds[i] = -1;
-#endif
- if (prime_fds[i] == -1) {
- while (--i >= 0)
- close(prime_fds[i]);
- return FALSE;
- }
- strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
- offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
- }
-
- return TRUE;
-}
-#endif
-
-static Bool
-init_buffer_params_fallback(struct xwl_pixmap *xwl_pixmap,
- uint64_t *modifier,
- int *num_planes,
- int *prime_fds,
- uint32_t *strides,
- uint32_t *offsets)
-{
- *num_planes = 1;
- *modifier = DRM_FORMAT_MOD_INVALID;
- prime_fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
- if (prime_fds[0] == -1)
- return FALSE;
-
- strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
- offsets[0] = 0;
-
- return TRUE;
-}
-
-struct wl_buffer *
-xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- unsigned short width = pixmap->drawable.width;
- unsigned short height = pixmap->drawable.height;
- uint32_t format;
- int num_planes;
- int prime_fds[4];
- uint32_t strides[4];
- uint32_t offsets[4];
- uint64_t modifier;
- int i;
-
- if (xwl_pixmap == NULL)
- return NULL;
-
- if (xwl_pixmap->buffer) {
- /* Buffer already exists. */
- return xwl_pixmap->buffer;
- }
-
- if (!xwl_pixmap->bo)
- return NULL;
-
- format = wl_drm_format_for_depth(pixmap->drawable.depth);
-
-#ifdef GBM_BO_WITH_MODIFIERS
- if (!xwl_pixmap->implicit_modifier) {
- if (!init_buffer_params_with_modifiers(xwl_pixmap,
- &modifier,
- &num_planes,
- prime_fds,
- strides,
- offsets))
- return NULL;
- } else
-#endif
- {
- if (!init_buffer_params_fallback(xwl_pixmap,
- &modifier,
- &num_planes,
- prime_fds,
- strides,
- offsets))
- return NULL;
- }
-
- if (xwl_screen->dmabuf &&
- xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
- struct zwp_linux_buffer_params_v1 *params;
-
- params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
- for (i = 0; i < num_planes; i++) {
- zwp_linux_buffer_params_v1_add(params, prime_fds[i], i,
- offsets[i], strides[i],
- modifier >> 32, modifier & 0xffffffff);
- }
-
- xwl_pixmap->buffer =
- zwp_linux_buffer_params_v1_create_immed(params, width, height,
- format, 0);
- zwp_linux_buffer_params_v1_destroy(params);
- } else if (num_planes == 1 && modifier == DRM_FORMAT_MOD_INVALID &&
- xwl_gbm->drm) {
- xwl_pixmap->buffer =
- wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fds[0], width, height,
- format,
- 0, gbm_bo_get_stride(xwl_pixmap->bo),
- 0, 0,
- 0, 0);
- }
-
- for (i = 0; i < num_planes; i++)
- close(prime_fds[i]);
-
- /* Add our listener now */
- if (xwl_pixmap->buffer)
- wl_buffer_add_listener(xwl_pixmap->buffer,
- &xwl_glamor_gbm_buffer_listener, pixmap);
-
- return xwl_pixmap->buffer;
-}
-
-static void
-xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- if (!xwl_gbm)
- return;
-
- /* Cannot use GBM after clean-up, disable GLAMOR support from now on */
- ErrorF("XWAYLAND: Disabling GLAMOR support\n");
- xwl_screen->glamor = XWL_GLAMOR_NONE;
-
- if (xwl_gbm->device_name)
- free(xwl_gbm->device_name);
- drmFreeDevice(&xwl_gbm->device);
- if (xwl_gbm->drm_fd)
- close(xwl_gbm->drm_fd);
- if (xwl_gbm->drm)
- wl_drm_destroy(xwl_gbm->drm);
- if (xwl_gbm->gbm)
- gbm_device_destroy(xwl_gbm->gbm);
- if (xwl_screen->explicit_sync)
- wp_linux_drm_syncobj_manager_v1_destroy(xwl_screen->explicit_sync);
-
- dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
- NULL);
- free(xwl_gbm);
-}
-
-struct xwl_auth_state {
- int fd;
- ClientPtr client;
- struct wl_callback *callback;
-};
-
-static void
-free_xwl_auth_state(ClientPtr pClient, struct xwl_auth_state *state)
-{
- dixSetPrivate(&pClient->devPrivates, &xwl_auth_state_private_key, NULL);
- if (state) {
- wl_callback_destroy(state->callback);
- free(state);
- }
-}
-
-static void
-xwl_auth_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
-{
- NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
- ClientPtr pClient = clientinfo->client;
- struct xwl_auth_state *state;
-
- switch (pClient->clientState) {
- case ClientStateGone:
- case ClientStateRetained:
- state = dixLookupPrivate(&pClient->devPrivates,
- &xwl_auth_state_private_key);
- free_xwl_auth_state(pClient, state);
- break;
- default:
- break;
- }
-}
-
-#ifdef DRI3
-static void
-sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
-{
- struct xwl_auth_state *state = data;
- ClientPtr client = state->client;
-
- /* if the client is gone, the callback is cancelled so it's safe to
- * assume the client is still in ClientStateRunning at this point...
- */
- dri3_send_open_reply(client, state->fd);
- AttendClient(client);
- free_xwl_auth_state(client, state);
-}
-
-static const struct wl_callback_listener sync_listener = {
- sync_callback
-};
-
-static int
-xwl_dri3_open_client(ClientPtr client,
- ScreenPtr screen,
- RRProviderPtr provider,
- int *pfd)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- struct xwl_auth_state *state;
- drm_magic_t magic;
- int fd;
-
- fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
- if (fd < 0)
- return BadAlloc;
- if (xwl_gbm->fd_render_node) {
- *pfd = fd;
- return Success;
- }
-
- state = malloc(sizeof *state);
- if (state == NULL) {
- close(fd);
- return BadAlloc;
- }
-
- state->client = client;
- state->fd = fd;
-
- if (drmGetMagic(state->fd, &magic) < 0) {
- close(state->fd);
- free(state);
- return BadMatch;
- }
-
- wl_drm_authenticate(xwl_gbm->drm, magic);
- state->callback = wl_display_sync(xwl_screen->display);
- wl_callback_add_listener(state->callback, &sync_listener, state);
- dixSetPrivate(&client->devPrivates, &xwl_auth_state_private_key, state);
-
- IgnoreClient(client);
-
- return Success;
-}
-#endif /* DRI3 */
-
-PixmapPtr
-glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds,
- CARD16 width, CARD16 height,
- const CARD32 *strides, const CARD32 *offsets,
- CARD8 depth, CARD8 bpp, uint64_t modifier)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- struct gbm_bo *bo = NULL;
- PixmapPtr pixmap;
- int i;
- Bool implicit = FALSE;
-
- if (width == 0 || height == 0 || num_fds == 0 ||
- depth < 15 || bpp != BitsPerPixel(depth) ||
- strides[0] < width * bpp / 8)
- goto error;
-
- if (xwl_gbm->dmabuf_capable && modifier != DRM_FORMAT_MOD_INVALID) {
-#ifdef GBM_BO_WITH_MODIFIERS
- struct gbm_import_fd_modifier_data data;
-
- data.width = width;
- data.height = height;
- data.num_fds = num_fds;
- data.format = gbm_format_for_depth(depth, xwl_gbm->glamor_gles);
- data.modifier = modifier;
- for (i = 0; i < num_fds; i++) {
- data.fds[i] = fds[i];
- data.strides[i] = strides[i];
- data.offsets[i] = offsets[i];
- }
- bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD_MODIFIER, &data,
- GBM_BO_USE_RENDERING);
-#endif
- } else if (num_fds == 1) {
- struct gbm_import_fd_data data;
-
- data.fd = fds[0];
- data.width = width;
- data.height = height;
- data.stride = strides[0];
- data.format = gbm_format_for_depth(depth, xwl_gbm->glamor_gles);
- bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD, &data,
- GBM_BO_USE_RENDERING);
- implicit = TRUE;
- } else {
- goto error;
- }
-
- if (bo == NULL)
- goto error;
-
- pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth, implicit);
- if (pixmap == NULL) {
- gbm_bo_destroy(bo);
- goto error;
- }
-
- return pixmap;
-
-error:
- return NULL;
-}
-
-int
-glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
- uint32_t *strides, uint32_t *offsets,
- uint64_t *modifier)
-{
- struct xwl_pixmap *xwl_pixmap;
-#ifdef GBM_BO_WITH_MODIFIERS
-#ifndef GBM_BO_FD_FOR_PLANE
- int32_t first_handle;
-#endif
- uint32_t num_fds;
- int i;
-#endif
-
- xwl_pixmap = xwl_pixmap_get(pixmap);
-
- if (xwl_pixmap == NULL)
- return 0;
-
- if (!xwl_pixmap->bo)
- return 0;
-
-#ifdef GBM_BO_WITH_MODIFIERS
- num_fds = gbm_bo_get_plane_count(xwl_pixmap->bo);
- *modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
-
- for (i = 0; i < num_fds; i++) {
-#ifdef GBM_BO_FD_FOR_PLANE
- fds[i] = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, i);
-#else
- union gbm_bo_handle plane_handle;
-
- plane_handle = gbm_bo_get_handle_for_plane(xwl_pixmap->bo, i);
- if (i == 0)
- first_handle = plane_handle.s32;
-
- /* If all planes point to the same object as the first plane, i.e. they
- * all have the same handle, we can fall back to the non-planar
- * gbm_bo_get_fd without losing information. If they point to different
- * objects we are out of luck and need to give up.
- */
- if (first_handle == plane_handle.s32)
- fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
- else
- fds[i] = -1;
-#endif
- if (fds[i] == -1) {
- while (--i >= 0)
- close(fds[i]);
- return 0;
- }
- strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
- offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
- }
-
- return num_fds;
-#else
- *modifier = DRM_FORMAT_MOD_INVALID;
- fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
- if (fds[0] == -1)
- return 0;
- strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
- offsets[0] = 0;
- return 1;
-#endif
-}
-
-/* Not actually used, just defined here so there's something for
- * _glamor_egl_fds_from_pixmap() to link against
- */
-int
-glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
- CARD16 *stride, CARD32 *size)
-{
- return -1;
-}
-
-int
-xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
- struct xwl_pixmap *xwl_pixmap;
- int num_planes;
- int sync_file = -1;
- int p;
-#ifndef GBM_BO_FD_FOR_PLANE
- int32_t first_handle;
-#endif
-
- if (!xwl_screen->glamor)
- return -1;
-
-#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
- xwl_pixmap = xwl_pixmap_get(pixmap);
- num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
-
- for (p = 0; p < num_planes; ++p) {
- int plane_fd;
-#ifdef GBM_BO_FD_FOR_PLANE
- plane_fd = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, p);
-#else
- union gbm_bo_handle plane_handle =
- gbm_bo_get_handle_for_plane(xwl_pixmap->bo, p);
- if (p == 0)
- first_handle = plane_handle.s32;
-
- if (plane_handle.s32 == first_handle)
- plane_fd = gbm_bo_get_fd(xwl_pixmap->bo);
- else
- continue;
-#endif /* GBM_BO_FD_FOR_PLANE */
- struct dma_buf_export_sync_file export_args = { 0 };
- export_args.fd = -1;
- export_args.flags = DMA_BUF_SYNC_READ;
- drmIoctl(plane_fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &export_args);
- close(plane_fd);
- if (sync_file == -1) {
- sync_file = export_args.fd;
- } else {
- struct sync_merge_data merge_args = { 0 };
- merge_args.fd2 = export_args.fd;
- ioctl(sync_file, SYNC_IOC_MERGE, &merge_args);
- close(export_args.fd);
- close(sync_file);
- sync_file = merge_args.fence;
- }
- }
-#endif /* DMA_BUF_IOCTL_EXPORT_SYNC_FILE */
- return sync_file;
-}
-
-void
-xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
- struct xwl_pixmap *xwl_pixmap;
- int num_planes;
- int p;
-#ifndef GBM_BO_FD_FOR_PLANE
- int32_t first_handle;
-#endif
-
- if (!xwl_screen->glamor)
- return;
-
-#ifdef DMA_BUF_IOCTL_IMPORT_SYNC_FILE
- xwl_pixmap = xwl_pixmap_get(pixmap);
- num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
-
- for (p = 0; p < num_planes; ++p) {
- int plane_fd;
-#ifdef GBM_BO_FD_FOR_PLANE
- plane_fd = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, p);
-#else
- union gbm_bo_handle plane_handle =
- gbm_bo_get_handle_for_plane(xwl_pixmap->bo, p);
- if (p == 0)
- first_handle = plane_handle.s32;
-
- if (plane_handle.s32 == first_handle)
- plane_fd = gbm_bo_get_fd(xwl_pixmap->bo);
- else
- continue;
-#endif /* GBM_BO_FD_FOR_PLANE */
- struct dma_buf_import_sync_file import_args = { 0 };
- import_args.fd = sync_file;
- import_args.flags = DMA_BUF_SYNC_WRITE;
- drmIoctl(plane_fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_args);
- close(plane_fd);
- }
-#endif /* DMA_BUF_IOCTL_IMPORT_SYNC_FILE */
- close(sync_file);
-}
-
-#ifdef DRI3
-struct xwl_dri3_syncobj
-{
- struct dri3_syncobj base;
- uint32_t handle;
- struct wp_linux_drm_syncobj_timeline_v1 *timeline;
-};
-
-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)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_dri3_syncobj *xwl_acquire_syncobj = (struct xwl_dri3_syncobj *)acquire_syncobj;
- struct xwl_dri3_syncobj *xwl_release_syncobj = (struct xwl_dri3_syncobj *)release_syncobj;
- uint32_t acquire_hi = acquire_point >> 32;
- uint32_t acquire_lo = acquire_point & 0xffffffff;
- uint32_t release_hi = release_point >> 32;
- uint32_t release_lo = release_point & 0xffffffff;
-
- if (!xwl_window->surface_sync)
- xwl_window->surface_sync =
- wp_linux_drm_syncobj_manager_v1_get_surface(xwl_screen->explicit_sync,
- xwl_window->surface);
-
- wp_linux_drm_syncobj_surface_v1_set_acquire_point(xwl_window->surface_sync,
- xwl_acquire_syncobj->timeline,
- acquire_hi, acquire_lo);
- wp_linux_drm_syncobj_surface_v1_set_release_point(xwl_window->surface_sync,
- xwl_release_syncobj->timeline,
- release_hi, release_lo);
-}
-
-static Bool
-xwl_dri3_check_syncobj(struct dri3_syncobj *syncobj, uint64_t point, Bool check_avail)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- return !drmSyncobjTimelineWait(xwl_gbm->drm_fd,
- &xwl_syncobj->handle, &point, 1,
- 0 /* timeout */,
- check_avail ?
- DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE :
- DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
- NULL /* first_signaled */);
-}
-
-static Bool
-xwl_dri3_syncobj_has_fence(struct dri3_syncobj *syncobj, uint64_t point)
-{
- return xwl_dri3_check_syncobj(syncobj, point, TRUE /* check_avail */);
-}
-
-static Bool
-xwl_dri3_syncobj_is_signaled(struct dri3_syncobj *syncobj, uint64_t point)
-{
- return xwl_dri3_check_syncobj(syncobj, point, FALSE /* check_avail */);
-}
-
-static int
-xwl_dri3_syncobj_export_fence(struct dri3_syncobj *syncobj, uint64_t point)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- uint32_t temp_syncobj;
- int fd = -1;
-
- drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
- drmSyncobjTransfer(xwl_gbm->drm_fd, temp_syncobj, 0,
- xwl_syncobj->handle, point, 0);
- drmSyncobjExportSyncFile(xwl_gbm->drm_fd, temp_syncobj, &fd);
- drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
- return fd;
-}
-
-static void
-xwl_dri3_syncobj_import_fence(struct dri3_syncobj *syncobj,
- uint64_t point, int fd)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- uint32_t temp_syncobj;
-
- drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
- drmSyncobjImportSyncFile(xwl_gbm->drm_fd, temp_syncobj, fd);
- drmSyncobjTransfer(xwl_gbm->drm_fd, xwl_syncobj->handle, point,
- temp_syncobj, 0, 0);
- drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
- close(fd);
-}
-
-static void
-xwl_dri3_signal_syncobj(struct dri3_syncobj *syncobj, uint64_t point)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- drmSyncobjTimelineSignal(xwl_gbm->drm_fd, &xwl_syncobj->handle, &point, 1);
-}
-
-static void
-xwl_dri3_free_syncobj(struct dri3_syncobj *syncobj)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- if (xwl_syncobj->timeline)
- wp_linux_drm_syncobj_timeline_v1_destroy(xwl_syncobj->timeline);
-
- if (xwl_syncobj->handle)
- drmSyncobjDestroy(xwl_gbm->drm_fd, xwl_syncobj->handle);
-
- free(xwl_syncobj);
-}
-
-static void
-xwl_dri3_syncobj_eventfd(struct dri3_syncobj *syncobj, uint64_t point,
- int efd, Bool wait_avail)
-{
- struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
- struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- drmSyncobjEventfd(xwl_gbm->drm_fd, xwl_syncobj->handle, point, efd,
- wait_avail ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE : 0);
-}
-
-static void
-xwl_dri3_syncobj_submitted_eventfd(struct dri3_syncobj *syncobj,
- uint64_t point, int efd)
-{
- xwl_dri3_syncobj_eventfd(syncobj, point, efd, TRUE /* wait_avail */);
-}
-
-static void
-xwl_dri3_syncobj_signaled_eventfd(struct dri3_syncobj *syncobj,
- uint64_t point, int efd)
-{
- xwl_dri3_syncobj_eventfd(syncobj, point, efd, FALSE /* wait_avail */);
-}
-
-static struct dri3_syncobj *
-xwl_dri3_create_syncobj(struct xwl_screen *xwl_screen, uint32_t handle)
-{
- struct xwl_dri3_syncobj *syncobj = calloc(1, sizeof (*syncobj));
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- Bool create = !handle;
-
- if (!syncobj)
- return NULL;
-
- if (create && drmSyncobjCreate(xwl_gbm->drm_fd, 0, &handle))
- goto fail;
-
- if (xwl_screen->explicit_sync) {
- int syncobj_fd = -1;
- if (drmSyncobjHandleToFD(xwl_gbm->drm_fd, handle, &syncobj_fd))
- goto fail;
-
- syncobj->timeline =
- wp_linux_drm_syncobj_manager_v1_import_timeline(xwl_screen->explicit_sync,
- syncobj_fd);
- close(syncobj_fd);
- if (!syncobj->timeline)
- goto fail;
- }
-
- syncobj->handle = handle;
- syncobj->base.screen = xwl_screen->screen;
- syncobj->base.refcount = 1;
-
- syncobj->base.free = xwl_dri3_free_syncobj;
- syncobj->base.has_fence = xwl_dri3_syncobj_has_fence;
- syncobj->base.is_signaled = xwl_dri3_syncobj_is_signaled;
- syncobj->base.export_fence = xwl_dri3_syncobj_export_fence;
- syncobj->base.import_fence = xwl_dri3_syncobj_import_fence;
- syncobj->base.signal = xwl_dri3_signal_syncobj;
- syncobj->base.signaled_eventfd = xwl_dri3_syncobj_signaled_eventfd;
- syncobj->base.submitted_eventfd = xwl_dri3_syncobj_submitted_eventfd;
- return &syncobj->base;
-
-fail:
- if (create && handle)
- drmSyncobjDestroy(xwl_gbm->drm_fd, handle);
- free(syncobj);
- return NULL;
-}
-
-struct dri3_syncobj *
-xwl_glamor_dri3_syncobj_create(struct xwl_screen *xwl_screen)
-{
- return xwl_dri3_create_syncobj(xwl_screen, 0 /* allocate new handle */);
-}
-
-static struct dri3_syncobj *
-xwl_dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- struct xwl_dri3_syncobj *syncobj = NULL;
- uint32_t handle;
-
- if (drmSyncobjFDToHandle(xwl_gbm->drm_fd, fd, &handle))
- return NULL;
-
- syncobj = (struct xwl_dri3_syncobj *)xwl_dri3_create_syncobj(xwl_screen, handle);
- if (!syncobj) {
- drmSyncobjDestroy(xwl_gbm->drm_fd, handle);
- return NULL;
- }
-
- syncobj->base.id = id;
-
- return &syncobj->base;
-}
-
-static Bool
-xwl_gbm_supports_syncobjs(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- uint64_t syncobj_cap = 0;
-
- if (drmGetCap(xwl_gbm->drm_fd, DRM_CAP_SYNCOBJ_TIMELINE,
- &syncobj_cap) || !syncobj_cap)
- return FALSE;
-
- /* Check if syncobj eventfd is supported. */
- drmSyncobjEventfd(xwl_gbm->drm_fd, 0, 0, -1, 0);
- if (errno != ENOENT)
- return FALSE;
-
-#if !defined(DMA_BUF_IOCTL_EXPORT_SYNC_FILE) || \
- !defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE)
- return FALSE;
-#else
- return TRUE;
-#endif
-}
-
-static dri3_screen_info_rec xwl_dri3_info = {
- .version = 2,
- .open = NULL,
- .pixmap_from_fds = glamor_pixmap_from_fds,
- .fds_from_pixmap = glamor_fds_from_pixmap,
- .open_client = xwl_dri3_open_client,
- .get_formats = xwl_glamor_get_formats,
- .get_modifiers = xwl_glamor_get_modifiers,
- .get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
- .import_syncobj = NULL, /* need to check for kernel support */
-};
-#endif /* DRI3 */
-
-static const char *
-get_render_node_path_for_device(const drmDevicePtr drm_device,
- const char *device_path)
-{
- const char *render_node_path;
- int i;
-
- if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)))
- return NULL;
- render_node_path = drm_device->nodes[DRM_NODE_RENDER];
-
- for (i = 0; i < DRM_NODE_MAX; i++) {
- if (!(drm_device->available_nodes & (1 << i)))
- continue;
- if (strcmp(device_path, drm_device->nodes[i]) == 0)
- return render_node_path;
- }
-
- return NULL;
-}
-
-static char *
-get_render_node_path(const char *device_path)
-{
- drmDevicePtr *devices = NULL;
- char *render_node_path = NULL;
- int i, n_devices, max_devices;
-
- max_devices = drmGetDevices2(0, NULL, 0);
- if (max_devices <= 0)
- goto out;
-
- devices = calloc(max_devices, sizeof(drmDevicePtr));
- if (!devices)
- goto out;
-
- n_devices = drmGetDevices2(0, devices, max_devices);
- if (n_devices < 0)
- goto out;
-
- for (i = 0; i < n_devices; i++) {
- const char *node_path = get_render_node_path_for_device(devices[i],
- device_path);
- if (node_path) {
- render_node_path = strdup(node_path);
- break;
- }
- }
-
-out:
- free(devices);
- return render_node_path;
-}
-
-static void
-xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
-{
- struct xwl_screen *xwl_screen = data;
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- drm_magic_t magic;
- char *render_node_path = NULL;
-
- if (!is_device_path_render_node(device))
- render_node_path = get_render_node_path(device);
-
- if (render_node_path)
- xwl_gbm->device_name = render_node_path;
- else
- xwl_gbm->device_name = strdup(device);
-
- if (!xwl_gbm->device_name) {
- xwl_glamor_gbm_cleanup(xwl_screen);
- xwl_screen->expecting_event--;
- return;
- }
-
- xwl_gbm->drm_fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
- if (xwl_gbm->drm_fd == -1) {
- ErrorF("wayland-egl: could not open %s (%s)\n",
- xwl_gbm->device_name, strerror(errno));
- xwl_glamor_gbm_cleanup(xwl_screen);
- xwl_screen->expecting_event--;
- return;
- }
-
- if (drmGetDevice2(xwl_gbm->drm_fd, 0, &xwl_gbm->device) != 0) {
- ErrorF("wayland-egl: Could not fetch DRM device %s\n",
- xwl_gbm->device_name);
- xwl_screen->expecting_event--;
- return;
- }
-
- if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) {
- xwl_gbm->fd_render_node = TRUE;
- xwl_screen->expecting_event--;
- } else {
- drmGetMagic(xwl_gbm->drm_fd, &magic);
- wl_drm_authenticate(xwl_gbm->drm, magic);
- }
-}
-
-static void
-xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
-{
-}
-
-static void
-xwl_drm_handle_authenticated(void *data, struct wl_drm *drm)
-{
- struct xwl_screen *xwl_screen = data;
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- xwl_gbm->drm_authenticated = TRUE;
- xwl_screen->expecting_event--;
-}
-
-static void
-xwl_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
-{
- xwl_gbm_get(data)->capabilities = value;
-}
-
-static const struct wl_drm_listener xwl_drm_listener = {
- xwl_drm_handle_device,
- xwl_drm_handle_format,
- xwl_drm_handle_authenticated,
- xwl_drm_handle_capabilities
-};
-
-Bool
-xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- if (version < 2)
- return FALSE;
-
- xwl_gbm->drm =
- wl_registry_bind(xwl_screen->registry, id, &wl_drm_interface, 2);
- wl_drm_add_listener(xwl_gbm->drm, &xwl_drm_listener, xwl_screen);
- xwl_screen->expecting_event++;
-
- return TRUE;
-}
-
-Bool
-xwl_screen_set_syncobj_interface(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- xwl_screen->explicit_sync =
- wl_registry_bind(xwl_screen->registry, id,
- &wp_linux_drm_syncobj_manager_v1_interface,
- version);
- return TRUE;
-}
-
-static Bool
-xwl_glamor_gbm_has_egl_extension(void)
-{
- return (epoxy_has_egl_extension(NULL, "EGL_MESA_platform_gbm") ||
- epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
-}
-
-#ifdef DRI3
-static void
-xwl_glamor_gbm_release_fence_avail(int fd, int xevents, void *data)
-{
- struct xwl_pixmap *xwl_pixmap = data;
- struct xwl_window_buffer *xwl_window_buffer = xwl_pixmap->xwl_window_buffer;
-
- SetNotifyFd(fd, NULL, 0, NULL);
- close(fd);
- xwl_pixmap->efd = -1;
-
- xwl_window_buffer_release(xwl_window_buffer);
-}
-#endif /* DRI3 */
-
-Bool
-xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
-{
- /* absent glamor, implicit sync is irrelevant so just return TRUE */
- return !xwl_screen->glamor ||
- xwl_gbm_get(xwl_screen)->implicit_sync;
-}
-
-Bool
-xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen)
-{
- return xwl_screen->glamor &&
- xwl_gbm_get(xwl_screen)->supports_syncobjs;
-}
-
-Bool
-xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap)
-{
-#ifdef DRI3
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- uint64_t acquire_point;
- uint64_t release_point;
- int fence_fd;
-
- if (!xwl_screen->glamor)
- return FALSE;
-
- if (!xwl_pixmap) {
- ErrorF("XWAYLAND: Failed to set synchronization point, no backing xwl_pixmap!\n");
- return FALSE;
- }
-
- acquire_point = ++xwl_pixmap->timeline_point;
- release_point = ++xwl_pixmap->timeline_point;
-
- if (!xwl_pixmap->syncobj) {
- struct dri3_syncobj *syncobj = xwl_glamor_dri3_syncobj_create(xwl_screen);
- if (!syncobj)
- goto fail;
- xwl_pixmap->syncobj = syncobj;
- }
-
- fence_fd = xwl_glamor_get_fence(xwl_screen);
- if (fence_fd >= 0)
- xwl_pixmap->syncobj->import_fence(xwl_pixmap->syncobj, acquire_point, fence_fd);
- else
- goto fail;
-
- xwl_glamor_dri3_syncobj_passthrough(xwl_window,
- xwl_pixmap->syncobj,
- xwl_pixmap->syncobj,
- acquire_point,
- release_point);
- return TRUE;
-
-fail:
- /* can't use explicit sync, we will do a glFinish() before presenting */
- if (xwl_pixmap->syncobj) {
- xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
- xwl_pixmap->syncobj = NULL;
- }
-#endif /* DRI3 */
- return FALSE;
-}
-
-void
-xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap)
-{
-#ifdef DRI3
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
-
- if (!xwl_screen->glamor || !xwl_pixmap)
- return;
-
- if (xwl_pixmap->syncobj) {
- xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
- xwl_pixmap->syncobj = NULL;
- }
-
- if (xwl_pixmap->efd >= 0) {
- SetNotifyFd(xwl_pixmap->efd, NULL, 0, NULL);
- close(xwl_pixmap->efd);
- }
-#endif /* DRI3 */
-}
-
-void
-xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap)
-{
-#ifdef DRI3
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
-
- if (!xwl_screen->glamor || !xwl_pixmap)
- return;
-
- if (xwl_pixmap->syncobj) {
- int fence_fd = xwl_pixmap->syncobj->export_fence(xwl_pixmap->syncobj,
- xwl_pixmap->timeline_point);
-
- xwl_glamor_wait_fence(xwl_screen, fence_fd);
- }
-#endif /* DRI3 */
-}
-
-void
-xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
- PixmapPtr pixmap,
- struct xwl_window_buffer *xwl_window_buffer)
-{
-#ifdef DRI3
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
-
- if (!xwl_screen->glamor || !xwl_pixmap || !xwl_window_buffer)
- return;
-
- xwl_pixmap->xwl_window_buffer = xwl_window_buffer;
- /* wait until the release fence is available before re-using this buffer */
- xwl_pixmap->efd = eventfd(0, EFD_CLOEXEC);
- SetNotifyFd(xwl_pixmap->efd, xwl_glamor_gbm_release_fence_avail, X_NOTIFY_READ,
- xwl_pixmap);
- xwl_pixmap->syncobj->submitted_eventfd(xwl_pixmap->syncobj,
- xwl_pixmap->timeline_point,
- xwl_pixmap->efd);
-#endif /* DRI3 */
-}
-
-static Bool
-xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
-{
- if (xwl_screen->egl_context == EGL_NO_CONTEXT)
- return FALSE;
-
- return eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
- EGL_NO_SURFACE, xwl_screen->egl_context);
-}
-
-static void
-xwl_glamor_maybe_destroy_context(struct xwl_screen *xwl_screen)
-{
- if (xwl_screen->egl_context == EGL_NO_CONTEXT)
- return;
-
- eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(xwl_screen->egl_display, xwl_screen->egl_context);
- xwl_screen->egl_context = EGL_NO_CONTEXT;
-}
-
-static Bool
-xwl_glamor_try_big_gl_api(struct xwl_screen *xwl_screen)
-{
- static const EGLint config_attribs_core[] = {
- EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
- EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
- EGL_CONTEXT_MAJOR_VERSION_KHR,
- GLAMOR_GL_CORE_VER_MAJOR,
- EGL_CONTEXT_MINOR_VERSION_KHR,
- GLAMOR_GL_CORE_VER_MINOR,
- EGL_NONE
- };
- int gl_version;
-
- if (!(xwl_screen->glamor & XWL_GLAMOR_GL))
- return FALSE;
-
- eglBindAPI(EGL_OPENGL_API);
-
- xwl_screen->egl_context =
- eglCreateContext(xwl_screen->egl_display, EGL_NO_CONFIG_KHR,
- EGL_NO_CONTEXT, config_attribs_core);
-
- if (xwl_screen->egl_context == EGL_NO_CONTEXT)
- xwl_screen->egl_context =
- eglCreateContext(xwl_screen->egl_display, EGL_NO_CONFIG_KHR,
- EGL_NO_CONTEXT, NULL);
-
- if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
- ErrorF("Failed to make EGL context current with GL\n");
- xwl_glamor_maybe_destroy_context(xwl_screen);
- return FALSE;
- }
-
- /* glamor needs at least GL 2.1, if the GL version is less than 2.1,
- * drop the context we created, it's useless.
- */
- gl_version = epoxy_gl_version();
- if (gl_version < 21) {
- ErrorF("Supported GL version is not sufficient (required 21, found %i)\n",
- gl_version);
- xwl_glamor_maybe_destroy_context(xwl_screen);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-xwl_glamor_try_gles_api(struct xwl_screen *xwl_screen)
-{
- const EGLint gles_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION,
- 2,
- EGL_NONE,
- };
-
- if (!(xwl_screen->glamor & XWL_GLAMOR_GLES))
- return FALSE;
-
- eglBindAPI(EGL_OPENGL_ES_API);
-
- xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display,
- EGL_NO_CONFIG_KHR,
- EGL_NO_CONTEXT, gles_attribs);
-
- if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
- ErrorF("Failed to make EGL context current with GLES2\n");
- xwl_glamor_maybe_destroy_context(xwl_screen);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-xwl_glamor_gbm_init_main_dev(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- drmDevice *main_dev;
-
- while (!xwl_screen->default_feedback.feedback_done) {
- if (wl_display_dispatch(xwl_screen->display) < 0) {
- ErrorF("Failed to dispatch Wayland display\n");
- return FALSE;
- }
- }
-
- main_dev = xwl_screen->default_feedback.main_dev;
- if (!main_dev) {
- ErrorF("No main linux-dmabuf device advertised by compositor\n");
- return FALSE;
- }
-
- if (!(main_dev->available_nodes & (1 << DRM_NODE_RENDER))) {
- ErrorF("Main linux-dmabuf device has no render node\n");
- return FALSE;
- }
-
- xwl_gbm->device_name = strdup(main_dev->nodes[DRM_NODE_RENDER]);
- if (!xwl_gbm->device_name) {
- return FALSE;
- }
-
- xwl_gbm->drm_fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
- if (xwl_gbm->drm_fd < 0) {
- ErrorF("wayland-egl: could not open %s (%s)\n",
- xwl_gbm->device_name, strerror(errno));
- return FALSE;
- }
-
- if (drmGetDevice2(xwl_gbm->drm_fd, 0, &xwl_gbm->device) != 0) {
- ErrorF("wayland-egl: Could not fetch DRM device %s\n",
- xwl_gbm->device_name);
- return FALSE;
- }
-
- xwl_gbm->fd_render_node = TRUE;
- return TRUE;
-}
-
-Bool
-xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- EGLint major, minor;
- const GLubyte *renderer;
- const char *gbm_backend_name, *egl_vendor;
-
- if (!xwl_gbm->drm && !xwl_glamor_gbm_init_main_dev(xwl_screen))
- return FALSE;
-
- if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
- ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
- return FALSE;
- }
-
- xwl_gbm->gbm = gbm_create_device(xwl_gbm->drm_fd);
- if (!xwl_gbm->gbm) {
- ErrorF("couldn't create gbm device\n");
- goto error;
- }
-
- xwl_screen->egl_display = glamor_egl_get_display(EGL_PLATFORM_GBM_MESA,
- xwl_gbm->gbm);
- if (xwl_screen->egl_display == EGL_NO_DISPLAY) {
- ErrorF("glamor_egl_get_display() failed\n");
- goto error;
- }
-
- if (!eglInitialize(xwl_screen->egl_display, &major, &minor)) {
- ErrorF("eglInitialize() failed\n");
- goto error;
- }
-
- if (!xwl_glamor_try_big_gl_api(xwl_screen) &&
- !xwl_glamor_try_gles_api(xwl_screen)) {
- ErrorF("Cannot use neither GL nor GLES2\n");
- goto error;
- }
-
- renderer = glGetString(GL_RENDERER);
- if (!renderer) {
- ErrorF("glGetString() returned NULL, your GL is broken\n");
- goto error;
- }
- if (strstr((const char *)renderer, "softpipe")) {
- ErrorF("Refusing to try glamor on softpipe\n");
- goto error;
- }
- if (!strncmp("llvmpipe", (const char *)renderer, strlen("llvmpipe"))) {
- ErrorF("Refusing to try glamor on llvmpipe\n");
- goto error;
- }
-
- if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
- ErrorF("GL_OES_EGL_image not available\n");
- goto error;
- }
-
- if (epoxy_has_egl_extension(xwl_screen->egl_display,
- "EXT_image_dma_buf_import") &&
- epoxy_has_egl_extension(xwl_screen->egl_display,
- "EXT_image_dma_buf_import_modifiers"))
- xwl_gbm->dmabuf_capable = TRUE;
-
- gbm_backend_name = gbm_device_get_backend_name(xwl_gbm->gbm);
- /* Mesa uses "drm" as backend name, in that case, just do nothing */
- if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
- xwl_screen->glvnd_vendor = gbm_backend_name;
- xwl_gbm->glamor_gles = !epoxy_is_desktop_gl();
-
- egl_vendor = eglQueryString(xwl_screen->egl_display, EGL_VENDOR);
- if (!egl_vendor) {
- ErrorF("Could not determine EGL vendor\n");
- goto error;
- }
- /* NVIDIA driver does not support implicit sync */
- xwl_gbm->implicit_sync = !strstr(egl_vendor, "NVIDIA");
-#ifdef DRI3
- if (xwl_gbm_supports_syncobjs(xwl_screen) &&
- epoxy_has_egl_extension(xwl_screen->egl_display,
- "ANDROID_native_fence_sync"))
- xwl_gbm->supports_syncobjs = TRUE;
-
- if (!xwl_gbm->supports_syncobjs && xwl_screen->explicit_sync) {
- /* explicit sync requires syncobj support */
- wp_linux_drm_syncobj_manager_v1_destroy(xwl_screen->explicit_sync);
- xwl_screen->explicit_sync = NULL;
- }
-#endif /* DRI3 */
- return TRUE;
-error:
- if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
- xwl_glamor_maybe_destroy_context(xwl_screen);
- eglTerminate(xwl_screen->egl_display);
- xwl_screen->egl_display = EGL_NO_DISPLAY;
- }
-
- xwl_glamor_gbm_cleanup(xwl_screen);
- return FALSE;
-}
-
-Bool
-xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-#ifdef DRI3
- if (xwl_gbm->supports_syncobjs) {
- xwl_dri3_info.version = 4;
- xwl_dri3_info.import_syncobj = xwl_dri3_import_syncobj;
- }
-
- if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
- ErrorF("Failed to initialize dri3\n");
- goto error;
- }
-#endif /* DRI3 */
- if (xwl_gbm->fd_render_node)
- goto skip_drm_auth;
-
- if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT,
- 0)) {
- ErrorF("Failed to register private key\n");
- goto error;
- }
-
- if (!AddCallback(&ClientStateCallback, xwl_auth_state_client_callback,
- NULL)) {
- ErrorF("Failed to add client state callback\n");
- goto error;
- }
-
-skip_drm_auth:
- xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap;
- xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap;
-
- return TRUE;
-error:
- xwl_glamor_gbm_cleanup(xwl_screen);
- return FALSE;
-}
-
-drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- return xwl_gbm->device;
-}
-
-Bool
-xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
-{
- struct xwl_gbm_private *xwl_gbm;
-
- if (!xwl_glamor_gbm_has_egl_extension())
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0))
- return FALSE;
-
- xwl_gbm = calloc(1, sizeof(*xwl_gbm));
- if (!xwl_gbm) {
- ErrorF("glamor: Not enough memory to setup GBM, disabling\n");
- return FALSE;
- }
-
- dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
- xwl_gbm);
-
- return TRUE;
-}
diff --git a/hw/xwayland/xwayland-glamor-gbm.h b/hw/xwayland/xwayland-glamor-gbm.h
deleted file mode 100644
index b346a0ba6..000000000
--- a/hw/xwayland/xwayland-glamor-gbm.h
+++ /dev/null
@@ -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
-
-#include
-
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-glamor-xv.c b/hw/xwayland/xwayland-glamor-xv.c
deleted file mode 100644
index 68bae5737..000000000
--- a/hw/xwayland/xwayland-glamor-xv.c
+++ /dev/null
@@ -1,415 +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
- *
- * Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv
- * implementations
- */
-
-#include
-
-#include "glamor_priv.h"
-
-#include
-
-#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;
-
- CloseScreenProcPtr CloseScreen;
-} 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 = FakeClientID(0)))
- 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 Bool
-xwl_glamor_xv_close_screen(ScreenPtr pScreen)
-{
- xwlXvScreenPtr xwlXvScreen;
-
- xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
- xwlXvScreenPrivateKey);
-
- if (xwlXvScreen->glxv_adaptor) {
- XvFreeAdaptor(xwlXvScreen->glxv_adaptor);
- free(xwlXvScreen->glxv_adaptor);
- }
- free(xwlXvScreen->port_privates);
-
- pScreen->CloseScreen = xwlXvScreen->CloseScreen;
-
- return pScreen->CloseScreen(pScreen);
-}
-
-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;
- xwlXvScreen->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xwl_glamor_xv_close_screen;
-
- glamor_xv_core_init(pScreen);
-
- return xwl_glamor_xv_add_adaptors(pScreen);
-}
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
deleted file mode 100644
index b7f98d3ac..000000000
--- a/hw/xwayland/xwayland-glamor.c
+++ /dev/null
@@ -1,270 +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
-
-#define MESA_EGL_NO_X11_HEADERS
-#define EGL_NO_X11
-#include
-
-#include
-#include
-#include
-#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 "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
-
-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);
- int ret;
-
- screen->CreateScreenResources = xwl_screen->CreateScreenResources;
- ret = (*screen->CreateScreenResources) (screen);
- xwl_screen->CreateScreenResources = screen->CreateScreenResources;
- screen->CreateScreenResources = xwl_glamor_create_screen_resources;
-
- if (!ret)
- return ret;
-
- 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;
- }
-
- xwl_screen->CreateScreenResources = screen->CreateScreenResources;
- 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;
-}
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
deleted file mode 100644
index ef312a857..000000000
--- a/hw/xwayland/xwayland-glamor.h
+++ /dev/null
@@ -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
-
-#include
-
-#include
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
deleted file mode 100644
index 2ecf1026e..000000000
--- a/hw/xwayland/xwayland-input.c
+++ /dev/null
@@ -1,3689 +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.
- */
-
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "xwayland-cursor.h"
-#include "xwayland-input.h"
-#include "xwayland-window.h"
-#include "xwayland-screen.h"
-
-#ifdef XWL_HAS_EI
-#include "xwayland-xtest.h"
-#endif
-
-#include "pointer-constraints-unstable-v1-client-protocol.h"
-#include "relative-pointer-unstable-v1-client-protocol.h"
-#include "tablet-unstable-v2-client-protocol.h"
-#include "pointer-gestures-unstable-v1-client-protocol.h"
-#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
-#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
-#include "xdg-system-bell-v1-client-protocol.h"
-
-#define SCROLL_AXIS_HORIZ 2
-#define SCROLL_AXIS_VERT 3
-
-struct sync_pending {
- struct xorg_list l;
- DeviceIntPtr pending_dev;
-};
-
-static DevPrivateKeyRec xwl_tablet_private_key;
-
-static void
-xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator,
- double dx,
- double dy,
- double dx_unaccel,
- double dy_unaccel);
-static void
-xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emulator,
- struct xwl_window *xwl_window,
- SpritePtr sprite,
- int x, int y);
-
-static Bool
-xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat *xwl_seat);
-
-static void
-xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat);
-
-static void
-init_tablet_manager_seat(struct xwl_screen *xwl_screen,
- struct xwl_seat *xwl_seat);
-static void
-release_tablet_manager_seat(struct xwl_seat *xwl_seat);
-
-static void
-xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
-{
- /* Nothing to do, dix handles all settings */
-}
-
-static DeviceIntPtr
-get_pointer_device(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->relative_pointer)
- return xwl_seat->relative_pointer;
- else
- return xwl_seat->pointer;
-}
-
-static Bool
-init_pointer_buttons(DeviceIntPtr device)
-{
-#define NBUTTONS 10
- BYTE map[NBUTTONS + 1];
- int i = 0;
- Atom btn_labels[NBUTTONS] = { 0 };
-
- for (i = 1; i <= NBUTTONS; i++)
- map[i] = i;
-
- btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
- btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
- btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
- btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
- btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
- btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
- btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
- /* don't know about the rest */
-
- if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-maybe_fake_grab_devices(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct xwl_window *xwl_window;
-
- if (xwl_screen->rootless)
- return;
-
- if (!xwl_screen->host_grab)
- return;
-
- if (!xwl_screen->has_grab)
- return;
-
- if (!xwl_screen->screen->root)
- return;
-
- xwl_window = xwl_window_get(xwl_screen->screen->root);
- if (!xwl_window)
- return;
-
- xwl_seat_confine_pointer(xwl_seat, xwl_window);
-
- if (!xwl_screen->shortcuts_inhibit_manager)
- return;
-
- if (xwl_screen->shortcuts_inhibit)
- return;
-
- xwl_screen->shortcuts_inhibit =
- zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts (
- xwl_screen->shortcuts_inhibit_manager,
- xwl_window->surface,
- xwl_seat->seat);
-}
-
-static void
-maybe_fake_ungrab_devices(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
-
- xwl_seat_unconfine_pointer(xwl_seat);
-
- if (!xwl_screen->shortcuts_inhibit)
- return;
-
- zwp_keyboard_shortcuts_inhibitor_v1_destroy (xwl_screen->shortcuts_inhibit);
- xwl_screen->shortcuts_inhibit = NULL;
-}
-
-static int
-xwl_pointer_proc(DeviceIntPtr device, int what)
-{
-#define NAXES 4
- Atom axes_labels[NAXES] = { 0 };
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- if (!init_pointer_buttons(device))
- return BadValue;
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
- axes_labels[SCROLL_AXIS_HORIZ] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
- axes_labels[SCROLL_AXIS_VERT] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Absolute))
- return BadValue;
-
- /* Valuators */
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- 0, 0xFFFF, 10000, 0, 10000, Absolute);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- 0, 0xFFFF, 10000, 0, 10000, Absolute);
- InitValuatorAxisStruct(device, SCROLL_AXIS_HORIZ, axes_labels[2],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
- InitValuatorAxisStruct(device, SCROLL_AXIS_VERT, axes_labels[3],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
-
- SetScrollValuator(device, SCROLL_AXIS_HORIZ, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
- SetScrollValuator(device, SCROLL_AXIS_VERT, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED);
-
- if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
- return BadValue;
-
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-
-#undef NBUTTONS
-#undef NAXES
-}
-
-static int
-xwl_pointer_proc_relative(DeviceIntPtr device, int what)
-{
-#define NAXES 4
- Atom axes_labels[NAXES] = { 0 };
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
- axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
- axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
-
- /*
- * We'll never send buttons, but XGetPointerMapping might in certain
- * situations make the client think we have no buttons.
- */
- if (!init_pointer_buttons(device))
- return BadValue;
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Relative))
- return BadValue;
-
- /* Valuators */
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
- InitValuatorAxisStruct(device, 2, axes_labels[2],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
- InitValuatorAxisStruct(device, 3, axes_labels[3],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
-
- SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
- SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED);
-
- if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
- return BadValue;
-
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-
-#undef NAXES
-}
-
-static int
-xwl_pointer_proc_pointer_gestures(DeviceIntPtr device, int what)
-{
-#define NTOUCHPOINTS 20
-#define NAXES 2
- Atom axes_labels[NAXES] = { 0 };
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- /* We need to setup a pointer device so that the device is attached to
- master pointer device.
- */
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
-
- /*
- * We'll never send buttons, but XGetPointerMapping might in certain
- * situations make the client think we have no buttons.
- */
- if (!init_pointer_buttons(device))
- return BadValue;
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Relative))
- return BadValue;
-
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
-
- InitGestureClassDeviceStruct(device, NTOUCHPOINTS);
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-
-#undef NTOUCHPOINTS
-#undef NAXES
-}
-
-static void
-xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
-{
-}
-
-static int
-xwl_keyboard_proc(DeviceIntPtr device, int what)
-{
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- int len;
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
- if (xwl_seat->keymap)
- len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size);
- else
- len = 0;
- if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap,
- len,
- NULL, xwl_keyboard_control))
- return BadValue;
-
- return Success;
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-}
-
-static int
-xwl_touch_proc(DeviceIntPtr device, int what)
-{
-#define NTOUCHPOINTS 20
-#define NBUTTONS 1
-#define NAXES 2
- Atom btn_labels[NBUTTONS] = { 0 };
- Atom axes_labels[NAXES] = { 0 };
- BYTE map[NBUTTONS + 1] = { 0 };
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y);
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Absolute))
- return BadValue;
-
- if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
- return BadValue;
-
- if (!InitTouchClassDeviceStruct(device, NTOUCHPOINTS,
- XIDirectTouch, NAXES))
- return BadValue;
-
- /* Valuators */
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- 0, 0xFFFF, 10000, 0, 10000, Absolute);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- 0, 0xFFFF, 10000, 0, 10000, Absolute);
-
- if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
- return BadValue;
-
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-#undef NAXES
-#undef NBUTTONS
-#undef NTOUCHPOINTS
-}
-
-static int
-xwl_tablet_proc(DeviceIntPtr device, int what)
-{
-#define NBUTTONS 9
-#define NAXES 6
- Atom btn_labels[NBUTTONS] = { 0 };
- Atom axes_labels[NAXES] = { 0 };
- BYTE map[NBUTTONS + 1] = { 0 };
- int i;
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- for (i = 1; i <= NBUTTONS; i++)
- map[i] = i;
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
- axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
- axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
- axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
- axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL);
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Absolute))
- return BadValue;
-
- /* Valuators - match the xf86-input-wacom ranges */
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- 0, 262143, 10000, 0, 10000, Absolute);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- 0, 262143, 10000, 0, 10000, Absolute);
- /* pressure */
- InitValuatorAxisStruct(device, 2, axes_labels[2],
- 0, 65535, 1, 0, 1, Absolute);
- /* tilt x */
- InitValuatorAxisStruct(device, 3, axes_labels[3],
- -64, 63, 57, 0, 57, Absolute);
- /* tilt y */
- InitValuatorAxisStruct(device, 4, axes_labels[4],
- -64, 63, 57, 0, 57, Absolute);
- /* abs wheel (airbrush) or rotation (artpen) */
- InitValuatorAxisStruct(device, 5, axes_labels[5],
- -900, 899, 1, 0, 1, Absolute);
-
- if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
- return BadValue;
-
- if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map))
- return BadValue;
-
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-#undef NAXES
-#undef NBUTTONS
-}
-
-static void
-pointer_handle_enter(void *data, struct wl_pointer *pointer,
- uint32_t serial, struct wl_surface *surface,
- wl_fixed_t sx_w, wl_fixed_t sy_w)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- DeviceIntPtr dev = get_pointer_device(xwl_seat);
- DeviceIntPtr master;
- int i;
- int sx, sy;
- int dx, dy;
- ScreenPtr pScreen = xwl_screen->screen;
- xwl_seat->pointer_enter_count++;
- ValuatorMask mask;
- DeviceEvent enter;
-
- /* There's a race here where if we create and then immediately
- * destroy a surface, we might end up in a state where the Wayland
- * compositor sends us an event for a surface that doesn't exist.
- *
- * Don't process enter events in this case.
- */
- if (surface == NULL)
- return;
-
- if (!is_surface_from_xwl_window(surface))
- return;
-
- sx = wl_fixed_to_int(sx_w) * xwl_screen->global_surface_scale;
- sy = wl_fixed_to_int(sy_w) * xwl_screen->global_surface_scale;
-
- xwl_seat->xwl_screen->serial = serial;
- xwl_seat->pointer_enter_serial = serial;
-
- xwl_seat->focus_window = wl_surface_get_user_data(surface);
- dx = xwl_seat->focus_window->toplevel->drawable.x;
- dy = xwl_seat->focus_window->toplevel->drawable.y;
-
- /* We just entered a new xwindow, forget about the old last xwindow */
- xwl_seat->last_focus_window = NULL;
-
- master = GetMaster(dev, POINTER_OR_FLOAT);
- (*pScreen->SetCursorPosition) (dev, pScreen, dx + sx, dy + sy, TRUE);
-
- miPointerInvalidateSprite(master);
- init_device_event(&enter, dev, currentTime.milliseconds, EVENT_SOURCE_FOCUS);
- enter.type = ET_Enter;
-
- CheckMotion(&enter, master);
-
- /* Ideally, X clients shouldn't see these button releases. When
- * the pointer leaves a window with buttons down, it means that
- * the wayland compositor has grabbed the pointer. The button
- * release event is consumed by whatever grab in the compositor
- * and won't be sent to clients (the X server is a client).
- * However, we need to reset X's idea of which buttons are up and
- * down, and they're all up (by definition) when the pointer
- * enters a window. We should figure out a way to swallow these
- * events, perhaps using an X grab whenever the pointer is not in
- * any X window, but for now just send the events. */
- valuator_mask_zero(&mask);
- for (i = 0; i < dev->button->numButtons; i++)
- if (BitIsOn(dev->button->down, i))
- QueuePointerEvents(dev, ButtonRelease, i, 0, &mask);
-
- /* The last cursor frame we committed before the pointer left one
- * of our surfaces might not have been shown. In that case we'll
- * have a cursor surface frame callback pending which we need to
- * clear so that we can continue submitting new cursor frames. */
- if (xwl_cursor_clear_frame_cb(&xwl_seat->cursor))
- xwl_seat_set_cursor(xwl_seat);
-
- if (xwl_seat->pointer_warp_emulator) {
- xwl_pointer_warp_emulator_maybe_lock(xwl_seat->pointer_warp_emulator,
- xwl_seat->focus_window,
- NULL, 0, 0);
- }
- else {
- xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat);
- }
-
- maybe_fake_grab_devices(xwl_seat);
-}
-
-void
-xwl_seat_leave_ptr(struct xwl_seat *xwl_seat, Bool focus_lost)
-{
- DeviceIntPtr dev = get_pointer_device(xwl_seat);
-
- if (!dev)
- return;
-
- if (focus_lost)
- CheckMotion(NULL, GetMaster(dev, POINTER_OR_FLOAT));
-
- maybe_fake_ungrab_devices(xwl_seat);
-}
-
-static void
-pointer_handle_leave(void *data, struct wl_pointer *pointer,
- uint32_t serial, struct wl_surface *surface)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- Bool focus_lost = FALSE;
-
- xwl_screen->serial = serial;
- BUG_WARN(xwl_seat->pointer_enter_count == 0);
- if (xwl_seat->pointer_enter_count > 0)
- xwl_seat->pointer_enter_count--;
-
- /* The pointer has left a known xwindow, save it for a possible match
- * in sprite_check_lost_focus()
- */
- if (xwl_seat->focus_window) {
- xwl_seat->last_focus_window = xwl_seat->focus_window;
- xwl_seat->focus_window = NULL;
- focus_lost = TRUE;
- }
-
- if (xwl_screen->rootless)
- xwl_seat_leave_ptr(xwl_seat, focus_lost);
-}
-
-static void
-dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- double dx, dx_unaccel;
- double dy, dy_unaccel;
-
- dx = xwl_seat->pending_pointer_event.dx;
- dy = xwl_seat->pending_pointer_event.dy;
- dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
- dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
-
- dx *= xwl_screen->global_surface_scale;
- dy *= xwl_screen->global_surface_scale;
- dx_unaccel *= xwl_screen->global_surface_scale;
- dy_unaccel *= xwl_screen->global_surface_scale;
-
- dx *= xwl_seat->focus_window->viewport_scale_x;
- dy *= xwl_seat->focus_window->viewport_scale_y;
- dx_unaccel *= xwl_seat->focus_window->viewport_scale_x;
- dy_unaccel *= xwl_seat->focus_window->viewport_scale_y;
-
- xwl_pointer_warp_emulator_handle_motion(xwl_seat->pointer_warp_emulator,
- dx, dy,
- dx_unaccel, dy_unaccel);
-}
-
-static void
-dispatch_absolute_motion(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- ValuatorMask mask;
- DeviceIntPtr device;
- int flags;
- int event_x = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
- int event_y = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
- int drawable_x = xwl_seat->focus_window->toplevel->drawable.x;
- int drawable_y = xwl_seat->focus_window->toplevel->drawable.y;
- int x;
- int y;
-
- event_x *= xwl_screen->global_surface_scale;
- event_y *= xwl_screen->global_surface_scale;
-
- event_x *= xwl_seat->focus_window->viewport_scale_x;
- event_y *= xwl_seat->focus_window->viewport_scale_y;
-
- x = drawable_x + event_x;
- y = drawable_y + event_y;
-
- valuator_mask_zero(&mask);
- valuator_mask_set(&mask, 0, x);
- valuator_mask_set(&mask, 1, y);
-
- if (xwl_seat->pending_pointer_event.has_relative) {
- flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
- device = xwl_seat->relative_pointer;
- } else {
- flags = POINTER_ABSOLUTE | POINTER_SCREEN;
- device = xwl_seat->pointer;
- }
-
- QueuePointerEvents(device, MotionNotify, 0, flags, &mask);
-}
-
-static void
-dispatch_relative_motion(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- ValuatorMask mask;
- double event_dx = xwl_seat->pending_pointer_event.dx;
- double event_dy = xwl_seat->pending_pointer_event.dy;
- double event_dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
- double event_dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
-
- event_dx *= xwl_screen->global_surface_scale;
- event_dy *= xwl_screen->global_surface_scale;
- event_dx_unaccel *= xwl_screen->global_surface_scale;
- event_dy_unaccel *= xwl_screen->global_surface_scale;
-
- event_dx *= xwl_seat->focus_window->viewport_scale_x;
- event_dy *= xwl_seat->focus_window->viewport_scale_y;
- event_dx_unaccel *= xwl_seat->focus_window->viewport_scale_x;
- event_dy_unaccel *= xwl_seat->focus_window->viewport_scale_y;
-
- valuator_mask_zero(&mask);
- valuator_mask_set_unaccelerated(&mask, 0, event_dx, event_dx_unaccel);
- valuator_mask_set_unaccelerated(&mask, 1, event_dy, event_dy_unaccel);
-
- QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
- POINTER_RAWONLY, &mask);
-}
-
-static void
-dispatch_scroll_motion(struct xwl_seat *xwl_seat)
-{
- ValuatorMask mask;
- const int divisor = 10;
- wl_fixed_t dy = xwl_seat->pending_pointer_event.scroll_dy;
- wl_fixed_t dx = xwl_seat->pending_pointer_event.scroll_dx;
- int32_t dy_v120 = xwl_seat->pending_pointer_event.scroll_dy_v120;
- int32_t dx_v120 = xwl_seat->pending_pointer_event.scroll_dx_v120;
-
- valuator_mask_zero(&mask);
- if (xwl_seat->pending_pointer_event.has_vertical_scroll_v120)
- valuator_mask_set_double(&mask, SCROLL_AXIS_VERT, dy_v120 / 120.0);
- else if (xwl_seat->pending_pointer_event.has_vertical_scroll)
- valuator_mask_set_double(&mask,
- SCROLL_AXIS_VERT,
- wl_fixed_to_double(dy) / divisor);
-
- if (xwl_seat->pending_pointer_event.has_horizontal_scroll_v120)
- valuator_mask_set_double(&mask, SCROLL_AXIS_HORIZ, dx_v120 / 120.0);
- else if (xwl_seat->pending_pointer_event.has_horizontal_scroll)
- valuator_mask_set_double(&mask,
- SCROLL_AXIS_HORIZ,
- wl_fixed_to_double(dx) / divisor);
-
- QueuePointerEvents(get_pointer_device(xwl_seat),
- MotionNotify, 0, POINTER_RELATIVE, &mask);
-}
-
-static void
-dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
-{
- Bool has_relative = xwl_seat->pending_pointer_event.has_relative;
- Bool has_absolute = xwl_seat->pending_pointer_event.has_absolute;
-
- if (xwl_seat->pointer_warp_emulator && has_relative) {
- dispatch_relative_motion_with_warp(xwl_seat);
- } else {
- if (has_relative)
- dispatch_relative_motion(xwl_seat);
-
- if (has_absolute)
- dispatch_absolute_motion(xwl_seat);
- }
-
- if (xwl_seat->pending_pointer_event.has_vertical_scroll ||
- xwl_seat->pending_pointer_event.has_horizontal_scroll ||
- xwl_seat->pending_pointer_event.has_vertical_scroll_v120 ||
- xwl_seat->pending_pointer_event.has_horizontal_scroll_v120)
- dispatch_scroll_motion(xwl_seat);
-
- xwl_seat->pending_pointer_event.has_absolute = FALSE;
- xwl_seat->pending_pointer_event.has_relative = FALSE;
- xwl_seat->pending_pointer_event.has_vertical_scroll = FALSE;
- xwl_seat->pending_pointer_event.has_horizontal_scroll = FALSE;
- xwl_seat->pending_pointer_event.has_vertical_scroll_v120 = FALSE;
- xwl_seat->pending_pointer_event.has_horizontal_scroll_v120 = FALSE;
-}
-
-static void
-pointer_handle_motion(void *data, struct wl_pointer *pointer,
- uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
-{
- struct xwl_seat *xwl_seat = data;
-
- if (!xwl_seat->focus_window)
- return;
-
- xwl_seat->pending_pointer_event.has_absolute = TRUE;
- xwl_seat->pending_pointer_event.x = sx_w;
- xwl_seat->pending_pointer_event.y = sy_w;
-
- if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
- dispatch_pointer_motion_event(xwl_seat);
-}
-
-static void
-pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
- uint32_t time, uint32_t button, uint32_t state)
-{
- struct xwl_seat *xwl_seat = data;
- int index;
- ValuatorMask mask;
-
- xwl_seat->xwl_screen->serial = serial;
-
- switch (button) {
- case BTN_LEFT:
- index = 1;
- break;
- case BTN_MIDDLE:
- index = 2;
- break;
- case BTN_RIGHT:
- index = 3;
- break;
- default:
- /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
- The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
- index = 8 + button - BTN_SIDE;
- break;
- }
-
- valuator_mask_zero(&mask);
- QueuePointerEvents(get_pointer_device(xwl_seat),
- state ? ButtonPress : ButtonRelease, index, 0, &mask);
-}
-
-static void
-pointer_handle_axis(void *data, struct wl_pointer *pointer,
- uint32_t time, uint32_t axis, wl_fixed_t value)
-{
- struct xwl_seat *xwl_seat = data;
-
- switch (axis) {
- case WL_POINTER_AXIS_VERTICAL_SCROLL:
- xwl_seat->pending_pointer_event.has_vertical_scroll = TRUE;
- xwl_seat->pending_pointer_event.scroll_dy = value;
- break;
- case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
- xwl_seat->pending_pointer_event.has_horizontal_scroll = TRUE;
- xwl_seat->pending_pointer_event.scroll_dx = value;
- break;
- }
-}
-
-static void
-pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
-{
- struct xwl_seat *xwl_seat = data;
-
- if (!xwl_seat->focus_window)
- return;
-
- dispatch_pointer_motion_event(xwl_seat);
-}
-
-static void
-pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source)
-{
-}
-
-static void
-pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
- uint32_t time, uint32_t axis)
-{
- struct xwl_seat *xwl_seat = data;
-
- switch (axis) {
- case WL_POINTER_AXIS_VERTICAL_SCROLL:
- xwl_seat->pending_pointer_event.has_vertical_scroll = TRUE;
- xwl_seat->pending_pointer_event.scroll_dy = 0;
- break;
- case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
- xwl_seat->pending_pointer_event.has_horizontal_scroll = TRUE;
- xwl_seat->pending_pointer_event.scroll_dx = 0;
- break;
- }
-}
-
-static void
-pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
- uint32_t axis, int32_t discrete)
-{
- struct xwl_seat *xwl_seat = data;
-
- switch (axis) {
- case WL_POINTER_AXIS_VERTICAL_SCROLL:
- xwl_seat->pending_pointer_event.has_vertical_scroll_v120 = TRUE;
- xwl_seat->pending_pointer_event.scroll_dy_v120 = 120 * discrete;
- break;
- case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
- xwl_seat->pending_pointer_event.has_horizontal_scroll_v120 = TRUE;
- xwl_seat->pending_pointer_event.scroll_dx_v120 = 120 * discrete;
- break;
- }
-}
-
-static void
-pointer_handle_axis_v120(void *data, struct wl_pointer *pointer,
- uint32_t axis, int32_t v120)
-{
- struct xwl_seat *xwl_seat = data;
-
- switch (axis) {
- case WL_POINTER_AXIS_VERTICAL_SCROLL:
- xwl_seat->pending_pointer_event.has_vertical_scroll_v120 = TRUE;
- xwl_seat->pending_pointer_event.scroll_dy_v120 = v120;
- break;
- case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
- xwl_seat->pending_pointer_event.has_horizontal_scroll_v120 = TRUE;
- xwl_seat->pending_pointer_event.scroll_dx_v120 = v120;
- break;
- }
-}
-
-static const struct wl_pointer_listener pointer_listener = {
- pointer_handle_enter,
- pointer_handle_leave,
- pointer_handle_motion,
- pointer_handle_button,
- pointer_handle_axis,
- pointer_handle_frame,
- pointer_handle_axis_source,
- pointer_handle_axis_stop,
- pointer_handle_axis_discrete,
- pointer_handle_axis_v120,
-};
-
-static void
-relative_pointer_handle_relative_motion(void *data,
- struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
- uint32_t utime_hi,
- uint32_t utime_lo,
- wl_fixed_t dxf,
- wl_fixed_t dyf,
- wl_fixed_t dx_unaccelf,
- wl_fixed_t dy_unaccelf)
-{
- struct xwl_seat *xwl_seat = data;
-
- xwl_seat->pending_pointer_event.has_relative = TRUE;
- xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf);
- xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf);
- xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf);
- xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf);
-
- if (!xwl_seat->focus_window)
- return;
-
- if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
- dispatch_pointer_motion_event(xwl_seat);
-}
-
-static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
- relative_pointer_handle_relative_motion,
-};
-
-static void
-pointer_gesture_swipe_handle_begin(void *data,
- struct zwp_pointer_gesture_swipe_v1 *swipe,
- uint32_t serial,
- uint32_t time,
- struct wl_surface *surface,
- uint32_t fingers)
-{
- struct xwl_seat *xwl_seat = data;
-
- if (surface != NULL && !is_surface_from_xwl_window(surface))
- return;
-
- xwl_seat->pointer_gesture_swipe_fingers = fingers;
- QueueGestureSwipeEvents(xwl_seat->pointer_gestures,
- XI_GestureSwipeBegin, fingers, 0, 0.0, 0.0, 0.0, 0.0);
-}
-
-static void
-pointer_gesture_swipe_handle_update(void *data,
- struct zwp_pointer_gesture_swipe_v1 *swipe,
- uint32_t time,
- wl_fixed_t dxf,
- wl_fixed_t dyf)
-{
- struct xwl_seat *xwl_seat = data;
- double dx = wl_fixed_to_double(dxf);
- double dy = wl_fixed_to_double(dyf);
-
- QueueGestureSwipeEvents(xwl_seat->pointer_gestures,
- XI_GestureSwipeUpdate,
- xwl_seat->pointer_gesture_swipe_fingers,
- 0,
- dx, dy,
- dx, dy);
-}
-
-static void
-pointer_gesture_swipe_handle_end(void *data,
- struct zwp_pointer_gesture_swipe_v1 *swipe,
- uint32_t serial,
- uint32_t time,
- int32_t cancelled)
-{
- struct xwl_seat *xwl_seat = data;
- uint32_t flags = 0;
-
- if (cancelled)
- flags |= XIGestureSwipeEventCancelled;
-
- QueueGestureSwipeEvents(xwl_seat->pointer_gestures,
- XI_GestureSwipeEnd,
- xwl_seat->pointer_gesture_swipe_fingers,
- flags, 0.0, 0.0, 0.0, 0.0);
-}
-
-static const struct zwp_pointer_gesture_swipe_v1_listener pointer_gesture_swipe_listener = {
- pointer_gesture_swipe_handle_begin,
- pointer_gesture_swipe_handle_update,
- pointer_gesture_swipe_handle_end
-};
-
-static void
-pointer_gesture_pinch_handle_begin(void *data,
- struct zwp_pointer_gesture_pinch_v1 *pinch,
- uint32_t serial,
- uint32_t time,
- struct wl_surface *surface,
- uint32_t fingers)
-{
- struct xwl_seat *xwl_seat = data;
-
- if (surface != NULL && !is_surface_from_xwl_window(surface))
- return;
-
- xwl_seat->pointer_gesture_pinch_fingers = fingers;
- xwl_seat->pointer_gesture_pinch_last_scale = 1.0;
- QueueGesturePinchEvents(xwl_seat->pointer_gestures,
- XI_GesturePinchBegin, fingers, 0, 0.0, 0.0, 0.0, 0.0,
- 1.0, 0.0);
-}
-
-static void
-pointer_gesture_pinch_handle_update(void *data,
- struct zwp_pointer_gesture_pinch_v1 *pinch,
- uint32_t time,
- wl_fixed_t dxf,
- wl_fixed_t dyf,
- wl_fixed_t scalef,
- wl_fixed_t rotation)
-{
- struct xwl_seat *xwl_seat = data;
- double dx = wl_fixed_to_double(dxf);
- double dy = wl_fixed_to_double(dyf);
- double scale = wl_fixed_to_double(scalef);
-
- xwl_seat->pointer_gesture_pinch_last_scale = scale;
- QueueGesturePinchEvents(xwl_seat->pointer_gestures,
- XI_GesturePinchUpdate,
- xwl_seat->pointer_gesture_pinch_fingers,
- 0,
- dx, dy,
- dx, dy,
- scale, wl_fixed_to_double(rotation));
-}
-
-static void
-pointer_gesture_pinch_handle_end(void *data,
- struct zwp_pointer_gesture_pinch_v1 *pinch,
- uint32_t serial,
- uint32_t time,
- int32_t cancelled)
-{
- struct xwl_seat *xwl_seat = data;
- uint32_t flags = 0;
-
- if (cancelled)
- flags |= XIGesturePinchEventCancelled;
-
- QueueGesturePinchEvents(xwl_seat->pointer_gestures,
- XI_GesturePinchEnd,
- xwl_seat->pointer_gesture_pinch_fingers,
- flags, 0.0, 0.0, 0.0, 0.0,
- xwl_seat->pointer_gesture_pinch_last_scale, 0.0);
-}
-
-static const struct zwp_pointer_gesture_pinch_v1_listener pointer_gesture_pinch_listener = {
- pointer_gesture_pinch_handle_begin,
- pointer_gesture_pinch_handle_update,
- pointer_gesture_pinch_handle_end
-};
-
-static void
-maybe_toggle_fake_grab(struct xwl_seat *xwl_seat, uint32_t key)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct xwl_window *xwl_window;
- XkbStateRec state_rec;
- uint32_t xkb_state;
-
- if (xwl_screen->rootless)
- return;
-
- if (!xwl_screen->host_grab)
- return;
-
- state_rec = xwl_seat->keyboard->key->xkbInfo->state;
- xkb_state = (XkbStateFieldFromRec(&state_rec) & 0xff);
-
- if (((key == KEY_LEFTSHIFT || key == KEY_RIGHTSHIFT) && (xkb_state & ControlMask)) ||
- ((key == KEY_LEFTCTRL || key == KEY_RIGHTCTRL) && (xkb_state & ShiftMask))) {
-
- xwl_screen->has_grab = !xwl_screen->has_grab;
-
- if (xwl_screen->has_grab)
- maybe_fake_grab_devices(xwl_seat);
- else
- maybe_fake_ungrab_devices(xwl_seat);
-
- xwl_window = xwl_window_get(xwl_screen->screen->root);
- if (xwl_window)
- xwl_window_rootful_update_title(xwl_window);
- }
-}
-
-static void
-keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
- uint32_t time, uint32_t key, uint32_t state)
-{
- struct xwl_seat *xwl_seat = data;
- uint32_t *k, *end;
-
- xwl_seat->xwl_screen->serial = serial;
-
- end = (uint32_t *) ((char *) xwl_seat->keys.data + xwl_seat->keys.size);
- for (k = xwl_seat->keys.data; k < end; k++) {
- if (*k == key)
- *k = *--end;
- }
- xwl_seat->keys.size = (char *) end - (char *) xwl_seat->keys.data;
- if (state) {
- k = wl_array_add(&xwl_seat->keys, sizeof *k);
- *k = key;
- }
-
- QueueKeyboardEvents(xwl_seat->keyboard,
- state ? KeyPress : KeyRelease, key + 8);
-
- if (!state)
- maybe_toggle_fake_grab(xwl_seat, key);
-}
-
-static void
-keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
- uint32_t format, int fd, uint32_t size)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- DeviceIntPtr master;
- XkbDescPtr xkb;
- XkbChangesRec changes = { 0 };
-
- if (xwl_screen->nokeymap)
- return;
-
- if (xwl_seat->keymap)
- munmap(xwl_seat->keymap, xwl_seat->keymap_size);
-
- xwl_seat->keymap_size = size;
- xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (xwl_seat->keymap == MAP_FAILED) {
- xwl_seat->keymap_size = 0;
- xwl_seat->keymap = NULL;
- goto out;
- }
-
- xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap,
- strnlen(xwl_seat->keymap,
- xwl_seat->keymap_size));
- if (!xkb)
- goto out;
-
- XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes);
-
- memcpy(
- xwl_seat->keyboard->kbdfeed->ctrl.autoRepeats,
- xkb->ctrls->per_key_repeat,
- XkbPerKeyBitArraySize
- );
- if (xwl_seat->keyboard->key) {
- /* Keep the current controls */
- XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc);
- memcpy(
- xkb->ctrls->per_key_repeat,
- xwl_seat->keyboard->kbdfeed->ctrl.autoRepeats,
- XkbPerKeyBitArraySize
- );
- }
-
- XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb);
- xwl_seat->keyboard->hasDdxKeymap = TRUE;
-
- master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
- if (master) {
- XkbDeviceApplyKeymap(master, xkb);
- master->hasDdxKeymap = TRUE;
- }
-
- XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE);
-
- out:
- close(fd);
-}
-
-static void
-keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
- uint32_t serial,
- struct wl_surface *surface, struct wl_array *keys)
-{
- struct xwl_seat *xwl_seat = data;
- uint32_t *k;
-
- if (surface != NULL && !is_surface_from_xwl_window(surface))
- return;
-
- xwl_seat->xwl_screen->serial = serial;
- xwl_seat->keyboard_focus = surface;
-
- /* If `leave` wasn't sent (for a destroyed surface), release keys here. */
- wl_array_for_each(k, &xwl_seat->keys)
- QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
-
- wl_array_copy(&xwl_seat->keys, keys);
- wl_array_for_each(k, &xwl_seat->keys)
- QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8);
-
- maybe_fake_grab_devices(xwl_seat);
-}
-
-void
-xwl_seat_leave_kbd(struct xwl_seat *xwl_seat)
-{
- uint32_t *k;
-
- wl_array_for_each(k, &xwl_seat->keys)
- QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
- xwl_seat->keys.size = 0;
-
- xwl_seat->keyboard_focus = NULL;
-
- maybe_fake_ungrab_devices(xwl_seat);
-}
-
-static void
-keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, struct wl_surface *surface)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
-
- xwl_screen->serial = serial;
-
- if (xwl_screen->rootless)
- xwl_seat_leave_kbd(xwl_seat);
-}
-
-static void
-keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, uint32_t mods_depressed,
- uint32_t mods_latched, uint32_t mods_locked,
- uint32_t group)
-{
- struct xwl_seat *xwl_seat = data;
- DeviceIntPtr dev;
- XkbStateRec old_state, *new_state;
- xkbStateNotify sn;
- CARD16 changed;
-
- mieqProcessInputEvents();
-
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev != xwl_seat->keyboard &&
- dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
- continue;
-
- old_state = dev->key->xkbInfo->state;
- new_state = &dev->key->xkbInfo->state;
-
- new_state->base_group = 0;
- new_state->latched_group = 0;
- new_state->locked_group = group & XkbAllGroupsMask;
- new_state->base_mods = mods_depressed & XkbAllModifiersMask;
- new_state->latched_mods = mods_latched & XkbAllModifiersMask;
- new_state->locked_mods = mods_locked & XkbAllModifiersMask;
-
- XkbComputeDerivedState(dev->key->xkbInfo);
-
- changed = XkbStateChangedFlags(&old_state, new_state);
- if (!changed)
- continue;
-
- sn.keycode = 0;
- sn.eventType = 0;
- sn.requestMajor = XkbReqCode;
- sn.requestMinor = X_kbLatchLockState; /* close enough */
- sn.changed = changed;
- XkbSendStateNotify(dev, &sn);
- }
-}
-
-static void
-remove_sync_pending(DeviceIntPtr dev)
-{
- struct xwl_seat *xwl_seat = dev->public.devicePrivate;
- struct sync_pending *p, *npd;
-
- if (!xwl_seat)
- return;
-
- xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) {
- if (p->pending_dev == dev) {
- xorg_list_del(&xwl_seat->sync_pending);
- free (p);
- return;
- }
- }
-}
-
-static void
-sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
-{
- DeviceIntPtr dev = (DeviceIntPtr) data;
-
- remove_sync_pending(dev);
- wl_callback_destroy(callback);
-}
-
-static const struct wl_callback_listener sync_listener = {
- sync_callback
-};
-
-static Bool
-keyboard_check_repeat (DeviceIntPtr dev, XkbSrvInfoPtr xkbi, unsigned key)
-{
- struct xwl_seat *xwl_seat = dev->public.devicePrivate;
- struct xwl_screen *xwl_screen;
- struct wl_callback *callback;
- struct sync_pending *p;
-
- if (!xwl_seat)
- return FALSE;
-
- /* Make sure we didn't miss a possible reply from the compositor */
- xwl_screen = xwl_seat->xwl_screen;
- xwl_sync_events (xwl_screen);
-
- xorg_list_for_each_entry(p, &xwl_seat->sync_pending, l) {
- if (p->pending_dev == dev) {
- ErrorF("Key repeat discarded, Wayland compositor doesn't "
- "seem to be processing events fast enough!\n");
-
- return FALSE;
- }
- }
-
- p = XNFalloc(sizeof(struct sync_pending));
- p->pending_dev = dev;
- callback = wl_display_sync (xwl_screen->display);
- xorg_list_add(&p->l, &xwl_seat->sync_pending);
-
- wl_callback_add_listener(callback, &sync_listener, dev);
-
- return TRUE;
-}
-
-static void
-keyboard_handle_repeat_info (void *data, struct wl_keyboard *keyboard,
- int32_t rate, int32_t delay)
-{
- struct xwl_seat *xwl_seat = data;
- DeviceIntPtr dev;
- XkbControlsPtr ctrl;
-
- if (rate < 0 || delay < 0) {
- ErrorF("Wrong rate/delay: %d, %d\n", rate, delay);
- return;
- }
-
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev != xwl_seat->keyboard &&
- dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
- continue;
-
- if (rate != 0) {
- ctrl = dev->key->xkbInfo->desc->ctrls;
- ctrl->repeat_delay = delay;
- /* rate is number of keys per second */
- ctrl->repeat_interval = 1000 / rate;
-
- XkbSetRepeatKeys(dev, -1, AutoRepeatModeOn);
- } else
- XkbSetRepeatKeys(dev, -1, AutoRepeatModeOff);
- }
-}
-
-static const struct wl_keyboard_listener keyboard_listener = {
- keyboard_handle_keymap,
- keyboard_handle_enter,
- keyboard_handle_leave,
- keyboard_handle_key,
- keyboard_handle_modifiers,
- keyboard_handle_repeat_info,
-};
-
-static struct xwl_touch *
-xwl_seat_lookup_touch(struct xwl_seat *xwl_seat, int32_t id)
-{
- struct xwl_touch *xwl_touch, *next_xwl_touch;
-
- xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
- &xwl_seat->touches, link_touch) {
- if (xwl_touch->id == id)
- return xwl_touch;
- }
-
- return NULL;
-}
-
-static void
-xwl_touch_send_event(struct xwl_touch *xwl_touch,
- struct xwl_seat *xwl_seat, int type)
-{
- double dx, dy, x, y;
- ValuatorMask mask;
-
- dx = xwl_touch->window->toplevel->drawable.x;
- dy = xwl_touch->window->toplevel->drawable.y;
-
- x = (dx + xwl_touch->x) * 0xFFFF / xwl_screen_get_width(xwl_seat->xwl_screen);
- y = (dy + xwl_touch->y) * 0xFFFF / xwl_screen_get_height(xwl_seat->xwl_screen);
-
- valuator_mask_zero(&mask);
- valuator_mask_set_double(&mask, 0, x);
- valuator_mask_set_double(&mask, 1, y);
- QueueTouchEvents(xwl_seat->touch, type, xwl_touch->id, 0, &mask);
-}
-
-static void
-touch_handle_down(void *data, struct wl_touch *wl_touch,
- uint32_t serial, uint32_t time,
- struct wl_surface *surface,
- int32_t id, wl_fixed_t sx_w, wl_fixed_t sy_w)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct xwl_touch *xwl_touch;
-
- if (surface == NULL)
- return;
-
- if (!is_surface_from_xwl_window(surface))
- return;
-
- xwl_touch = calloc(1, sizeof *xwl_touch);
- if (xwl_touch == NULL) {
- ErrorF("%s: ENOMEM\n", __func__);
- return;
- }
-
- xwl_touch->window = wl_surface_get_user_data(surface);
- xwl_touch->id = id;
- xwl_touch->x = wl_fixed_to_int(sx_w);
- xwl_touch->y = wl_fixed_to_int(sy_w);
- xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches);
-
- xwl_touch->x *= xwl_screen->global_surface_scale;
- xwl_touch->y *= xwl_screen->global_surface_scale;
-
- xwl_touch->x *= xwl_touch->window->viewport_scale_x;
- xwl_touch->y *= xwl_touch->window->viewport_scale_y;
-
- xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin);
-}
-
-static void
-touch_handle_up(void *data, struct wl_touch *wl_touch,
- uint32_t serial, uint32_t time, int32_t id)
-{
- struct xwl_touch *xwl_touch;
- struct xwl_seat *xwl_seat = data;
-
- xwl_touch = xwl_seat_lookup_touch(xwl_seat, id);
-
- if (!xwl_touch)
- return;
-
- xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchEnd);
- xorg_list_del(&xwl_touch->link_touch);
- free(xwl_touch);
-}
-
-static void
-touch_handle_motion(void *data, struct wl_touch *wl_touch,
- uint32_t time, int32_t id,
- wl_fixed_t sx_w, wl_fixed_t sy_w)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct xwl_touch *xwl_touch;
-
- xwl_touch = xwl_seat_lookup_touch(xwl_seat, id);
-
- if (!xwl_touch)
- return;
-
- xwl_touch->x = wl_fixed_to_int(sx_w);
- xwl_touch->y = wl_fixed_to_int(sy_w);
-
- xwl_touch->x *= xwl_screen->global_surface_scale;
- xwl_touch->y *= xwl_screen->global_surface_scale;
-
- xwl_touch->x *= xwl_touch->window->viewport_scale_x;
- xwl_touch->y *= xwl_touch->window->viewport_scale_y;
-
- xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate);
-}
-
-static void
-touch_handle_frame(void *data, struct wl_touch *wl_touch)
-{
-}
-
-static void
-touch_handle_cancel(void *data, struct wl_touch *wl_touch)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_touch *xwl_touch, *next_xwl_touch;
-
- xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
- &xwl_seat->touches, link_touch) {
- /* We can't properly notify of cancellation to the X client
- * once it thinks it has the ownership, send at least a
- * TouchEnd event.
- */
- xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchEnd);
- xorg_list_del(&xwl_touch->link_touch);
- free(xwl_touch);
- }
-}
-
-static const struct wl_touch_listener touch_listener = {
- touch_handle_down,
- touch_handle_up,
- touch_handle_motion,
- touch_handle_frame,
- touch_handle_cancel
-};
-
-static struct xwl_seat *
-find_matching_seat(DeviceIntPtr device)
-{
- DeviceIntPtr dev;
-
- for (dev = inputInfo.devices; dev; dev = dev->next)
- if (dev->deviceProc == xwl_keyboard_proc &&
- device == GetMaster(dev, MASTER_KEYBOARD))
- return (struct xwl_seat *) dev->public.devicePrivate;
-
- return NULL;
-}
-
-static void
-release_grab(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->keyboard_grab)
- zwp_xwayland_keyboard_grab_v1_destroy(xwl_seat->keyboard_grab);
- xwl_seat->keyboard_grab = NULL;
-}
-
-static void
-set_grab(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen;
-
- if (!xwl_window)
- return;
-
- /* We already have a grab */
- if (xwl_seat->keyboard_grab)
- release_grab (xwl_seat);
-
- xwl_screen = xwl_seat->xwl_screen;
- xwl_seat->keyboard_grab =
- zwp_xwayland_keyboard_grab_manager_v1_grab_keyboard(xwl_screen->wp_grab,
- xwl_window->surface,
- xwl_seat->seat);
-}
-
-static void
-find_toplevel_callback(void *resource, XID id, void *user_data)
-{
- WindowPtr window = resource;
- WindowPtr *toplevel = user_data;
-
- while (*toplevel == NullWindow && window) {
- /* Pick the first realized toplevel we find */
- if (window->realized && xwl_window_is_toplevel(window))
- *toplevel = window;
- else
- window = window->parent;
- }
-}
-
-static WindowPtr
-xwl_keyboard_search_window(ClientPtr client)
-{
- WindowPtr window = NullWindow;
-
- FindClientResourcesByType(client, X11_RESTYPE_WINDOW, find_toplevel_callback, &window);
-
- return window;
-}
-
-static void
-xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bool passive)
-{
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- WindowPtr grab_window = grab->window;
-
- /* We are not interested in passive grabs */
- if (!passive) {
- /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
- if (xwl_seat == NULL)
- xwl_seat = find_matching_seat(device);
- if (xwl_seat) {
- if (grab_window == xwl_seat->xwl_screen->screen->root)
- grab_window = xwl_keyboard_search_window(GetCurrentClient());
- if (grab_window)
- set_grab(xwl_seat, xwl_window_from_window(grab_window));
- }
- }
-
- ActivateKeyboardGrab(device, grab, time, passive);
-}
-
-static void
-xwl_keyboard_deactivate_grab(DeviceIntPtr device)
-{
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
-
- /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
- if (xwl_seat == NULL)
- xwl_seat = find_matching_seat(device);
- if (xwl_seat)
- release_grab (xwl_seat);
-
- DeactivateKeyboardGrab(device);
-}
-
-static void
-setup_keyboard_grab_handler (DeviceIntPtr device)
-{
- device->deviceGrab.ActivateGrab = xwl_keyboard_activate_grab;
- device->deviceGrab.DeactivateGrab = xwl_keyboard_deactivate_grab;
-}
-
-static DeviceIntPtr
-add_device(struct xwl_seat *xwl_seat,
- const char *driver, DeviceProc device_proc)
-{
- DeviceIntPtr dev = NULL;
- static Atom type_atom;
- char name[32];
-
- dev = AddInputDevice(serverClient, device_proc, TRUE);
- if (dev == NULL)
- return NULL;
-
- if (type_atom == None)
- type_atom = MakeAtom(driver, strlen(driver), TRUE);
- snprintf(name, sizeof name, "%s:%d", driver, xwl_seat->id);
- AssignTypeAndName(dev, type_atom, name);
- dev->public.devicePrivate = xwl_seat;
- dev->type = SLAVE;
- dev->spriteInfo->spriteOwner = FALSE;
- dev->ignoreXkbActionsBehaviors = TRUE;
-
- return dev;
-}
-
-static void
-disable_device(DeviceIntPtr dev)
-{
- DisableDevice(dev, TRUE);
- dev->public.devicePrivate = NULL;
-}
-
-static void
-enable_device(struct xwl_seat *xwl_seat, DeviceIntPtr dev)
-{
- dev->public.devicePrivate = xwl_seat;
- EnableDevice(dev, TRUE);
-}
-
-static void
-init_pointer(struct xwl_seat *xwl_seat)
-{
- xwl_seat->wl_pointer = wl_seat_get_pointer(xwl_seat->seat);
- wl_pointer_add_listener(xwl_seat->wl_pointer,
- &pointer_listener, xwl_seat);
-
- if (xwl_seat->pointer == NULL) {
- xwl_seat_set_cursor(xwl_seat);
- xwl_seat->pointer =
- add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc);
- ActivateDevice(xwl_seat->pointer, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->pointer);
-}
-
-static void
-release_pointer(struct xwl_seat *xwl_seat)
-{
- wl_pointer_release(xwl_seat->wl_pointer);
- xwl_seat->wl_pointer = NULL;
-
- if (xwl_seat->pointer)
- disable_device(xwl_seat->pointer);
-}
-
-static void
-init_relative_pointer(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->relative_pointer == NULL) {
- xwl_seat->relative_pointer =
- add_device(xwl_seat, "xwayland-relative-pointer",
- xwl_pointer_proc_relative);
- ActivateDevice(xwl_seat->relative_pointer, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->relative_pointer);
-}
-
-static void
-init_relative_pointer_listener(struct xwl_seat *xwl_seat)
-{
- struct zwp_relative_pointer_manager_v1 *relative_pointer_manager =
- xwl_seat->xwl_screen->relative_pointer_manager;
-
- if (relative_pointer_manager) {
- xwl_seat->wp_relative_pointer =
- zwp_relative_pointer_manager_v1_get_relative_pointer(
- relative_pointer_manager, xwl_seat->wl_pointer);
- zwp_relative_pointer_v1_add_listener(xwl_seat->wp_relative_pointer,
- &relative_pointer_listener,
- xwl_seat);
- }
-}
-
-static void
-release_relative_pointer(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->wp_relative_pointer) {
- zwp_relative_pointer_v1_destroy(xwl_seat->wp_relative_pointer);
- xwl_seat->wp_relative_pointer = NULL;
- }
-
- if (xwl_seat->relative_pointer)
- disable_device(xwl_seat->relative_pointer);
-}
-
-static void
-init_pointer_gestures_device(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->pointer_gestures == NULL) {
- xwl_seat->pointer_gestures =
- add_device(xwl_seat, "xwayland-pointer-gestures",
- xwl_pointer_proc_pointer_gestures);
- ActivateDevice(xwl_seat->pointer_gestures, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->pointer_gestures);
-}
-
-static void
-init_pointer_gestures_listener(struct xwl_seat *xwl_seat)
-{
- struct zwp_pointer_gestures_v1 *pointer_gestures =
- xwl_seat->xwl_screen->pointer_gestures;
-
- if (pointer_gestures && !xwl_seat->wp_pointer_gesture_swipe) {
- xwl_seat->wp_pointer_gesture_swipe =
- zwp_pointer_gestures_v1_get_swipe_gesture(pointer_gestures,
- xwl_seat->wl_pointer);
- zwp_pointer_gesture_swipe_v1_set_user_data(xwl_seat->wp_pointer_gesture_swipe,
- xwl_seat);
- zwp_pointer_gesture_swipe_v1_add_listener(xwl_seat->wp_pointer_gesture_swipe,
- &pointer_gesture_swipe_listener,
- xwl_seat);
- }
-
- if (pointer_gestures && !xwl_seat->wp_pointer_gesture_pinch) {
- xwl_seat->wp_pointer_gesture_pinch =
- zwp_pointer_gestures_v1_get_pinch_gesture(pointer_gestures,
- xwl_seat->wl_pointer);
- zwp_pointer_gesture_pinch_v1_set_user_data(xwl_seat->wp_pointer_gesture_pinch,
- xwl_seat);
- zwp_pointer_gesture_pinch_v1_add_listener(xwl_seat->wp_pointer_gesture_pinch,
- &pointer_gesture_pinch_listener,
- xwl_seat);
- }
-}
-
-static void
-release_pointer_gestures_device(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->wp_pointer_gesture_swipe) {
- zwp_pointer_gesture_swipe_v1_destroy(xwl_seat->wp_pointer_gesture_swipe);
- xwl_seat->wp_pointer_gesture_swipe = NULL;
- }
-
- if (xwl_seat->wp_pointer_gesture_pinch) {
- zwp_pointer_gesture_pinch_v1_destroy(xwl_seat->wp_pointer_gesture_pinch);
- xwl_seat->wp_pointer_gesture_pinch = NULL;
- }
-
- if (xwl_seat->pointer_gestures)
- disable_device(xwl_seat->pointer_gestures);
-}
-
-static void
-init_keyboard(struct xwl_seat *xwl_seat)
-{
- DeviceIntPtr master;
-
- xwl_seat->wl_keyboard = wl_seat_get_keyboard(xwl_seat->seat);
- wl_keyboard_add_listener(xwl_seat->wl_keyboard,
- &keyboard_listener, xwl_seat);
-
- if (xwl_seat->keyboard == NULL) {
- xwl_seat->keyboard =
- add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc);
- ActivateDevice(xwl_seat->keyboard, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->keyboard);
- xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat;
-
- if (xwl_seat->xwl_screen->wp_grab) {
- /* We have Xwayland grab protocol supported by the compositor */
- master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
- if (master)
- setup_keyboard_grab_handler(master);
- }
-}
-
-static void
-release_keyboard(struct xwl_seat *xwl_seat)
-{
- release_grab(xwl_seat);
- wl_keyboard_release(xwl_seat->wl_keyboard);
- xwl_seat->wl_keyboard = NULL;
-
- if (xwl_seat->keyboard) {
- remove_sync_pending(xwl_seat->keyboard);
- disable_device(xwl_seat->keyboard);
- }
-}
-
-static void
-init_touch(struct xwl_seat *xwl_seat)
-{
- xwl_seat->wl_touch = wl_seat_get_touch(xwl_seat->seat);
- wl_touch_add_listener(xwl_seat->wl_touch,
- &touch_listener, xwl_seat);
-
- if (xwl_seat->touch == NULL) {
- xwl_seat->touch =
- add_device(xwl_seat, "xwayland-touch", xwl_touch_proc);
- ActivateDevice(xwl_seat->touch, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->touch);
-}
-
-static void
-release_touch(struct xwl_seat *xwl_seat)
-{
- wl_touch_release(xwl_seat->wl_touch);
- xwl_seat->wl_touch = NULL;
-
- if (xwl_seat->touch)
- disable_device(xwl_seat->touch);
-}
-
-static void
-seat_handle_capabilities(void *data, struct wl_seat *seat,
- enum wl_seat_capability caps)
-{
- struct xwl_seat *xwl_seat = data;
-
- if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->wl_pointer == NULL) {
- init_pointer(xwl_seat);
- init_relative_pointer(xwl_seat);
- init_relative_pointer_listener(xwl_seat);
- init_pointer_gestures_device(xwl_seat);
- init_pointer_gestures_listener(xwl_seat);
- } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->wl_pointer) {
- release_pointer(xwl_seat);
- release_relative_pointer(xwl_seat);
- release_pointer_gestures_device(xwl_seat);
- }
-
- if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) {
- init_keyboard(xwl_seat);
- } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->wl_keyboard) {
- release_keyboard(xwl_seat);
- }
-
- if (caps & WL_SEAT_CAPABILITY_TOUCH && xwl_seat->wl_touch == NULL) {
- init_touch(xwl_seat);
- } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && xwl_seat->wl_touch) {
- release_touch(xwl_seat);
- }
-
- if (xwl_seat->caps_initialized == FALSE) {
- xwl_seat->caps_initialized = TRUE;
- xwl_seat->xwl_screen->expecting_event--;
- }
-}
-
-static void
-seat_handle_name(void *data, struct wl_seat *seat,
- const char *name)
-{
-
-}
-
-static const struct wl_seat_listener seat_listener = {
- seat_handle_capabilities,
- seat_handle_name
-};
-
-static void
-xwl_cursor_init(struct xwl_cursor *xwl_cursor, struct xwl_screen *xwl_screen,
- void (* update_proc)(struct xwl_cursor *))
-{
- xwl_cursor->surface = wl_compositor_create_surface(xwl_screen->compositor);
- xwl_cursor->update_proc = update_proc;
- xwl_cursor->frame_cb = NULL;
- xwl_cursor->needs_update = FALSE;
-}
-
-static void
-xwl_seat_update_cursor(struct xwl_cursor *xwl_cursor)
-{
- struct xwl_seat *xwl_seat = wl_container_of(xwl_cursor, xwl_seat, cursor);
- xwl_seat_set_cursor(xwl_seat);
-}
-
-static void
-create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
-{
- struct xwl_seat *xwl_seat;
- int seat_version = 8;
-
- xwl_seat = calloc(1, sizeof *xwl_seat);
- if (xwl_seat == NULL) {
- ErrorF("%s: ENOMEM\n", __func__);
- return;
- }
-
- xwl_seat->xwl_screen = xwl_screen;
- xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
-
- xwl_seat->seat =
- wl_registry_bind(xwl_screen->registry, id,
- &wl_seat_interface, min(version, seat_version));
- xwl_seat->id = id;
- xwl_seat->caps_initialized = FALSE;
-
- xwl_cursor_init(&xwl_seat->cursor, xwl_seat->xwl_screen,
- xwl_seat_update_cursor);
- wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
-
- init_tablet_manager_seat(xwl_screen, xwl_seat);
-
- wl_array_init(&xwl_seat->keys);
-
- xorg_list_init(&xwl_seat->touches);
- xorg_list_init(&xwl_seat->sync_pending);
-}
-
-void
-xwl_seat_destroy(struct xwl_seat *xwl_seat)
-{
- struct xwl_touch *xwl_touch, *next_xwl_touch;
- struct sync_pending *p, *npd;
-
- xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
- &xwl_seat->touches, link_touch) {
- xorg_list_del(&xwl_touch->link_touch);
- free(xwl_touch);
- }
-
- xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) {
- xorg_list_del(&xwl_seat->sync_pending);
- free (p);
- }
-
- release_tablet_manager_seat(xwl_seat);
-
- release_grab(xwl_seat);
- wl_seat_destroy(xwl_seat->seat);
- xwl_cursor_release(&xwl_seat->cursor);
- wl_array_release(&xwl_seat->keys);
- free(xwl_seat);
-}
-
-static void
-tablet_handle_name(void *data, struct zwp_tablet_v2 *tablet, const char *name)
-{
-}
-
-static void
-tablet_handle_id(void *data, struct zwp_tablet_v2 *tablet, uint32_t vid,
- uint32_t pid)
-{
-}
-
-static void
-tablet_handle_path(void *data, struct zwp_tablet_v2 *tablet, const char *path)
-{
-}
-
-static void
-tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet)
-{
- struct xwl_tablet *xwl_tablet = data;
- struct xwl_seat *xwl_seat = xwl_tablet->seat;
-
- if (xwl_seat->stylus == NULL) {
- xwl_seat->stylus = add_device(xwl_seat, "xwayland-tablet stylus", xwl_tablet_proc);
- ActivateDevice(xwl_seat->stylus, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->stylus);
-
- if (xwl_seat->eraser == NULL) {
- xwl_seat->eraser = add_device(xwl_seat, "xwayland-tablet eraser", xwl_tablet_proc);
- ActivateDevice(xwl_seat->eraser, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->eraser);
-
- if (xwl_seat->puck == NULL) {
- xwl_seat->puck = add_device(xwl_seat, "xwayland-tablet cursor", xwl_tablet_proc);
- ActivateDevice(xwl_seat->puck, TRUE);
- }
- enable_device(xwl_seat, xwl_seat->puck);
-}
-
-static void
-tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet)
-{
- struct xwl_tablet *xwl_tablet = data;
- struct xwl_seat *xwl_seat = xwl_tablet->seat;
-
- xorg_list_del(&xwl_tablet->link);
-
- /* The tablet is merely disabled, not removed. The next tablet
- will re-use the same X devices */
- if (xorg_list_is_empty(&xwl_seat->tablets)) {
- if (xwl_seat->stylus)
- disable_device(xwl_seat->stylus);
- if (xwl_seat->eraser)
- disable_device(xwl_seat->eraser);
- if (xwl_seat->puck)
- disable_device(xwl_seat->puck);
- /* pads are removed separately */
- }
-
- zwp_tablet_v2_destroy(tablet);
- free(xwl_tablet);
-}
-
-static const struct zwp_tablet_v2_listener tablet_listener = {
- tablet_handle_name,
- tablet_handle_id,
- tablet_handle_path,
- tablet_handle_done,
- tablet_handle_removed
-};
-
-static void
-tablet_tool_receive_type(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t type)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- switch (type) {
- case ZWP_TABLET_TOOL_V2_TYPE_ERASER:
- xwl_tablet_tool->xdevice = xwl_seat->eraser;
- break;
- case ZWP_TABLET_TOOL_V2_TYPE_MOUSE:
- case ZWP_TABLET_TOOL_V2_TYPE_LENS:
- xwl_tablet_tool->xdevice = xwl_seat->puck;
- break;
- default:
- xwl_tablet_tool->xdevice = xwl_seat->stylus;
- break;
- }
-}
-
-static void
-tablet_tool_receive_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t hi, uint32_t low)
-{
-}
-
-static void
-tablet_tool_receive_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t hi, uint32_t low)
-{
-}
-
-static void
-tablet_tool_receive_capability(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t capability)
-{
-}
-
-static void
-tablet_tool_receive_done(void *data, struct zwp_tablet_tool_v2 *tool)
-{
-}
-
-static void
-tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
-
- xorg_list_del(&xwl_tablet_tool->link);
- xwl_cursor_release(&xwl_tablet_tool->cursor);
- zwp_tablet_tool_v2_destroy(tool);
- free(xwl_tablet_tool);
-}
-
-static void
-tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t serial, struct zwp_tablet_v2 *tablet,
- struct wl_surface *wl_surface)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- /* There's a race here where if we create and then immediately
- * destroy a surface, we might end up in a state where the Wayland
- * compositor sends us an event for a surface that doesn't exist.
- *
- * Don't process enter events in this case.
- *
- * see pointer_handle_enter()
- */
- if (wl_surface == NULL)
- return;
-
- if (!is_surface_from_xwl_window(wl_surface))
- return;
-
- xwl_tablet_tool->proximity_in_serial = serial;
- xwl_seat->tablet_focus_window = wl_surface_get_user_data(wl_surface);
-
- /* If there is a cursor surface frame callback pending, we need to clear it
- * so that we can continue submitting new cursor frames.
- */
- xwl_cursor_clear_frame_cb(&xwl_tablet_tool->cursor);
- xwl_tablet_tool_set_cursor(xwl_tablet_tool);
-}
-
-static void
-tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- xwl_tablet_tool->proximity_in_serial = 0;
- xwl_seat->tablet_focus_window = NULL;
-
- xwl_tablet_tool->pressure = 0;
- xwl_tablet_tool->tilt_x = 0;
- xwl_tablet_tool->tilt_y = 0;
- xwl_tablet_tool->rotation = 0;
- xwl_tablet_tool->slider = 0;
-}
-
-static void
-tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- xwl_tablet_tool->tip = TRUE;
- xwl_seat->xwl_screen->serial = serial;
-}
-
-static void
-tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
-
- xwl_tablet_tool->tip = FALSE;
-}
-
-static void
-tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
- wl_fixed_t x, wl_fixed_t y)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- int32_t dx, dy;
- double sx = wl_fixed_to_double(x);
- double sy = wl_fixed_to_double(y);
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- sx *= xwl_screen->global_surface_scale;
- sy *= xwl_screen->global_surface_scale;
-
- sx *= xwl_seat->tablet_focus_window->viewport_scale_x;
- sy *= xwl_seat->tablet_focus_window->viewport_scale_y;
-
- dx = xwl_seat->tablet_focus_window->toplevel->drawable.x;
- dy = xwl_seat->tablet_focus_window->toplevel->drawable.y;
-
- xwl_tablet_tool->x = (double) dx + sx;
- xwl_tablet_tool->y = (double) dy + sy;
-}
-
-static void
-tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t pressure)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- /* normalized to 65535 already */
- xwl_tablet_tool->pressure = pressure;
-}
-
-static void
-tablet_tool_distance(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t distance_raw)
-{
-}
-
-static void
-tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool,
- wl_fixed_t tilt_x, wl_fixed_t tilt_y)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x);
- xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y);
-
- xwl_tablet_tool->tilt_x *= xwl_screen->global_surface_scale;
- xwl_tablet_tool->tilt_y *= xwl_screen->global_surface_scale;
-
- xwl_tablet_tool->tilt_x *= xwl_seat->tablet_focus_window->viewport_scale_x;
- xwl_tablet_tool->tilt_y *= xwl_seat->tablet_focus_window->viewport_scale_y;
-}
-
-static void
-tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool,
- wl_fixed_t angle)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- double rotation = wl_fixed_to_double(angle);
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- /* change origin (buttons facing right [libinput +90 degrees]) and
- * scaling (5 points per degree) to match wacom driver behavior
- */
- rotation = remainderf(rotation + 90.0f, 360.0f);
- rotation *= 5.0f;
- xwl_tablet_tool->rotation = rotation;
-}
-
-static void
-tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool,
- int32_t position_raw)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- float position = position_raw / 65535.0;
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f;
-}
-
-static void
-tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool,
- wl_fixed_t degrees, int32_t clicks)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
-
- if (!xwl_seat->tablet_focus_window)
- return;
-
- xwl_tablet_tool->wheel_clicks = clicks;
-}
-
-static void
-tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
- uint32_t serial, uint32_t button, uint32_t state)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- uint32_t *mask = &xwl_tablet_tool->buttons;
- int xbtn = 0;
-
- /* BTN_0 .. BTN_9 */
- if (button >= 0x100 && button <= 0x109) {
- xbtn = button - 0x100 + 1;
- }
- /* BTN_A .. BTN_Z */
- else if (button >= 0x130 && button <= 0x135) {
- xbtn = button - 0x130 + 10;
- }
- /* BTN_BASE .. BTN_BASE6 */
- else if (button >= 0x126 && button <= 0x12b) {
- xbtn = button - 0x126 + 16;
- }
- else {
- switch (button) {
- case 0x110: /* BTN_LEFT */
- case 0x14a: /* BTN_TOUCH */
- xbtn = 1;
- break;
-
- case 0x112: /* BTN_MIDDLE */
- case 0x14b: /* BTN_STYLUS */
- xbtn = 2;
- break;
-
- case 0x111: /* BTN_RIGHT */
- case 0x14c: /* BTN_STYLUS2 */
- xbtn = 3;
- break;
-
- case 0x113: /* BTN_SIDE */
- case 0x116: /* BTN_BACK */
- case 0x149: /* BTN_STYLUS3 */
- xbtn = 8;
- break;
-
- case 0x114: /* BTN_EXTRA */
- case 0x115: /* BTN_FORWARD */
- xbtn = 9;
- break;
- }
- }
-
- if (!xbtn) {
- ErrorF("unknown tablet button number %d\n", button);
- return;
- }
-
- BUG_RETURN(xbtn >= 8 * sizeof(*mask));
-
- if (state)
- SetBit(mask, xbtn - 1);
- else
- ClearBit(mask, xbtn - 1);
-
- xwl_seat->xwl_screen->serial = serial;
-}
-
-static void
-tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = data;
- ValuatorMask mask;
- uint32_t effective_buttons, released, pressed, diff;
- int button;
-
- valuator_mask_zero(&mask);
- valuator_mask_set_double(&mask, 0, xwl_tablet_tool->x);
- valuator_mask_set_double(&mask, 1, xwl_tablet_tool->y);
- valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure);
- valuator_mask_set_double(&mask, 3, xwl_tablet_tool->tilt_x);
- valuator_mask_set_double(&mask, 4, xwl_tablet_tool->tilt_y);
- valuator_mask_set_double(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider);
-
- QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0,
- POINTER_ABSOLUTE | POINTER_DESKTOP, &mask);
-
- valuator_mask_zero(&mask);
-
- effective_buttons = xwl_tablet_tool->buttons;
- if (xwl_tablet_tool->tip) {
- SetBit(&effective_buttons, 0);
- }
-
- diff = effective_buttons ^ xwl_tablet_tool->effective_buttons;
- released = diff & ~effective_buttons;
- pressed = diff & effective_buttons;
-
- button = 1;
- while (released) {
- if (released & 0x1)
- QueuePointerEvents(xwl_tablet_tool->xdevice,
- ButtonRelease, button, 0, &mask);
- button++;
- released >>= 1;
- }
-
- button = 1;
- while (pressed) {
- if (pressed & 0x1)
- QueuePointerEvents(xwl_tablet_tool->xdevice,
- ButtonPress, button, 0, &mask);
- button++;
- pressed >>= 1;
- }
-
- xwl_tablet_tool->effective_buttons = effective_buttons;
-
- while (xwl_tablet_tool->wheel_clicks) {
- if (xwl_tablet_tool->wheel_clicks < 0) {
- button = 4;
- xwl_tablet_tool->wheel_clicks++;
- }
- else {
- button = 5;
- xwl_tablet_tool->wheel_clicks--;
- }
-
- QueuePointerEvents(xwl_tablet_tool->xdevice,
- ButtonPress, button, 0, &mask);
- QueuePointerEvents(xwl_tablet_tool->xdevice,
- ButtonRelease, button, 0, &mask);
-
- }
-}
-
-static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
- tablet_tool_receive_type,
- tablet_tool_receive_hardware_serial,
- tablet_tool_receive_hardware_id_wacom,
- tablet_tool_receive_capability,
- tablet_tool_receive_done,
- tablet_tool_receive_removed,
- tablet_tool_proximity_in,
- tablet_tool_proximity_out,
- tablet_tool_down,
- tablet_tool_up,
- tablet_tool_motion,
- tablet_tool_pressure,
- tablet_tool_distance,
- tablet_tool_tilt,
- tablet_tool_rotation,
- tablet_tool_slider,
- tablet_tool_wheel,
- tablet_tool_button_state,
- tablet_tool_frame
-};
-
-static void
-tablet_pad_ring_destroy(struct xwl_tablet_pad_ring *ring)
-{
- zwp_tablet_pad_ring_v2_destroy(ring->ring);
- xorg_list_del(&ring->link);
- free(ring);
-}
-
-static void
-tablet_pad_ring_source(void *data,
- struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
- uint32_t source)
-{
-}
-
-static void
-tablet_pad_ring_angle(void *data,
- struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
- wl_fixed_t degrees)
-{
- struct xwl_tablet_pad_ring *ring = data;
- struct xwl_tablet_pad *pad = ring->group->pad;
- double deg = wl_fixed_to_double(degrees);
- ValuatorMask mask;
-
- valuator_mask_zero(&mask);
- valuator_mask_set(&mask, 5 + ring->index, deg/360.0 * 71);
- QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
-}
-
-static void
-tablet_pad_ring_stop(void *data,
- struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2)
-{
-}
-
-static void
-tablet_pad_ring_frame(void *data,
- struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
- uint32_t time)
-{
-}
-
-static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = {
- tablet_pad_ring_source,
- tablet_pad_ring_angle,
- tablet_pad_ring_stop,
- tablet_pad_ring_frame,
-};
-
-static void
-tablet_pad_strip_destroy(struct xwl_tablet_pad_strip *strip)
-{
- zwp_tablet_pad_strip_v2_destroy(strip->strip);
- xorg_list_del(&strip->link);
- free(strip);
-}
-
-static void
-tablet_pad_strip_source(void *data,
- struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
- uint32_t source)
-{
-}
-
-static void
-tablet_pad_strip_position(void *data,
- struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
- uint32_t position)
-{
- struct xwl_tablet_pad_strip *strip = data;
- struct xwl_tablet_pad *pad = strip->group->pad;
- ValuatorMask mask;
-
- valuator_mask_zero(&mask);
- valuator_mask_set(&mask, 3 + strip->index, position/65535.0 * 2048);
- QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask);
-}
-
-static void
-tablet_pad_strip_stop(void *data,
- struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2)
-{
-}
-
-static void
-tablet_pad_strip_frame(void *data,
- struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
- uint32_t time)
-{
-}
-
-static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener = {
- tablet_pad_strip_source,
- tablet_pad_strip_position,
- tablet_pad_strip_stop,
- tablet_pad_strip_frame,
-};
-
-static void
-tablet_pad_group_destroy(struct xwl_tablet_pad_group *group)
-{
- struct xwl_tablet_pad_ring *r, *tr;
- struct xwl_tablet_pad_strip *s, *ts;
-
- xorg_list_for_each_entry_safe(r, tr,
- &group->pad_group_ring_list,
- link)
- tablet_pad_ring_destroy(r);
-
- xorg_list_for_each_entry_safe(s, ts,
- &group->pad_group_strip_list,
- link)
- tablet_pad_strip_destroy(s);
-
- zwp_tablet_pad_group_v2_destroy(group->group);
- xorg_list_del(&group->link);
- free(group);
-}
-
-static void
-tablet_pad_group_buttons(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
- struct wl_array *buttons)
-{
-
-}
-
-static void
-tablet_pad_group_ring(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
- struct zwp_tablet_pad_ring_v2 *wp_ring)
-{
- static unsigned int ring_index = 0;
- struct xwl_tablet_pad_group *group = data;
- struct xwl_tablet_pad_ring *ring;
-
- ring = calloc(1, sizeof *ring);
- if (ring == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- ring->index = ring_index++;
- ring->group = group;
- ring->ring = wp_ring;
-
- xorg_list_add(&ring->link, &group->pad_group_ring_list);
-
- zwp_tablet_pad_ring_v2_add_listener(wp_ring, &tablet_pad_ring_listener,
- ring);
-}
-
-static void
-tablet_pad_group_strip(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
- struct zwp_tablet_pad_strip_v2 *wp_strip)
-{
- static unsigned int strip_index = 0;
- struct xwl_tablet_pad_group *group = data;
- struct xwl_tablet_pad_strip *strip;
-
- strip = calloc(1, sizeof *strip);
- if (strip == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- strip->index = strip_index++;
- strip->group = group;
- strip->strip = wp_strip;
-
- xorg_list_add(&strip->link, &group->pad_group_strip_list);
-
- zwp_tablet_pad_strip_v2_add_listener(wp_strip, &tablet_pad_strip_listener,
- strip);
-}
-
-static void
-tablet_pad_group_modes(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
- uint32_t modes)
-{
-
-}
-
-static void
-tablet_pad_group_done(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2)
-{
-
-}
-
-static void
-tablet_pad_group_mode_switch(void *data,
- struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
- uint32_t time,
- uint32_t serial,
- uint32_t mode)
-{
-
-}
-
-static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = {
- tablet_pad_group_buttons,
- tablet_pad_group_ring,
- tablet_pad_group_strip,
- tablet_pad_group_modes,
- tablet_pad_group_done,
- tablet_pad_group_mode_switch,
-};
-
-static int
-xwl_tablet_pad_proc(DeviceIntPtr device, int what)
-{
- struct xwl_tablet_pad *pad = dixGetPrivate(&device->devPrivates,
- &xwl_tablet_private_key);
- /* Axis layout mirrors that of xf86-input-wacom to have better
- compatibility with existing clients */
-#define NAXES 7
- Atom axes_labels[NAXES] = { 0 };
- BYTE map[MAX_BUTTONS + 1];
- int i = 0;
- Atom btn_labels[MAX_BUTTONS] = { 0 }; /* btn labels are meaningless */
- int nbuttons;
-
- switch (what) {
- case DEVICE_INIT:
- device->public.on = FALSE;
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
- /* The others have no good mapping */
-
- if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
- GetMotionHistorySize(), Absolute))
- return BadValue;
-
- for (i = 1; i <= MAX_BUTTONS; i++)
- map[i] = i;
-
- /* We need at least 7 buttons to allow scrolling */
- nbuttons = min(max(pad->nbuttons + 4, 7), MAX_BUTTONS);
-
- if (!InitButtonClassDeviceStruct(device, nbuttons,
- btn_labels, map))
- return BadValue;
-
- /* Valuators */
- InitValuatorAxisStruct(device, 0, axes_labels[0],
- 0, 100, 1, 0, 1, Absolute);
- InitValuatorAxisStruct(device, 1, axes_labels[1],
- 0, 100, 1, 0, 1, Absolute);
- /* Pressure - unused, for backwards compat only */
- InitValuatorAxisStruct(device, 2, axes_labels[2],
- 0, 2048, 1, 0, 1, Absolute);
- /* strip x */
- InitValuatorAxisStruct(device, 3, axes_labels[3],
- 0, 2048, 1, 0, 1, Absolute);
- /* strip y */
- InitValuatorAxisStruct(device, 4, axes_labels[4],
- 0, 2048, 1, 0, 1, Absolute);
- /* ring */
- InitValuatorAxisStruct(device, 5, axes_labels[5],
- 0, 71, 1, 0, 1, Absolute);
- /* ring2 */
- InitValuatorAxisStruct(device, 6, axes_labels[6],
- 0, 71, 1, 0, 1, Absolute);
-
- if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
- return BadValue;
-
- return Success;
-
- case DEVICE_ON:
- device->public.on = TRUE;
- return Success;
-
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- device->public.on = FALSE;
- return Success;
- }
-
- return BadMatch;
-#undef NAXES
-}
-
-static void
-tablet_pad_group(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- struct zwp_tablet_pad_group_v2 *pad_group)
-{
- struct xwl_tablet_pad *pad = data;
- struct xwl_tablet_pad_group *group;
-
- group = calloc(1, sizeof *group);
- if (group == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- group->pad = pad;
- group->group = pad_group;
- xorg_list_init(&group->pad_group_ring_list);
- xorg_list_init(&group->pad_group_strip_list);
-
- xorg_list_add(&group->link, &pad->pad_group_list);
-
- zwp_tablet_pad_group_v2_add_listener(pad_group,
- &tablet_pad_group_listener,
- group);
-}
-
-static void
-tablet_pad_path(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- const char *path)
-{
-
-}
-
-static void
-tablet_pad_buttons(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- uint32_t buttons)
-{
- struct xwl_tablet_pad *pad = data;
-
- pad->nbuttons = buttons;
-}
-
-static void
-tablet_pad_done(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
-{
- struct xwl_tablet_pad *pad = data;
-
- pad->xdevice = add_device(pad->seat, "xwayland-tablet-pad",
- xwl_tablet_pad_proc);
- dixSetPrivate(&pad->xdevice->devPrivates, &xwl_tablet_private_key, pad);
- ActivateDevice(pad->xdevice, TRUE);
- EnableDevice(pad->xdevice, TRUE);
-}
-
-static void
-tablet_pad_button(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- uint32_t time,
- uint32_t button,
- uint32_t state)
-{
- struct xwl_tablet_pad *pad = data;
- ValuatorMask mask;
-
- button++; /* wayland index vs X's 1-offset */
- /* skip scroll wheel buttons 4-7 */
- button = button > 3 ? button + 4 : button;
-
- valuator_mask_zero(&mask);
- QueuePointerEvents(pad->xdevice,
- state ? ButtonPress : ButtonRelease, button, 0, &mask);
-}
-
-static void
-tablet_pad_enter(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- uint32_t serial,
- struct zwp_tablet_v2 *tablet,
- struct wl_surface *surface)
-{
- /* pairs the pad with the tablet but also to set the focus. We
- * don't care about the pairing and always use X's focus */
-}
-
-static void
-tablet_pad_leave(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
- uint32_t serial,
- struct wl_surface *surface)
-{
- /* pairs the pad with the tablet but also to set the focus. We
- * don't care about the pairing and always use X's focus */
-}
-
-static void
-tablet_pad_removed(void *data,
- struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2)
-{
- struct xwl_tablet_pad *pad = data;
- struct xwl_tablet_pad_group *g, *tg;
-
- xorg_list_for_each_entry_safe(g, tg, &pad->pad_group_list, link)
- tablet_pad_group_destroy(g);
-
- RemoveDevice(pad->xdevice, TRUE);
- xorg_list_del(&pad->link);
- zwp_tablet_pad_v2_destroy(pad->pad);
- free(pad);
-}
-
-static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
- tablet_pad_group,
- tablet_pad_path,
- tablet_pad_buttons,
- tablet_pad_done,
- tablet_pad_button,
- tablet_pad_enter,
- tablet_pad_leave,
- tablet_pad_removed,
-};
-
-static void
-tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
- struct zwp_tablet_v2 *tablet)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_tablet *xwl_tablet;
-
- xwl_tablet = calloc(1, sizeof *xwl_tablet);
- if (xwl_tablet == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- xwl_tablet->tablet = tablet;
- xwl_tablet->seat = xwl_seat;
-
- xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets);
-
- zwp_tablet_v2_add_listener(tablet, &tablet_listener, xwl_tablet);
-}
-
-static void
-xwl_tablet_tool_update_cursor(struct xwl_cursor *xwl_cursor)
-{
- struct xwl_tablet_tool *xwl_tablet_tool = wl_container_of(xwl_cursor,
- xwl_tablet_tool,
- cursor);
- xwl_tablet_tool_set_cursor(xwl_tablet_tool);
-}
-
-static void
-tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
- struct zwp_tablet_tool_v2 *tool)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct xwl_tablet_tool *xwl_tablet_tool;
-
- xwl_tablet_tool = calloc(1, sizeof *xwl_tablet_tool);
- if (xwl_tablet_tool == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- xwl_tablet_tool->tool = tool;
- xwl_tablet_tool->seat = xwl_seat;
- xwl_cursor_init(&xwl_tablet_tool->cursor, xwl_screen,
- xwl_tablet_tool_update_cursor);
-
- xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools);
-
- zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, xwl_tablet_tool);
-}
-
-static void
-tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat,
- struct zwp_tablet_pad_v2 *pad)
-{
- struct xwl_seat *xwl_seat = data;
- struct xwl_tablet_pad *xwl_tablet_pad;
-
- xwl_tablet_pad = calloc(1, sizeof *xwl_tablet_pad);
- if (xwl_tablet_pad == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return;
- }
-
- xwl_tablet_pad->pad = pad;
- xwl_tablet_pad->seat = xwl_seat;
- xorg_list_init(&xwl_tablet_pad->pad_group_list);
-
- xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads);
-
- zwp_tablet_pad_v2_add_listener(pad, &tablet_pad_listener,
- xwl_tablet_pad);
-}
-
-static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
- tablet_seat_handle_add_tablet,
- tablet_seat_handle_add_tool,
- tablet_seat_handle_add_pad
-};
-
-static void
-init_tablet_manager_seat(struct xwl_screen *xwl_screen,
- struct xwl_seat *xwl_seat)
-{
- xorg_list_init(&xwl_seat->tablets);
- xorg_list_init(&xwl_seat->tablet_tools);
- xorg_list_init(&xwl_seat->tablet_pads);
-
- if (!xwl_screen->tablet_manager)
- return;
-
- xwl_seat->tablet_seat =
- zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager,
- xwl_seat->seat);
-
- zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat);
-}
-
-static void
-release_tablet_manager_seat(struct xwl_seat *xwl_seat)
-{
- struct xwl_tablet *xwl_tablet, *next_xwl_tablet;
- struct xwl_tablet_tool *xwl_tablet_tool, *next_xwl_tablet_tool;
- struct xwl_tablet_pad *xwl_tablet_pad, *next_xwl_tablet_pad;
-
- xorg_list_for_each_entry_safe(xwl_tablet_pad, next_xwl_tablet_pad,
- &xwl_seat->tablet_pads, link) {
- xorg_list_del(&xwl_tablet_pad->link);
- zwp_tablet_pad_v2_destroy(xwl_tablet_pad->pad);
- free(xwl_tablet_pad);
- }
-
- xorg_list_for_each_entry_safe(xwl_tablet_tool, next_xwl_tablet_tool,
- &xwl_seat->tablet_tools, link) {
- xorg_list_del(&xwl_tablet_tool->link);
- zwp_tablet_tool_v2_destroy(xwl_tablet_tool->tool);
- free(xwl_tablet_tool);
- }
-
- xorg_list_for_each_entry_safe(xwl_tablet, next_xwl_tablet,
- &xwl_seat->tablets, link) {
- xorg_list_del(&xwl_tablet->link);
- zwp_tablet_v2_destroy(xwl_tablet->tablet);
- free(xwl_tablet);
- }
-
- if (xwl_seat->tablet_seat) {
- zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat);
- xwl_seat->tablet_seat = NULL;
- }
-}
-
-static void
-init_tablet_manager(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
-{
- struct xwl_seat *xwl_seat;
-
- xwl_screen->tablet_manager = wl_registry_bind(xwl_screen->registry,
- id,
- &zwp_tablet_manager_v2_interface,
- min(version,1));
-
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- init_tablet_manager_seat(xwl_screen, xwl_seat);
- }
-}
-
-void
-xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen)
-{
- if (xwl_screen->tablet_manager) {
- zwp_tablet_manager_v2_destroy(xwl_screen->tablet_manager);
- xwl_screen->tablet_manager = NULL;
- }
-}
-
-static void
-init_relative_pointer_manager(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- xwl_screen->relative_pointer_manager =
- wl_registry_bind(xwl_screen->registry, id,
- &zwp_relative_pointer_manager_v1_interface,
- 1);
-}
-
-static void
-init_pointer_constraints(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- xwl_screen->pointer_constraints =
- wl_registry_bind(xwl_screen->registry, id,
- &zwp_pointer_constraints_v1_interface,
- 1);
-}
-
-static void
-init_pointer_gestures(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- xwl_screen->pointer_gestures =
- wl_registry_bind(xwl_screen->registry, id,
- &zwp_pointer_gestures_v1_interface,
- 1);
-}
-
-static void
-init_keyboard_grab(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- struct xwl_seat *xwl_seat;
- DeviceIntPtr master;
-
- xwl_screen->wp_grab =
- wl_registry_bind(xwl_screen->registry, id,
- &zwp_xwayland_keyboard_grab_manager_v1_interface,
- 1);
-
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- if (xwl_seat->keyboard) {
- master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
- if (master)
- setup_keyboard_grab_handler(master);
- }
- }
-}
-
-static void
-init_keyboard_shortcuts_inhibit(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- xwl_screen->shortcuts_inhibit_manager =
- wl_registry_bind(xwl_screen->registry, id,
- &zwp_keyboard_shortcuts_inhibit_manager_v1_interface,
- 1);
-}
-
-static void
-init_system_bell(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version)
-{
- xwl_screen->system_bell =
- wl_registry_bind(xwl_screen->registry, id,
- &xdg_system_bell_v1_interface,
- 1);
-}
-
-/* The compositor may send us wl_seat and its capabilities before sending e.g.
- relative_pointer_manager or pointer_gesture interfaces. This would result in
- devices being created in capabilities handler, but listeners not, because
- the interfaces weren't available at the time. So we manually attempt to setup
- listeners again.
-*/
-static void
-maybe_init_relative_pointer_listeners_after_capabilities(struct xwl_screen* xwl_screen)
-{
- struct xwl_seat *xwl_seat;
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- if (xwl_seat->wl_pointer) {
- init_relative_pointer_listener(xwl_seat);
- }
- }
-}
-
-static void
-maybe_init_pointer_gesture_listeners_after_capabilities(struct xwl_screen* xwl_screen)
-{
- struct xwl_seat *xwl_seat;
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- if (xwl_seat->wl_pointer) {
- init_pointer_gestures_listener(xwl_seat);
- }
- }
-}
-
-static void
-input_handler(void *data, struct wl_registry *registry, uint32_t id,
- const char *interface, uint32_t version)
-{
- struct xwl_screen *xwl_screen = data;
-
- if (strcmp(interface, wl_seat_interface.name) == 0 && version >= 3) {
- create_input_device(xwl_screen, id, version);
- xwl_screen->expecting_event++;
- } else if (strcmp(interface, zwp_relative_pointer_manager_v1_interface.name) == 0) {
- init_relative_pointer_manager(xwl_screen, id, version);
- maybe_init_relative_pointer_listeners_after_capabilities(xwl_screen);
- } else if (strcmp(interface, zwp_pointer_constraints_v1_interface.name) == 0) {
- init_pointer_constraints(xwl_screen, id, version);
- } else if (strcmp(interface, zwp_pointer_gestures_v1_interface.name) == 0) {
- init_pointer_gestures(xwl_screen, id, version);
- maybe_init_pointer_gesture_listeners_after_capabilities(xwl_screen);
- } else if (strcmp(interface, zwp_tablet_manager_v2_interface.name) == 0) {
- init_tablet_manager(xwl_screen, id, version);
- } else if (strcmp(interface, zwp_xwayland_keyboard_grab_manager_v1_interface.name) == 0) {
- init_keyboard_grab(xwl_screen, id, version);
- } else if (strcmp(interface, zwp_keyboard_shortcuts_inhibit_manager_v1_interface.name) == 0) {
- init_keyboard_shortcuts_inhibit(xwl_screen, id, version);
- } else if (strcmp(interface, xdg_system_bell_v1_interface.name) == 0) {
- init_system_bell(xwl_screen, id, version);
- }
-}
-
-static void
-global_remove(void *data, struct wl_registry *registry, uint32_t name)
-{
-}
-
-static const struct wl_registry_listener input_listener = {
- input_handler,
- global_remove,
-};
-
-void
-ProcessInputEvents(void)
-{
- mieqProcessInputEvents();
-}
-
-void
-DDXRingBell(int volume, int pitch, int duration)
-{
- ScreenPtr screen = screenInfo.screens[0];
- struct xwl_screen *xwl_screen;
- struct xwl_seat *xwl_seat;
-
- xwl_screen = xwl_screen_get(screen);
- if (!xwl_screen->system_bell)
- return;
-
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- if (!xwl_seat->keyboard)
- continue;
-
- if (!xwl_seat->keyboard->coreEvents)
- continue;
-
- if (!xwl_seat->keyboard_focus)
- continue;
-
- DebugF("XWAYLAND: Ringing the bell\n");
- xdg_system_bell_v1_ring (xwl_screen->system_bell, xwl_seat->keyboard_focus);
- return;
- }
-}
-
-static Bool
-sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
-{
- DeviceIntPtr device, master;
- struct xwl_seat *xwl_seat;
- Bool pointer_crossing;
-
- for (device = inputInfo.devices; device; device = device->next) {
- /* Ignore non-wayland devices */
- if (device->deviceProc == xwl_pointer_proc &&
- device->spriteInfo->sprite == sprite)
- break;
- }
-
- if (!device)
- return FALSE;
-
- xwl_seat = device->public.devicePrivate;
- if (!xwl_seat)
- return FALSE;
-
- pointer_crossing = (xwl_seat->pointer_enter_count > 0);
- master = GetMaster(device, POINTER_OR_FLOAT);
- if (!master || !master->lastSlave)
- return !pointer_crossing;
-
- /* We do want the last active slave, we only check on slave xwayland
- * devices so we can find out the xwl_seat, but those don't actually own
- * their sprite, so the match doesn't mean a lot.
- */
- if (master->lastSlave != get_pointer_device(xwl_seat))
- return !pointer_crossing;
-
- /* If we left the surface with a button down, it means the wayland compositor
- * has grabbed the pointer so we will not get button release events from the
- * compositor, so leave the window processing untouched, so that we do not
- * end up with the wrong cursor, for example, when processing events once
- * the pointer enters the X11 surface again.
- */
- if (master->button->buttonsDown)
- return FALSE;
-
- if (xwl_seat->focus_window != NULL &&
- xwl_seat->cursor_confinement_window != NULL &&
- xwl_seat->focus_window != xwl_seat->cursor_confinement_window)
- return TRUE;
-
- if (xwl_seat->focus_window == NULL &&
- xwl_seat->last_focus_window != NULL &&
- (xwl_seat->last_focus_window->toplevel == window ||
- IsParent(xwl_seat->last_focus_window->toplevel, window)))
- return TRUE;
-
- return !pointer_crossing;
-}
-
-static WindowPtr
-xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y)
-{
- struct xwl_screen *xwl_screen;
- WindowPtr ret;
-
- xwl_screen = xwl_screen_get(screen);
-
- screen->XYToWindow = xwl_screen->XYToWindow;
- ret = screen->XYToWindow(screen, sprite, x, y);
- xwl_screen->XYToWindow = screen->XYToWindow;
- screen->XYToWindow = xwl_xy_to_window;
-
- /* If the device controlling the sprite has left the Wayland surface but
- * the DIX still finds the pointer within the X11 window, it means that
- * the pointer has crossed to another native Wayland window, in this
- * case, pretend we entered the root window so that a LeaveNotify
- * event is emitted.
- */
- if (sprite_check_lost_focus(sprite, ret)) {
- sprite->spriteTraceGood = 1;
- return sprite->spriteTrace[0];
- }
-
- return ret;
-}
-
-void
-xwl_seat_clear_touch(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window)
-{
- struct xwl_touch *xwl_touch, *next_xwl_touch;
-
- xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
- &xwl_seat->touches, link_touch) {
- if (xwl_touch->window == xwl_window) {
- xorg_list_del(&xwl_touch->link_touch);
- free(xwl_touch);
- }
- }
-}
-
-static void
-xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_emulator,
- int x,
- int y)
-{
- struct zwp_locked_pointer_v1 *locked_pointer =
- warp_emulator->locked_pointer;
- struct xwl_window *focus_window;
- WindowPtr window;
- int sx, sy;
-
- if (!warp_emulator->locked_pointer)
- return;
-
- focus_window = warp_emulator->xwl_seat->focus_window;
- if (!focus_window)
- return;
-
- window = focus_window->toplevel;
- if (x >= window->drawable.x ||
- y >= window->drawable.y ||
- x < (window->drawable.x + window->drawable.width) ||
- y < (window->drawable.y + window->drawable.height)) {
- sx = round((double) (x - window->drawable.x) /
- focus_window->viewport_scale_x);
- sy = round((double) (y - window->drawable.y) /
- focus_window->viewport_scale_y);
- zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer,
- wl_fixed_from_int(sx),
- wl_fixed_from_int(sy));
- wl_surface_commit(focus_window->surface);
- }
-}
-
-static Bool
-xwl_pointer_warp_emulator_is_locked(struct xwl_pointer_warp_emulator *warp_emulator)
-{
- if (warp_emulator->locked_pointer)
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-xwl_pointer_warp_emulator_lock(struct xwl_pointer_warp_emulator *warp_emulator)
-{
- struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
- struct zwp_pointer_constraints_v1 *pointer_constraints =
- xwl_screen->pointer_constraints;
- struct xwl_window *lock_window = xwl_seat->focus_window;
-
- warp_emulator->locked_window = lock_window;
-
- warp_emulator->locked_pointer =
- zwp_pointer_constraints_v1_lock_pointer(pointer_constraints,
- lock_window->surface,
- xwl_seat->wl_pointer,
- NULL,
- ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
-}
-
-static void
-xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emulator,
- struct xwl_window *xwl_window,
- SpritePtr sprite,
- int x, int y)
-{
- struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
- GrabPtr pointer_grab = xwl_seat->pointer->deviceGrab.grab;
-
- if (warp_emulator->locked_pointer)
- return;
-
- /*
- * If there is no grab, and the window doesn't have pointer focus, ignore
- * the warp, as under Wayland it won't receive input anyway.
- */
- if (!pointer_grab && xwl_seat->focus_window != xwl_window)
- return;
-
- /*
- * If there is a grab, but it's not an ownerEvents grab and the destination
- * is not the pointer focus, ignore it, as events wouldn't be delivered
- * there anyway.
- */
- if (pointer_grab &&
- !pointer_grab->ownerEvents &&
- sprite &&
- XYToWindow(sprite, x, y) != xwl_seat->focus_window->toplevel)
- return;
-
- xwl_pointer_warp_emulator_lock(warp_emulator);
-}
-
-static void
-xwl_pointer_warp_emulator_warp(struct xwl_pointer_warp_emulator *warp_emulator,
- struct xwl_window *xwl_window,
- SpritePtr sprite,
- int x, int y)
-{
- xwl_pointer_warp_emulator_maybe_lock(warp_emulator,
- xwl_window,
- sprite,
- x, y);
- xwl_pointer_warp_emulator_set_fake_pos(warp_emulator, x, y);
-}
-
-static void
-xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator,
- double dx,
- double dy,
- double dx_unaccel,
- double dy_unaccel)
-{
- struct xwl_seat *xwl_seat = warp_emulator->xwl_seat;
- ValuatorMask mask;
- WindowPtr window;
- int x, y;
-
- valuator_mask_zero(&mask);
- valuator_mask_set_unaccelerated(&mask, 0, dx, dx_unaccel);
- valuator_mask_set_unaccelerated(&mask, 1, dy, dy_unaccel);
-
- QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
- POINTER_RELATIVE, &mask);
-
- window = xwl_seat->focus_window->toplevel;
- miPointerGetPosition(xwl_seat->pointer, &x, &y);
-
- if (xwl_pointer_warp_emulator_is_locked(warp_emulator) &&
- xwl_seat->cursor_confinement_window != warp_emulator->locked_window &&
- (x < window->drawable.x ||
- y < window->drawable.y ||
- x >= (window->drawable.x + window->drawable.width) ||
- y >= (window->drawable.y + window->drawable.height)))
- xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
- else
- xwl_pointer_warp_emulator_set_fake_pos(warp_emulator, x, y);
-}
-
-static struct xwl_pointer_warp_emulator *
-xwl_pointer_warp_emulator_create(struct xwl_seat *xwl_seat)
-{
- struct xwl_pointer_warp_emulator *warp_emulator;
-
- warp_emulator = calloc(1, sizeof *warp_emulator);
- if (!warp_emulator) {
- ErrorF("%s: ENOMEM\n", __func__);
- return NULL;
- }
-
- warp_emulator->xwl_seat = xwl_seat;
-
- return warp_emulator;
-}
-
-static void
-xwl_pointer_warp_emulator_destroy(struct xwl_pointer_warp_emulator *warp_emulator)
-{
- if (warp_emulator->locked_pointer)
- zwp_locked_pointer_v1_destroy(warp_emulator->locked_pointer);
- free(warp_emulator);
-}
-
-static void
-xwl_seat_create_pointer_warp_emulator(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->confined_pointer)
- xwl_seat_destroy_confined_pointer(xwl_seat);
-
- xwl_seat->pointer_warp_emulator =
- xwl_pointer_warp_emulator_create(xwl_seat);
-}
-
-static Bool
-xwl_seat_can_emulate_pointer_warp(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen;
-
- if (!xwl_seat)
- return FALSE;
-
- if (!xwl_seat->pointer)
- return FALSE;
-
- xwl_screen = xwl_seat->xwl_screen;
-
- if (!xwl_screen->relative_pointer_manager)
- return FALSE;
-
- if (!xwl_screen->pointer_constraints)
- return FALSE;
-
- return TRUE;
-}
-
-void
-xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
- struct xwl_window *xwl_window,
- SpritePtr sprite,
- int x, int y)
-{
- if (!xwl_seat_can_emulate_pointer_warp(xwl_seat))
- return;
-
- if (xwl_seat->x_cursor != NULL)
- return;
-
- if (!xwl_seat->pointer_warp_emulator)
- xwl_seat_create_pointer_warp_emulator(xwl_seat);
-
- if (!xwl_seat->pointer_warp_emulator)
- return;
-
- xwl_pointer_warp_emulator_warp(xwl_seat->pointer_warp_emulator,
- xwl_window,
- sprite,
- x, y);
-}
-
-static Bool
-xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat *xwl_seat)
-{
- struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
-
- /* Some clients use hidden cursor+confineTo+relative motion
- * to implement infinite panning (eg. 3D views), lock the
- * pointer for so the relative pointer is used.
- */
- if (xwl_seat->x_cursor)
- return FALSE;
-
- if (!xwl_seat->focus_window)
- return FALSE;
-
- if (!xwl_screen->rootless)
- return FALSE;
-
- if (xwl_seat->cursor_confinement_window != xwl_seat->focus_window)
- return FALSE;
-
- if (xwl_seat->confined_pointer)
- xwl_seat_destroy_confined_pointer(xwl_seat);
-
- xwl_seat_create_pointer_warp_emulator(xwl_seat);
- xwl_pointer_warp_emulator_lock(xwl_seat->pointer_warp_emulator);
- return TRUE;
-}
-
-void
-xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat)
-{
- if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL) {
- xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
- } else if (!xwl_seat->x_cursor && xwl_seat->cursor_confinement_window) {
- /* If the cursor goes hidden as is confined, lock it for
- * relative motion to work. */
- xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat);
- }
-}
-
-void
-xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat)
-{
- if (!xwl_seat->pointer_warp_emulator)
- return;
-
- xwl_pointer_warp_emulator_destroy(xwl_seat->pointer_warp_emulator);
- xwl_seat->pointer_warp_emulator = NULL;
-
- if (xwl_seat->cursor_confinement_window) {
- xwl_seat_confine_pointer(xwl_seat,
- xwl_seat->cursor_confinement_window);
- }
-}
-
-void
-xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
- struct xwl_window *xwl_window)
-{
- struct zwp_pointer_constraints_v1 *pointer_constraints =
- xwl_seat->xwl_screen->pointer_constraints;
-
- if (!pointer_constraints)
- return;
-
- if (!xwl_seat->wl_pointer)
- return;
-
- if (xwl_seat->cursor_confinement_window == xwl_window &&
- xwl_seat->confined_pointer)
- return;
-
- xwl_seat_unconfine_pointer(xwl_seat);
-
- xwl_seat->cursor_confinement_window = xwl_window;
-
- if (xwl_seat->pointer_warp_emulator)
- return;
-
- if (xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat))
- return;
-
- xwl_seat->confined_pointer =
- zwp_pointer_constraints_v1_confine_pointer(pointer_constraints,
- xwl_window->surface,
- xwl_seat->wl_pointer,
- NULL,
- ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
-}
-
-static void
-xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat)
-{
- zwp_confined_pointer_v1_destroy(xwl_seat->confined_pointer);
- xwl_seat->confined_pointer = NULL;
-}
-
-void
-xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat)
-{
- xwl_seat->cursor_confinement_window = NULL;
-
- if (xwl_seat->confined_pointer)
- xwl_seat_destroy_confined_pointer(xwl_seat);
-}
-
-void
-InitInput(int argc, char *argv[])
-{
- ScreenPtr pScreen = screenInfo.screens[0];
- struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
-
- if (!dixRegisterPrivateKey(&xwl_tablet_private_key, PRIVATE_DEVICE, 0)) {
- ErrorF("Failed to register private key\n");
- return;
- }
-
- mieqInit();
-
- inputInfo.keyboard->ignoreXkbActionsBehaviors = TRUE;
- xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
- wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
- xwl_screen);
-
- xwl_screen->XYToWindow = pScreen->XYToWindow;
- pScreen->XYToWindow = xwl_xy_to_window;
-
- xwl_screen_roundtrip(xwl_screen);
-#ifdef XWL_HAS_EI
- if (xwl_screen->rootless)
- xwayland_override_xtest();
-#endif
-}
-
-void
-CloseInput(void)
-{
-#ifdef XWL_HAS_EI
- xwayland_restore_xtest();
-#endif
- mieqFini();
-}
diff --git a/hw/xwayland/xwayland-input.h b/hw/xwayland/xwayland-input.h
deleted file mode 100644
index 9a2a40d72..000000000
--- a/hw/xwayland/xwayland-input.h
+++ /dev/null
@@ -1,218 +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
-#include
-
-#include
-#include
-
-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;
- uint8_t pointer_enter_count;
- Bool caps_initialized;
- 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;
- Bool tip;
- uint32_t effective_buttons;
-
- 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 */
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
deleted file mode 100644
index 447a14b5d..000000000
--- a/hw/xwayland/xwayland-output.c
+++ /dev/null
@@ -1,1474 +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
-
-#include
-
-#include
-#include "randrstr_priv.h"
-
-#include "xwayland-cvt.h"
-#include "xwayland-output.h"
-#include "xwayland-screen.h"
-#include "xwayland-window.h"
-
-#include "xdg-output-unstable-v1-client-protocol.h"
-
-static void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
-
-static Rotation
-wl_transform_to_xrandr(enum wl_output_transform transform)
-{
- switch (transform) {
- default:
- case WL_OUTPUT_TRANSFORM_NORMAL:
- return RR_Rotate_0;
- case WL_OUTPUT_TRANSFORM_90:
- return RR_Rotate_90;
- case WL_OUTPUT_TRANSFORM_180:
- return RR_Rotate_180;
- case WL_OUTPUT_TRANSFORM_270:
- return RR_Rotate_270;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- return RR_Reflect_X | RR_Rotate_0;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- return RR_Reflect_X | RR_Rotate_90;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- return RR_Reflect_X | RR_Rotate_180;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- return RR_Reflect_X | RR_Rotate_270;
- }
-}
-
-static int
-wl_subpixel_to_xrandr(int subpixel)
-{
- switch (subpixel) {
- default:
- case WL_OUTPUT_SUBPIXEL_UNKNOWN:
- return SubPixelUnknown;
- case WL_OUTPUT_SUBPIXEL_NONE:
- return SubPixelNone;
- case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
- return SubPixelHorizontalRGB;
- case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
- return SubPixelHorizontalBGR;
- case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
- return SubPixelVerticalRGB;
- case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
- return SubPixelVerticalBGR;
- }
-}
-
-static void
-output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
- int physical_width, int physical_height, int subpixel,
- const char *make, const char *model, int transform)
-{
- struct xwl_output *xwl_output = data;
-
- if (xwl_output->randr_output) {
- RROutputSetPhysicalSize(xwl_output->randr_output,
- physical_width, physical_height);
- RROutputSetSubpixelOrder(xwl_output->randr_output,
- wl_subpixel_to_xrandr(subpixel));
- }
-
- /* Apply the change from wl_output only if xdg-output is not supported */
- if (!xwl_output->xdg_output) {
- xwl_output->logical_x = x;
- xwl_output->logical_y = y;
- }
- xwl_output->rotation = wl_transform_to_xrandr(transform);
-}
-
-static void
-output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
- int width, int height, int refresh)
-{
- struct xwl_output *xwl_output = data;
-
- if (!(flags & WL_OUTPUT_MODE_CURRENT))
- return;
-
- /* Apply the change from wl_output only if xdg-output is not supported */
- if (!xwl_output->xdg_output) {
- xwl_output->logical_w = width;
- xwl_output->logical_h = height;
- }
-
- xwl_output->mode_width = width;
- xwl_output->mode_height = height;
- xwl_output->refresh = refresh;
-}
-
-static void
-output_get_logical_mode(struct xwl_output *xwl_output, int *width, int *height)
-{
- /* When we have xdg-output support the stored size is already rotated. */
- if (xwl_output->xdg_output == NULL ||
- (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180))) {
- *width = xwl_output->logical_w;
- *height = xwl_output->logical_h;
- } else {
- *width = xwl_output->logical_h;
- *height = xwl_output->logical_w;
- }
-}
-
-void
-output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height)
-{
- /* When we have xdg-output support the stored size is already rotated. */
- if (xwl_output->xdg_output ||
- (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180))) {
- *width = xwl_output->logical_w;
- *height = xwl_output->logical_h;
- } else {
- *width = xwl_output->logical_h;
- *height = xwl_output->logical_w;
- }
-}
-
-/**
- * Decides on the maximum expanse of an output in logical space (i.e. in the
- * Wayland compositor plane) respective to some fix width and height values. The
- * function sets the provided values to these maxima on return.
- */
-static inline void
-output_get_new_size(struct xwl_output *xwl_output, int *width, int *height)
-{
- int logical_width, logical_height, max_width, max_height;
-
- output_get_logical_extents(xwl_output, &logical_width, &logical_height);
-
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
- max_width = max(logical_width, xwl_output->mode_width);
- max_height = max(logical_height, xwl_output->mode_height);
- } else {
- max_width = max(logical_width, xwl_output->mode_height);
- max_height = max(logical_height, xwl_output->mode_width);
- }
-
- if (*width < xwl_output->logical_x + max_width)
- *width = xwl_output->logical_x + max_width;
-
- if (*height < xwl_output->logical_y + max_height)
- *height = xwl_output->logical_y + max_height;
-}
-
-static int
-xwl_set_pixmap_visit_window(WindowPtr window, void *data)
-{
- ScreenPtr screen = window->drawable.pScreen;
-
- if (screen->GetWindowPixmap(window) == data) {
- screen->SetWindowPixmap(window, screen->GetScreenPixmap(screen));
- return WT_WALKCHILDREN;
- }
-
- return WT_DONTWALKCHILDREN;
-}
-
-static void
-update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height)
-{
- ScreenPtr pScreen = xwl_screen->screen;
- WindowPtr pRoot = pScreen->root;
- PixmapPtr old_pixmap, new_pixmap;
-
- old_pixmap = pScreen->GetScreenPixmap(pScreen);
- new_pixmap = pScreen->CreatePixmap(pScreen, width, height,
- pScreen->rootDepth,
- CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
- pScreen->SetScreenPixmap(new_pixmap);
-
- if (old_pixmap) {
- TraverseTree(pRoot, xwl_set_pixmap_visit_window, old_pixmap);
- pScreen->DestroyPixmap(old_pixmap);
- }
-
- pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
-}
-
-static void
-update_screen_size(struct xwl_screen *xwl_screen, int width, int height)
-{
- if (xwl_screen_get_width(xwl_screen) != width)
- xwl_screen->width = width;
-
- if (xwl_screen_get_height(xwl_screen) != height)
- xwl_screen->height = height;
-
- if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
- SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
-
- if (!xwl_screen->rootless && xwl_screen->screen->root)
- update_backing_pixmaps (xwl_screen, width, height);
-
- xwl_screen->screen->width = width;
- xwl_screen->screen->height = height;
- xwl_screen->screen->mmWidth = (width * 25.4) / monitorResolution;
- xwl_screen->screen->mmHeight = (height * 25.4) / monitorResolution;
-
- SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
-
- if (xwl_screen->screen->root) {
- BoxRec box = { 0, 0, width, height };
-
- xwl_screen->screen->root->drawable.width = width;
- xwl_screen->screen->root->drawable.height = height;
- RegionReset(&xwl_screen->screen->root->winSize, &box);
- RRScreenSizeNotify(xwl_screen->screen);
- }
-
- update_desktop_dimensions();
-
- RRTellChanged(xwl_screen->screen);
-}
-
-struct xwl_emulated_mode *
-xwl_output_get_emulated_mode_for_client(struct xwl_output *xwl_output,
- ClientPtr client)
-{
- struct xwl_client *xwl_client = xwl_client_get(client);
- int i;
-
- if (!xwl_output)
- return NULL;
-
- /* We don't do XRandr emulation when rootful or a fake lease display */
- if (!xwl_output->xwl_screen->rootless || !xwl_output->output)
- return NULL;
-
- for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
- if (xwl_client->emulated_modes[i].server_output_id ==
- xwl_output->server_output_id)
- return &xwl_client->emulated_modes[i];
- }
-
- return NULL;
-}
-
-static void
-xwl_output_add_emulated_mode_for_client(struct xwl_output *xwl_output,
- ClientPtr client,
- RRModePtr mode,
- Bool from_vidmode)
-{
- struct xwl_client *xwl_client = xwl_client_get(client);
- struct xwl_emulated_mode *emulated_mode;
- int i;
-
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
- if (!emulated_mode) {
- /* Find a free spot in the emulated modes array */
- for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
- if (xwl_client->emulated_modes[i].server_output_id == 0) {
- emulated_mode = &xwl_client->emulated_modes[i];
- break;
- }
- }
- }
- if (!emulated_mode) {
- static Bool warned;
-
- if (!warned) {
- ErrorF("Ran out of space for emulated-modes, not adding mode");
- warned = TRUE;
- }
-
- return;
- }
-
- emulated_mode->server_output_id = xwl_output->server_output_id;
- emulated_mode->width = mode->mode.width;
- emulated_mode->height = mode->mode.height;
- emulated_mode->id = mode->mode.id;
- emulated_mode->from_vidmode = from_vidmode;
-}
-
-static void
-xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output,
- ClientPtr client)
-{
- struct xwl_emulated_mode *emulated_mode;
-
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
- if (emulated_mode) {
- DebugF("XWAYLAND: xwl_output_remove_emulated_mode: %dx%d\n",
- emulated_mode->width, emulated_mode->height);
- memset(emulated_mode, 0, sizeof(*emulated_mode));
- }
-}
-
-/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
-const int32_t xwl_output_fake_modes[][2] = {
- { 5120, 2880 }, /* 16:9 (1.77) */
- { 4096, 2304 }, /* 16:9 (1.77) */
- { 3840, 2160 }, /* 16:9 (1.77) */
- { 3200, 1800 }, /* 16:9 (1.77) */
- { 2880, 1620 }, /* 16:9 (1.77) */
- { 2560, 1600 }, /* 16:10 (1.6) */
- { 2560, 1440 }, /* 16:9 (1.77) */
- { 2048, 1536 }, /* 4:3 (1.33) */
- { 2048, 1152 }, /* 16:9 (1.77) */
- { 1920, 1440 }, /* 4:3 (1.33) */
- { 1920, 1200 }, /* 16:10 (1.6) */
- { 1920, 1080 }, /* 16:9 (1.77) */
- { 1680, 1050 }, /* 16:10 (1.6) */
- { 1600, 1200 }, /* 4:3 (1.33) */
- { 1600, 900 }, /* 16:9 (1.77) */
- { 1440, 1080 }, /* 4:3 (1.33) */
- { 1440, 900 }, /* 16:10 (1.6) */
- { 1400, 1050 }, /* 4:3 (1.33) */
- { 1368, 768 }, /* 16:9 (1.77) */
- { 1280, 1024 }, /* 5:4 (1.25) */
- { 1280, 960 }, /* 4:3 (1.33) */
- { 1280, 800 }, /* 16:10 (1.6) */
- { 1280, 720 }, /* 16:9 (1.77) */
- { 1152, 864 }, /* 4:3 (1.33) */
- { 1152, 720 }, /* 16:10 (1.6) */
- { 1024, 768 }, /* 4:3 (1.33) */
- { 1024, 576 }, /* 16:9 (1.77) */
- { 960, 600 }, /* 16:10 (1.6) */
- { 928, 580 }, /* 16:10 (1.6) */
- { 864, 486 }, /* 16:9 (1.77) */
- { 800, 600 }, /* 4:3 (1.33) */
- { 800, 500 }, /* 16:10 (1.6) */
- { 768, 480 }, /* 16:10 (1.6) */
- { 720, 480 }, /* 3:2 (1.5) */
- { 720, 400 }, /* 16:9 (1.77) */
- { 640, 480 }, /* 4:3 (1.33) */
- { 640, 400 }, /* 16:10 (1.6) */
- { 640, 350 }, /* 16:9 (1.77) */
- { 320, 240 }, /* 4:3 (1.33) */
- { 320, 200 }, /* 16:10 (1.6) */
-};
-
-/* Build an array with RRModes the first mode is the actual output mode, the
- * rest are fake modes from the xwl_output_fake_modes list. We do this for apps
- * which want to change resolution when they go fullscreen.
- * When an app requests a mode-change, we fake it using WPviewport.
- */
-static RRModePtr *
-output_get_rr_modes(struct xwl_output *xwl_output,
- int32_t width, int32_t height,
- int *count, int *logical_mode)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- RRModePtr *rr_modes;
- int i = 0;
-
- rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 2, sizeof(RRModePtr));
- if (!rr_modes)
- goto err;
-
- *count = 0;
-
- if (xwl_screen_has_resolution_change_emulation(xwl_screen) &&
- (width != xwl_output->mode_width || height != xwl_output->mode_height)) {
- /* Add native output mode as preferred */
- rr_modes[0] = xwayland_cvt(xwl_output->mode_width, xwl_output->mode_height,
- xwl_output->refresh / 1000.0, 0, 0);
- if (!rr_modes[0])
- goto err;
-
- *count = 1;
-
- /* Add fake modes larger than logical mode */
- for (; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
- if (xwl_output_fake_modes[i][0] <= width &&
- xwl_output_fake_modes[i][1] <= height)
- break;
-
- /* Skip modes which are too big, avoid downscaling */
- if (xwl_output_fake_modes[i][0] >= xwl_output->mode_width &&
- xwl_output_fake_modes[i][1] >= xwl_output->mode_height)
- continue;
-
- rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
- xwl_output_fake_modes[i][1],
- xwl_output->refresh / 1000.0, 0, 0);
- if (!rr_modes[*count])
- goto err;
-
- (*count)++;
- }
- }
-
- /* Add logical output mode */
- rr_modes[*count] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0);
- if (!rr_modes[*count])
- goto err;
-
- *logical_mode = (*count)++;
-
- if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation)
- return rr_modes;
-
- /* Add fake modes */
- for (; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
- /* Skip logical output mode, already added */
- if (xwl_output_fake_modes[i][0] == width &&
- xwl_output_fake_modes[i][1] == height)
- continue;
-
- /* Skip native output mode, already added */
- if (xwl_output_fake_modes[i][0] == xwl_output->mode_width &&
- xwl_output_fake_modes[i][1] == xwl_output->mode_height)
- continue;
-
- /* Skip modes which are too big, avoid downscaling */
- if (xwl_output_fake_modes[i][0] > max(width, xwl_output->mode_width) ||
- xwl_output_fake_modes[i][1] > max(height, xwl_output->mode_height))
- continue;
-
- rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
- xwl_output_fake_modes[i][1],
- xwl_output->refresh / 1000.0, 0, 0);
- if (!rr_modes[*count])
- goto err;
-
- (*count)++;
- }
-
- return rr_modes;
-err:
- FatalError("Failed to allocate memory for list of RR modes");
-}
-
-RRModePtr
-xwl_output_find_mode(struct xwl_output *xwl_output,
- int32_t width, int32_t height)
-{
- RROutputPtr output = xwl_output->randr_output;
- int i;
-
- /* width & height -1 means we want the actual output mode */
- if (width == -1 && height == -1) {
- if (xwl_output == xwl_output->xwl_screen->fixed_output &&
- xwl_output->mode_width > 0 && xwl_output->mode_height > 0) {
- /* If running rootful, use the current fixed size to search for the mode */
- width = xwl_output->mode_width;
- height = xwl_output->mode_height;
- }
- else {
- output_get_logical_mode(xwl_output, &width, &height);
-
- if (output->numModes &&
- (width <= 0 || height <= 0))
- return output->modes[0];
- }
- }
-
- for (i = 0; i < output->numModes; i++) {
- if (output->modes[i]->mode.width == width && output->modes[i]->mode.height == height)
- return output->modes[i];
- }
-
- ErrorF("XWAYLAND: mode %dx%d is not available\n", width, height);
- return NULL;
-}
-
-struct xwl_output_randr_emu_prop {
- Atom atom;
- uint32_t rects[XWL_CLIENT_MAX_EMULATED_MODES][4];
- int rect_count;
-};
-
-static void
-xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
- struct xwl_output_randr_emu_prop *prop)
-{
- static const char atom_name[] = "_XWAYLAND_RANDR_EMU_MONITOR_RECTS";
- struct xwl_emulated_mode *emulated_mode;
- struct xwl_output *xwl_output;
- int index = 0;
-
- prop->atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
-
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
- if (!emulated_mode)
- continue;
-
- prop->rects[index][0] = xwl_output->logical_x;
- prop->rects[index][1] = xwl_output->logical_y;
-
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
- prop->rects[index][2] = emulated_mode->width;
- prop->rects[index][3] = emulated_mode->height;
- } else {
- prop->rects[index][2] = emulated_mode->height;
- prop->rects[index][3] = emulated_mode->width;
- }
-
- index++;
- }
-
- prop->rect_count = index;
-}
-
-static void
-xwl_output_set_randr_emu_prop(WindowPtr window,
- struct xwl_output_randr_emu_prop *prop)
-{
- if (prop->rect_count) {
- dixChangeWindowProperty(serverClient, window, prop->atom,
- XA_CARDINAL, 32, PropModeReplace,
- prop->rect_count * 4, prop->rects, TRUE);
- } else {
- DeleteProperty(serverClient, window, prop->atom);
- }
-}
-
-static void
-xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
-{
- if (xwl_window_is_toplevel(resource))
- xwl_output_set_randr_emu_prop(resource, user_data);
-}
-
-static void
-xwl_output_set_randr_emu_props(struct xwl_screen *xwl_screen, ClientPtr client)
-{
- struct xwl_output_randr_emu_prop prop = {};
-
- xwl_output_randr_emu_prop(xwl_screen, client, &prop);
- FindClientResourcesByType(client, X11_RESTYPE_WINDOW,
- xwl_output_set_randr_emu_prop_callback, &prop);
-}
-
-static inline void
-xwl_output_get_emulated_root_size(struct xwl_output *xwl_output,
- ClientPtr client,
- int *width,
- int *height)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- struct xwl_emulated_mode *emulated_mode;
-
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
- /* If not an emulated mode, just return the actual screen size */
- if (!emulated_mode) {
- *width = xwl_screen_get_width(xwl_screen);
- *height = xwl_screen_get_height(xwl_screen);
- return;
- }
-
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
- *width = emulated_mode->width;
- *height = emulated_mode->height;
- } else {
- *width = emulated_mode->height;
- *height = emulated_mode->width;
- }
-}
-
-static int
-xwl_output_get_rr_event_mask(WindowPtr pWin, ClientPtr client)
-{
- RREventPtr pRREvent, *pHead;
-
- dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
- RREventType, client, DixReadAccess);
-
- pRREvent = NULL;
- if (pHead) {
- for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
- if (pRREvent->client == client)
- break;
- }
-
- if (pRREvent)
- return pRREvent->mask;
-
- return 0;
-}
-
-static void
-xwl_output_notify_emulated_root_size(struct xwl_output *xwl_output,
- ClientPtr client,
- int new_emulated_root_width,
- int new_emulated_root_height)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- ScreenPtr pScreen = xwl_screen->screen;
- WindowPtr pRoot = pScreen->root;
- xEvent event = {
- .u.configureNotify.event = pRoot->drawable.id,
- .u.configureNotify.window = pRoot->drawable.id,
- .u.configureNotify.aboveSibling = None,
- .u.configureNotify.x = 0,
- .u.configureNotify.y = 0,
- .u.configureNotify.width = new_emulated_root_width,
- .u.configureNotify.height = new_emulated_root_height,
- .u.configureNotify.borderWidth = pRoot->borderWidth,
- .u.configureNotify.override = pRoot->overrideRedirect
- };
- event.u.u.type = ConfigureNotify;
-
- if (!client || client == serverClient || client->clientGone)
- return;
-
- if (EventMaskForClient(pRoot, client) & StructureNotifyMask)
- WriteEventsToClient(client, 1, &event);
-
- if (xwl_output_get_rr_event_mask(pRoot, client) & RRScreenChangeNotifyMask)
- RRDeliverScreenEvent(client, pRoot, pScreen);
-}
-
-void
-xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
- WindowPtr window)
-{
- struct xwl_output_randr_emu_prop prop = {};
-
- xwl_output_randr_emu_prop(xwl_screen, wClient(window), &prop);
- xwl_output_set_randr_emu_prop(window, &prop);
-}
-
-void
-xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
- RRModePtr mode, Bool from_vidmode)
-{
- int old_emulated_width, old_emulated_height;
- int logical_width, logical_height;
- int new_emulated_width, new_emulated_height;
-
- DebugF("XWAYLAND: xwl_output_set_emulated_mode from %s: %dx%d\n",
- from_vidmode ? "vidmode" : "randr",
- mode->mode.width, mode->mode.height);
-
- xwl_output_get_emulated_root_size(xwl_output, client,
- &old_emulated_width, &old_emulated_height);
-
- /* Skip the logical (not-emulated) output mode */
- output_get_logical_mode(xwl_output, &logical_width, &logical_height);
- if (mode->mode.width == logical_width && mode->mode.height == logical_height)
- xwl_output_remove_emulated_mode_for_client(xwl_output, client);
- else
- xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
-
- xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
-
- xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
-
- xwl_output_get_emulated_root_size(xwl_output, client,
- &new_emulated_width, &new_emulated_height);
-
- if (new_emulated_width != old_emulated_width ||
- new_emulated_height != old_emulated_height)
- xwl_output_notify_emulated_root_size(xwl_output, client,
- new_emulated_width,
- new_emulated_height);
-}
-
-static void
-maybe_update_fullscreen_state(struct xwl_output *xwl_output)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- struct xwl_window *xwl_window;
-
- if (xwl_screen->fullscreen) {
- /* The root window may not yet be created */
- if (xwl_screen->screen->root) {
- xwl_window = xwl_window_get(xwl_screen->screen->root);
- xwl_window_rootful_update_fullscreen(xwl_window, xwl_output);
- }
- }
-}
-
-static void
-apply_output_change(struct xwl_output *xwl_output)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- struct xwl_output *it;
- int logical_width, logical_height, count, has_this_output = 0;
- RRModePtr *randr_modes;
- int logical_mode;
-
- /* Clear out the "done" received flags */
- xwl_output->wl_output_done = FALSE;
- xwl_output->xdg_output_done = FALSE;
-
- output_get_logical_mode(xwl_output, &logical_width, &logical_height);
-
- if (xwl_output->randr_output) {
- /* Build a fresh modes array using the current refresh rate */
- randr_modes = output_get_rr_modes(xwl_output, logical_width, logical_height,
- &count, &logical_mode);
-
- RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
- RRCrtcNotify(xwl_output->randr_crtc, randr_modes[logical_mode],
- xwl_output->logical_x, xwl_output->logical_y,
- xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
- /* RROutputSetModes takes ownership of the passed in modes, so we only
- * have to free the pointer array.
- */
- free(randr_modes);
- }
-
- logical_width = logical_height = 0;
- xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
- /* output done event is sent even when some property
- * of output is changed. That means that we may already
- * have this output. If it is true, we must not add it
- * into the output_list otherwise we'll corrupt it */
- if (it == xwl_output)
- has_this_output = 1;
-
- output_get_new_size(it, &logical_width, &logical_height);
- }
-
- if (!has_this_output) {
- xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
-
- /* we did not check this output for new screen size, do it now */
- output_get_new_size(xwl_output, &logical_width, &logical_height);
-
- --xwl_screen->expecting_event;
- }
-
- if (xwl_screen->fixed_output == NULL)
- update_screen_size(xwl_screen, logical_width, logical_height);
- else
- RRTellChanged(xwl_screen->screen);
-
- /* If running rootful and fullscreen, make sure to match the new setup */
- maybe_update_fullscreen_state(xwl_output);
-}
-
-void
-xwl_output_set_name(struct xwl_output *xwl_output, const char *name)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- rrScrPrivPtr pScrPriv;
- RRLeasePtr lease;
- int i;
-
- if (xwl_output->randr_output == NULL)
- return; /* rootful */
-
- /* Check whether the compositor is sending us something useful */
- if (!name || !strlen(name)) {
- ErrorF("Not using the provided output name, invalid");
- return;
- }
-
- /* Check for duplicate names to be safe */
- pScrPriv = rrGetScrPriv(xwl_screen->screen);
- for (i = 0; i < pScrPriv->numOutputs; i++) {
- if (!strcmp(name, pScrPriv->outputs[i]->name)) {
- ErrorF("An output named '%s' already exists", name);
- return;
- }
- }
- /* And leases' names as well */
- xorg_list_for_each_entry(lease, &pScrPriv->leases, list) {
- for (i = 0; i < lease->numOutputs; i++) {
- if (!strcmp(name, lease->outputs[i]->name)) {
- ErrorF("A lease output named '%s' already exists", name);
- return;
- }
- }
- }
-
- snprintf(xwl_output->randr_output->name, MAX_OUTPUT_NAME, "%s", name);
- xwl_output->randr_output->nameLength = strlen(xwl_output->randr_output->name);
-
- if (xwl_screen->output_name && strcmp(name, xwl_screen->output_name) == 0)
- maybe_update_fullscreen_state(xwl_output);
-}
-
-static void
-output_handle_done(void *data, struct wl_output *wl_output)
-{
- struct xwl_output *xwl_output = data;
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-
- xwl_output->wl_output_done = TRUE;
- if (xwl_screen->fixed_output)
- return;
-
- /* Apply the changes from wl_output only if both "done" events are received,
- * if xdg-output is not supported or if xdg-output version is high enough.
- */
- if (xwl_output->xdg_output_done || !xwl_output->xdg_output ||
- zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3)
- apply_output_change(xwl_output);
-}
-
-static void
-output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
-{
- struct xwl_output *xwl_output = data;
-
- xwl_output->scale = factor;
-}
-
-static void
-output_handle_name(void *data, struct wl_output *wl_output,
- const char *name)
-{
- struct xwl_output *xwl_output = data;
-
- xwl_output_set_name(xwl_output, name);
-}
-
-static void
-output_handle_description(void *data, struct wl_output *wl_output,
- const char *description)
-{
-}
-
-static const struct wl_output_listener output_listener = {
- output_handle_geometry,
- output_handle_mode,
- output_handle_done,
- output_handle_scale,
- output_handle_name,
- output_handle_description,
-};
-
-static void
-xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output,
- int32_t x, int32_t y)
-{
- struct xwl_output *xwl_output = data;
-
- xwl_output->logical_x = x;
- xwl_output->logical_y = y;
-}
-
-static void
-xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
- int32_t width, int32_t height)
-{
- struct xwl_output *xwl_output = data;
-
- xwl_output->logical_w = width;
- xwl_output->logical_h = height;
-}
-
-static void
-xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
-{
- struct xwl_output *xwl_output = data;
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-
- xwl_output->xdg_output_done = TRUE;
-
- if (xwl_screen->fixed_output)
- return;
-
- if (xwl_output->wl_output_done &&
- zxdg_output_v1_get_version(xdg_output) < 3)
- apply_output_change(xwl_output);
-}
-
-static void
-xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
- const char *name)
-{
- struct xwl_output *xwl_output = data;
-
- if (wl_output_get_version(xwl_output->output) >= 4)
- return; /* wl_output.name is preferred */
-
- xwl_output_set_name(xwl_output, name);
-}
-
-static void
-xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
- const char *description)
-{
-}
-
-static const struct zxdg_output_v1_listener xdg_output_listener = {
- xdg_output_handle_logical_position,
- xdg_output_handle_logical_size,
- xdg_output_handle_done,
- xdg_output_handle_name,
- xdg_output_handle_description,
-};
-
-#define XRANDR_EMULATION_PROP "RANDR Emulation"
-static Atom
-get_rand_emulation_property(void)
-{
- const char *emulStr = XRANDR_EMULATION_PROP;
-
- return MakeAtom(emulStr, strlen(emulStr), TRUE);
-}
-
-static void
-xwl_output_set_emulated(struct xwl_output *xwl_output)
-{
- int32_t val = TRUE;
-
- RRChangeOutputProperty(xwl_output->randr_output,
- get_rand_emulation_property(),
- XA_INTEGER,
- 32, PropModeReplace, 1,
- &val, FALSE, FALSE);
-}
-
-struct xwl_output*
-xwl_output_from_wl_output(struct xwl_screen *xwl_screen,
- struct wl_output* wl_output)
-{
- struct xwl_output *xwl_output;
-
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- if (xwl_output->output == wl_output)
- return xwl_output;
- }
-
- return NULL;
-}
-
-struct xwl_output *
-xwl_output_get_output_from_name(struct xwl_screen *xwl_screen, const char *name)
-{
- struct xwl_output *xwl_output;
-
- if (name == NULL)
- return NULL;
-
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- if (xwl_output->randr_output == NULL)
- continue;
-
- if (strcmp(xwl_output->randr_output->name, name) == 0) {
- return xwl_output;
- }
- }
-
- return NULL;
-}
-
-struct xwl_output *
-xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id,
- Bool connected, uint32_t version)
-{
- struct xwl_output *xwl_output;
- char name[MAX_OUTPUT_NAME] = { 0 };
-
- --xwl_screen->expecting_event;
-
- xwl_output = calloc(1, sizeof *xwl_output);
- if (xwl_output == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return NULL;
- }
-
- xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
- &wl_output_interface, min(version, 4));
- if (!xwl_output->output) {
- ErrorF("Failed binding wl_output\n");
- goto err;
- }
-
- xwl_output->server_output_id = id;
- wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
- xwl_output->xscale = 1.0;
-
- xwl_output->xwl_screen = xwl_screen;
-
- 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);
-
- /* Allocate MAX_OUTPUT_NAME data for the output name, all filled with zeros */
- xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
- MAX_OUTPUT_NAME, xwl_output);
- if (!xwl_output->randr_output) {
- ErrorF("Failed creating RandR Output\n");
- goto err;
- }
- /* Set the default output name to a sensible value */
- snprintf(name, MAX_OUTPUT_NAME, "XWAYLAND%d",
- xwl_screen_get_next_output_serial(xwl_screen));
- xwl_output_set_name(xwl_output, name);
- xwl_output_set_emulated(xwl_output);
-
- RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
- RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
- RROutputSetConnection(xwl_output->randr_output,
- connected ? RR_Connected : RR_Disconnected);
-
- /* We want the output to be in the list as soon as created so we can
- * use it when binding to the xdg-output protocol...
- */
- xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
-
- if (xwl_screen->xdg_output_manager)
- xwl_output_get_xdg_output(xwl_output);
-
- return xwl_output;
-
-err:
- if (xwl_output->randr_crtc)
- RRCrtcDestroy(xwl_output->randr_crtc);
- if (xwl_output->output)
- wl_output_destroy(xwl_output->output);
- free(xwl_output);
- return NULL;
-}
-
-void
-xwl_output_destroy(struct xwl_output *xwl_output)
-{
- if (xwl_output->lease_connector)
- wp_drm_lease_connector_v1_destroy(xwl_output->lease_connector);
- if (xwl_output->transform)
- free(xwl_output->transform);
- if (xwl_output->xdg_output)
- zxdg_output_v1_destroy(xwl_output->xdg_output);
- if (xwl_output->output)
- wl_output_destroy(xwl_output->output);
- free(xwl_output);
-}
-
-void
-xwl_output_remove(struct xwl_output *xwl_output)
-{
- struct xwl_output *it;
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
- struct xwl_window *xwl_window;
- int width = 0, height = 0;
-
- /* Not all compositors send a "leave" event on output removal */
- xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window)
- xwl_window_leave_output(xwl_window, xwl_output);
-
- xorg_list_del(&xwl_output->link);
-
- if (xwl_output->randr_output)
- RROutputSetConnection(xwl_output->randr_output, RR_Disconnected);
-
- if (xwl_screen->fixed_output == NULL) {
- xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
- output_get_new_size(it, &width, &height);
- update_screen_size(xwl_screen, width, height);
- }
-
- if (xwl_output->randr_crtc)
- RRCrtcDestroy(xwl_output->randr_crtc);
- if (xwl_output->randr_output) {
- RROutputDestroy(xwl_output->randr_output);
- RRTellChanged(xwl_screen->screen);
- }
- xwl_output_destroy(xwl_output);
-}
-
-static Bool
-xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations)
-{
- *rotations = ALL_ROTATIONS;
-
- return TRUE;
-}
-
-#ifdef RANDR_10_INTERFACE
-static Bool
-xwl_randr_set_config(ScreenPtr pScreen,
- Rotation rotation, int rate, RRScreenSizePtr pSize)
-{
- return FALSE;
-}
-#endif
-
-#if RANDR_12_INTERFACE
-static Bool
-xwl_randr_screen_set_size(ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth, CARD32 mmHeight)
-{
- return TRUE;
-}
-
-static Bool
-xwl_randr_crtc_set(ScreenPtr pScreen,
- RRCrtcPtr crtc,
- RRModePtr new_mode,
- int x,
- int y,
- Rotation rotation,
- int numOutputs, RROutputPtr * outputs)
-{
- struct xwl_output *xwl_output = crtc->devPrivate;
- RRModePtr mode;
-
- if (new_mode) {
- mode = xwl_output_find_mode(xwl_output,
- new_mode->mode.width,
- new_mode->mode.height);
- } else {
- mode = xwl_output_find_mode(xwl_output, -1, -1);
- }
- if (!mode)
- return FALSE;
-
- xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), mode, FALSE);
-
- /* A real randr implementation would call:
- * RRCrtcNotify(xwl_output->randr_crtc, mode, xwl_output->x, xwl_output->y,
- * xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
- * here to update the mode reported to clients querying the randr settings
- * but that influences *all* clients and we do randr mode change emulation
- * on a per client basis. So we just return success here.
- */
-
- return TRUE;
-}
-
-static void
-xwl_randr_crtc_get(ScreenPtr pScreen,
- RRCrtcPtr crtc,
- xRRGetCrtcInfoReply *rep)
-{
- struct xwl_output *xwl_output = crtc->devPrivate;
-
- struct xwl_emulated_mode *mode = xwl_output_get_emulated_mode_for_client(
- xwl_output, GetCurrentClient());
-
- if (mode)
- rep->mode = mode->id;
-}
-
-static Bool
-xwl_randr_crtc_set_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
-{
- return TRUE;
-}
-
-static Bool
-xwl_randr_crtc_get_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
-{
- return TRUE;
-}
-
-static Bool
-xwl_randr_output_set_property(ScreenPtr pScreen,
- RROutputPtr output,
- Atom property,
- RRPropertyValuePtr value)
-{
- /* RANDR Emulation property is read-only. */
- if (get_rand_emulation_property() == property)
- return FALSE;
-
- return TRUE;
-}
-
-static Bool
-xwl_output_validate_mode(ScreenPtr pScreen,
- RROutputPtr output,
- RRModePtr mode)
-{
- return TRUE;
-}
-
-static void
-xwl_randr_mode_destroy(ScreenPtr pScreen, RRModePtr mode)
-{
- return;
-}
-#endif
-
-Bool
-xwl_screen_init_output(struct xwl_screen *xwl_screen)
-{
- rrScrPrivPtr rp;
-
- if (!RRScreenInit(xwl_screen->screen))
- return FALSE;
-
- xwl_screen->screen->ConstrainCursorHarder = NULL;
-
- RRScreenSetSizeRange(xwl_screen->screen, 16, 16, 32767, 32767);
-
- rp = rrGetScrPriv(xwl_screen->screen);
- rp->rrGetInfo = xwl_randr_get_info;
-
-#if RANDR_10_INTERFACE
- rp->rrSetConfig = xwl_randr_set_config;
-#endif
-
-#if RANDR_12_INTERFACE
- rp->rrScreenSetSize = xwl_randr_screen_set_size;
- rp->rrCrtcSet = xwl_randr_crtc_set;
- rp->rrCrtcGet = xwl_randr_crtc_get;
- rp->rrCrtcSetGamma = xwl_randr_crtc_set_gamma;
- rp->rrCrtcGetGamma = xwl_randr_crtc_get_gamma;
- rp->rrOutputSetProperty = xwl_randr_output_set_property;
- rp->rrOutputValidateMode = xwl_output_validate_mode;
- rp->rrModeDestroy = xwl_randr_mode_destroy;
-#endif
-
- rp->rrRequestLease = xwl_randr_request_lease;
- rp->rrGetLease = xwl_randr_get_lease;
- rp->rrTerminateLease = xwl_randr_terminate_lease;
-
- return TRUE;
-}
-
-static int
-mode_sort(const void *left, const void *right)
-{
- const RRModePtr *mode_a = left;
- const RRModePtr *mode_b = right;
-
- if ((*mode_b)->mode.width == (*mode_a)->mode.width)
- return (*mode_b)->mode.height - (*mode_a)->mode.height;
-
- return (*mode_b)->mode.width - (*mode_a)->mode.width;
-}
-
-static void
-xwl_output_set_transform(struct xwl_output *xwl_output)
-{
- pixman_fixed_t transform_xscale;
- RRModePtr mode;
-
- mode = xwl_output_find_mode(xwl_output, xwl_output->mode_width, xwl_output->mode_height);
- if (!mode) {
- ErrorF("XWAYLAND: Failed to find mode for %ix%i\n",
- xwl_output->mode_width, xwl_output->mode_height);
- return;
- }
-
- if (xwl_output->transform == NULL) {
- xwl_output->transform = XNFalloc(sizeof(RRTransformRec));
- RRTransformInit(xwl_output->transform);
- }
-
- transform_xscale = pixman_double_to_fixed(xwl_output->xscale);
- pixman_transform_init_scale(&xwl_output->transform->transform,
- transform_xscale, transform_xscale);
- pixman_f_transform_init_scale(&xwl_output->transform->f_transform,
- xwl_output->xscale, xwl_output->xscale);
- pixman_f_transform_invert(&xwl_output->transform->f_inverse,
- &xwl_output->transform->f_transform);
-
- RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0,
- xwl_output->transform, 1, &xwl_output->randr_output);
-}
-
-void
-xwl_output_set_xscale(struct xwl_output *xwl_output, double xscale)
-{
- xwl_output->xscale = xscale;
- xwl_output_set_transform(xwl_output);
-}
-
-Bool
-xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
- int current_width, int current_height)
-{
- RRModePtr *modes = NULL;
- RRModePtr mode;
- int i, nmodes, current;
-
- modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
- if (!modes) {
- ErrorF("Failed to allocated RandR modes\n");
- return FALSE;
- }
-
- xwl_output->mode_width = current_width;
- xwl_output->mode_height = current_height;
-
- nmodes = 0;
- current = 0;
-
- /* Add fake modes */
- for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
- if (xwl_output_fake_modes[i][0] == current_width &&
- xwl_output_fake_modes[i][1] == current_height)
- current = 1;
-
- mode = xwayland_cvt(xwl_output_fake_modes[i][0],
- xwl_output_fake_modes[i][1],
- 60, 0, 0);
-
- if (mode)
- modes[nmodes++] = mode;
- }
-
- if (!current) {
- /* Add the current mode as it's not part of the fake modes. */
- mode = xwayland_cvt(current_width, current_height, 60, 0, 0);
-
- if (mode)
- modes[nmodes++] = mode;
- }
-
- qsort(modes, nmodes, sizeof(RRModePtr), mode_sort);
- RROutputSetModes(xwl_output->randr_output, modes, nmodes, 1);
- free(modes);
-
- return TRUE;
-}
-
-void
-xwl_output_set_mode_fixed(struct xwl_output *xwl_output, RRModePtr mode)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-
- xwl_output->mode_width = mode->mode.width;
- xwl_output->mode_height = mode->mode.height;
-
- update_screen_size(xwl_screen,
- round((double) mode->mode.width * xwl_output->xscale),
- round((double) mode->mode.height * xwl_output->xscale));
-
- xwl_output_set_transform(xwl_output);
-}
-
-static Bool
-xwl_randr_set_config_fixed(ScreenPtr pScreen,
- Rotation randr, int rate, RRScreenSizePtr pSize)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
-
- update_screen_size(xwl_screen, pSize->width, pSize->height);
-
- return TRUE;
-}
-
-/* Create a single RR output/mode used with a fixed geometry */
-Bool
-xwl_screen_init_randr_fixed(struct xwl_screen *xwl_screen)
-{
- struct xwl_output *xwl_output;
- char name[MAX_OUTPUT_NAME] = { 0 };
- rrScrPrivPtr rp;
- RRModePtr mode;
-
- xwl_output = calloc(1, sizeof *xwl_output);
- if (xwl_output == NULL) {
- ErrorF("%s ENOMEM\n", __func__);
- return FALSE;
- }
-
- if (!RRScreenInit(xwl_screen->screen))
- goto err;
-
- RRScreenSetSizeRange(xwl_screen->screen, 16, 16, 32767, 32767);
-
- rp = rrGetScrPriv(xwl_screen->screen);
- rp->rrGetInfo = xwl_randr_get_info;
- rp->rrSetConfig = xwl_randr_set_config_fixed;
-
- snprintf(name, MAX_OUTPUT_NAME, "XWAYLAND%d",
- xwl_screen_get_next_output_serial(xwl_screen));
- xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
- strlen(name), NULL);
- if (!xwl_output->randr_output) {
- ErrorF("Failed to create RandR output\n");
- goto err;
- }
-
- xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
- if (!xwl_output->randr_crtc) {
- ErrorF("Failed to create RandR CRTC\n");
- goto err;
- }
- RRCrtcSetRotations (xwl_output->randr_crtc, RR_Rotate_0);
- RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
- RRCrtcSetTransformSupport(xwl_output->randr_crtc, TRUE);
- RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
-
- xwl_randr_add_modes_fixed(xwl_output,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen));
- /* Current mode */
- mode = xwl_output_find_mode(xwl_output,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen));
- RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0,
- NULL, 1, &xwl_output->randr_output);
-
- RROutputSetPhysicalSize(xwl_output->randr_output,
- (xwl_screen->width * 25.4) / monitorResolution,
- (xwl_screen->height * 25.4) / monitorResolution);
-
- RROutputSetConnection(xwl_output->randr_output, RR_Connected);
-
- xwl_output->xwl_screen = xwl_screen;
- xwl_screen->fixed_output = xwl_output;
- xwl_output->xscale = 1.0;
-
- return TRUE;
-
-err:
- if (xwl_output->randr_crtc)
- RRCrtcDestroy(xwl_output->randr_crtc);
- if (xwl_output->randr_output)
- RROutputDestroy(xwl_output->randr_output);
- free(xwl_output);
-
- return FALSE;
-}
-
-static void
-xwl_output_get_xdg_output(struct xwl_output *xwl_output)
-{
- struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-
- if (!xwl_output->output) {
- /* This can happen when an output is created from a leasable DRM
- * connector */
- return;
- }
-
- xwl_output->xdg_output =
- zxdg_output_manager_v1_get_xdg_output (xwl_screen->xdg_output_manager,
- xwl_output->output);
-
- zxdg_output_v1_add_listener(xwl_output->xdg_output,
- &xdg_output_listener,
- xwl_output);
-}
-
-void
-xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen)
-{
- struct xwl_output *it;
-
- assert(xwl_screen->xdg_output_manager);
-
- xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
- xwl_output_get_xdg_output(it);
-}
diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h
deleted file mode 100644
index 8bce0ba63..000000000
--- a/hw/xwayland/xwayland-output.h
+++ /dev/null
@@ -1,126 +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
-#include
-
-#include
-#include
-#include
-
-#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 logical_x, logical_y, logical_w, logical_h;
- int32_t mode_width, mode_height, refresh, scale;
- 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);
-
-void output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height);
-
-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 */
diff --git a/hw/xwayland/xwayland-pixmap.c b/hw/xwayland/xwayland-pixmap.c
deleted file mode 100644
index 8e929f029..000000000
--- a/hw/xwayland/xwayland-pixmap.c
+++ /dev/null
@@ -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
-
-#include
-
-#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;
-}
diff --git a/hw/xwayland/xwayland-pixmap.h b/hw/xwayland/xwayland-pixmap.h
deleted file mode 100644
index 036b532ef..000000000
--- a/hw/xwayland/xwayland-pixmap.h
+++ /dev/null
@@ -1,54 +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
-#include
-
-#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 clients[CLIENT_ID(pixmap->drawable.id)] != serverClient;
-}
-
-#endif /* XWAYLAND_PIXMAP_H */
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
deleted file mode 100644
index f349f711b..000000000
--- a/hw/xwayland/xwayland-present.c
+++ /dev/null
@@ -1,1406 +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.
- */
-
-#include
-
-#include
-#ifdef XWL_HAS_GLAMOR
-#include
-#endif
-#include
-#include
-#ifdef DRI3
-#include
-#endif /* DRI3 */
-
-#include "xwayland-present.h"
-#include "xwayland-screen.h"
-#include "xwayland-shm.h"
-#include "xwayland-window.h"
-#include "xwayland-window-buffers.h"
-#include "xwayland-pixmap.h"
-
-#include "tearing-control-v1-client-protocol.h"
-#include "linux-drm-syncobj-v1-client-protocol.h"
-
-#define XWL_PRESENT_CAPS PresentCapabilityAsync | PresentCapabilityAsyncMayTear
-
-/*
- * When not flipping let Present copy with 60fps.
- * When flipping wait on frame_callback, otherwise
- * the surface is not visible, in this case update
- * with long interval.
- */
-#define TIMER_LEN_COPY 17 // ~60fps
-#define TIMER_LEN_FLIP 1000 // 1fps
-
-static DevPrivateKeyRec xwl_present_window_private_key;
-
-static struct xwl_present_window *
-xwl_present_window_priv(WindowPtr window)
-{
- return dixGetPrivate(&window->devPrivates,
- &xwl_present_window_private_key);
-}
-
-static struct xwl_present_window *
-xwl_present_window_get_priv(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-
- if (xwl_present_window == NULL) {
- xwl_present_window = calloc (1, sizeof (struct xwl_present_window));
- if (!xwl_present_window)
- return NULL;
-
- xwl_present_window->window = window;
- xwl_present_window->msc = 1;
- xwl_present_window->ust = GetTimeInMicros();
-
- xorg_list_init(&xwl_present_window->frame_callback_list);
- xorg_list_init(&xwl_present_window->wait_list);
- xorg_list_init(&xwl_present_window->flip_queue);
- xorg_list_init(&xwl_present_window->idle_queue);
- xorg_list_init(&xwl_present_window->blocked_queue);
-
- dixSetPrivate(&window->devPrivates,
- &xwl_present_window_private_key,
- xwl_present_window);
- }
-
- return xwl_present_window;
-}
-
-static struct xwl_present_event *
-xwl_present_event_from_id(WindowPtr present_window, uint64_t event_id)
-{
- present_window_priv_ptr window_priv = present_get_window_priv(present_window, TRUE);
- struct xwl_present_event *event;
-
- xorg_list_for_each_entry(event, &window_priv->vblank, vblank.window_list) {
- if (event->vblank.event_id == event_id)
- return event;
- }
- return NULL;
-}
-
-static struct xwl_present_event *
-xwl_present_event_from_vblank(present_vblank_ptr vblank)
-{
- return container_of(vblank, struct xwl_present_event, vblank);
-}
-
-static Bool entered_for_each_frame_callback;
-
-Bool
-xwl_present_entered_for_each_frame_callback(void)
-{
- return entered_for_each_frame_callback;
-}
-
-void
-xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
- void iter_func(struct xwl_present_window *))
-{
- struct xwl_present_window *xwl_present_window, *tmp;
-
- if (entered_for_each_frame_callback)
- FatalError("Nested xwl_present_for_each_frame_callback call");
-
- entered_for_each_frame_callback = TRUE;
-
- xorg_list_for_each_entry_safe(xwl_present_window, tmp,
- &xwl_window->frame_callback_list,
- frame_callback_list)
- iter_func(xwl_present_window);
-
- entered_for_each_frame_callback = FALSE;
-}
-
-static void
-xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
-{
- TimerFree(xwl_present_window->frame_timer);
- xwl_present_window->frame_timer = NULL;
- xwl_present_window->timer_armed = 0;
-}
-
-static CARD32
-xwl_present_timer_callback(OsTimerPtr timer,
- CARD32 time,
- void *arg);
-
-static present_vblank_ptr
-xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
-{
- present_vblank_ptr flip_pending;
-
- if (xorg_list_is_empty(&xwl_present_window->flip_queue))
- return NULL;
-
- flip_pending = xorg_list_first_entry(&xwl_present_window->flip_queue, present_vblank_rec,
- event_queue);
-
- if (flip_pending->queued)
- return NULL;
-
- return flip_pending;
-}
-
-static inline Bool
-xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
-{
- present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
-
- return (flip_pending && flip_pending->sync_flip) ||
- !xorg_list_is_empty(&xwl_present_window->wait_list) ||
- !xorg_list_is_empty(&xwl_present_window->blocked_queue);
-}
-
-void
-xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
-{
- if (xwl_present_has_pending_events(xwl_present_window)) {
- struct xwl_window *xwl_window = xwl_window_from_window(xwl_present_window->window);
- CARD32 now = GetTimeInMillis();
- CARD32 timeout;
-
- if (xwl_window && xwl_window->frame_callback &&
- !xorg_list_is_empty(&xwl_present_window->frame_callback_list))
- timeout = TIMER_LEN_FLIP;
- else
- timeout = TIMER_LEN_COPY;
-
- /* Make sure the timer callback runs if at least a second has passed
- * since we first armed the timer. This can happen e.g. if the Wayland
- * compositor doesn't send a pending frame event, e.g. because the
- * Wayland surface isn't visible anywhere.
- */
- if (xwl_present_window->timer_armed) {
- if ((int)(now - xwl_present_window->timer_armed) > 1000) {
- xwl_present_timer_callback(xwl_present_window->frame_timer, now,
- xwl_present_window);
- return;
- }
- } else {
- xwl_present_window->timer_armed = now;
- }
-
- xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
- 0, timeout,
- &xwl_present_timer_callback,
- xwl_present_window);
- } else {
- xwl_present_free_timer(xwl_present_window);
- }
-}
-
-static void
-xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
-
-static int
-xwl_present_queue_vblank(ScreenPtr screen,
- WindowPtr present_window,
- RRCrtcPtr crtc,
- uint64_t event_id,
- uint64_t msc);
-
-static uint32_t
-xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
- return xwl_screen->present_capabilities;
-}
-
-static int
-xwl_present_get_ust_msc(ScreenPtr screen,
- WindowPtr present_window,
- uint64_t *ust,
- uint64_t *msc)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
- if (!xwl_present_window)
- return BadAlloc;
-
- *ust = xwl_present_window->ust;
- *msc = xwl_present_window->msc;
-
- return Success;
-}
-
-static uint64_t
-xwl_present_get_exec_msc(uint32_t options, uint64_t target_msc)
-{
- /* Synchronous Xwayland presentations always complete (at least) one frame after they
- * are executed
- */
- if (options & PresentOptionAsyncMayTear)
- return target_msc;
-
- return target_msc - 1;
-}
-
-/*
- * When the wait fence or previous flip is completed, it's time
- * to re-try the request
- */
-static void
-xwl_present_re_execute(present_vblank_ptr vblank)
-{
- struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
- uint64_t ust = 0, crtc_msc = 0;
-
- (void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
- /* re-compute target / exec msc */
- vblank->target_msc = present_get_target_msc(0, crtc_msc,
- event->divisor,
- event->remainder,
- event->options);
- vblank->exec_msc = xwl_present_get_exec_msc(event->options,
- vblank->target_msc);
-
- vblank->queued = TRUE;
- if (msc_is_after(vblank->exec_msc, crtc_msc) &&
- xwl_present_queue_vblank(vblank->screen, vblank->window,
- vblank->crtc,
- vblank->event_id,
- vblank->exec_msc) == Success) {
- return;
- }
-
- xwl_present_execute(vblank, ust, crtc_msc);
-}
-
-static void
-xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
-{
- present_vblank_ptr vblank;
-
- xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
- if (vblank->queued) {
- xwl_present_re_execute(vblank);
- return;
- }
- }
-}
-
-static void
-xwl_present_release_pixmap(struct xwl_present_event *event)
-{
- if (!event->pixmap)
- return;
-
- xwl_pixmap_del_buffer_release_cb(event->pixmap);
- dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
- event->pixmap = NULL;
-}
-
-static void
-xwl_present_free_event(struct xwl_present_event *event)
-{
- xwl_present_release_pixmap(event);
- xorg_list_del(&event->vblank.event_queue);
- present_vblank_destroy(&event->vblank);
-}
-
-static void
-xwl_present_free_idle_vblank(present_vblank_ptr vblank)
-{
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
- if (vblank->release_syncobj) {
- /* transfer implicit fence to release syncobj */
- int fence_fd = xwl_glamor_dmabuf_export_sync_file(vblank->pixmap);
- vblank->release_syncobj->import_fence(vblank->release_syncobj,
- vblank->release_point,
- fence_fd);
- } else
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
- present_pixmap_idle(vblank->pixmap, vblank->window,
- vblank->serial, vblank->idle_fence);
- xwl_present_free_event(xwl_present_event_from_vblank(vblank));
-}
-
-static WindowPtr
-xwl_present_toplvl_pixmap_window(WindowPtr window)
-{
- ScreenPtr screen = window->drawable.pScreen;
- PixmapPtr pixmap = (*screen->GetWindowPixmap)(window);
- WindowPtr w = window;
- WindowPtr next_w;
-
- while(w->parent) {
- next_w = w->parent;
- if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
- break;
- }
- w = next_w;
- }
- return w;
-}
-
-static void
-xwl_present_flips_stop(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
- present_vblank_ptr vblank, tmp;
-
- /* Change back to the fast refresh rate */
- xwl_present_reset_timer(xwl_present_window);
-
- /* Free any left over idle vblanks */
- xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue)
- xwl_present_free_idle_vblank(vblank);
-
- if (xwl_present_window->flip_active) {
- struct xwl_present_event *event;
-
- vblank = xwl_present_window->flip_active;
- event = xwl_present_event_from_vblank(vblank);
- if (event->pixmap)
- xwl_present_free_idle_vblank(vblank);
- else
- xwl_present_free_event(event);
-
- xwl_present_window->flip_active = NULL;
- }
-
- xwl_present_flip_try_ready(xwl_present_window);
-}
-
-static void
-xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-{
- WindowPtr window = vblank->window;
-#ifdef DRI3
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
-#endif /* DRI3 */
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
- uint8_t mode = PresentCompleteModeFlip;
-
- DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
- vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
- vblank->pixmap ? vblank->pixmap->drawable.id : 0,
- vblank->window ? vblank->window->drawable.id : 0));
-
- assert (&vblank->event_queue == xwl_present_window->flip_queue.next);
-
- xorg_list_del(&vblank->event_queue);
-
- if (xwl_present_window->flip_active) {
- struct xwl_present_event *event =
- xwl_present_event_from_vblank(xwl_present_window->flip_active);
-
- if (!event->pixmap
-#ifdef DRI3
- /* If this flip used explicit sync, we won't get a release event */
- || (xwl_screen->explicit_sync && vblank->release_syncobj)
-#endif /* DRI3 */
- ) {
- xwl_present_free_event(event);
- } else
- /* Put the previous flip in the idle_queue and wait for further notice from
- * the Wayland compositor
- */
- xorg_list_append(&xwl_present_window->flip_active->event_queue, &xwl_present_window->idle_queue);
- }
-
- xwl_present_window->flip_active = vblank;
-
- if (vblank->reason == PRESENT_FLIP_REASON_BUFFER_FORMAT)
- mode = PresentCompleteModeSuboptimalCopy;
-
- present_vblank_notify(vblank, PresentCompleteKindPixmap, mode, ust, crtc_msc);
-
- if (vblank->abort_flip)
- xwl_present_flips_stop(window);
-
- xwl_present_flip_try_ready(xwl_present_window);
-}
-
-static void
-xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
-{
- /* Crtc unchanged, no offset. */
- if (crtc == window_priv->crtc)
- return;
-
- /* No crtc earlier to offset against, just set the crtc. */
- if (window_priv->crtc == PresentCrtcNeverSet) {
- window_priv->msc_offset = 0;
- window_priv->crtc = crtc;
- return;
- }
-
- /* In window-mode the last correct msc-offset is always kept
- * in window-priv struct because msc is saved per window and
- * not per crtc as in screen-mode.
- */
- window_priv->msc_offset += new_msc - window_priv->msc;
- window_priv->crtc = crtc;
-}
-
-void
-xwl_present_cleanup(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
- present_window_priv_ptr window_priv = present_window_priv(window);
- struct xwl_present_event *event, *tmp;
-
- if (!xwl_present_window)
- return;
-
- xorg_list_del(&xwl_present_window->frame_callback_list);
-
- if (xwl_present_window->sync_callback) {
- wl_callback_destroy(xwl_present_window->sync_callback);
- xwl_present_window->sync_callback = NULL;
- }
-
- if (window_priv) {
- /* Clear remaining events */
- xorg_list_for_each_entry_safe(event, tmp, &window_priv->vblank, vblank.window_list)
- xwl_present_free_event(event);
- }
-
- /* Clear timer */
- xwl_present_free_timer(xwl_present_window);
- TimerFree(xwl_present_window->unredirect_timer);
-
- /* Remove from privates so we don't try to access it later */
- dixSetPrivate(&window->devPrivates,
- &xwl_present_window_private_key,
- NULL);
-
- free(xwl_present_window);
-}
-
-static void
-xwl_present_buffer_release(void *data)
-{
- struct xwl_present_window *xwl_present_window;
- struct xwl_present_event *event = data;
- present_vblank_ptr vblank;
-
- if (!event)
- return;
-
- vblank = &event->vblank;
-
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
- if (vblank->release_syncobj) {
- /* transfer implicit fence to release syncobj */
- int fence_fd = xwl_glamor_dmabuf_export_sync_file(vblank->pixmap);
- vblank->release_syncobj->import_fence(vblank->release_syncobj,
- vblank->release_point,
- fence_fd);
- } else
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
- present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-
- xwl_present_window = xwl_present_window_priv(vblank->window);
- if (xwl_present_window->flip_active == vblank ||
- xwl_present_get_pending_flip(xwl_present_window) == vblank)
- xwl_present_release_pixmap(event);
- else
- xwl_present_free_event(event);
-}
-
-static void
-xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
-{
- present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
- uint64_t msc = ++xwl_present_window->msc;
- present_vblank_ptr vblank, tmp;
-
- xwl_present_window->ust = GetTimeInMicros();
-
- xwl_present_window->timer_armed = 0;
-
- if (flip_pending && flip_pending->sync_flip)
- xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
-
- xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->wait_list, event_queue) {
- if (vblank->exec_msc <= msc) {
- DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
- vblank->event_id, xwl_present_window->ust, msc));
-
- xwl_present_execute(vblank, xwl_present_window->ust, msc);
- }
- }
-}
-
-static CARD32
-xwl_present_timer_callback(OsTimerPtr timer,
- CARD32 time,
- void *arg)
-{
- struct xwl_present_window *xwl_present_window = arg;
-
- /* If we were expecting a frame callback for this window, it didn't arrive
- * in a second. Stop listening to it to avoid double-bumping the MSC
- */
- xorg_list_del(&xwl_present_window->frame_callback_list);
-
- xwl_present_msc_bump(xwl_present_window);
- xwl_present_reset_timer(xwl_present_window);
-
- return 0;
-}
-
-void
-xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
-{
- xorg_list_del(&xwl_present_window->frame_callback_list);
-
- xwl_present_msc_bump(xwl_present_window);
-
- /* we do not need the timer anymore for this frame,
- * reset it for potentially the next one
- */
- xwl_present_reset_timer(xwl_present_window);
-}
-
-static void
-xwl_present_sync_callback(void *data,
- struct wl_callback *callback,
- uint32_t time)
-{
- present_vblank_ptr vblank = data;
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(vblank->window);
-
- wl_callback_destroy(xwl_present_window->sync_callback);
- xwl_present_window->sync_callback = NULL;
-
- xwl_present_flip_notify_vblank(vblank, xwl_present_window->ust, xwl_present_window->msc);
-}
-
-static const struct wl_callback_listener xwl_present_sync_listener = {
- xwl_present_sync_callback
-};
-
-static RRCrtcPtr
-xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
- WindowPtr present_window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
- rrScrPrivPtr rr_private;
-
- if (xwl_present_window == NULL)
- return NULL;
-
- rr_private = rrGetScrPriv(present_window->drawable.pScreen);
-
- if (rr_private->numCrtcs == 0)
- return NULL;
-
- return rr_private->crtcs[0];
-}
-
-/*
- * Queue an event to report back to the Present extension when the specified
- * MSC has passed
- */
-static int
-xwl_present_queue_vblank(ScreenPtr screen,
- WindowPtr present_window,
- RRCrtcPtr crtc,
- uint64_t event_id,
- uint64_t msc)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- struct xwl_present_event *event = xwl_present_event_from_id(present_window, event_id);
-
- if (!event) {
- ErrorF("present: Error getting event\n");
- return BadImplementation;
- }
-
- event->vblank.exec_msc = msc;
-
- xorg_list_del(&event->vblank.event_queue);
- xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
-
- /* Hook up to frame callback */
- if (xwl_window &&
- xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
- xorg_list_add(&xwl_present_window->frame_callback_list,
- &xwl_window->frame_callback_list);
- }
-
- if ((xwl_window && xwl_window->frame_callback) ||
- !xwl_present_window->frame_timer)
- xwl_present_reset_timer(xwl_present_window);
-
- return Success;
-}
-
-/*
- * Remove a pending vblank event so that it is not reported
- * to the extension
- */
-static void
-xwl_present_abort_vblank(ScreenPtr screen,
- WindowPtr present_window,
- RRCrtcPtr crtc,
- uint64_t event_id,
- uint64_t msc)
-{
- static Bool called;
-
- if (called)
- return;
-
- /* xwl_present_cleanup should have cleaned up everything,
- * present_free_window_vblank shouldn't need to call this.
- */
- ErrorF("Unexpected call to %s:\n", __func__);
- xorg_backtrace();
-}
-
-static void
-xwl_present_flush(WindowPtr window)
-{
-#ifdef XWL_HAS_GLAMOR
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-
- if (xwl_screen->glamor)
- glamor_block_handler(screen);
-#endif
-}
-
-static void
-xwl_present_maybe_set_reason(struct xwl_window *xwl_window, PresentFlipReason *reason)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
- if (!reason || xwl_screen->dmabuf_protocol_version < 4)
- return;
-
- if (xwl_window->feedback.unprocessed_feedback_pending) {
- xwl_window->feedback.unprocessed_feedback_pending = 0;
-
- *reason = PRESENT_FLIP_REASON_BUFFER_FORMAT;
- }
-
- if (xwl_screen->default_feedback.unprocessed_feedback_pending) {
- xwl_screen->default_feedback.unprocessed_feedback_pending = 0;
-
- *reason = PRESENT_FLIP_REASON_BUFFER_FORMAT;
- }
-}
-
-static int
-xwl_present_flush_fenced(WindowPtr window)
-{
- int fence = -1;
-#ifdef XWL_HAS_GLAMOR
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
- fence = xwl_glamor_get_fence(xwl_screen);
-#endif /* XWL_HAS_GLAMOR */
- xwl_present_flush(window);
- return fence;
-}
-
-static Bool
-xwl_present_check_flip(RRCrtcPtr crtc,
- WindowPtr present_window,
- PixmapPtr pixmap,
- Bool sync_flip,
- RegionPtr valid,
- int16_t x_off,
- int16_t y_off,
- PresentFlipReason *reason)
-{
- WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- ScreenPtr screen = pixmap->drawable.pScreen;
- PixmapPtr window_pixmap = screen->GetWindowPixmap(present_window);
-
- if (reason)
- *reason = PRESENT_FLIP_REASON_UNKNOWN;
-
- if (!xwl_window)
- return FALSE;
-
- xwl_present_maybe_set_reason(xwl_window, reason);
-
- if (!crtc)
- return FALSE;
-
- /* Source pixmap must align with window exactly */
- if (x_off || y_off)
- return FALSE;
-
- /* Valid area must contain window (for simplicity for now just never flip when one is set). */
- if (valid)
- return FALSE;
-
- /* Flip pixmap must have same dimensions as the window and its pixmap */
- if (present_window->drawable.width != pixmap->drawable.width ||
- present_window->drawable.height != pixmap->drawable.height ||
- pixmap->drawable.width != window_pixmap->drawable.width ||
- pixmap->drawable.height != window_pixmap->drawable.height)
- return FALSE;
-
- if (!xwl_pixmap_get_wl_buffer(pixmap))
- return FALSE;
-
- /* Window must be same region as toplevel window */
- if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
- return FALSE;
-
- /* Can't flip if window clipped by children */
- if (!RegionEqual(&present_window->clipList, &present_window->winSize))
- return FALSE;
-
- /* Can't flip if the window pixmap doesn't match the xwl_window parent
- * window's, e.g. because a client redirected this window or one of its
- * parents.
- */
- if (screen->GetWindowPixmap(xwl_window->surface_window) != window_pixmap)
- return FALSE;
-
- /*
- * We currently only allow flips of windows, that have the same
- * dimensions as their xwl_window parent window. For the case of
- * different sizes subsurfaces are presumably the way forward.
- */
- if (!RegionEqual(&xwl_window->toplevel->winSize, &present_window->winSize))
- return FALSE;
-
-#ifdef XWL_HAS_GLAMOR
- if (!xwl_glamor_supports_implicit_sync(xwl_window->xwl_screen) &&
- !xwl_window->xwl_screen->explicit_sync)
- return FALSE;
-
- if (xwl_window->xwl_screen->glamor &&
- !xwl_glamor_check_flip(present_window, pixmap))
- return FALSE;
-#endif /* XWL_HAS_GLAMOR */
-
- return TRUE;
-}
-
-/*
- * 'window' is being reconfigured. Check to see if it is involved
- * in flipping and clean up as necessary.
- */
-static void
-xwl_present_check_flip_window (WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
- present_window_priv_ptr window_priv = present_window_priv(window);
- present_vblank_ptr flip_pending;
- present_vblank_ptr flip_active;
- present_vblank_ptr vblank;
- PresentFlipReason reason;
-
- /* If this window hasn't ever been used with Present, it can't be
- * flipping
- */
- if (!xwl_present_window || !window_priv)
- return;
-
- flip_pending = xwl_present_get_pending_flip(xwl_present_window);
- flip_active = xwl_present_window->flip_active;
-
- if (flip_pending) {
- if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
- flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
- flip_pending->abort_flip = TRUE;
- } else if (flip_active) {
- if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
- flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
- xwl_present_flips_stop(window);
- }
-
- /* Now check any queued vblanks */
- xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
- if (vblank->queued && vblank->flip &&
- !xwl_present_check_flip(vblank->crtc, window, vblank->pixmap,
- vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
- vblank->flip = FALSE;
- vblank->reason = reason;
- }
- }
-}
-
-/*
- * Clean up any pending or current flips for this window
- */
-static void
-xwl_present_clear_window_flip(WindowPtr window)
-{
- /* xwl_present_cleanup cleaned up everything */
-}
-
-static Bool
-xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
-{
- WindowPtr present_window = vblank->window;
- PixmapPtr pixmap = vblank->pixmap;
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
- BoxPtr damage_box;
- struct wl_buffer *buffer;
- struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
- Bool implicit_sync = TRUE;
-
- if (!xwl_window ||
- !xwl_window->allow_commits ||
- xwl_window->awaiting_initial_configure_event)
- return FALSE;
-
- buffer = xwl_pixmap_get_wl_buffer(pixmap);
- if (!buffer) {
- ErrorF("present: Error getting buffer\n");
- return FALSE;
- }
-
- damage_box = RegionExtents(damage);
-
- pixmap->refcnt++;
-
- event->pixmap = pixmap;
-
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
- if (vblank->acquire_syncobj && vblank->release_syncobj) {
- if (xwl_window->xwl_screen->explicit_sync) {
- xwl_glamor_dri3_syncobj_passthrough(xwl_window,
- vblank->acquire_syncobj,
- vblank->release_syncobj,
- vblank->acquire_point,
- vblank->release_point);
- implicit_sync = FALSE;
- } else {
- /* transfer from acquire syncobj to implicit fence */
- int fence_fd =
- vblank->acquire_syncobj->export_fence(vblank->acquire_syncobj,
- vblank->acquire_point);
- xwl_glamor_dmabuf_import_sync_file(vblank->pixmap, fence_fd);
- }
- }
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
-
- if (implicit_sync) {
- xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
-
- if (xwl_window->surface_sync) {
- wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
- xwl_window->surface_sync = NULL;
- }
- }
-
- /* We can flip directly to the main surface (full screen window without clips) */
- wl_surface_attach(xwl_window->surface, buffer, 0, 0);
-
- if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
- xorg_list_add(&xwl_present_window->frame_callback_list,
- &xwl_window->frame_callback_list);
- }
-
- if (!xwl_window->frame_callback)
- xwl_window_create_frame_callback(xwl_window);
-
- xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
- damage_box->x1 - present_window->drawable.x,
- damage_box->y1 - present_window->drawable.y,
- damage_box->x2 - damage_box->x1,
- damage_box->y2 - damage_box->y1);
-
- if (xwl_window->tearing_control) {
- uint32_t hint;
- if (event->options & PresentOptionAsyncMayTear)
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
- else
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
-
- wp_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control, hint);
- }
-
- wl_surface_commit(xwl_window->surface);
-
- if (!vblank->sync_flip) {
- xwl_present_window->sync_callback =
- wl_display_sync(xwl_window->xwl_screen->display);
- wl_callback_add_listener(xwl_present_window->sync_callback,
- &xwl_present_sync_listener,
- &event->vblank);
- }
-
- wl_display_flush(xwl_window->xwl_screen->display);
- return TRUE;
-}
-
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
-static void
-xwl_present_acquire_fence_avail(int fd, int xevents, void *data)
-{
- present_vblank_ptr vblank = data;
-
- SetNotifyFd(fd, NULL, 0, NULL);
- close(fd);
- vblank->efd = -1;
-
- xwl_present_re_execute(vblank);
-}
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
-
-static Bool
-xwl_present_wait_acquire_fence_avail(struct xwl_screen *xwl_screen,
- present_vblank_ptr vblank)
-{
-#if defined(XWL_HAS_GLAMOR) && defined(DRI3)
- /* If the compositor does not support explicit sync we need to wait for the
- * acquire fence to be submitted before flipping. */
- if (vblank->flip && !xwl_screen->explicit_sync &&
- vblank->pixmap && vblank->acquire_syncobj &&
- !vblank->acquire_syncobj->has_fence(vblank->acquire_syncobj,
- vblank->acquire_point)) {
- vblank->efd = eventfd(0, EFD_CLOEXEC);
- SetNotifyFd(vblank->efd, xwl_present_acquire_fence_avail, X_NOTIFY_READ, vblank);
- vblank->acquire_syncobj->submitted_eventfd(vblank->acquire_syncobj,
- vblank->acquire_point,
- vblank->efd);
- return TRUE;
- }
-#endif /* defined(XWL_HAS_GLAMOR) && defined(DRI3) */
- return FALSE;
-}
-
-static void
-xwl_present_flush_blocked(struct xwl_present_window *xwl_present_window,
- uint64_t crtc_msc)
-{
- struct xwl_screen *xwl_screen =
- xwl_screen_get(xwl_present_window->window->drawable.pScreen);
- struct xwl_present_event *blocked_event, *tmp;
-
- if (!xwl_present_window->blocking_event)
- return;
-
- xwl_present_window->blocking_event = 0;
-
- xorg_list_for_each_entry_safe(blocked_event, tmp,
- &xwl_present_window->blocked_queue,
- blocked) {
- present_vblank_ptr blocked_vblank = &blocked_event->vblank;
- xorg_list_del(&blocked_event->blocked);
- if (present_execute_wait(blocked_vblank, crtc_msc) ||
- xwl_present_wait_acquire_fence_avail(xwl_screen, blocked_vblank)) {
- xwl_present_window->blocking_event = blocked_vblank->event_id;
- return;
- }
-
- xwl_present_re_execute(blocked_vblank);
- }
-}
-
-/*
- * Once the required MSC has been reached, execute the pending request.
- *
- * For requests to actually present something, either blt contents to
- * the window pixmap or queue a window buffer swap on the backend.
- *
- * For requests to just get the current MSC/UST combo, skip that part and
- * go straight to event delivery.
- */
-static void
-xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-{
- WindowPtr window = vblank->window;
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
- present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
- struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
- Bool notify_only = !vblank->window || !vblank->pixmap;
-
- xorg_list_del(&vblank->event_queue);
-
- if (!notify_only && !event->copy_executed &&
- xwl_present_window->blocking_event &&
- xwl_present_window->blocking_event != event->vblank.event_id) {
- /* an earlier request is blocking execution */
- xorg_list_append(&event->blocked, &xwl_present_window->blocked_queue);
- return;
- }
-
-retry:
- if (present_execute_wait(vblank, crtc_msc) ||
- xwl_present_wait_acquire_fence_avail(xwl_screen, vblank)) {
- if (!notify_only)
- /* block execution of subsequent requests until this request is ready */
- xwl_present_window->blocking_event = event->vblank.event_id;
- return;
- }
-
- if (flip_pending && vblank->flip && !notify_only) {
- present_vblank_ptr flip_queued_last;
-
- flip_queued_last = xorg_list_last_entry(&xwl_present_window->flip_queue,
- present_vblank_rec, event_queue);
-
- /* Do mailbox handling for queued flips, to prevent the flip queue from
- * growing unbounded.
- */
- if (flip_queued_last != flip_pending &&
- (flip_queued_last->sync_flip
-#ifdef DRI3
- || vblank->acquire_syncobj
-#endif
- )) {
- xorg_list_del(&flip_queued_last->event_queue);
- present_vblank_scrap(flip_queued_last);
- xwl_present_re_execute(flip_queued_last);
- }
-
- DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
- vblank->event_id, vblank, flip_pending));
- xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
- return;
- }
-
- vblank->queued = FALSE;
-
- if (!notify_only && !event->copy_executed) {
- ScreenPtr screen = window->drawable.pScreen;
- int ret;
-
- if (vblank->flip) {
- RegionPtr damage;
-
- DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
- vblank->event_id, vblank, crtc_msc,
- vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
- /* Set update region as damaged */
- if (vblank->update) {
- damage = RegionDuplicate(vblank->update);
- /* Translate update region to screen space */
- assert(vblank->x_off == 0 && vblank->y_off == 0);
- RegionTranslate(damage, window->drawable.x, window->drawable.y);
- RegionIntersect(damage, damage, &window->clipList);
- } else
- damage = RegionDuplicate(&window->clipList);
-
- if (xwl_present_flip(vblank, damage)) {
- WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
- struct xwl_window *xwl_window = xwl_window_from_window(window);
- PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
-
- /* Replace window pixmap with flip pixmap */
-#ifdef COMPOSITE
- vblank->pixmap->screen_x = old_pixmap->screen_x;
- vblank->pixmap->screen_y = old_pixmap->screen_y;
-#endif
- present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
-
- if (toplvl_window == screen->root &&
- screen->GetScreenPixmap(screen) == old_pixmap)
- screen->SetScreenPixmap(vblank->pixmap);
-
- vblank->pixmap->refcnt++;
- dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
-
- /* Report damage, let damage_report ignore it though */
- xwl_screen->ignore_damage = TRUE;
- DamageDamageRegion(&vblank->window->drawable, damage);
- xwl_screen->ignore_damage = FALSE;
- RegionDestroy(damage);
-
- /* Clear damage region, to ensure damage_report is called before
- * any drawing to the window
- */
- xwl_window_buffer_add_damage_region(xwl_window);
- RegionEmpty(xwl_window_get_damage_region(xwl_window));
- xorg_list_del(&xwl_window->link_damage);
-
- /* Put pending flip at the flip queue head */
- xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
-
- /* Realign timer */
- xwl_present_reset_timer(xwl_present_window);
-
- xwl_present_flush_blocked(xwl_present_window, crtc_msc);
- return;
- }
-
- vblank->flip = FALSE;
- /* re-execute, falling through to copy */
- goto retry;
- }
- DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
- vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
- if (flip_pending)
- flip_pending->abort_flip = TRUE;
- else if (xwl_present_window->flip_active)
- xwl_present_flips_stop(window);
-
- present_execute_copy(vblank, crtc_msc);
- assert(!vblank->queued);
-
- /* Set the copy_executed field, so this will fall through to present_execute_post next time */
- event->copy_executed = TRUE;
-
- ret = xwl_present_queue_vblank(screen, window, vblank->crtc,
- vblank->event_id, crtc_msc + 1);
-
- xwl_present_flush_blocked(xwl_present_window, crtc_msc);
-
- if (ret == Success)
- return;
- }
-
- present_execute_post(vblank, ust, crtc_msc);
-}
-
-static int
-xwl_present_pixmap(WindowPtr window,
- PixmapPtr pixmap,
- CARD32 serial,
- RegionPtr valid,
- RegionPtr update,
- int16_t x_off,
- int16_t y_off,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-#ifdef DRI3
- struct dri3_syncobj *acquire_syncobj,
- struct dri3_syncobj *release_syncobj,
- uint64_t acquire_point,
- uint64_t release_point,
-#endif /* DRI3 */
- uint32_t options,
- uint64_t target_window_msc,
- uint64_t divisor,
- uint64_t remainder,
- present_notify_ptr notifies,
- int num_notifies)
-{
- static uint64_t xwl_present_event_id;
- uint64_t ust = 0;
- uint64_t target_msc;
- uint64_t crtc_msc = 0;
- int ret;
- present_vblank_ptr vblank;
- ScreenPtr screen = window->drawable.pScreen;
- present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
- present_screen_priv_ptr screen_priv = present_screen_priv(screen);
- struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
- uint32_t caps = xwl_screen->present_capabilities;
- struct xwl_present_event *event;
-
- if (!window_priv)
- return BadAlloc;
-
-#ifdef DRI3
- if (!(caps & PresentCapabilitySyncobj) &&
- (acquire_syncobj || release_syncobj))
- return BadValue;
-#endif /* DRI3 */
-
- target_crtc = xwl_present_get_crtc(screen_priv, window);
-
- ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
-
- xwl_present_update_window_crtc(window_priv, target_crtc, crtc_msc);
-
- if (ret == Success) {
- /* Stash the current MSC away in case we need it later
- */
- window_priv->msc = crtc_msc;
- }
-
- target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
- crtc_msc,
- divisor,
- remainder,
- options);
-
- event = calloc(1, sizeof(*event));
- if (!event)
- return BadAlloc;
-
- vblank = &event->vblank;
- if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
- target_crtc, wait_fence, idle_fence,
-#ifdef DRI3
- acquire_syncobj, release_syncobj, acquire_point, release_point,
-#endif /* DRI3 */
- options, caps, notifies, num_notifies, target_msc, crtc_msc)) {
- present_vblank_destroy(vblank);
- return BadAlloc;
- }
-
- vblank->event_id = ++xwl_present_event_id;
- event->options = options;
- event->divisor = divisor;
- event->remainder = remainder;
- vblank->exec_msc = xwl_present_get_exec_msc(options, vblank->target_msc);
-
- vblank->queued = TRUE;
- if (crtc_msc < vblank->exec_msc) {
- if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
- return Success;
-
- DebugPresent(("present_queue_vblank failed\n"));
- }
-
- xwl_present_execute(vblank, ust, crtc_msc);
- return Success;
-}
-
-void
-xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
-{
- /* The pending frame callback may never be called, so drop it and shorten
- * the frame timer interval.
- */
- xorg_list_del(&xwl_present_window->frame_callback_list);
-
- /* Make sure the timer callback doesn't get called */
- xwl_present_window->timer_armed = 0;
- xwl_present_reset_timer(xwl_present_window);
-}
-
-Bool
-xwl_present_maybe_redirect_window(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
- struct xwl_window *xwl_window = xwl_window_from_window(window);
-
- if (xwl_present_window->redirect_failed)
- return FALSE;
-
- if (compRedirectWindow(serverClient, window, CompositeRedirectManual) != Success) {
- xwl_present_window->redirect_failed = TRUE;
- return FALSE;
- }
-
- xwl_present_window->redirected = TRUE;
-
- xwl_window_update_surface_window(xwl_window);
- if (xwl_window->surface_window != window) {
- compUnredirectWindow(serverClient, window, CompositeRedirectManual);
- xwl_present_window->redirected = FALSE;
- xwl_present_window->redirect_failed = TRUE;
- xwl_window_update_surface_window(xwl_window);
- return FALSE;
- }
-
- if (!xwl_window->surface_window_damage)
- xwl_window->surface_window_damage = RegionCreate(NullBox, 1);
-
- return TRUE;
-}
-
-static CARD32
-unredirect_window(OsTimerPtr timer, CARD32 time, void *arg)
-{
- WindowPtr window = arg;
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-
- compUnredirectWindow(serverClient, window, CompositeRedirectManual);
- xwl_present_window->redirected = FALSE;
-
- xwl_present_window->unredirect_timer = NULL;
- return 0;
-}
-
-Bool
-xwl_present_maybe_unredirect_window(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-
- if (!xwl_present_window || !xwl_present_window->redirected)
- return FALSE;
-
- /* This function may get called from composite layer code, in which case
- * calling compUnredirectWindow would blow up. To avoid this, set up a timer
- * which will call it "as soon as possible".
- */
- if (!xwl_present_window->unredirect_timer) {
- xwl_present_window->unredirect_timer =
- TimerSet(NULL, 0, 1, unredirect_window, window);
- }
-
- return TRUE;
-}
-
-Bool
-xwl_present_window_redirected(WindowPtr window)
-{
- struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-
- return xwl_present_window->redirected;
-}
-
-Bool
-xwl_present_init(ScreenPtr screen)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- present_screen_priv_ptr screen_priv;
-
- if (!present_screen_register_priv_keys())
- return FALSE;
-
- if (present_screen_priv(screen))
- return TRUE;
-
- screen_priv = present_screen_priv_init(screen);
- if (!screen_priv)
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
- return FALSE;
-
- xwl_screen->present_capabilities = XWL_PRESENT_CAPS;
-#ifdef XWL_HAS_GLAMOR
- if (xwl_glamor_supports_syncobjs(xwl_screen))
- xwl_screen->present_capabilities |=
- PresentCapabilitySyncobj;
-#endif /* XWL_HAS_GLAMOR */
-
- screen_priv->query_capabilities = xwl_present_query_capabilities;
- screen_priv->get_crtc = xwl_present_get_crtc;
-
- screen_priv->check_flip = xwl_present_check_flip;
- screen_priv->check_flip_window = xwl_present_check_flip_window;
- screen_priv->clear_window_flip = xwl_present_clear_window_flip;
-
- screen_priv->present_pixmap = xwl_present_pixmap;
- screen_priv->queue_vblank = xwl_present_queue_vblank;
- screen_priv->flush = xwl_present_flush;
- screen_priv->flush_fenced = xwl_present_flush_fenced;
- screen_priv->re_execute = xwl_present_re_execute;
-
- screen_priv->abort_vblank = xwl_present_abort_vblank;
-
- return TRUE;
-}
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
deleted file mode 100644
index 527233910..000000000
--- a/hw/xwayland/xwayland-present.h
+++ /dev/null
@@ -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
-
-#include
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
deleted file mode 100644
index 44e4a8055..000000000
--- a/hw/xwayland/xwayland-screen.c
+++ /dev/null
@@ -1,1192 +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
-
-#include
-#include
-#include
-#include
-
-#ifdef XWL_HAS_GLAMOR
-#include
-#endif
-
-#include
-#include
-
-#include "os/xserver_poll.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "xwayland-cursor.h"
-#include "xwayland-screen.h"
-#include "xwayland-window.h"
-#include "xwayland-input.h"
-#include "xwayland-output.h"
-#include "xwayland-pixmap.h"
-#include "xwayland-present.h"
-#include "xwayland-shm.h"
-#ifdef XWL_HAS_EI
-#include "xwayland-xtest.h"
-#endif
-#ifdef XWL_HAS_GLAMOR
-#include "xwayland-glamor.h"
-#endif
-
-#ifdef MITSHM
-#include "shmint.h"
-#endif
-
-#include "xdg-output-unstable-v1-client-protocol.h"
-#include "viewporter-client-protocol.h"
-#include "xdg-shell-client-protocol.h"
-#include "xwayland-shell-v1-client-protocol.h"
-#include "tearing-control-v1-client-protocol.h"
-#include "fractional-scale-v1-client-protocol.h"
-
-static DevPrivateKeyRec xwl_screen_private_key;
-static DevPrivateKeyRec xwl_client_private_key;
-
-#define DEFAULT_DPI 96
-
-_X_NORETURN
-static void _X_ATTRIBUTE_PRINTF(1, 2)
-xwl_give_up(const char *f, ...)
-{
- va_list args;
-
- va_start(args, f);
- VErrorFSigSafe(f, args);
- va_end(args);
-
- CloseWellKnownConnections();
- OsCleanup(TRUE);
- fflush(stderr);
- exit(1);
-}
-
-struct xwl_client *
-xwl_client_get(ClientPtr client)
-{
- return dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
-}
-
-struct xwl_screen *
-xwl_screen_get(ScreenPtr screen)
-{
- return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
-}
-
-Bool
-xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen)
-{
- return wl_compositor_get_version(xwl_screen->compositor) >=
- WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION &&
- xwl_screen->viewporter != NULL;
-}
-
-Bool
-xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
-{
- /* Resolution change emulation is only supported in rootless mode and
- * it requires viewport support.
- */
- return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
-}
-
-/* Return the output @ 0x0, falling back to the first output in the list */
-struct xwl_output *
-xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
-{
- struct xwl_output *xwl_output;
-
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- if (xwl_output->logical_x == 0 && xwl_output->logical_y == 0)
- return xwl_output;
- }
-
- if (xorg_list_is_empty(&xwl_screen->output_list))
- return NULL;
-
- return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
-}
-
-struct xwl_output *
-xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen)
-{
- if (xwl_screen->fixed_output)
- return xwl_screen->fixed_output;
-
- return xwl_screen_get_first_output(xwl_screen);
-}
-
-int
-xwl_screen_get_width(struct xwl_screen *xwl_screen)
-{
- return round(xwl_screen->width);
-}
-
-int
-xwl_screen_get_height(struct xwl_screen *xwl_screen)
-{
- return round(xwl_screen->height);
-}
-
-static void
-xwl_property_callback(CallbackListPtr *pcbl, void *closure,
- void *calldata)
-{
- ScreenPtr screen = closure;
- PropertyStateRec *rec = calldata;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
-
- if (rec->win->drawable.pScreen != screen)
- return;
-
- xwl_window = xwl_window_get(rec->win);
- if (!xwl_window)
- return;
-
- xwl_screen = xwl_screen_get(screen);
-
- if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
- xwl_window_update_property(xwl_window, rec);
-}
-
-#ifdef XACE
-#define readOnlyPropertyAccessMask (DixReadAccess |\
- DixGetAttrAccess |\
- DixListPropAccess |\
- DixGetPropAccess)
-
-static void
-xwl_access_property_callback(CallbackListPtr *pcbl, void *closure,
- void *calldata)
-{
- XacePropertyAccessRec *rec = calldata;
- PropertyPtr prop = *rec->ppProp;
- ClientPtr client = rec->client;
- Mask access_mode = rec->access_mode;
- ScreenPtr pScreen = closure;
- struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
-
- if (prop->propertyName == xwl_screen->allow_commits_prop) {
- /* Only the WM and the Xserver itself */
- if (client != serverClient &&
- client->index != xwl_screen->wm_client_id &&
- (access_mode & ~readOnlyPropertyAccessMask) != 0)
- rec->status = BadAccess;
- }
-}
-
-#undef readOnlyPropertyAccessMask
-#endif /* XACE */
-
-static void
-xwl_root_window_finalized_callback(CallbackListPtr *pcbl,
- void *closure,
- void *calldata)
-{
- ScreenPtr screen = closure;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_queued_drm_lease_device *queued_device, *next;
-
- xorg_list_for_each_entry_safe(queued_device, next,
- &xwl_screen->queued_drm_lease_devices, link) {
- xwl_screen_add_drm_lease_device(xwl_screen, queued_device->id);
- xorg_list_del(&queued_device->link);
- free(queued_device);
- }
- DeleteCallback(&RootWindowFinalizeCallback, xwl_root_window_finalized_callback, screen);
-}
-
-Bool
-xwl_close_screen(ScreenPtr screen)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_output *xwl_output, *next_xwl_output;
- struct xwl_seat *xwl_seat, *next_xwl_seat;
- struct xwl_wl_surface *xwl_wl_surface, *xwl_wl_surface_next;
-#ifdef XWL_HAS_GLAMOR
- xwl_dmabuf_feedback_destroy(&xwl_screen->default_feedback);
-#endif
- DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen);
-#ifdef XACE
- XaceDeleteCallback(XACE_PROPERTY_ACCESS, xwl_access_property_callback, screen);
-#endif
-
- xorg_list_for_each_entry_safe(xwl_output, next_xwl_output,
- &xwl_screen->output_list, link)
- xwl_output_destroy(xwl_output);
-
- if (xwl_screen->fixed_output)
- xwl_output_destroy(xwl_screen->fixed_output);
-
- xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat,
- &xwl_screen->seat_list, link)
- xwl_seat_destroy(xwl_seat);
-
- xwl_screen_release_tablet_manager(xwl_screen);
-
- struct xwl_drm_lease_device *device_data, *next;
- xorg_list_for_each_entry_safe(device_data, next,
- &xwl_screen->drm_lease_devices, link)
- xwl_screen_destroy_drm_lease_device(xwl_screen,
- device_data->drm_lease_device);
-
- xorg_list_for_each_entry_safe(xwl_wl_surface, xwl_wl_surface_next,
- &xwl_screen->pending_wl_surface_destroy, link)
- xwl_window_surface_do_destroy(xwl_wl_surface);
-
- RemoveNotifyFd(xwl_screen->wayland_fd);
-
- wl_display_disconnect(xwl_screen->display);
-
- screen->CloseScreen = xwl_screen->CloseScreen;
-
- free(xwl_screen);
-
- return screen->CloseScreen(screen);
-}
-
-static struct xwl_seat *
-xwl_screen_get_default_seat(struct xwl_screen *xwl_screen)
-{
- if (xorg_list_is_empty(&xwl_screen->seat_list))
- return NULL;
-
- return container_of(xwl_screen->seat_list.prev,
- struct xwl_seat,
- link);
-}
-
-static void
-xwl_cursor_warped_to(DeviceIntPtr device,
- ScreenPtr screen,
- ClientPtr client,
- WindowPtr window,
- SpritePtr sprite,
- int x, int y)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- struct xwl_window *xwl_window;
- WindowPtr focus;
-
- if (!xwl_seat)
- xwl_seat = xwl_screen_get_default_seat(xwl_screen);
-
- if (!window)
- window = XYToWindow(sprite, x, y);
-
- xwl_window = xwl_window_from_window(window);
- if (!xwl_window && xwl_seat->focus_window) {
- focus = xwl_seat->focus_window->toplevel;
-
- /* Warps on non wl_surface backed Windows are only allowed
- * as long as the pointer stays within the focus window.
- */
- if (x >= focus->drawable.x &&
- y >= focus->drawable.y &&
- x < focus->drawable.x + focus->drawable.width &&
- y < focus->drawable.y + focus->drawable.height) {
- if (!window) {
- DebugF("Warp relative to pointer, assuming pointer focus\n");
- xwl_window = xwl_seat->focus_window;
- } else if (window == screen->root) {
- DebugF("Warp on root window, assuming pointer focus\n");
- xwl_window = xwl_seat->focus_window;
- }
- }
- }
- if (!xwl_window)
- return;
-
- xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
-}
-
-static void
-xwl_set_shape(WindowPtr window,
- int kind)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
-
- xwl_screen = xwl_screen_get(screen);
- xwl_window = xwl_window_get(window);
-
- screen->SetShape = xwl_screen->SetShape;
- (*screen->SetShape) (window, kind);
- xwl_screen->SetShape = screen->SetShape;
- screen->SetShape = xwl_set_shape;
-
- if (!xwl_window)
- return;
-
- if (kind == ShapeInput) {
- xwl_window_set_input_region(xwl_window, wInputShape(window));
- if (xwl_window->allow_commits)
- wl_surface_commit(xwl_window->surface);
- }
-}
-
-static struct xwl_window *
-find_matching_input_output_window(struct xwl_screen *xwl_screen,
- WindowPtr window)
-{
- struct xwl_window *xwl_window;
-
- xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) {
- /* When confining happens on InputOnly windows, work out the InputOutput
- * window that would be covered by its geometry.
- */
- if (window->drawable.x < xwl_window->toplevel->drawable.x ||
- window->drawable.x + window->drawable.width >
- xwl_window->toplevel->drawable.x + xwl_window->toplevel->drawable.width ||
- window->drawable.y < xwl_window->toplevel->drawable.y ||
- window->drawable.y + window->drawable.height >
- xwl_window->toplevel->drawable.y + xwl_window->toplevel->drawable.height)
- continue;
-
- if (xwl_window->toplevel->drawable.class == InputOnly)
- continue;
-
- return xwl_window;
- }
-
- return NULL;
-}
-
-static void
-xwl_cursor_confined_to(DeviceIntPtr device,
- ScreenPtr screen,
- WindowPtr window)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- struct xwl_window *xwl_window;
-
- /* If running rootful with host grab requested, do not tamper with
- * pointer confinement.
- */
- if (!xwl_screen->rootless && xwl_screen->host_grab && xwl_screen->has_grab)
- return;
-
- if (!xwl_seat)
- xwl_seat = xwl_screen_get_default_seat(xwl_screen);
-
- /* xwl_seat hasn't been setup yet, don't do anything just yet */
- if (!xwl_seat)
- return;
-
- if (window == screen->root) {
- xwl_seat_unconfine_pointer(xwl_seat);
- return;
- }
-
- xwl_window = xwl_window_from_window(window);
- if (!xwl_window && window->drawable.class == InputOnly) {
- DebugF("Confine on InputOnly window, finding matching toplevel\n");
- xwl_window = find_matching_input_output_window(xwl_screen, window);
- }
- if (!xwl_window)
- return;
-
- xwl_seat_confine_pointer(xwl_seat, xwl_window);
-}
-
-void
-xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
-{
- struct xwl_window *xwl_window;
-
- xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window)
- xwl_window_check_resolution_change_emulation(xwl_window);
-}
-
-static void
-xwl_screen_post_damage(struct xwl_screen *xwl_screen)
-{
- struct xwl_window *xwl_window, *next_xwl_window;
- struct xorg_list commit_window_list;
-
- xorg_list_init(&commit_window_list);
-
- xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
- &xwl_screen->damage_window_list, link_damage) {
- /* If we're waiting on a frame callback from the server,
- * don't attach a new buffer. */
- if (xwl_window->frame_callback)
- continue;
-
- if (!xwl_window->allow_commits)
- continue;
-
- /* Running rootful, we must wait for the initial configuration
- * negotiation to complete before we can post damage.
- */
- if (xwl_window->awaiting_initial_configure_event)
- continue;
-
- xwl_window_post_damage(xwl_window);
- xorg_list_del(&xwl_window->link_damage);
- xorg_list_append(&xwl_window->link_damage, &commit_window_list);
- }
-
- if (xorg_list_is_empty(&commit_window_list))
- return;
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor)
- glamor_block_handler(xwl_screen->screen);
-#endif
-
- xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
- &commit_window_list, link_damage) {
- wl_surface_commit(xwl_window->surface);
- xorg_list_del(&xwl_window->link_damage);
- }
-}
-
-static void
-xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base,
- uint32_t serial)
-{
- xdg_wm_base_pong(xdg_wm_base, serial);
-}
-
-static const struct xdg_wm_base_listener xdg_wm_base_listener = {
- xdg_wm_base_ping,
-};
-
-static void
-registry_global(void *data, struct wl_registry *registry, uint32_t id,
- const char *interface, uint32_t version)
-{
- struct xwl_screen *xwl_screen = data;
-
- if (strcmp(interface, wl_compositor_interface.name) == 0) {
- uint32_t request_version = WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION;
-
- if (version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
- request_version = WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION;
-
- xwl_screen->compositor =
- wl_registry_bind(registry, id, &wl_compositor_interface, request_version);
- }
- else if (strcmp(interface, wl_shm_interface.name) == 0) {
- xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
- }
- else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
- xwl_screen->xdg_wm_base =
- wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
- xdg_wm_base_add_listener(xwl_screen->xdg_wm_base,
- &xdg_wm_base_listener,
- NULL);
- }
- else if (strcmp(interface, wl_output_interface.name) == 0 && version >= 2) {
- if (xwl_output_create(xwl_screen, id, (xwl_screen->fixed_output == NULL), version))
- xwl_screen->expecting_event++;
- }
- else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
- /* We support xdg-output from version 1 to version 3 */
- version = min(version, 3);
- xwl_screen->xdg_output_manager =
- wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, version);
- xwl_screen_init_xdg_output(xwl_screen);
- }
- else if (strcmp(interface, wp_drm_lease_device_v1_interface.name) == 0) {
- if (xwl_screen->screen->root == NULL) {
- struct xwl_queued_drm_lease_device *queued = malloc(sizeof(struct xwl_queued_drm_lease_device));
- queued->id = id;
- xorg_list_append(&queued->link, &xwl_screen->queued_drm_lease_devices);
- } else {
- xwl_screen_add_drm_lease_device(xwl_screen, id);
- }
- }
- else if (strcmp(interface, wp_viewporter_interface.name) == 0) {
- xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
- }
- else if (strcmp(interface, xwayland_shell_v1_interface.name) == 0 && xwl_screen->rootless) {
- xwl_screen->xwayland_shell =
- wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1);
- }
- else if (strcmp(interface, wp_tearing_control_manager_v1_interface.name) == 0) {
- xwl_screen->tearing_control_manager =
- wl_registry_bind(registry, id, &wp_tearing_control_manager_v1_interface, 1);
- }
- else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) {
- xwl_screen->fractional_scale_manager =
- wl_registry_bind(registry, id, &wp_fractional_scale_manager_v1_interface, 1);
- }
-#ifdef XWL_HAS_GLAMOR
- else if (xwl_screen->glamor) {
- xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
- version);
- }
-#endif
-}
-
-static void
-global_remove(void *data, struct wl_registry *registry, uint32_t name)
-{
- struct xwl_screen *xwl_screen = data;
- struct xwl_output *xwl_output, *tmp_xwl_output;
- struct xwl_drm_lease_device *lease_device, *tmp_lease_device;
-
- xorg_list_for_each_entry_safe(xwl_output, tmp_xwl_output,
- &xwl_screen->output_list, link) {
- if (xwl_output->server_output_id == name) {
- xwl_output_remove(xwl_output);
- break;
- }
- }
-
- xorg_list_for_each_entry_safe(lease_device, tmp_lease_device,
- &xwl_screen->drm_lease_devices, link) {
- if (lease_device->id == name) {
- wp_drm_lease_device_v1_release(lease_device->drm_lease_device);
- break;
- }
- }
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_global,
- global_remove
-};
-
-static void
-xwl_read_events (struct xwl_screen *xwl_screen)
-{
- int ret;
-
- if (xwl_screen->wait_flush)
- return;
-
- ret = wl_display_read_events(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to read Wayland events: %s\n", strerror(errno));
-
- xwl_screen->prepare_read = 0;
-
- ret = wl_display_dispatch_pending(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to dispatch Wayland events: %s\n", strerror(errno));
-}
-
-static int
-xwl_display_pollout (struct xwl_screen *xwl_screen, int timeout)
-{
- struct pollfd poll_fd;
-
- poll_fd.fd = wl_display_get_fd(xwl_screen->display);
- poll_fd.events = POLLOUT;
-
- return xserver_poll(&poll_fd, 1, timeout);
-}
-
-#ifdef XWL_HAS_LIBDECOR
-static void
-xwl_dispatch_events_with_libdecor(struct xwl_screen *xwl_screen)
-{
- int ret = 0;
-
- assert(!xwl_screen->rootless);
-
- ret = libdecor_dispatch(xwl_screen->libdecor_context, 0);
- if (ret == -1)
- xwl_give_up("failed to dispatch Wayland events with libdecor: %s\n",
- strerror(errno));
-}
-
-static void
-handle_libdecor_error(struct libdecor *context,
- enum libdecor_error error,
- const char *message)
-{
- xwl_give_up("libdecor error (%d): %s\n", error, message);
-}
-
-static struct libdecor_interface libdecor_iface = {
- .error = handle_libdecor_error,
-};
-#endif
-
-static void
-xwl_dispatch_events (struct xwl_screen *xwl_screen)
-{
- int ret = 0;
- int ready;
-
- if (xwl_screen->wait_flush)
- goto pollout;
-
- while (xwl_screen->prepare_read == 0 &&
- wl_display_prepare_read(xwl_screen->display) == -1) {
- ret = wl_display_dispatch_pending(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to dispatch Wayland events: %s\n",
- strerror(errno));
- }
-
- xwl_screen->prepare_read = 1;
-
-pollout:
- ready = xwl_display_pollout(xwl_screen, 5);
- if (ready == -1 && errno != EINTR)
- xwl_give_up("error polling on Xwayland fd: %s\n", strerror(errno));
-
- if (ready > 0)
- ret = wl_display_flush(xwl_screen->display);
-
- if (ret == -1 && errno != EAGAIN)
- xwl_give_up("failed to write to Xwayland fd: %s\n", strerror(errno));
-
- xwl_screen->wait_flush = (ready == 0 || ready == -1 || ret == -1);
-}
-
-static void
-socket_handler(int fd, int ready, void *data)
-{
- struct xwl_screen *xwl_screen = data;
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_screen->libdecor_context) {
- xwl_dispatch_events_with_libdecor(xwl_screen);
- return;
- }
-#endif
- xwl_read_events (xwl_screen);
-}
-
-static void
-wakeup_handler(void *data, int err)
-{
-}
-
-static void
-block_handler(void *data, void *timeout)
-{
- struct xwl_screen *xwl_screen = data;
-
- xwl_screen_post_damage(xwl_screen);
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_screen->libdecor_context) {
- xwl_dispatch_events_with_libdecor(xwl_screen);
- return;
- }
-#endif
- xwl_dispatch_events (xwl_screen);
-}
-
-void
-xwl_sync_events (struct xwl_screen *xwl_screen)
-{
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_screen->libdecor_context) {
- xwl_dispatch_events_with_libdecor(xwl_screen);
- return;
- }
-#endif
- xwl_dispatch_events (xwl_screen);
- xwl_read_events (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)
-{
- if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
- wl_surface_damage_buffer(surface, x, y, width, height);
- else
- wl_surface_damage(surface, x, y, width, height);
-}
-
-void
-xwl_screen_roundtrip(struct xwl_screen *xwl_screen)
-{
- int ret;
-
- do {
- ret = wl_display_roundtrip(xwl_screen->display);
- } while (ret >= 0 && xwl_screen->expecting_event);
-
- if (ret < 0)
- xwl_give_up("could not connect to wayland server\n");
-}
-
-static int
-xwl_server_grab(ClientPtr client)
-{
- struct xwl_screen *xwl_screen;
-
- /* Allow GrabServer for the X11 window manager.
- * Xwayland only has 1 screen (no Zaphod for Xwayland) so we check
- * for the first and only screen here.
- */
- xwl_screen = xwl_screen_get(screenInfo.screens[0]);
- if (xwl_screen->wm_client_id == client->index)
- return xwl_screen->GrabServer(client);
-
- /* For all other clients, just pretend it works for compatibility,
- but do nothing */
- return Success;
-}
-
-static int
-xwl_server_ungrab(ClientPtr client)
-{
- struct xwl_screen *xwl_screen;
-
- /* Same as above, allow UngrabServer for the X11 window manager only */
- xwl_screen = xwl_screen_get(screenInfo.screens[0]);
- if (xwl_screen->wm_client_id == client->index)
- return xwl_screen->UngrabServer(client);
-
- /* For all other clients, just pretend it works for compatibility,
- but do nothing */
- return Success;
-}
-
-static void
-xwl_screen_setup_custom_vector(struct xwl_screen *xwl_screen)
-{
- /* Rootfull Xwayland does not need a custom ProcVector (yet?) */
- if (!xwl_screen->rootless)
- return;
-
- xwl_screen->GrabServer = ProcVector[X_GrabServer];
- xwl_screen->UngrabServer = ProcVector[X_UngrabServer];
-
- ProcVector[X_GrabServer] = xwl_server_grab;
- ProcVector[X_UngrabServer] = xwl_server_ungrab;
-}
-
-int
-xwl_screen_get_next_output_serial(struct xwl_screen *xwl_screen)
-{
- return xwl_screen->output_name_serial++;
-}
-
-void
-xwl_screen_lost_focus(struct xwl_screen *xwl_screen)
-{
- struct xwl_seat *xwl_seat;
-
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- xwl_seat_leave_ptr(xwl_seat, TRUE);
- xwl_seat_leave_kbd(xwl_seat);
- }
-}
-
-Bool
-xwl_screen_should_use_fractional_scale(struct xwl_screen *xwl_screen)
-{
- /* Fullscreen uses a viewport already */
- if (xwl_screen->fullscreen)
- return FALSE;
-
- if (xwl_screen->rootless)
- return FALSE;
-
- /* We need both fractional scale and viewporter protocols */
- if (!xwl_screen->fractional_scale_manager)
- return FALSE;
-
- if (!xwl_screen->viewporter)
- return FALSE;
-
- return xwl_screen->hidpi;
-}
-
-Bool
-xwl_screen_update_global_surface_scale(struct xwl_screen *xwl_screen)
-{
- ScreenPtr screen = xwl_screen->screen;
- struct xwl_window *xwl_window;
- int32_t old_scale;
-
- if (xwl_screen_should_use_fractional_scale(xwl_screen))
- return FALSE;
-
- if (xwl_screen->rootless)
- return FALSE;
-
- if (xwl_screen->fullscreen)
- return FALSE;
-
- if (!xwl_screen->hidpi)
- return FALSE;
-
- if (screen->root == NullWindow)
- return FALSE;
-
- xwl_window = xwl_window_get(screen->root);
- if (!xwl_window)
- return FALSE;
-
- old_scale = xwl_screen->global_surface_scale;
- xwl_screen->global_surface_scale = xwl_window_get_max_output_scale(xwl_window);
-
- return (xwl_screen->global_surface_scale != old_scale);
-}
-
-Bool
-xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
-{
- static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
- struct xwl_screen *xwl_screen;
- Pixel red_mask, blue_mask, green_mask;
- int ret, bpc, green_bpc, i;
- unsigned int xwl_width = 640;
- unsigned int xwl_height = 480;
- Bool use_fixed_size = FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!xwl_pixmap_init())
- return FALSE;
- if (!xwl_window_init())
- return FALSE;
- /* There are no easy to use new / delete client hooks, we could use a
- * ClientStateCallback, but it is easier to let the dix code manage the
- * memory for us. This will zero fill the initial xwl_client data.
- */
- if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT,
- sizeof(struct xwl_client)))
- return FALSE;
-
- xwl_screen = calloc(1, sizeof *xwl_screen);
- if (xwl_screen == NULL)
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
- xwl_screen->screen = pScreen;
-
-#ifdef XWL_HAS_EI
- if (!xwayland_ei_init())
- return FALSE;
-#endif
-
-#ifdef XWL_HAS_GLAMOR
- xwl_screen->glamor = XWL_GLAMOR_DEFAULT;
-#endif
-
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-rootless") == 0) {
- xwl_screen->rootless = 1;
-
- /* Disable the XSS extension on Xwayland rootless.
- *
- * Xwayland is just a Wayland client, no X11 screensaver
- * should be expected to work reliably on Xwayland rootless.
- */
-#ifdef SCREENSAVER
- noScreenSaverExtension = TRUE;
-#endif
- ScreenSaverTime = 0;
- ScreenSaverInterval = 0;
- defaultScreenSaverTime = 0;
- defaultScreenSaverInterval = 0;
- }
- else if (strcmp(argv[i], "-shm") == 0) {
- xwl_screen->glamor = XWL_GLAMOR_NONE;
- }
-#ifdef XWL_HAS_GLAMOR
- else if (strcmp(argv[i], "-glamor") == 0) {
- if (strncmp(argv[i + 1], "es", 2) == 0)
- xwl_screen->glamor = XWL_GLAMOR_GLES;
- else if (strncmp(argv[i + 1], "gl", 2) == 0)
- xwl_screen->glamor = XWL_GLAMOR_GL;
- else if (strncmp(argv[i + 1], "off", 3) == 0)
- xwl_screen->glamor = XWL_GLAMOR_NONE;
- else
- ErrorF("Xwayland glamor: unknown rendering API selected\n");
- }
-#endif
- else if (strcmp(argv[i], "-force-xrandr-emulation") == 0) {
- xwl_screen->force_xrandr_emulation = 1;
- }
- else if (strcmp(argv[i], "-geometry") == 0) {
- sscanf(argv[i + 1], "%ix%i", &xwl_width, &xwl_height);
- if (xwl_width == 0 || xwl_height == 0) {
- ErrorF("invalid argument for -geometry %s\n", argv[i + 1]);
- return FALSE;
- }
- use_fixed_size = 1;
- }
- else if (strcmp(argv[i], "-fullscreen") == 0) {
- use_fixed_size = 1;
- xwl_screen->fullscreen = 1;
- }
- else if (strcmp(argv[i], "-output") == 0) {
- xwl_screen->output_name = argv[i + 1];
- }
- else if (strcmp(argv[i], "-host-grab") == 0) {
- xwl_screen->host_grab = 1;
- xwl_screen->has_grab = 1;
- }
- else if (strcmp(argv[i], "-decorate") == 0) {
-#ifdef XWL_HAS_LIBDECOR
- xwl_screen->decorate = 1;
- use_fixed_size = 1;
-#else
- ErrorF("This build does not have libdecor support\n");
-#endif
- }
- else if (strcmp(argv[i], "-enable-ei-portal") == 0) {
-#ifdef XWL_HAS_EI_PORTAL
- xwl_screen->enable_ei_portal = 1;
-#else
- ErrorF("This build does not have XDG portal support\n");
-#endif
- }
- else if (strcmp(argv[i], "-nokeymap") == 0) {
- xwl_screen->nokeymap = 1;
- }
- else if (strcmp(argv[i], "-hidpi") == 0) {
- xwl_screen->hidpi = 1;
- }
- }
-
- if (!xwl_screen->rootless) {
- use_fixed_size = 1;
- xwl_screen->width = xwl_width;
- xwl_screen->height = xwl_height;
- } else if (use_fixed_size) {
- ErrorF("error, cannot set a geometry when running rootless\n");
- return FALSE;
- }
-
- xwl_screen->display = wl_display_connect(NULL);
- if (xwl_screen->display == NULL) {
- ErrorF("could not connect to wayland server\n");
- return FALSE;
- }
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor && !xwl_glamor_init_gbm(xwl_screen)) {
- ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
- xwl_screen->glamor = 0;
- }
-#endif
-
- /* In rootless mode, we don't have any screen storage, and the only
- * rendering should be to redirected mode. */
- if (xwl_screen->rootless)
- xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY;
- else
- xwl_screen->root_clip_mode = ROOT_CLIP_FULL;
-
- xorg_list_init(&xwl_screen->output_list);
- xorg_list_init(&xwl_screen->seat_list);
- xorg_list_init(&xwl_screen->damage_window_list);
- xorg_list_init(&xwl_screen->window_list);
- xorg_list_init(&xwl_screen->drm_lease_devices);
- xorg_list_init(&xwl_screen->queued_drm_lease_devices);
- xorg_list_init(&xwl_screen->drm_leases);
- xorg_list_init(&xwl_screen->pending_wl_surface_destroy);
- xwl_screen->depth = 24;
- xwl_screen->global_surface_scale = 1;
-
- if (!monitorResolution)
- monitorResolution = DEFAULT_DPI;
-
- if (use_fixed_size) {
- if (!xwl_screen_init_randr_fixed(xwl_screen))
- return FALSE;
- } else {
- if (!xwl_screen_init_output(xwl_screen))
- return FALSE;
- }
-
- xwl_screen->expecting_event = 0;
- xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
- wl_registry_add_listener(xwl_screen->registry,
- ®istry_listener, xwl_screen);
- xwl_screen_roundtrip(xwl_screen);
-
- if (xwl_screen->fullscreen && xwl_screen->rootless) {
- ErrorF("error, cannot set fullscreen when running rootless\n");
- return FALSE;
- }
-
- if (xwl_screen->fullscreen && xwl_screen->decorate) {
- ErrorF("error, cannot use the decorate option when running fullscreen\n");
- return FALSE;
- }
-
- if (xwl_screen->fullscreen && !xwl_screen_has_viewport_support(xwl_screen)) {
- ErrorF("missing viewport support in the compositor, ignoring fullscreen\n");
- xwl_screen->fullscreen = FALSE;
- }
-
- if (xwl_screen->host_grab && xwl_screen->rootless) {
- ErrorF("error, cannot use host grab when running rootless\n");
- return FALSE;
- }
-
- if (!xwl_screen->rootless && !xwl_screen->xdg_wm_base) {
- ErrorF("missing XDG-WM-Base protocol\n");
- return FALSE;
- }
-
- bpc = xwl_screen->depth / 3;
- green_bpc = xwl_screen->depth - 2 * bpc;
- blue_mask = (1 << bpc) - 1;
- green_mask = ((1 << green_bpc) - 1) << bpc;
- red_mask = blue_mask << (green_bpc + bpc);
-
- miSetVisualTypesAndMasks(xwl_screen->depth,
- ((1 << TrueColor) | (1 << DirectColor)),
- green_bpc, TrueColor,
- red_mask, green_mask, blue_mask);
-
- miSetPixmapDepths();
-
- ret = fbScreenInit(pScreen, NULL,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen),
- monitorResolution, monitorResolution, 0,
- BitsPerPixel(xwl_screen->depth));
- if (!ret)
- return FALSE;
-
- fbPictureInit(pScreen, 0, 0);
-
-#ifdef MITSHM
- ShmRegisterFbFuncs(pScreen);
-#endif
-
-#ifdef HAVE_XSHMFENCE
- if (!miSyncShmScreenInit(pScreen))
- return FALSE;
-#endif
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_screen->decorate && !xwl_screen->rootless) {
- xwl_screen->libdecor_context = libdecor_new(xwl_screen->display, &libdecor_iface);
- xwl_screen->wayland_fd = libdecor_get_fd(xwl_screen->libdecor_context);
- }
- else
-#endif
- {
- xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
- }
- SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
- RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
-
- pScreen->blackPixel = 0;
- pScreen->whitePixel = 1;
-
- ret = fbCreateDefColormap(pScreen);
-
- if (!xwl_screen_init_cursor(xwl_screen))
- return FALSE;
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) {
- ErrorF("Failed to initialize glamor, falling back to sw\n");
- xwl_screen->glamor = XWL_GLAMOR_NONE;
- }
-#endif
-
- xwl_screen->present = xwl_present_init(pScreen);
-
- if (!xwl_screen->glamor) {
- xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = xwl_shm_create_screen_resources;
- pScreen->CreatePixmap = xwl_shm_create_pixmap;
- pScreen->DestroyPixmap = xwl_shm_destroy_pixmap;
- }
-
- xwl_screen->RealizeWindow = pScreen->RealizeWindow;
- pScreen->RealizeWindow = xwl_realize_window;
-
- xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreen->UnrealizeWindow = xwl_unrealize_window;
-
- xwl_screen->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = xwl_destroy_window;
-
- xwl_screen->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xwl_close_screen;
-
- xwl_screen->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
- pScreen->ChangeWindowAttributes = xwl_change_window_attributes;
-
- xwl_screen->ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = xwl_clip_notify;
-
- xwl_screen->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = xwl_config_notify;
-
- xwl_screen->ReparentWindow = pScreen->ReparentWindow;
- pScreen->ReparentWindow = xwl_reparent_window;
-
- xwl_screen->ResizeWindow = pScreen->ResizeWindow;
- pScreen->ResizeWindow = xwl_resize_window;
-
- xwl_screen->MoveWindow = pScreen->MoveWindow;
- pScreen->MoveWindow = xwl_move_window;
-
- xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
- pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
-
- xwl_screen->SetShape = pScreen->SetShape;
- pScreen->SetShape = xwl_set_shape;
-
- pScreen->CursorWarpedTo = xwl_cursor_warped_to;
- pScreen->CursorConfinedTo = xwl_cursor_confined_to;
-
- xwl_screen->allow_commits_prop = MakeAtom(allow_commits,
- strlen(allow_commits),
- TRUE);
- if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
- return FALSE;
-
- AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
- AddCallback(&RootWindowFinalizeCallback, xwl_root_window_finalized_callback, pScreen);
-#ifdef XACE
- XaceRegisterCallback(XACE_PROPERTY_ACCESS, xwl_access_property_callback, pScreen);
-#endif
-
- xwl_screen_setup_custom_vector(xwl_screen);
-
- xwl_screen_roundtrip(xwl_screen);
-
- return ret;
-}
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
deleted file mode 100644
index ffbaa09e7..000000000
--- a/hw/xwayland/xwayland-screen.h
+++ /dev/null
@@ -1,187 +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
-
-#include
-#include
-#include
-#include
-
-#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
-#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;
- CreateScreenResourcesProcPtr CreateScreenResources;
- CloseScreenProcPtr CloseScreen;
- ConfigNotifyProcPtr ConfigNotify;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- DestroyWindowProcPtr DestroyWindow;
- XYToWindowProcPtr XYToWindow;
- SetWindowPixmapProcPtr SetWindowPixmap;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- ReparentWindowProcPtr ReparentWindow;
- 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_close_screen(ScreenPtr 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 */
diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
deleted file mode 100644
index faca5224e..000000000
--- a/hw/xwayland/xwayland-shm.c
+++ /dev/null
@@ -1,376 +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
-
-#include "os.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#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;
- char *name;
- 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;
- }
-
- name = malloc(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);
- int ret;
-
- screen->CreateScreenResources = xwl_screen->CreateScreenResources;
- ret = (*screen->CreateScreenResources) (screen);
- xwl_screen->CreateScreenResources = screen->CreateScreenResources;
- screen->CreateScreenResources = xwl_shm_create_screen_resources;
-
- if (!ret)
- return ret;
-
- 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;
-}
diff --git a/hw/xwayland/xwayland-shm.h b/hw/xwayland/xwayland-shm.h
deleted file mode 100644
index 3c94000b6..000000000
--- a/hw/xwayland/xwayland-shm.h
+++ /dev/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
-
-#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 */
diff --git a/hw/xwayland/xwayland-types.h b/hw/xwayland/xwayland-types.h
deleted file mode 100644
index d3fd2a0fc..000000000
--- a/hw/xwayland/xwayland-types.h
+++ /dev/null
@@ -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 */
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
deleted file mode 100644
index 973ae1e93..000000000
--- a/hw/xwayland/xwayland-vidmode.c
+++ /dev/null
@@ -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).
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include
-#endif
-
-#include
-#include "misc.h"
-#include "os.h"
-#include "extinit.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->logical_x && y == xwl_output->logical_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->logical_x;
- *y = xwl_output->logical_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 */
diff --git a/hw/xwayland/xwayland-vidmode.h b/hw/xwayland/xwayland-vidmode.h
deleted file mode 100644
index 4e3236eb1..000000000
--- a/hw/xwayland/xwayland-vidmode.h
+++ /dev/null
@@ -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
-
-#ifdef XF86VIDMODE
-void xwlVidModeExtensionInit(void);
-#endif
-
-#endif /* XWAYLAND_VIDMODE_H */
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
deleted file mode 100644
index a470ef313..000000000
--- a/hw/xwayland/xwayland-window-buffers.c
+++ /dev/null
@@ -1,477 +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
- */
-
-#include
-
-#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
-#ifdef DRI3
-#include
-#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)
-{
- ScreenPtr pScreen = xwl_window_buffer->pixmap->drawable.pScreen;
-
- xwl_pixmap_del_buffer_release_cb(xwl_window_buffer->pixmap);
- (*pScreen->DestroyPixmap) (xwl_window_buffer->pixmap);
- 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;
-
-#ifdef COMPOSITE
- pixmap->screen_x = visit.old->screen_x;
- pixmap->screen_y = visit.old->screen_y;
-#endif
-
- 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);
- screen->DestroyPixmap(window_pixmap);
-}
-
-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;
-}
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
deleted file mode 100644
index dabb343c1..000000000
--- a/hw/xwayland/xwayland-window-buffers.h
+++ /dev/null
@@ -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
- */
-
-#ifndef XWAYLAND_WINDOW_BUFFERS_H
-#define XWAYLAND_WINDOW_BUFFERS_H
-
-#include
-
-#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 */
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
deleted file mode 100644
index b0e0cddd9..000000000
--- a/hw/xwayland/xwayland-window.c
+++ /dev/null
@@ -1,2165 +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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include
-#endif
-
-#include
-#include
-#include
-
-#include
-#include
-
-#include "compositeext.h"
-#include "compint.h"
-#include "inputstr.h"
-#include "propertyst.h"
-
-#include "xwayland-types.h"
-#include "xwayland-input.h"
-#include "xwayland-pixmap.h"
-#include "xwayland-present.h"
-#include "xwayland-screen.h"
-#include "xwayland-window.h"
-#include "xwayland-window-buffers.h"
-#include "xwayland-shm.h"
-#include "xwayland-dmabuf.h"
-
-#include "linux-dmabuf-unstable-v1-client-protocol.h"
-#include "tearing-control-v1-client-protocol.h"
-#include "viewporter-client-protocol.h"
-#include "xdg-shell-client-protocol.h"
-#include "xwayland-shell-v1-client-protocol.h"
-#include "fractional-scale-v1-client-protocol.h"
-#include "linux-drm-syncobj-v1-client-protocol.h"
-
-#define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
-
-#define MAX_ROOTFUL_WIDTH 32767
-#define MAX_ROOTFUL_HEIGHT 32767
-#define MIN_ROOTFUL_WIDTH 320
-#define MIN_ROOTFUL_HEIGHT 200
-
-#define FRACTIONAL_SCALE_DENOMINATOR 120
-
-static DevPrivateKeyRec xwl_window_private_key;
-static DevPrivateKeyRec xwl_wm_window_private_key;
-static DevPrivateKeyRec xwl_damage_private_key;
-static const char *xwl_surface_tag = "xwl-surface";
-
-static Bool xwl_window_attach_buffer(struct xwl_window *);
-
-struct xwl_window *
-xwl_window_get(WindowPtr window)
-{
- return dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
-}
-
-static DamagePtr
-window_get_damage(WindowPtr window)
-{
- return dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key);
-}
-
-RegionPtr
-xwl_window_get_damage_region(struct xwl_window *xwl_window)
-{
- return DamageRegion(window_get_damage(xwl_window->surface_window));
-}
-
-struct xwl_window *
-xwl_window_from_window(WindowPtr window)
-{
- struct xwl_window *xwl_window;
-
- while (window) {
- xwl_window = xwl_window_get(window);
- if (xwl_window)
- return xwl_window;
-
- window = window->parent;
- }
-
- return NULL;
-}
-
-static void
-xwl_window_set_xwayland_tag(struct xwl_window *xwl_window)
-{
- wl_proxy_set_tag((struct wl_proxy *)xwl_window->surface, &xwl_surface_tag);
-}
-
-static void
-xwl_window_clear_xwayland_tag(struct xwl_window *xwl_window)
-{
- wl_proxy_set_tag((struct wl_proxy *)xwl_window->surface, NULL);
-}
-
-Bool
-is_surface_from_xwl_window(struct wl_surface *surface)
-{
- return wl_proxy_get_tag((struct wl_proxy *) surface) == &xwl_surface_tag;
-}
-
-static void
-xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
- const char *debug_msg)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- DamagePtr damage;
-
- xwl_window->allow_commits = allow;
- DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
- xwl_window->toplevel->drawable.id, allow, debug_msg);
-
- damage = window_get_damage(xwl_window->surface_window);
- if (allow &&
- xorg_list_is_empty(&xwl_window->link_damage) &&
- damage &&
- RegionNotEmpty(DamageRegion(damage))) {
- xorg_list_add(&xwl_window->link_damage,
- &xwl_screen->damage_window_list);
- }
-}
-
-static void
-xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
- PropertyPtr prop)
-{
- static Bool warned = FALSE;
- CARD32 *propdata;
-
- if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
- FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
-
- if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
- /* Not properly set, so fall back to safe and glitchy */
- xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
-
- if (!warned) {
- LogMessageVerb(X_WARNING, 0, "Window manager is misusing property %s.\n",
- NameForAtom(prop->propertyName));
- warned = TRUE;
- }
- return;
- }
-
- propdata = prop->data;
- xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
-}
-
-void
-xwl_window_update_property(struct xwl_window *xwl_window,
- PropertyStateRec *propstate)
-{
- switch (propstate->state) {
- case PropertyNewValue:
- xwl_window_set_allow_commits_from_property(xwl_window, propstate->prop);
- break;
-
- case PropertyDelete:
- xwl_window_set_allow_commits(xwl_window, TRUE, "property deleted");
- break;
-
- default:
- break;
- }
-}
-
-static void
-need_source_validate_dec(struct xwl_screen *xwl_screen)
-{
- xwl_screen->need_source_validate--;
-
- if (!xwl_screen->need_source_validate)
- xwl_screen->screen->SourceValidate = xwl_screen->SourceValidate;
-}
-
-static void
-xwl_source_validate(DrawablePtr drawable, int x, int y, int width, int height,
- unsigned int sub_window_mode)
-{
- struct xwl_window *xwl_window;
- WindowPtr window, iterator;
- RegionRec region;
- BoxRec box;
-
- if (sub_window_mode != IncludeInferiors ||
- drawable->type != DRAWABLE_WINDOW)
- return;
-
- window = (WindowPtr)drawable;
- xwl_window = xwl_window_from_window(window);
- if (!xwl_window || !xwl_window->surface_window_damage ||
- !RegionNotEmpty(xwl_window->surface_window_damage))
- return;
-
- for (iterator = xwl_window->toplevel;
- ;
- iterator = iterator->firstChild) {
- if (iterator == xwl_window->surface_window)
- return;
-
- if (iterator == window)
- break;
- }
-
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + width;
- box.y2 = y + height;
- RegionInit(®ion, &box, 1);
- RegionIntersect(®ion, ®ion, xwl_window->surface_window_damage);
-
- if (RegionNotEmpty(®ion)) {
- ScreenPtr screen = drawable->pScreen;
- PixmapPtr dst_pix, src_pix;
- BoxPtr pbox;
- GCPtr pGC;
- int nbox;
-
- dst_pix = screen->GetWindowPixmap(window);
- pGC = GetScratchGC(dst_pix->drawable.depth, screen);
- if (!pGC)
- FatalError("GetScratchGC failed for depth %d", dst_pix->drawable.depth);
- ValidateGC(&dst_pix->drawable, pGC);
-
- src_pix = screen->GetWindowPixmap(xwl_window->surface_window);
-
- RegionSubtract(xwl_window->surface_window_damage,
- xwl_window->surface_window_damage,
- ®ion);
-
- if (!RegionNotEmpty(xwl_window->surface_window_damage))
- need_source_validate_dec(xwl_window->xwl_screen);
-
-#if defined(COMPOSITE)
- if (dst_pix->screen_x || dst_pix->screen_y)
- RegionTranslate(®ion, -dst_pix->screen_x, -dst_pix->screen_y);
-#endif
-
- pbox = RegionRects(®ion);
- nbox = RegionNumRects(®ion);
- while (nbox--) {
- (void) (*pGC->ops->CopyArea) (&src_pix->drawable,
- &dst_pix->drawable,
- pGC,
- pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- pbox->x1, pbox->y1);
- pbox++;
- }
- FreeScratchGC(pGC);
- }
-
- RegionUninit(®ion);
-}
-
-static void
-need_source_validate_inc(struct xwl_screen *xwl_screen)
-{
- if (!xwl_screen->need_source_validate) {
- ScreenPtr screen = xwl_screen->screen;
-
- xwl_screen->SourceValidate = screen->SourceValidate;
- screen->SourceValidate = xwl_source_validate;
- }
-
- xwl_screen->need_source_validate++;
-}
-
-static void
-damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
-{
- WindowPtr window = data;
- struct xwl_window *xwl_window = xwl_window_from_window(window);
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- PixmapPtr window_pixmap;
-
- if (xwl_window &&
- xwl_window->surface_window_damage &&
- RegionNotEmpty(pRegion)) {
- if (!RegionNotEmpty(xwl_window->surface_window_damage))
- need_source_validate_inc(xwl_screen);
-
- RegionUnion(xwl_window->surface_window_damage,
- xwl_window->surface_window_damage,
- DamageRegion(pDamage));
- }
-
- if (xwl_screen->ignore_damage)
- return;
-
- if (xwl_window && xorg_list_is_empty(&xwl_window->link_damage))
- xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
-
- window_pixmap = screen->GetWindowPixmap(xwl_window->surface_window);
- if (xwl_is_client_pixmap(window_pixmap))
- xwl_screen->screen->DestroyPixmap(xwl_window_swap_pixmap(xwl_window, FALSE));
-}
-
-static void
-damage_destroy(DamagePtr pDamage, void *data)
-{
-}
-
-static Bool
-register_damage(WindowPtr window)
-{
- DamagePtr damage;
-
- damage = DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
- FALSE, window->drawable.pScreen, window);
- if (damage == NULL) {
- ErrorF("Failed creating damage\n");
- return FALSE;
- }
-
- DamageRegister(&window->drawable, damage);
- dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, damage);
-
- return TRUE;
-}
-
-static void
-unregister_damage(WindowPtr window)
-{
- DamagePtr damage;
-
- damage = dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key);
- if (!damage)
- return;
-
- DamageUnregister(damage);
- DamageDestroy(damage);
-
- dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL);
-}
-
-static void
-xwl_window_maybe_commit_surface(struct xwl_window *xwl_window)
-{
- if (!xwl_window->awaiting_initial_configure_event)
- wl_surface_commit(xwl_window->surface);
-}
-
-static Bool
-xwl_window_update_fractional_scale(struct xwl_window *xwl_window,
- int fractional_scale_numerator)
-{
- int old_scale_numerator = xwl_window->fractional_scale_numerator;
-
- xwl_window->fractional_scale_numerator = fractional_scale_numerator;
-
- return (old_scale_numerator != fractional_scale_numerator);
-}
-
-static double
-xwl_window_get_fractional_scale_factor(struct xwl_window *xwl_window)
-{
- return (double) xwl_window->fractional_scale_numerator /
- (double) FRACTIONAL_SCALE_DENOMINATOR;
-}
-
-static Bool
-xwl_window_has_viewport_enabled(struct xwl_window *xwl_window)
-{
- return (xwl_window->viewport != NULL);
-}
-
-static void
-xwl_window_disable_viewport(struct xwl_window *xwl_window)
-{
- assert (xwl_window->viewport);
-
- DebugF("XWAYLAND: disabling viewport\n");
- wp_viewport_destroy(xwl_window->viewport);
- xwl_window->viewport = NULL;
- xwl_window->viewport_scale_x = 1.0;
- xwl_window->viewport_scale_y = 1.0;
- xwl_window_set_input_region(xwl_window, wInputShape(xwl_window->toplevel));
-}
-
-/* Enable the viewport for fractional scale support with Xwayland rootful.
- * Fractional scale support is not used with Xwayland rootful fullscreen (which
- * sets its own XRandR resolution) so we can use the viewport for either
- * fullscreen mode or fractional scale.
- */
-static void
-xwl_window_enable_viewport_for_fractional_scale(struct xwl_window *xwl_window,
- int width, int height)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- int buffer_width, buffer_height;
- double scale;
-
- scale = xwl_window_get_fractional_scale_factor(xwl_window);
- buffer_width = round((double) width / scale);
- buffer_height = round((double) height / scale);
-
- if (!xwl_window_has_viewport_enabled(xwl_window))
- xwl_window->viewport = wp_viewporter_get_viewport(xwl_screen->viewporter,
- xwl_window->surface);
-
- DebugF("XWAYLAND: enabling viewport for fractional scale %dx%d -> %dx%d\n",
- width, height, buffer_width, buffer_height);
- wp_viewport_set_source(xwl_window->viewport,
- wl_fixed_from_int(0),
- wl_fixed_from_int(0),
- wl_fixed_from_int(width),
- wl_fixed_from_int(height));
- wp_viewport_set_destination(xwl_window->viewport,
- buffer_width,
- buffer_height);
-
- xwl_window->viewport_scale_x = scale;
- xwl_window->viewport_scale_y = scale;
- xwl_window_set_input_region(xwl_window, wInputShape(xwl_window->toplevel));
-}
-
-/* Enable the viewport for Xwayland rootful fullscreen, to match the XRandR
- * resolution with the actual output size.
- */
-static void
-xwl_window_enable_viewport_for_output(struct xwl_window *xwl_window,
- struct xwl_output *xwl_output,
- struct xwl_emulated_mode *emulated_mode)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- int width, height, logical_width, logical_height;
-
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
- width = emulated_mode->width / xwl_screen->global_surface_scale;
- height = emulated_mode->height / xwl_screen->global_surface_scale;
- } else {
- width = emulated_mode->height / xwl_screen->global_surface_scale;
- height = emulated_mode->width / xwl_screen->global_surface_scale;
- }
-
- output_get_logical_extents(xwl_output, &logical_width, &logical_height);
-
- if (!xwl_window_has_viewport_enabled(xwl_window)) {
- DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n",
- width, height, logical_width, logical_height);
- xwl_window->viewport = wp_viewporter_get_viewport(xwl_window->xwl_screen->viewporter,
- xwl_window->surface);
- }
-
- wp_viewport_set_source(xwl_window->viewport,
- wl_fixed_from_int(0),
- wl_fixed_from_int(0),
- wl_fixed_from_int(width),
- wl_fixed_from_int(height));
- wp_viewport_set_destination(xwl_window->viewport,
- logical_width, logical_height);
-
- xwl_window->viewport_scale_x = (float) width / logical_width;
- xwl_window->viewport_scale_y = (float) height / logical_height;
- xwl_window_set_input_region(xwl_window, wInputShape(xwl_window->toplevel));
-}
-
-static Bool
-window_is_wm_window(WindowPtr window)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
- Bool *is_wm_window;
-
- if (CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id)
- return TRUE;
-
- is_wm_window = dixLookupPrivate(&window->devPrivates, &xwl_wm_window_private_key);
- return *is_wm_window;
-}
-
-static WindowPtr
-get_single_input_output_child(WindowPtr window)
-{
- WindowPtr iter, input_output_child = NULL;
-
- for (iter = window->firstChild; iter; iter = iter->nextSib) {
- if (iter->drawable.class != InputOutput)
- continue;
-
- /* We're looking for a single InputOutput child, bail if there are multiple */
- if (input_output_child)
- return NULL;
-
- input_output_child = iter;
- }
-
- return input_output_child;
-}
-
-static WindowPtr
-window_get_client_toplevel(WindowPtr window)
-{
- assert(window);
-
- /* If the toplevel window is owned by the window-manager, then the
- * actual client toplevel window has been reparented to some window-manager
- * decoration/wrapper windows. In that case recurse by checking the client
- * of the only InputOutput child of the decoration/wrapper window.
- */
- while (window && window_is_wm_window(window))
- window = get_single_input_output_child(window);
-
- return window;
-}
-
-static Bool
-is_output_suitable_for_fullscreen(struct xwl_output *xwl_output)
-{
- if (xwl_output == NULL)
- return FALSE;
-
- if (xwl_output->logical_w == 0 || xwl_output->logical_h == 0)
- return FALSE;
-
- return TRUE;
-}
-
-static struct xwl_output *
-xwl_window_get_output(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_output *xwl_output;
-
- xwl_output = xwl_output_get_output_from_name(xwl_screen, xwl_screen->output_name);
- if (is_output_suitable_for_fullscreen(xwl_output))
- return xwl_output;
-
- xwl_output = xwl_output_from_wl_output(xwl_screen, xwl_window->wl_output);
- if (is_output_suitable_for_fullscreen(xwl_output))
- return xwl_output;
-
- return xwl_screen_get_first_output(xwl_screen);
-}
-
-static Bool
-xwl_window_should_enable_viewport_fullscreen(struct xwl_window *xwl_window,
- struct xwl_output **xwl_output_ret,
- struct xwl_emulated_mode *emulated_mode_ret)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_output *xwl_output;
-
- xwl_output = xwl_window_get_output(xwl_window);
- if (!xwl_output)
- return FALSE;
-
- *xwl_output_ret = xwl_output;
- emulated_mode_ret->server_output_id = 0;
- emulated_mode_ret->width = xwl_screen_get_width(xwl_screen);
- emulated_mode_ret->height = xwl_screen_get_height(xwl_screen);
- emulated_mode_ret->from_vidmode = FALSE;
-
- return TRUE;
-}
-
-static Bool
-xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
- struct xwl_output **xwl_output_ret,
- struct xwl_emulated_mode *emulated_mode_ret)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_emulated_mode *emulated_mode;
- struct xwl_output *xwl_output;
- ClientPtr owner;
- WindowPtr window;
- DrawablePtr drawable;
-
- if (!xwl_screen_has_viewport_support(xwl_screen))
- return FALSE;
-
- if (xwl_screen->fullscreen)
- return xwl_window_should_enable_viewport_fullscreen(xwl_window,
- xwl_output_ret,
- emulated_mode_ret);
-
- if (!xwl_screen->rootless)
- return FALSE;
-
- window = window_get_client_toplevel(xwl_window->toplevel);
- if (!window)
- return FALSE;
-
- owner = wClient(window);
- drawable = &window->drawable;
-
- /* 1. Test if the window matches the emulated mode on one of the outputs
- * This path gets hit by most games / libs (e.g. SDL, SFML, OGRE)
- */
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- int emulated_width, emulated_height;
-
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner);
- if (!emulated_mode)
- continue;
-
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
- emulated_width = emulated_mode->width;
- emulated_height = emulated_mode->height;
- } else {
- emulated_width = emulated_mode->height;
- emulated_height = emulated_mode->width;
- }
-
- if (drawable->x == xwl_output->logical_x &&
- drawable->y == xwl_output->logical_y &&
- drawable->width == emulated_width &&
- drawable->height == emulated_height) {
-
- memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode));
- *xwl_output_ret = xwl_output;
- return TRUE;
- }
- }
-
- /* 2. Test if the window uses override-redirect + vidmode
- * and matches (fully covers) the entire screen.
- * This path gets hit by: allegro4, ClanLib-1.0.
- */
- xwl_output = xwl_screen_get_first_output(xwl_screen);
- emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner);
- if (xwl_output && xwl_window->toplevel->overrideRedirect &&
- emulated_mode && emulated_mode->from_vidmode &&
- drawable->x == 0 && drawable->y == 0 &&
- drawable->width == xwl_screen_get_width(xwl_screen) &&
- drawable->height == xwl_screen_get_height(xwl_screen)) {
-
- memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode));
- *xwl_output_ret = xwl_output;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static Bool
-xwl_window_should_enable_fractional_scale_viewport(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- double scale;
-
- if (!xwl_screen_should_use_fractional_scale(xwl_screen))
- return FALSE;
-
- scale = xwl_window_get_fractional_scale_factor(xwl_window);
-
- return fabs(scale - 1.00) > FLT_EPSILON;
-}
-
-static void
-xwl_window_check_fractional_scale_viewport(struct xwl_window *xwl_window,
- int width, int height)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
- if (!xwl_screen_should_use_fractional_scale(xwl_screen))
- return;
-
- if (xwl_window_should_enable_fractional_scale_viewport(xwl_window))
- xwl_window_enable_viewport_for_fractional_scale(xwl_window, width, height);
- else if (xwl_window_has_viewport_enabled(xwl_window))
- xwl_window_disable_viewport(xwl_window);
-}
-
-void
-xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window)
-{
- struct xwl_emulated_mode emulated_mode;
- struct xwl_output *xwl_output;
-
- if (xwl_window_should_enable_viewport(xwl_window, &xwl_output, &emulated_mode))
- xwl_window_enable_viewport_for_output(xwl_window, xwl_output, &emulated_mode);
- else if (xwl_window_should_enable_fractional_scale_viewport(xwl_window))
- return;
- else if (xwl_window_has_viewport_enabled(xwl_window))
- xwl_window_disable_viewport(xwl_window);
-}
-
-/* This checks if the passed in Window is a toplevel client window, note this
- * returns false for window-manager decoration windows and returns true for
- * the actual client top-level window even if it has been reparented to
- * a window-manager decoration window.
- */
-Bool
-xwl_window_is_toplevel(WindowPtr window)
-{
- if (!window->parent || window_is_wm_window(window))
- return FALSE;
-
- /* CSD and override-redirect toplevel windows */
- if (!window->parent->parent)
- return TRUE;
-
- /* Normal toplevel client windows, reparented to a window-manager window */
- return window_is_wm_window(window->parent);
-}
-
-static void
-xwl_window_init_allow_commits(struct xwl_window *xwl_window)
-{
- PropertyPtr prop = NULL;
- int ret;
-
- ret = dixLookupProperty(&prop, xwl_window->toplevel,
- xwl_window->xwl_screen->allow_commits_prop,
- serverClient, DixReadAccess);
- if (ret == Success && prop)
- xwl_window_set_allow_commits_from_property(xwl_window, prop);
- else
- xwl_window_set_allow_commits(xwl_window, TRUE, "no property");
-}
-
-static uint32_t
-serial_lo(uint64_t value)
-{
- return value & 0xFFFFFFFFu;
-}
-
-static uint32_t
-serial_hi(uint64_t value)
-{
- return value >> 32u;
-}
-
-static void
-send_window_client_message(struct xwl_window *xwl_window, Atom type_atom, uint64_t value)
-{
- DeviceIntPtr dev;
- xEvent e;
-
- e.u.u.type = ClientMessage;
- e.u.u.detail = 32;
- e.u.clientMessage.window = xwl_window->toplevel->drawable.id;
- e.u.clientMessage.u.l.type = type_atom;
- e.u.clientMessage.u.l.longs0 = serial_lo(value);
- e.u.clientMessage.u.l.longs1 = serial_hi(value);
- e.u.clientMessage.u.l.longs2 = 0;
- e.u.clientMessage.u.l.longs3 = 0;
- e.u.clientMessage.u.l.longs4 = 0;
-
- dev = PickPointer(serverClient);
- DeliverEventsToWindow(dev, xwl_window->xwl_screen->screen->root,
- &e, 1, SubstructureRedirectMask, NullGrab);
-}
-
-static void
-send_surface_id_event_serial(struct xwl_window *xwl_window)
-{
- static const char atom_name[] = "WL_SURFACE_SERIAL";
- static Atom type_atom;
- uint64_t serial;
-
- if (type_atom == None)
- type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
-
- serial = ++xwl_window->xwl_screen->surface_association_serial;
-
- send_window_client_message(xwl_window, type_atom, serial);
- xwayland_surface_v1_set_serial(xwl_window->xwayland_surface,
- serial_lo(serial), serial_hi(serial));
- wl_surface_commit(xwl_window->surface);
-
- /* Flush wayland display *after* commit in the new path. */
- wl_display_flush(xwl_window->xwl_screen->display);
-}
-
-static void
-send_surface_id_event_legacy(struct xwl_window *xwl_window)
-{
- static const char atom_name[] = "WL_SURFACE_ID";
- static Atom type_atom;
- uint32_t surface_id;
-
- if (type_atom == None)
- type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
-
- surface_id = wl_proxy_get_id((struct wl_proxy *) xwl_window->surface);
-
- /* Flush wayland display *before* setting the atom in the legacy path */
- wl_display_flush(xwl_window->xwl_screen->display);
-
- send_window_client_message(xwl_window, type_atom, (uint64_t)surface_id);
-}
-
-static void
-send_surface_id_event(struct xwl_window *xwl_window)
-{
- return xwl_window->xwayland_surface
- ? send_surface_id_event_serial(xwl_window)
- : send_surface_id_event_legacy(xwl_window);
-
-}
-
-static Bool
-xwl_window_set_fullscreen(struct xwl_window *xwl_window)
-{
- struct xwl_output *xwl_output;
- struct wl_output *wl_output = NULL;
-
- if (!xwl_window->xdg_toplevel)
- return FALSE;
-
- xwl_output = xwl_window_get_output(xwl_window);
- if (xwl_output)
- wl_output = xwl_output->output;
-
- if (wl_output && xwl_window->wl_output_fullscreen == wl_output)
- return FALSE;
-
- xdg_toplevel_set_fullscreen(xwl_window->xdg_toplevel, wl_output);
- xwl_window_check_resolution_change_emulation(xwl_window);
- xwl_window_maybe_commit_surface(xwl_window);
-
- xwl_window->wl_output_fullscreen = wl_output;
-
- return TRUE;
-}
-
-void
-xwl_window_rootful_update_fullscreen(struct xwl_window *xwl_window,
- struct xwl_output *xwl_output)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
- if (!xwl_screen->fullscreen)
- return;
-
- if (xwl_window->toplevel != xwl_screen->screen->root)
- return;
-
- if (xwl_window->wl_output_fullscreen != xwl_output->output)
- return;
-
- /* The size and position of the output may have changed, clear our
- * output to make sure the next call to xwl_window_set_fullscreen()
- * recomputes the size and updates the viewport as needed.
- */
- xwl_window->wl_output_fullscreen = NULL;
- xwl_window_set_fullscreen(xwl_window);
-}
-
-void
-xwl_window_rootful_update_title(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- char title[128];
- const char *grab_message = "";
-
- if (xwl_screen->host_grab) {
- if (xwl_screen->has_grab)
- grab_message = " - ([ctrl]+[shift] releases mouse and keyboard)";
- else
- grab_message = " - ([ctrl]+[shift] grabs mouse and keyboard)";
- }
-
- snprintf(title, sizeof(title), "Xwayland on :%s%s", display, grab_message);
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_window->libdecor_frame)
- libdecor_frame_set_title(xwl_window->libdecor_frame, title);
- else
-#endif
- if (xwl_window->xdg_toplevel)
- xdg_toplevel_set_title(xwl_window->xdg_toplevel, title);
-}
-
-static void
-xwl_window_rootful_set_app_id(struct xwl_window *xwl_window)
-{
- const char *app_id = "org.freedesktop.Xwayland";
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_window->libdecor_frame)
- libdecor_frame_set_app_id(xwl_window->libdecor_frame, app_id);
- else
-#endif
- if (xwl_window->xdg_toplevel)
- xdg_toplevel_set_app_id(xwl_window->xdg_toplevel, app_id);
-}
-
-static void
-xwl_window_maybe_resize(struct xwl_window *xwl_window, double width, double height)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_output *xwl_output;
- double scale;
- RRModePtr mode;
-
- /* Clamp the size */
- width = min(max(width, MIN_ROOTFUL_WIDTH), MAX_ROOTFUL_WIDTH);
- height = min(max(height, MIN_ROOTFUL_HEIGHT), MAX_ROOTFUL_HEIGHT);
-
- /* Make sure the size is a multiple of the scale, it's a protocol error otherwise. */
- scale = xwl_screen->global_surface_scale;
- if (scale > 1.0) {
- width = round(width / scale) * scale;
- height = round(height / scale) * scale;
- }
-
- if (width == xwl_screen->width && height == xwl_screen->height)
- return;
-
- xwl_screen->width = width;
- xwl_screen->height = height;
-
- /* When fractional scale is used, the global surface scale is 1, and vice
- * versa, so we can multiply the two here, and have the resulting scale
- * apply for both cases, the legacy wl_surface buffer scale and fractional
- * scaling.
- */
- scale *= xwl_window_get_fractional_scale_factor(xwl_window);
-
- xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
- if (!xwl_randr_add_modes_fixed(xwl_output, round(width / scale), round(height / scale)))
- return;
-
- mode = xwl_output_find_mode(xwl_output, round(width / scale), round(height / scale));
- xwl_output_set_mode_fixed(xwl_output, mode);
-
- xwl_window_attach_buffer(xwl_window);
-}
-
-#ifdef XWL_HAS_LIBDECOR
-static void
-xwl_window_libdecor_set_size_limits(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
- libdecor_frame_set_min_content_size(xwl_window->libdecor_frame,
- MIN_ROOTFUL_WIDTH /
- xwl_screen->global_surface_scale,
- MIN_ROOTFUL_HEIGHT /
- xwl_screen->global_surface_scale);
- libdecor_frame_set_max_content_size(xwl_window->libdecor_frame,
- MAX_ROOTFUL_WIDTH /
- xwl_screen->global_surface_scale,
- MAX_ROOTFUL_HEIGHT /
- xwl_screen->global_surface_scale);
-}
-
-static void
-xwl_window_update_libdecor_size(struct xwl_window *xwl_window,
- struct libdecor_configuration *configuration /* nullable */,
- int width, int height)
-{
- struct libdecor_state *state;
- double scale;
-
- if (xwl_window->libdecor_frame) {
- scale = xwl_window_get_fractional_scale_factor(xwl_window);
- state = libdecor_state_new(round((double) width / scale),
- round((double) height / scale));
- libdecor_frame_commit(xwl_window->libdecor_frame, state, configuration);
- libdecor_state_free(state);
- }
-}
-
-static void
-handle_libdecor_configure(struct libdecor_frame *frame,
- struct libdecor_configuration *configuration,
- void *data)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- int width, height;
- double new_width, new_height;
- double scale;
-
- if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
- new_width = (double) width;
- new_height = (double) height;
- }
- else {
- new_width = xwl_screen->width / xwl_screen->global_surface_scale;
- new_height = xwl_screen->height / xwl_screen->global_surface_scale;
- }
-
- new_width *= xwl_screen->global_surface_scale;
- new_height *= xwl_screen->global_surface_scale;
-
- scale = xwl_window_get_fractional_scale_factor(xwl_window);
- new_width *= scale;
- new_height *= scale;
-
- xwl_window_maybe_resize(xwl_window, new_width, new_height);
-
- new_width = xwl_screen->width / xwl_screen->global_surface_scale;
- new_height = xwl_screen->height / xwl_screen->global_surface_scale;
-
- xwl_window_update_libdecor_size(xwl_window, configuration,
- round(new_width), round(new_height));
-
- if (xwl_window->awaiting_initial_configure_event) {
- xwl_window->awaiting_initial_configure_event = FALSE;
- xwl_window_attach_buffer(xwl_window);
- wl_surface_commit(xwl_window->surface);
- }
-}
-
-static void
-handle_libdecor_close(struct libdecor_frame *frame,
- void *data)
-{
- DebugF("Terminating on compositor request");
- GiveUp(0);
-}
-
-static void
-handle_libdecor_commit(struct libdecor_frame *frame,
- void *data)
-{
- struct xwl_window *xwl_window = data;
- wl_surface_commit(xwl_window->surface);
-}
-
-static void
-handle_libdecor_dismiss_popup(struct libdecor_frame *frame,
- const char *seat_name,
- void *data)
-{
-}
-
-static struct libdecor_frame_interface libdecor_frame_iface = {
- handle_libdecor_configure,
- handle_libdecor_close,
- handle_libdecor_commit,
- handle_libdecor_dismiss_popup,
-};
-#endif
-
-static void
-xdg_surface_handle_configure(void *data,
- struct xdg_surface *xdg_surface,
- uint32_t serial)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
- if (xwl_screen->fullscreen)
- xwl_window_set_fullscreen(xwl_window);
-
- xdg_surface_ack_configure(xdg_surface, serial);
-
- if (xwl_window->awaiting_initial_configure_event) {
- xwl_window->awaiting_initial_configure_event = FALSE;
- xwl_window_attach_buffer(xwl_window);
- wl_surface_commit(xwl_window->surface);
- }
-}
-
-static const struct xdg_surface_listener xdg_surface_listener = {
- xdg_surface_handle_configure,
-};
-
-static void
-xwl_window_update_surface_scale(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- int previous_scale, new_scale;
- double new_width, new_height;
-
- previous_scale = xwl_screen->global_surface_scale;
- assert(previous_scale != 0);
- xwl_window->surface_scale = xwl_window_get_max_output_scale(xwl_window);
-
- if (xwl_screen_update_global_surface_scale(xwl_screen)) {
- new_scale = xwl_screen->global_surface_scale;
-
- DebugF("XWAYLAND: Global scale is now %i (was %i)\n",
- new_scale, previous_scale);
-
- new_width = xwl_screen->width / previous_scale * new_scale;
- new_height = xwl_screen->height / previous_scale * new_scale;
-
- wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_surface_scale);
- /* Reflect the scale factor using XRandR transform */
- xwl_output_set_xscale(xwl_screen->fixed_output, new_scale);
- xwl_window_maybe_resize(xwl_window, new_width, new_height);
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_window->libdecor_frame) {
- xwl_window_libdecor_set_size_limits(xwl_window);
- xwl_window_update_libdecor_size(xwl_window,
- NULL,
- round(new_width / new_scale),
- round(new_height / new_scale));
- }
- else
-#endif
- xwl_window_maybe_commit_surface(xwl_window);
- }
-}
-
-static void
-xwl_window_enter_output(struct xwl_window *xwl_window, struct xwl_output *xwl_output)
-{
- struct xwl_window_output *window_output;
-
- window_output = XNFcallocarray(1, sizeof(struct xwl_window_output));
- window_output->xwl_output = xwl_output;
- xorg_list_add(&window_output->link, &xwl_window->xwl_output_list);
-}
-
-void
-xwl_window_leave_output(struct xwl_window *xwl_window, struct xwl_output *xwl_output)
-{
- struct xwl_window_output *window_output, *tmp;
-
- xorg_list_for_each_entry_safe(window_output, tmp, &xwl_window->xwl_output_list, link) {
- if (window_output->xwl_output == xwl_output) {
- xorg_list_del(&window_output->link);
- free(window_output);
- }
- }
-}
-
-static void
-xwl_window_free_outputs(struct xwl_window *xwl_window)
-{
- struct xwl_window_output *window_output, *tmp;
-
- xorg_list_for_each_entry_safe(window_output, tmp, &xwl_window->xwl_output_list, link) {
- xorg_list_del(&window_output->link);
- free(window_output);
- }
-}
-
-int
-xwl_window_get_max_output_scale(struct xwl_window *xwl_window)
-{
- struct xwl_window_output *window_output;
- struct xwl_output *xwl_output;
- int scale = 1;
-
- xorg_list_for_each_entry(window_output, &xwl_window->xwl_output_list, link) {
- xwl_output = window_output->xwl_output;
- if (xwl_output->scale > scale)
- scale = xwl_output->scale;
- }
-
- return scale;
-}
-
-static void
-xwl_window_surface_enter(void *data,
- struct wl_surface *wl_surface,
- struct wl_output *wl_output)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_output *xwl_output = xwl_output_from_wl_output(xwl_screen, wl_output);
-
- if (xwl_output) {
- xwl_window_enter_output(xwl_window, xwl_output);
- xwl_window_update_surface_scale(xwl_window);
- }
-
- if (xwl_window->wl_output != wl_output) {
- xwl_window->wl_output = wl_output;
-
- if (xwl_screen->fullscreen)
- xwl_window_set_fullscreen(xwl_window);
- }
-}
-
-static void
-xwl_window_surface_leave(void *data,
- struct wl_surface *wl_surface,
- struct wl_output *wl_output)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_output *xwl_output = xwl_output_from_wl_output(xwl_screen, wl_output);
-
- if (xwl_output) {
- xwl_window_leave_output(xwl_window, xwl_output);
- xwl_window_update_surface_scale(xwl_window);
- }
-
- if (xwl_window->wl_output == wl_output)
- xwl_window->wl_output = NULL;
-}
-
-static const struct wl_surface_listener surface_listener = {
- xwl_window_surface_enter,
- xwl_window_surface_leave
-};
-
-static void
-xdg_toplevel_handle_configure(void *data,
- struct xdg_toplevel *xdg_toplevel,
- int32_t width,
- int32_t height,
- struct wl_array *states)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- uint32_t *p;
- Bool old_active = xwl_screen->active;
- double scale, new_width, new_height;
-
- /* Maintain our current size if no dimensions are requested */
- if (width == 0 && height == 0)
- return;
-
- if (!xwl_screen->fullscreen) {
- new_width = (double) (width * xwl_screen->global_surface_scale);
- new_height = (double) (height * xwl_screen->global_surface_scale);
-
- scale = xwl_window_get_fractional_scale_factor(xwl_window);
- new_width *= scale;
- new_height *= scale;
-
- /* This will be committed by the xdg_surface.configure handler */
- xwl_window_maybe_resize(xwl_window, new_width, new_height);
- }
-
- xwl_screen->active = FALSE;
- wl_array_for_each (p, states) {
- uint32_t state = *p;
- if (state == XDG_TOPLEVEL_STATE_ACTIVATED) {
- xwl_screen->active = TRUE;
- break;
- }
- }
-
- if (old_active != xwl_screen->active) {
- if (!xwl_screen->active)
- xwl_screen_lost_focus(xwl_screen);
- }
-}
-
-static void
-xdg_toplevel_handle_close(void *data,
- struct xdg_toplevel *xdg_toplevel)
-{
- DebugF("Terminating on compositor request");
- GiveUp(0);
-}
-
-static const struct xdg_toplevel_listener xdg_toplevel_listener = {
- xdg_toplevel_handle_configure,
- xdg_toplevel_handle_close,
-};
-
-static void
-xwl_window_update_rootful_scale(struct xwl_window *xwl_window, double previous_scale)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- double new_scale, new_width, new_height;
-
- new_scale = xwl_window_get_fractional_scale_factor(xwl_window);
- new_width = xwl_screen->width / previous_scale * new_scale;
- new_height = xwl_screen->height / previous_scale * new_scale;
-
- DebugF("XWAYLAND: Fractional scale is now %.2f (was %.2f)\n",
- new_scale, previous_scale);
-
- xwl_output_set_xscale(xwl_screen->fixed_output, new_scale);
- xwl_window_maybe_resize(xwl_window, new_width, new_height);
- xwl_window_check_fractional_scale_viewport(xwl_window,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen));
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_window->libdecor_frame) {
- xwl_window_libdecor_set_size_limits(xwl_window);
- xwl_window_update_libdecor_size(xwl_window,
- NULL,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen));
- }
- else
-#endif
- xwl_window_maybe_commit_surface(xwl_window);
-}
-
-static void
-wp_fractional_scale_preferred_scale(void *data,
- struct wp_fractional_scale_v1 *fractional_scale,
- uint32_t scale_numerator)
-{
- struct xwl_window *xwl_window = data;
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- double previous_scale = xwl_window_get_fractional_scale_factor(xwl_window);
-
- if (xwl_window_update_fractional_scale(xwl_window, scale_numerator)) {
- if (xwl_screen->fixed_output) { /* We're running rootful */
- xwl_window_update_rootful_scale(xwl_window, previous_scale);
- }
- }
-}
-
-static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
- wp_fractional_scale_preferred_scale,
-};
-
-static Bool
-xwl_create_root_surface(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- WindowPtr window = xwl_window->toplevel;
- struct wl_region *region;
-
-#ifdef XWL_HAS_LIBDECOR
- if (xwl_screen->decorate) {
- xwl_window->libdecor_frame =
- libdecor_decorate(xwl_screen->libdecor_context,
- xwl_window->surface,
- &libdecor_frame_iface,
- xwl_window);
- xwl_window_libdecor_set_size_limits(xwl_window);
- libdecor_frame_map(xwl_window->libdecor_frame);
- }
- else
-#endif
- {
- xwl_window->xdg_surface =
- xdg_wm_base_get_xdg_surface(xwl_screen->xdg_wm_base, xwl_window->surface);
- if (xwl_window->xdg_surface == NULL) {
- ErrorF("Failed creating xdg_wm_base xdg_surface\n");
- goto err_surf;
- }
-
- xwl_window->xdg_toplevel =
- xdg_surface_get_toplevel(xwl_window->xdg_surface);
- if (xwl_window->xdg_surface == NULL) {
- ErrorF("Failed creating xdg_toplevel\n");
- goto err_surf;
- }
-
- xdg_surface_add_listener(xwl_window->xdg_surface,
- &xdg_surface_listener, xwl_window);
-
- xdg_toplevel_add_listener(xwl_window->xdg_toplevel,
- &xdg_toplevel_listener,
- xwl_window);
- }
-
- wl_surface_add_listener(xwl_window->surface,
- &surface_listener, xwl_window);
-
- if (xwl_screen_should_use_fractional_scale(xwl_screen)) {
- xwl_window->fractional_scale =
- wp_fractional_scale_manager_v1_get_fractional_scale(xwl_screen->fractional_scale_manager,
- xwl_window->surface);
- wp_fractional_scale_v1_add_listener(xwl_window->fractional_scale,
- &fractional_scale_listener, xwl_window);
- }
-
- xwl_window_rootful_update_title(xwl_window);
- xwl_window_rootful_set_app_id(xwl_window);
- wl_surface_commit(xwl_window->surface);
- xwl_window->awaiting_initial_configure_event = TRUE;
-
- region = wl_compositor_create_region(xwl_screen->compositor);
- if (region == NULL) {
- ErrorF("Failed creating region\n");
- goto err_surf;
- }
-
- wl_region_add(region, 0, 0,
- window->drawable.width, window->drawable.height);
- wl_surface_set_opaque_region(xwl_window->surface, region);
- wl_region_destroy(region);
-
- return TRUE;
-
-err_surf:
- if (xwl_window->xdg_toplevel)
- xdg_toplevel_destroy(xwl_window->xdg_toplevel);
- if (xwl_window->xdg_surface)
- xdg_surface_destroy(xwl_window->xdg_surface);
- wl_surface_destroy(xwl_window->surface);
-
- return FALSE;
-}
-
-void
-xwl_window_update_surface_window(struct xwl_window *xwl_window)
-{
- WindowPtr surface_window = xwl_window->toplevel;
- ScreenPtr screen = surface_window->drawable.pScreen;
- PixmapPtr surface_pixmap;
- DamagePtr window_damage;
- RegionRec damage_region;
- WindowPtr window;
-
- surface_pixmap = screen->GetWindowPixmap(surface_window);
-
- for (window = surface_window->firstChild; window; window = window->firstChild) {
- PixmapPtr window_pixmap;
-
- if (!RegionEqual(&window->winSize, &surface_window->winSize))
- break;
-
- if (!window->mapped)
- break;
-
- /* The surface window must be top-level for its window pixmap */
- window_pixmap = screen->GetWindowPixmap(window);
- if (window_pixmap == surface_pixmap)
- continue;
-
- surface_pixmap = window_pixmap;
-
- /* A descendant with alpha channel cannot be the surface window, since
- * any non-opaque areas need to take the contents of ancestors into
- * account.
- */
- if (window->drawable.depth == 32)
- continue;
-
- if (window->redirectDraw == RedirectDrawManual &&
- !xwl_present_window_redirected(window))
- break;
-
- surface_window = window;
- }
-
- if (xwl_window->surface_window == surface_window)
- return;
-
- if (xwl_window->surface_window_damage) {
- if (xwl_present_maybe_unredirect_window(xwl_window->surface_window) &&
- screen->SourceValidate == xwl_source_validate) {
- WindowPtr toplevel = xwl_window->toplevel;
-
- xwl_source_validate(&toplevel->drawable,
- toplevel->drawable.x, toplevel->drawable.y,
- toplevel->drawable.width,
- toplevel->drawable.height,
- IncludeInferiors);
- }
-
- if (RegionNotEmpty(xwl_window->surface_window_damage))
- need_source_validate_dec(xwl_window->xwl_screen);
-
- RegionDestroy(xwl_window->surface_window_damage);
- xwl_window->surface_window_damage = NULL;
- }
-
- window_damage = window_get_damage(xwl_window->surface_window);
- if (window_damage) {
- RegionInit(&damage_region, NullBox, 1);
- RegionCopy(&damage_region, DamageRegion(window_damage));
- unregister_damage(xwl_window->surface_window);
- }
-
- if (surface_window->drawable.depth != xwl_window->surface_window->drawable.depth)
- xwl_window_buffers_dispose(xwl_window, FALSE);
-
- xwl_window->surface_window = surface_window;
- register_damage(surface_window);
-
- if (window_damage) {
- RegionPtr new_region = DamageRegion(window_get_damage(surface_window));
-
- RegionUnion(new_region, new_region, &damage_region);
- RegionUninit(&damage_region);
- }
-}
-
-static struct xwl_window *
-ensure_surface_for_window(WindowPtr window)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
- WindowPtr toplevel;
-
- xwl_window = xwl_window_from_window(window);
- if (xwl_window)
- return xwl_window;
-
- xwl_screen = xwl_screen_get(screen);
-
- if (xwl_screen->rootless) {
- if (window->redirectDraw != RedirectDrawManual)
- return NULL;
- }
- else {
- if (window->parent)
- return NULL;
- }
-
- xwl_window = calloc(1, sizeof *xwl_window);
- if (xwl_window == NULL)
- return NULL;
-
- xwl_window->xwl_screen = xwl_screen;
- xwl_window->toplevel = window;
- xwl_window->surface_window = window;
- xwl_window->fractional_scale_numerator = FRACTIONAL_SCALE_DENOMINATOR;
- xwl_window->viewport_scale_x = 1.0;
- xwl_window->viewport_scale_y = 1.0;
- xwl_window->surface_scale = 1;
- xorg_list_init(&xwl_window->xwl_output_list);
- xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor);
- if (xwl_window->surface == NULL) {
- ErrorF("wl_display_create_surface failed\n");
- goto err;
- }
-
- if (xwl_screen->xwayland_shell) {
- xwl_window->xwayland_surface = xwayland_shell_v1_get_xwayland_surface(
- xwl_screen->xwayland_shell, xwl_window->surface);
- }
-
- if (!xwl_screen->rootless && !xwl_create_root_surface(xwl_window))
- goto err;
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->dmabuf_protocol_version >= 4)
- xwl_dmabuf_setup_feedback_for_window(xwl_window);
-#endif
-
- wl_display_flush(xwl_screen->display);
-
- send_surface_id_event(xwl_window);
-
- wl_surface_set_user_data(xwl_window->surface, xwl_window);
- xwl_window_set_xwayland_tag(xwl_window);
-
- compRedirectWindow(serverClient, window, CompositeRedirectManual);
-
- dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
- xorg_list_init(&xwl_window->link_damage);
- xorg_list_add(&xwl_window->link_window, &xwl_screen->window_list);
- xorg_list_init(&xwl_window->frame_callback_list);
-
- xwl_window_buffers_init(xwl_window);
-
- xwl_window_update_surface_window(xwl_window);
-
- xwl_window_init_allow_commits(xwl_window);
-
- /* When a new window-manager window is realized, then the randr emulation
- * props may have not been set on the managed client window yet.
- */
- if (!xwl_screen->fullscreen && window_is_wm_window(window)) {
- toplevel = window_get_client_toplevel(window);
- if (toplevel)
- xwl_output_set_window_randr_emu_props(xwl_screen, toplevel);
- } else {
- /* CSD or O-R toplevel window, check viewport on creation */
- xwl_window_check_resolution_change_emulation(xwl_window);
- }
-
- if (xwl_screen->tearing_control_manager) {
- xwl_window->tearing_control = wp_tearing_control_manager_v1_get_tearing_control(
- xwl_screen->tearing_control_manager, xwl_window->surface);
- }
-
- xwl_window_set_input_region(xwl_window, wInputShape(window));
-
- return xwl_window;
-
-err:
- free(xwl_window);
- return NULL;
-}
-
-Bool
-xwl_realize_window(WindowPtr window)
-{
- ScreenPtr screen = window->drawable.pScreen;
- CompScreenPtr comp_screen = GetCompScreen(screen);
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
- Bool ret;
-
- xwl_screen = xwl_screen_get(screen);
-
- screen->RealizeWindow = xwl_screen->RealizeWindow;
- ret = (*screen->RealizeWindow) (window);
- xwl_screen->RealizeWindow = screen->RealizeWindow;
- screen->RealizeWindow = xwl_realize_window;
-
- if (!ret)
- return FALSE;
-
- if (xwl_screen->rootless) {
- /* We do not want the COW to be mapped when rootless in Xwayland */
- if (window == comp_screen->pOverlayWin) {
- window->mapped = FALSE;
- return TRUE;
- }
-
- if (!window->parent) {
- BoxRec box = {
- 0,
- 0,
- xwl_screen_get_width(xwl_screen),
- xwl_screen_get_height(xwl_screen)
- };
-
- RegionReset(&window->winSize, &box);
- RegionNull(&window->clipList);
- RegionNull(&window->borderClip);
- }
- }
-
- if (xwl_screen->rootless ?
- (window->drawable.class == InputOutput &&
- window->parent == window->drawable.pScreen->root) :
- !window->parent) {
- if (!register_damage(window))
- return FALSE;
- }
-
- xwl_window = ensure_surface_for_window(window);
- if (!xwl_window)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-xwl_surface_destroy_free_timer(struct xwl_wl_surface *xwl_wl_surface)
-{
- if (xwl_wl_surface->wl_surface_destroy_timer) {
- TimerFree(xwl_wl_surface->wl_surface_destroy_timer);
- xwl_wl_surface->wl_surface_destroy_timer = NULL;
- }
-}
-
-void
-xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface)
-{
- wl_surface_destroy(xwl_wl_surface->wl_surface);
- xorg_list_del(&xwl_wl_surface->link);
- xwl_surface_destroy_free_timer(xwl_wl_surface);
- free(xwl_wl_surface);
-}
-
-static CARD32
-xwl_surface_destroy_callback(OsTimerPtr timer, CARD32 now, void *arg)
-{
- struct xwl_wl_surface *xwl_wl_surface = arg;
-
- xwl_window_surface_do_destroy(xwl_wl_surface);
-
- return 0;
-}
-
-static void
-release_wl_surface_for_window_legacy_delay(struct xwl_window *xwl_window)
-{
- struct xwl_wl_surface *xwl_wl_surface;
-
- /* If the Xserver is terminating, destroy the surface immediately */
- if ((dispatchException & DE_TERMINATE) == DE_TERMINATE) {
- wl_surface_destroy(xwl_window->surface);
- return;
- }
-
- /* Break the wl_surface / xwl_window relationship */
- wl_surface_set_user_data(xwl_window->surface, NULL);
- xwl_window_clear_xwayland_tag(xwl_window);
-
- /* Schedule the destruction later, to mitigate the race between X11
- * and Wayland processing so that the compositor has the time to
- * establish the association before the wl_surface is destroyed.
- */
- xwl_wl_surface = XNFcallocarray(1, sizeof *xwl_wl_surface);
- xwl_wl_surface->wl_surface = xwl_window->surface;
- xorg_list_add(&xwl_wl_surface->link,
- &xwl_window->xwl_screen->pending_wl_surface_destroy);
- xwl_wl_surface->wl_surface_destroy_timer =
- TimerSet(NULL, 0, DELAYED_WL_SURFACE_DESTROY,
- xwl_surface_destroy_callback, xwl_wl_surface);
-}
-
-static void
-release_wl_surface_for_window_shell(struct xwl_window *xwl_window)
-{
- xwayland_surface_v1_destroy(xwl_window->xwayland_surface);
- wl_surface_destroy(xwl_window->surface);
-}
-
-static void
-release_wl_surface_for_window(struct xwl_window *xwl_window)
-{
- if (xwl_window->xwayland_surface)
- release_wl_surface_for_window_shell(xwl_window);
- else
- release_wl_surface_for_window_legacy_delay(xwl_window);
-}
-
-static void
-xwl_window_dispose(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_seat *xwl_seat;
- WindowPtr window = xwl_window->toplevel;
- ScreenPtr screen = xwl_screen->screen;
-
- compUnredirectWindow(serverClient, window, CompositeRedirectManual);
-
- xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
- if (xwl_seat->focus_window == xwl_window)
- xwl_seat->focus_window = NULL;
- if (xwl_seat->tablet_focus_window == xwl_window)
- xwl_seat->tablet_focus_window = NULL;
- if (xwl_seat->last_focus_window == xwl_window)
- xwl_seat->last_focus_window = NULL;
- if (xwl_seat->cursor_confinement_window == xwl_window)
- xwl_seat_unconfine_pointer(xwl_seat);
- if (xwl_seat->pointer_warp_emulator &&
- xwl_seat->pointer_warp_emulator->locked_window == xwl_window)
- xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
- xwl_seat_clear_touch(xwl_seat, xwl_window);
- }
-
- if (xwl_window_has_viewport_enabled(xwl_window))
- xwl_window_disable_viewport(xwl_window);
-#ifdef XWL_HAS_GLAMOR
- xwl_dmabuf_feedback_destroy(&xwl_window->feedback);
-
-#ifdef GLAMOR_HAS_GBM
- if (xwl_window->xwl_screen->present)
- xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
-#endif /* GLAMOR_HAS_GBM */
-#endif /* XWL_HAS_GLAMOR */
-
- if (xwl_window->tearing_control)
- wp_tearing_control_v1_destroy(xwl_window->tearing_control);
-
- if (xwl_window->fractional_scale)
- wp_fractional_scale_v1_destroy(xwl_window->fractional_scale);
-
- if (xwl_window->surface_sync)
- wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
-
- release_wl_surface_for_window(xwl_window);
- xorg_list_del(&xwl_window->link_damage);
- xorg_list_del(&xwl_window->link_window);
-
- /* Special case for the root window in rootful mode */
- xwl_window_buffers_dispose(xwl_window,
- (!xwl_screen->rootless && window == screen->root));
-
- if (xwl_window->window_buffers_timer)
- TimerFree(xwl_window->window_buffers_timer);
-
- if (xwl_window->frame_callback)
- wl_callback_destroy(xwl_window->frame_callback);
-
- xwl_window_free_outputs(xwl_window);
-
- free(xwl_window);
- dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
-}
-
-Bool
-xwl_unrealize_window(WindowPtr window)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_window *xwl_window = xwl_window_from_window(window);
- Bool ret;
-
- screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
- ret = (*screen->UnrealizeWindow) (window);
- xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
- screen->UnrealizeWindow = xwl_unrealize_window;
-
- if (xwl_window) {
- if (window == xwl_window->toplevel) {
- unregister_damage(window);
- xwl_window_dispose(xwl_window);
- } else if (window == xwl_window->surface_window) {
- xwl_window_update_surface_window(xwl_window);
- }
- }
-
- return ret;
-}
-
-void
-xwl_window_set_window_pixmap(WindowPtr window,
- PixmapPtr pixmap)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
- PixmapPtr old_pixmap;
-
- old_pixmap = (*screen->GetWindowPixmap) (window);
- xwl_screen = xwl_screen_get(screen);
-
- screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
- (*screen->SetWindowPixmap) (window, pixmap);
- xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
- screen->SetWindowPixmap = xwl_window_set_window_pixmap;
-
- if (!RegionNotEmpty(&window->winSize))
- return;
-
- xwl_window = ensure_surface_for_window(window);
-
- if (!xwl_window ||
- (old_pixmap->drawable.width == pixmap->drawable.width &&
- old_pixmap->drawable.height == pixmap->drawable.height))
- return;
-
- xwl_window_buffers_dispose(xwl_window, FALSE);
-}
-
-Bool
-xwl_change_window_attributes(WindowPtr window, unsigned long mask)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- OtherClients *others;
- Bool ret;
-
- screen->ChangeWindowAttributes = xwl_screen->ChangeWindowAttributes;
- ret = (*screen->ChangeWindowAttributes) (window, mask);
- xwl_screen->ChangeWindowAttributes = screen->ChangeWindowAttributes;
- screen->ChangeWindowAttributes = xwl_change_window_attributes;
-
- if (window != screen->root || !(mask & CWEventMask))
- return ret;
-
- for (others = wOtherClients(window); others; others = others->next) {
- if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask))
- xwl_screen->wm_client_id = CLIENT_ID(others->resource);
- }
-
- return ret;
-}
-
-void
-xwl_clip_notify(WindowPtr window, int dx, int dy)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_window *xwl_window = xwl_window_from_window(window);
-
- screen->ClipNotify = xwl_screen->ClipNotify;
- (*screen->ClipNotify) (window, dx, dy);
- xwl_screen->ClipNotify = screen->ClipNotify;
- screen->ClipNotify = xwl_clip_notify;
-
- if (xwl_window)
- xwl_window_update_surface_window(xwl_window);
-}
-
-int
-xwl_config_notify(WindowPtr window,
- int x, int y,
- int width, int height, int bw,
- WindowPtr sib)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
- Bool size_changed;
- int ret;
-
- xwl_screen = xwl_screen_get(screen);
- xwl_window = xwl_window_from_window(window);
-
- size_changed = width != window->drawable.width || height != window->drawable.height;
- if (size_changed && xwl_window && xwl_window->toplevel == window &&
- screen->SourceValidate == xwl_source_validate) {
- xwl_source_validate(&window->drawable, window->drawable.x, window->drawable.y,
- window->drawable.width, window->drawable.height,
- IncludeInferiors);
- }
-
- screen->ConfigNotify = xwl_screen->ConfigNotify;
- ret = screen->ConfigNotify(window, x, y, width, height, bw, sib);
- xwl_screen->ConfigNotify = screen->ConfigNotify;
- screen->ConfigNotify = xwl_config_notify;
-
- return ret;
-}
-
-void
-xwl_reparent_window(WindowPtr window, WindowPtr prior_parent)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- WindowPtr parent = window->parent;
- Bool *is_wm_window;
-
- if (xwl_screen->ReparentWindow) {
- screen->ReparentWindow = xwl_screen->ReparentWindow;
- screen->ReparentWindow(window, prior_parent);
- xwl_screen->ReparentWindow = screen->ReparentWindow;
- screen->ReparentWindow = xwl_reparent_window;
- }
-
- if (!parent->parent ||
- GetCurrentClient()->index != xwl_screen->wm_client_id)
- return;
-
- /* If the WM client reparents a window, mark the new parent as a WM window */
- is_wm_window = dixLookupPrivate(&parent->devPrivates,
- &xwl_wm_window_private_key);
- *is_wm_window = TRUE;
-}
-
-void
-xwl_resize_window(WindowPtr window,
- int x, int y,
- unsigned int width, unsigned int height,
- WindowPtr sib)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
-
- xwl_screen = xwl_screen_get(screen);
- xwl_window = xwl_window_from_window(window);
-
- screen->ResizeWindow = xwl_screen->ResizeWindow;
- screen->ResizeWindow(window, x, y, width, height, sib);
- xwl_screen->ResizeWindow = screen->ResizeWindow;
- screen->ResizeWindow = xwl_resize_window;
-
- if (xwl_window) {
- if (xwl_window_get(window) || xwl_window_is_toplevel(window))
- xwl_window_check_resolution_change_emulation(xwl_window);
- if (window == screen->root) {
-#ifdef XWL_HAS_LIBDECOR
- unsigned int decor_width, decor_height;
-
- decor_width = width / xwl_screen->global_surface_scale;
- decor_height = height / xwl_screen->global_surface_scale;
- xwl_window_update_libdecor_size(xwl_window, NULL,
- decor_width, decor_height);
-#endif
- xwl_window_check_fractional_scale_viewport(xwl_window, width, height);
- }
- }
-}
-
-void
-xwl_move_window(WindowPtr window,
- int x, int y,
- WindowPtr next_sib,
- VTKind kind)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
-
- xwl_screen = xwl_screen_get(screen);
- xwl_window = xwl_window_from_window(window);
-
- screen->MoveWindow = xwl_screen->MoveWindow;
- (*screen->MoveWindow) (window, x, y, next_sib, kind);
- xwl_screen->MoveWindow = screen->MoveWindow;
- screen->MoveWindow = xwl_move_window;
-
- if (xwl_window && (xwl_window_get(window) || xwl_window_is_toplevel(window)))
- xwl_window_check_resolution_change_emulation(xwl_window);
-}
-
-static void
-frame_callback(void *data,
- struct wl_callback *callback,
- uint32_t time)
-{
- struct xwl_window *xwl_window = data;
-
- wl_callback_destroy (xwl_window->frame_callback);
- xwl_window->frame_callback = NULL;
-
- if (xwl_window->xwl_screen->present) {
- xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
-
- /* If xwl_window_create_frame_callback was called from
- * xwl_present_frame_callback, need to make sure all fallback timers
- * are adjusted correspondingly.
- */
- if (xwl_window->frame_callback)
- xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
- }
-}
-
-static const struct wl_callback_listener frame_listener = {
- frame_callback
-};
-
-void
-xwl_window_create_frame_callback(struct xwl_window *xwl_window)
-{
- xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
- wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
- xwl_window);
-
- /* If we get called from frame_callback, it will take care of calling
- * xwl_present_reset_timer.
- */
- if (xwl_window->xwl_screen->present &&
- !xwl_present_entered_for_each_frame_callback())
- xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
-}
-
-Bool
-xwl_destroy_window(WindowPtr window)
-{
- ScreenPtr screen = window->drawable.pScreen;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_window *xwl_window = xwl_window_get(window);
- Bool ret;
-
- if (xwl_screen->present)
- xwl_present_cleanup(window);
-
- if (xwl_window)
- xwl_window_dispose(xwl_window);
-
- screen->DestroyWindow = xwl_screen->DestroyWindow;
-
- if (screen->DestroyWindow)
- ret = screen->DestroyWindow (window);
- else
- ret = TRUE;
-
- xwl_screen->DestroyWindow = screen->DestroyWindow;
- screen->DestroyWindow = xwl_destroy_window;
-
- return ret;
-}
-
-static Bool
-xwl_window_attach_buffer(struct xwl_window *xwl_window)
-{
- struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- WindowPtr surface_window = xwl_window->surface_window;
- RegionPtr region;
- BoxPtr box;
- struct wl_buffer *buffer;
- PixmapPtr pixmap;
- int i;
-
- pixmap = xwl_window_swap_pixmap(xwl_window, TRUE);
- buffer = xwl_pixmap_get_wl_buffer(pixmap);
-
- if (!buffer) {
- ErrorF("Error getting buffer\n");
- return FALSE;
- }
-
- wl_surface_attach(xwl_window->surface, buffer, 0, 0);
-
- /* Arbitrary limit to try to avoid flooding the Wayland
- * connection. If we flood it too much anyway, this could
- * abort in libwayland-client.
- */
- region = xwl_window_get_damage_region(xwl_window);
- if (RegionNumRects(region) > 256) {
- box = RegionExtents(region);
- xwl_surface_damage(xwl_screen, xwl_window->surface,
- box->x1 + surface_window->borderWidth,
- box->y1 + surface_window->borderWidth,
- box->x2 - box->x1, box->y2 - box->y1);
- } else {
- box = RegionRects(region);
- for (i = 0; i < RegionNumRects(region); i++, box++) {
- xwl_surface_damage(xwl_screen, xwl_window->surface,
- box->x1 + surface_window->borderWidth,
- box->y1 + surface_window->borderWidth,
- box->x2 - box->x1, box->y2 - box->y1);
- }
- }
-
- return TRUE;
-}
-
-void
-xwl_window_post_damage(struct xwl_window *xwl_window)
-{
- assert(!xwl_window->frame_callback);
-
- if (!xwl_window_attach_buffer(xwl_window))
- return;
-
- xwl_window_create_frame_callback(xwl_window);
- DamageEmpty(window_get_damage(xwl_window->surface_window));
-}
-
-void
-xwl_window_set_input_region(struct xwl_window *xwl_window,
- RegionPtr input_shape)
-{
- struct wl_region *region;
- BoxPtr box;
- int i;
-
- if (!input_shape) {
- wl_surface_set_input_region(xwl_window->surface, NULL);
- return;
- }
-
- region = wl_compositor_create_region(xwl_window->xwl_screen->compositor);
- box = RegionRects(input_shape);
-
- for (i = 0; i < RegionNumRects(input_shape); ++i) {
- BoxRec b = box[i];
-
- if (xwl_window->viewport_scale_x != 1.0f) {
- b.x1 = floorf(b.x1 / xwl_window->viewport_scale_x);
- b.x2 = ceilf(b.x2 / xwl_window->viewport_scale_x);
- }
-
- if (xwl_window->viewport_scale_y != 1.0f) {
- b.y1 = floorf(b.y1 / xwl_window->viewport_scale_y);
- b.y2 = ceilf(b.y2 / xwl_window->viewport_scale_y);
- }
-
- wl_region_add(region, b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1);
- }
-
- wl_surface_set_input_region(xwl_window->surface, region);
- wl_region_destroy(region);
-}
-
-Bool
-xwl_window_init(void)
-{
- if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_wm_window_private_key, PRIVATE_WINDOW,
- sizeof(Bool)))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0))
- return FALSE;
-
- return TRUE;
-}
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
deleted file mode 100644
index 09d53054c..000000000
--- a/hw/xwayland/xwayland-window.h
+++ /dev/null
@@ -1,156 +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
-
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#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;
- Bool awaiting_initial_configure_event;
-};
-
-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_reparent_window(WindowPtr window, WindowPtr prior_parent);
-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);
-Bool xwl_destroy_window(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 */
diff --git a/hw/xwayland/xwayland-xtest.c b/hw/xwayland/xwayland-xtest.c
deleted file mode 100644
index 05919a246..000000000
--- a/hw/xwayland/xwayland-xtest.c
+++ /dev/null
@@ -1,959 +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
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#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);
- }
-}
diff --git a/hw/xwayland/xwayland-xtest.h b/hw/xwayland/xwayland-xtest.h
deleted file mode 100644
index 996fdcc27..000000000
--- a/hw/xwayland/xwayland-xtest.h
+++ /dev/null
@@ -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
-
-Bool xwayland_ei_init(void);
-void xwayland_override_xtest(void);
-void xwayland_restore_xtest(void);
-
-#endif
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
deleted file mode 100644
index 91c94681b..000000000
--- a/hw/xwayland/xwayland.c
+++ /dev/null
@@ -1,455 +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
-
-#if !defined(WIN32)
-#include
-#endif
-
-#include
-#include
-
-#include
-#include
-
-#include "os/xserver_poll.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "os/osdep.h"
-
-#include "xwayland-screen.h"
-#include "xwayland-vidmode.h"
-
-#ifdef XF86VIDMODE
-#include
-extern _X_EXPORT Bool noXFree86VidModeExtension;
-#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("-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 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;
-
- /* Only fiddle with the limit if not set explicitly from the command line */
- if (limitNoFile >= 0)
- return;
-
- 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], "-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
-
-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();
- }
-}
diff --git a/include/meson.build b/include/meson.build
index 129a42538..3f9805445 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -424,19 +424,6 @@ configure_file(output : 'xwin-config.h',
input : 'xwin-config.h.meson.in',
configuration : xwin_data)
-build_xwayland_glamor = build_glamor and gbm_dep.found()
-
-xwayland_data = configuration_data()
-xwayland_data.set('XWL_HAS_GLAMOR', build_xwayland_glamor ? '1' : false)
-xwayland_data.set('XWL_HAS_LIBDECOR', have_libdecor ? '1' : false)
-xwayland_data.set('XWL_HAS_XWAYLAND_EXTENSION', xwaylandproto_dep.found() ? '1' : false)
-xwayland_data.set('XWL_HAS_EI', build_ei)
-xwayland_data.set('XWL_HAS_EI_PORTAL', build_ei_portal)
-
-configure_file(output : 'xwayland-config.h',
- input : 'xwayland-config.h.meson.in',
- configuration : xwayland_data)
-
dtrace_hdr = []
dtrace_tmpl = files('Xserver.d')
if with_dtrace
diff --git a/include/xwayland-config.h.meson.in b/include/xwayland-config.h.meson.in
deleted file mode 100644
index 17ca8fcb0..000000000
--- a/include/xwayland-config.h.meson.in
+++ /dev/null
@@ -1,20 +0,0 @@
-/* xwayland-config.h.meson.in: not at all generated */
-
-#pragma once
-
-#include
-
-/* 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
diff --git a/meson.build b/meson.build
index b76083269..0698ae763 100644
--- a/meson.build
+++ b/meson.build
@@ -62,12 +62,10 @@ endforeach
add_project_arguments(common_wflags, language : ['c', 'objc'])
-libdrm_req = '>= 2.4.116'
+libdrm_req = '>= 2.4.109'
libselinux_req = '>= 2.0.86'
xext_req = '>= 1.0.99.4'
xproto_req = '>= 7.0.31'
-wayland_req = '>= 1.21.0'
-wayland_protocols_req = '>= 1.38'
gbm_req = '>= 10.2'
xf86dgaproto_req = '>= 2.0.99.1'
xshmfence_req = '>= 1.1'
@@ -100,7 +98,6 @@ xf86bigfontproto_dep = dependency('xf86bigfontproto', version: '>= 1.2.0', fallb
xf86vidmodeproto_dep = dependency('xf86vidmodeproto', version: '>= 2.2.99.1', fallback: ['xorgproto', 'ext_xorgproto'])
applewmproto_dep = dependency('applewmproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'], required: false)
xshmfence_dep = dependency('xshmfence', version: xshmfence_req, required: false)
-xwaylandproto_dep = dependency('xwaylandproto', version: '>= 1.0', fallback: ['xorgproto', 'ext_xorgproto'], required: false)
dpmsproto_dep = dependency('dpmsproto', version: '>= 1.2', required: get_option('dpms'))
pixman_dep = dependency('pixman-1')
@@ -214,38 +211,6 @@ endif
xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg')
libxcvt_dep = dependency('libxcvt', fallback: ['libxcvt', 'libxcvt_dep'], required: build_xorg)
-build_xwayland = false
-if (host_machine.system() != 'darwin' and
- host_machine.system() != 'windows' and
- get_option('xwayland') != 'false')
- xwayland_required = get_option('xwayland') == 'true'
- build_glamor = glamor_option == 'true' or glamor_option == 'auto'
-
- xwayland_path = get_option('xwayland-path')
- if (xwayland_path == '')
- xwayland_path = join_paths(get_option('prefix'), get_option('bindir'))
- endif
-
- xwayland_dep = [
- dependency('wayland-client', version: wayland_req, required: xwayland_required),
- dependency('wayland-protocols', version: wayland_protocols_req, required: xwayland_required),
- dependency('libxcvt', fallback: ['libxcvt', 'libxcvt_dep'], required: xwayland_required),
- ]
- if build_glamor
- xwayland_dep += dependency('xshmfence', version: xshmfence_req, required: xwayland_required)
- xwayland_dep += dependency('libdrm', version: libdrm_req, required: xwayland_required)
- xwayland_dep += dependency('epoxy', required: xwayland_required)
- endif
-
- build_xwayland = true
- # check for all the deps being found, to handle 'auto' mode.
- foreach d: xwayland_dep
- if not d.found()
- build_xwayland = false
- endif
- endforeach
-endif
-
## configure Xnest - nesting X server
build_xnest = get_option('xnest') != 'false'
xnest_required = get_option('xnest') == 'true'
@@ -292,7 +257,6 @@ build_xvfb = get_option('xvfb')
summary({
'Xorg': build_xorg,
- 'Xwayland': build_xwayland,
'Xephyr': build_xephyr,
'Xnest': build_xnest,
'Xvfb': build_xvfb,
@@ -366,7 +330,7 @@ endif
module_dir = join_paths(get_option('libdir'), get_option('module_dir'))
if glamor_option == 'auto'
- build_glamor = build_xorg or build_xwayland
+ build_glamor = build_xorg
else
build_glamor = glamor_option == 'true'
endif
@@ -378,32 +342,6 @@ if build_glamor
epoxy_dep = dependency('epoxy', required: false)
endif
-if build_xwayland
- libdecor_dep = dependency('libdecor-0', required: false)
- libdecor_option = get_option('libdecor')
- if libdecor_option == 'auto'
- have_libdecor = libdecor_dep.found()
- else
- have_libdecor = libdecor_option == 'true'
- if have_libdecor and not libdecor_dep.found()
- error('libdecor support requested but not found')
- endif
- endif
-else
- have_libdecor = false
-endif
-
-if build_xwayland
- libei_dep = dependency('libei-1.0', version: '>= 1.0.0', required: get_option('xwayland_ei') in ['portal', 'socket'])
- liboeffis_dep = dependency('liboeffis-1.0', version: '>= 1.0.0', required: get_option('xwayland_ei') == 'portal')
-
- build_ei = libei_dep.found() and get_option('xwayland_ei') != 'false'
- build_ei_portal = liboeffis_dep.found() and get_option('xwayland_ei') in ['portal', 'auto']
-else
- build_ei = false
- build_ei_portal = false
-endif
-
# Lots of sha1 options, because Linux is about choice :)
# The idea behind the ordering here is that we should first prefer system
diff --git a/meson_options.txt b/meson_options.txt
index 94698f218..05cc3cfe8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,12 +2,8 @@ option('xorg', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable Xorg X Server')
option('xephyr', type: 'boolean', value: false,
description: 'Enable Xephyr nested X server')
-option('xwayland', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
- description: 'Enable Xwayland X server')
option('glamor', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
- description: 'Enable glamor (default yes for Xorg/Xwayland builds)')
-option('xwayland_ei', type: 'combo', choices: ['socket', 'portal', 'false', 'auto'],
- value: 'auto', description: 'Enable emulated input support on Xwayland')
+ description: 'Enable glamor (default yes for Xorg builds)')
option('xnest', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Enable Xnest nested X server')
option('xvfb', type: 'boolean', value: true,
@@ -139,10 +135,6 @@ option('xpbproxy', type: 'boolean', value: false,
option('libunwind', type: 'boolean', value: false,
description: 'Use libunwind for backtrace reporting')
-option('xwayland-path', type: 'string', description: 'Directory containing Xwayland executable')
-option('libdecor', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
- description: 'Whether Xwayland should use libdecor when running rootful.')
-
option('docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
description: 'Build documentation')
option('devel-docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
diff --git a/miext/sync/meson.build b/miext/sync/meson.build
index 431032711..379cd55b5 100644
--- a/miext/sync/meson.build
+++ b/miext/sync/meson.build
@@ -10,7 +10,7 @@ hdrs_miext_sync = [
'misyncstr.h',
]
-if build_dri3 or build_xwayland or xshmfence_dep.found()
+if build_dri3 or xshmfence_dep.found()
srcs_miext_sync += 'misyncshm.c'
endif
diff --git a/test/meson.build b/test/meson.build
index 199431225..3f41d5df0 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -149,19 +149,6 @@ if get_option('xvfb')
endif
endif
-if build_xwayland
- xwayland_args = [
- xwayland_server.full_path(),
- ]
-
- test('XTS',
- find_program('scripts/xwayland-piglit.sh'),
- env: piglit_env,
- timeout: 1200,
- suite: 'xwayland'
- )
-endif
-
subdir('bigreq')
subdir('damage')
subdir('sync')
diff --git a/test/scripts/xwayland-piglit.sh b/test/scripts/xwayland-piglit.sh
deleted file mode 100755
index 9d6e54d01..000000000
--- a/test/scripts/xwayland-piglit.sh
+++ /dev/null
@@ -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