diff --git a/Makefile.am b/Makefile.am index abbea2856..75db64e1c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -180,7 +180,6 @@ EXTRA_DIST += \ hw/xfree86/xkb/meson.build \ hw/xnest/meson.build \ hw/xquartz/meson.build \ - hw/xwayland/meson.build \ hw/xwin/dri/meson.build \ hw/xwin/glx/meson.build \ hw/xwin/meson.build \ diff --git a/configure.ac b/configure.ac index 09e7a06ef..124aea331 100644 --- a/configure.ac +++ b/configure.ac @@ -67,8 +67,6 @@ dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs. AC_CONFIG_HEADERS(include/xkb-config.h) dnl xwin-config.h covers the XWin DDX. AC_CONFIG_HEADERS(include/xwin-config.h) -dnl xwayland-config.h covers Xwayland. -AC_CONFIG_HEADERS(include/xwayland-config.h) dnl version-config.h covers the version numbers so they can be bumped without dnl forcing an entire recompile.x AC_CONFIG_HEADERS(include/version-config.h) @@ -575,10 +573,6 @@ AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes]) AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto]) AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto]) -AC_ARG_ENABLE(xwayland, AS_HELP_STRING([--enable-xwayland], [Build Xwayland server (default: auto)]), [XWAYLAND=$enableval], [XWAYLAND=auto]) -AC_ARG_ENABLE(xwayland-eglstream, AS_HELP_STRING([--enable-xwayland-eglstream], [Build Xwayland eglstream support (default: no)]), [XWAYLAND_EGLSTREAM=$enableval], [XWAYLAND_EGLSTREAM=no]) -AC_ARG_WITH(xwayland-path, AS_HELP_STRING([--with-xwayland-path=PATH], [Directory containing Xwayland executable (default: ${bindir})]), - [ xwayland_path="$withval" ], [ xwayland_path="$bindir" ]) AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no]) AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: auto)]), [GLAMOR=$enableval], [GLAMOR=auto]) @@ -685,7 +679,6 @@ case $host_os in XQUARTZ=yes XVFB=no XNEST=no - XWAYLAND=no COMPOSITE=no DGA=no @@ -2019,7 +2012,7 @@ AM_CONDITIONAL([XORG_DRIVER_INPUT_INPUTTEST], [test "x$XORG_DRIVER_INPUT_INPUTTE dnl glamor if test "x$GLAMOR" = xauto; then - if echo "$XORG" "$XEPHYR" "$XWAYLAND" | grep -q yes ; then + if echo "$XORG" "$XEPHYR" | grep -q yes ; then GLAMOR=yes fi fi @@ -2234,92 +2227,6 @@ AC_SUBST([KDRIVE_LOCAL_LIBS]) AC_SUBST([KDRIVE_LIBS]) AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes]) -dnl Xwayland DDX - -XWAYLANDMODULES="wayland-client >= 1.5.0 wayland-protocols >= 1.18" -if test "x$XF86VIDMODE" = xyes; then - XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO" -fi -if test "x$DRM" = xyes; then - XWAYLANDMODULES="$XWAYLANDMODULES $LIBDRM" -fi -if test "x$GLAMOR" = xyes; then - XWAYLANDMODULES="$XWAYLANDMODULES epoxy" -fi -PKG_CHECK_MODULES(XWAYLANDMODULES, [$XWAYLANDMODULES], [have_xwayland=yes], [have_xwayland=no]) -AC_MSG_CHECKING([whether to build Xwayland DDX]) -if test "x$XWAYLAND" = xauto; then - XWAYLAND="$have_xwayland" -fi -AC_MSG_RESULT([$XWAYLAND]) -AM_CONDITIONAL(XWAYLAND, [test "x$XWAYLAND" = xyes]) - -if test "x$XWAYLAND" = xyes; then - if test "x$have_xwayland" = xno; then - AC_MSG_ERROR([Xwayland build explicitly requested, but required modules not found.]) - fi - - if test "x$GLAMOR" = xyes && test "x$GBM" = xyes; then - AC_DEFINE(XWL_HAS_GLAMOR, 1, - [Build xwayland with glamor support]) - AC_SUBST(have_glamor, "true") - else - AC_SUBST(have_glamor, "false") - fi - - PKG_CHECK_MODULES(WAYLAND_EGLSTREAM, [wayland-eglstream-protocols >= 1.0.2], [have_wl_eglstream=yes], [have_wl_eglstream=no]) - - if test "x$XWAYLAND_EGLSTREAM" = xauto; then - if test "x$have_wl_eglstream" = xyes && test "x$GLAMOR" = xyes; then - XWAYLAND_EGLSTREAM=yes - fi - fi - - if test "x$XWAYLAND_EGLSTREAM" = xyes; then - if test "x$GLAMOR" != xyes; then - AC_MSG_ERROR([Xwayland eglstream support explicitly requested, but required modules not found.]) - fi - - if test "x$have_wl_eglstream" = xno; then - AC_MSG_ERROR([Xwayland eglstream support requires wayland-eglstream-protocols >= 1.0.2]) - fi - - AC_SUBST(WAYLAND_EGLSTREAM_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-eglstream-protocols`) - AC_DEFINE(XWL_HAS_EGLSTREAM, 1, - [Build xwayland with eglstream support]) - AC_SUBST(have_eglstream, "true") - else - AC_SUBST(have_eglstream, "false") - fi - - PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT) - - XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB" - XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS $LIBXCVT_LIBS" - AC_SUBST([XWAYLAND_LIBS]) - AC_SUBST([XWAYLAND_SYS_LIBS]) - - if test "x$MONOTONIC_CLOCK" != xyes; then - AC_MSG_ERROR([Xwayland requires CLOCK_MONOTONIC support.]) - fi - - AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner]) - if test "x$WAYLAND_SCANNER" = x; then - PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner]) - AC_SUBST(WAYLAND_SCANNER, `$PKG_CONFIG --variable=wayland_scanner wayland-scanner`) - fi - - PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner >= 1.14.91], - AC_SUBST(SCANNER_ARG, 'private-code'), - AC_SUBST(SCANNER_ARG, 'code')) - - AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-protocols`) - - AC_SUBST(xwayland_path) - -fi -AM_CONDITIONAL(XWAYLAND_EGLSTREAM, [test "x$XWAYLAND_EGLSTREAM" = "xyes"]) - dnl and the rest of these are generic, so they're in config.h dnl @@ -2450,9 +2357,6 @@ hw/kdrive/Makefile hw/kdrive/ephyr/Makefile hw/kdrive/ephyr/man/Makefile hw/kdrive/src/Makefile -hw/xwayland/Makefile -hw/xwayland/man/Makefile -hw/xwayland/xwayland.pc test/Makefile xserver.ent xorg-server.pc diff --git a/hw/Makefile.am b/hw/Makefile.am index 006898bfb..1749018fa 100644 --- a/hw/Makefile.am +++ b/hw/Makefile.am @@ -22,20 +22,15 @@ if XQUARTZ XQUARTZ_SUBDIRS = xquartz endif -if XWAYLAND -XWAYLAND_SUBDIRS = xwayland -endif - SUBDIRS = \ $(XORG_SUBDIRS) \ $(XWIN_SUBDIRS) \ $(XVFB_SUBDIRS) \ $(XNEST_SUBDIRS) \ $(KDRIVE_SUBDIRS) \ - $(XQUARTZ_SUBDIRS) \ - $(XWAYLAND_SUBDIRS) + $(XQUARTZ_SUBDIRS) -DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive xwayland +DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive relink: $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done diff --git a/hw/meson.build b/hw/meson.build index 0f43ab6e2..f8bd28a25 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/Makefile.am b/hw/xwayland/Makefile.am deleted file mode 100644 index 0060df70a..000000000 --- a/hw/xwayland/Makefile.am +++ /dev/null @@ -1,189 +0,0 @@ -SUBDIRS = man - -DIST_SUBDIRS = man - -bindir = @xwayland_path@ -bin_PROGRAMS = Xwayland - -Xwayland_CFLAGS = \ - -I$(top_srcdir)/glamor \ - -I$(top_srcdir)/dri3 \ - -DHAVE_DIX_CONFIG_H \ - $(XWAYLANDMODULES_CFLAGS) \ - $(DIX_CFLAGS) \ - $(GLAMOR_CFLAGS) \ - $(GBM_CFLAGS) \ - $(LIBXCVT_CFLAGS) - -Xwayland_SOURCES = \ - xwayland.c \ - xwayland-input.c \ - xwayland-input.h \ - xwayland-cursor.c \ - xwayland-cursor.h \ - xwayland-glamor.h \ - xwayland-glx.h \ - xwayland-pixmap.c \ - xwayland-pixmap.h \ - 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 \ - $(top_srcdir)/Xi/stubs.c \ - $(top_srcdir)/mi/miinitext.c \ - $(top_srcdir)/mi/miinitext.h - -if GLAMOR -if GLX -Xwayland_SOURCES += \ - xwayland-glx.c -Xwayland_CFLAGS += \ - -I$(top_srcdir)/glx -GLXVND_LIB = $(top_builddir)/glx/libglxvnd.la -endif #GLX -endif # GLAMOR - -Xwayland_LDADD = \ - $(glamor_lib) \ - $(XWAYLAND_LIBS) \ - $(GLXVND_LIB) \ - $(XWAYLAND_SYS_LIBS) \ - $(top_builddir)/Xext/libXvidmode.la \ - $(XSERVER_SYS_LIBS) \ - $(LIBXCVT_LIBS) -Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) - -Xwayland_built_sources = - -if GLAMOR_EGL -Xwayland_SOURCES += \ - xwayland-glamor.c \ - xwayland-glamor-gbm.c \ - xwayland-present.c -if XV -Xwayland_SOURCES += \ - xwayland-glamor-xv.c -endif - -if XWAYLAND_EGLSTREAM -Xwayland_SOURCES += \ - xwayland-glamor-eglstream.c -endif - -glamor_built_sources = \ - drm-client-protocol.h \ - drm-protocol.c - -Xwayland_built_sources += $(glamor_built_sources) - -glamor_lib = $(top_builddir)/glamor/libglamor.la - -Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL -Xwayland_DEPENDENCIES = $(glamor_lib) $(XWAYLAND_LIBS) -endif - -Xwayland_built_sources += \ - relative-pointer-unstable-v1-client-protocol.h \ - relative-pointer-unstable-v1-protocol.c \ - pointer-constraints-unstable-v1-client-protocol.h \ - pointer-constraints-unstable-v1-protocol.c \ - tablet-unstable-v2-client-protocol.h \ - tablet-unstable-v2-protocol.c \ - xwayland-keyboard-grab-unstable-v1-protocol.c \ - xwayland-keyboard-grab-unstable-v1-client-protocol.h \ - xdg-output-unstable-v1-protocol.c \ - xdg-output-unstable-v1-client-protocol.h \ - linux-dmabuf-unstable-v1-client-protocol.h \ - linux-dmabuf-unstable-v1-protocol.c \ - viewporter-client-protocol.h \ - viewporter-protocol.c\ - xdg-shell-client-protocol.h\ - xdg-shell-protocol.c - -if XWAYLAND_EGLSTREAM -Xwayland_built_sources += \ - wayland-eglstream-client-protocol.h \ - wayland-eglstream-protocol.c \ - wayland-eglstream-controller-client-protocol.h \ - wayland-eglstream-controller-protocol.c -endif - -nodist_Xwayland_SOURCES = $(Xwayland_built_sources) -CLEANFILES = $(Xwayland_built_sources) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = xwayland.pc - -EXTRA_DIST = xwayland.pc.in drm.xml - -$(Xwayland_SOURCES): $(Xwayland_built_sources) - -relink: - $(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT) - -relative-pointer-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -relative-pointer-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -pointer-constraints-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -xwayland-keyboard-grab-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -xwayland-keyboard-grab-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ -xdg-output-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -xdg-output-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -linux-dmabuf-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -linux-dmabuf-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ -xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ -wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ - -wayland-eglstream-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ -wayland-eglstream-controller-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ - -%-protocol.c : %.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ - -%-client-protocol.h : %.xml - $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ 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/Makefile.am b/hw/xwayland/man/Makefile.am deleted file mode 100644 index 6e4b59e17..000000000 --- a/hw/xwayland/man/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -include $(top_srcdir)/manpages.am -appman_PRE = Xwayland.man diff --git a/hw/xwayland/man/Xwayland.man b/hw/xwayland/man/Xwayland.man deleted file mode 100644 index 15eb7f5f4..000000000 --- a/hw/xwayland/man/Xwayland.man +++ /dev/null @@ -1,107 +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 \fIXserver\fP(@miscmansuffix@) manual page. -The following additional arguments are supported as well. -.TP 8 -.B \-eglstream -Use EGLStream backend for NVidia GPUs. If \fIXwayland\fP was compiled with -EGLStream support, this option will instruct \fIXwayland\fP to try that -backend first, then fallback to the GBM backend if EGLStream is not supported -by the Wayland server. Without this option, \fIXwayland\fP tries the GBM -backend first, and fallback to EGLStream if GBM is not usable. -.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 \-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 -.BI \-shm -Force the shared memory backend instead of glamor (if available) for passing -buffers to the Wayland server. -.TP 8 -.BR \-verbose " [\fIn\fP]" -Sets the verbosity level for information printed on stderr. If the -.I n -value isn't supplied, each occurrence of this option increments the -verbosity level. When the -.I n -value is supplied, the verbosity level is set to that value. The default -verbosity level is 0. -.TP 8 -.BI \-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: \fIX\fP(@miscmansuffix@) diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build deleted file mode 100644 index 1dea64bff..000000000 --- a/hw/xwayland/meson.build +++ /dev/null @@ -1,160 +0,0 @@ -srcs = [ - 'xwayland.c', - 'xwayland-input.c', - 'xwayland-input.h', - 'xwayland-cursor.c', - 'xwayland-cursor.h', - 'xwayland-glamor.h', - 'xwayland-glx.h', - 'xwayland-pixmap.c', - 'xwayland-pixmap.h', - '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_pkgconfig_variable('wayland_scanner')) - -protocols_dep = dependency('wayland-protocols', version: wayland_protocols_req) -protodir = protocols_dep.get_pkgconfig_variable('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') -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') - -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@'] -) -srcs += client_header.process(relative_xml) -srcs += client_header.process(pointer_xml) -srcs += client_header.process(tablet_xml) -srcs += client_header.process(kbgrab_xml) -srcs += client_header.process(xdg_output_xml) -srcs += client_header.process(dmabuf_xml) -srcs += client_header.process(viewporter_xml) -srcs += client_header.process(xdg_shell_xml) -srcs += code.process(relative_xml) -srcs += code.process(pointer_xml) -srcs += code.process(tablet_xml) -srcs += code.process(kbgrab_xml) -srcs += code.process(xdg_output_xml) -srcs += code.process(dmabuf_xml) -srcs += code.process(viewporter_xml) -srcs += code.process(xdg_shell_xml) - -xwayland_glamor = [] -eglstream_srcs = [] -if build_glamor - srcs += 'xwayland-glamor.c' - if build_glx - srcs += 'xwayland-glx.c' - endif - if gbm_dep.found() - srcs += 'xwayland-glamor-gbm.c' - endif - if build_eglstream - eglstream_protodir = eglstream_dep.get_pkgconfig_variable('pkgdatadir') - eglstream_xml = join_paths(eglstream_protodir, 'wayland-eglstream.xml') - eglstream_controller_xml = join_paths(eglstream_protodir, 'wayland-eglstream-controller.xml') - - srcs += client_header.process(eglstream_xml) - srcs += client_header.process(eglstream_controller_xml) - srcs += code.process(eglstream_xml) - srcs += code.process(eglstream_controller_xml) - - srcs += 'xwayland-glamor-eglstream.c' - endif - srcs += 'xwayland-present.c' - 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 - -xwayland_server = executable( - 'Xwayland', - srcs, - include_directories: wayland_inc, - dependencies: [ - common_dep, - xwayland_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_data = configuration_data() -xwayland_data.set('prefix', get_option('prefix')) -xwayland_data.set('exec_prefix', '${prefix}') -xwayland_data.set('PACKAGE_VERSION', meson.project_version()) -xwayland_data.set('xwayland_path', xwayland_path) -xwayland_data.set('have_glamor', build_glamor ? 'true' : 'false') -xwayland_data.set('have_eglstream', build_eglstream ? 'true' : 'false') -configure_file( - input: 'xwayland.pc.in', - output: 'xwayland.pc', - configuration: xwayland_data, - install_dir: join_paths(get_option('prefix'), - get_option('libdir'), - 'pkgconfig'), -) - -xwayland_manpage = configure_file( - input: 'man/Xwayland.man', - output: 'Xwayland.1', - configuration: manpage_config, -) -install_man(xwayland_manpage) diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c deleted file mode 100644 index c4457cc2a..000000000 --- a/hw/xwayland/xwayland-cursor.c +++ /dev/null @@ -1,428 +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 DevPrivateKeyRec xwl_cursor_private_key; - -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->foreGreen >> 8); - bg = ((cursor->backRed & 0xff00) << 8) | - (cursor->backGreen & 0xff00) | (cursor->backGreen >> 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) -{ - PixmapPtr pixmap; - - pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width, - cursor->bits->height, 32, - CREATE_PIXMAP_USAGE_BACKING_PIXMAP); - dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap); - - return TRUE; -} - -static Bool -xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) -{ - PixmapPtr pixmap; - struct xwl_screen *xwl_screen; - struct xwl_seat *xwl_seat; - - pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); - if (!pixmap) - return TRUE; - - dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL); - - /* 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 xwl_shm_destroy_pixmap(pixmap); -} - -static void -clear_cursor_frame_callback(struct xwl_cursor *xwl_cursor) -{ - if (xwl_cursor->frame_cb) { - wl_callback_destroy (xwl_cursor->frame_cb); - xwl_cursor->frame_cb = NULL; - } -} - -static void -frame_callback(void *data, - struct wl_callback *callback, - uint32_t time) -{ - struct xwl_cursor *xwl_cursor = data; - - clear_cursor_frame_callback(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; - - 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); - xwl_surface_damage(xwl_seat->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); - - /* Hold a reference on the pixmap until it's released by the compositor */ - pixmap->refcnt++; - xwl_pixmap_set_buffer_release_cb(pixmap, - xwl_cursor_buffer_release_callback, - pixmap); - - wl_surface_commit(xwl_cursor->surface); -} - -void -xwl_seat_set_cursor(struct xwl_seat *xwl_seat) -{ - struct xwl_cursor *xwl_cursor = &xwl_seat->cursor; - PixmapPtr pixmap; - CursorPtr cursor; - - 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); - clear_cursor_frame_callback(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 = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); - if (!pixmap) - return; - - xwl_cursor_copy_bits_to_pixmap(cursor, pixmap); - - wl_pointer_set_cursor(xwl_seat->wl_pointer, - xwl_seat->pointer_enter_serial, - xwl_cursor->surface, - xwl_seat->x_cursor->bits->xhot, - xwl_seat->x_cursor->bits->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_cursor *xwl_cursor = &xwl_tablet_tool->cursor; - PixmapPtr pixmap; - CursorPtr cursor; - - if (!xwl_seat->x_cursor) { - zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, - xwl_tablet_tool->proximity_in_serial, - NULL, 0, 0); - clear_cursor_frame_callback(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 = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); - if (!pixmap) - return; - - xwl_cursor_copy_bits_to_pixmap(cursor, pixmap); - - zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, - xwl_tablet_tool->proximity_in_serial, - xwl_cursor->surface, - xwl_seat->x_cursor->bits->xhot, - xwl_seat->x_cursor->bits->yhot); - - xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap); -} - -static void -xwl_seat_update_cursor(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_cursor(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_cursor(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) -{ - if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0)) - return FALSE; - - 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 401e814a7..000000000 --- a/hw/xwayland/xwayland-cursor.h +++ /dev/null @@ -1,38 +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 - -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 ba8cbc9d1..000000000 --- a/hw/xwayland/xwayland-cvt.c +++ /dev/null @@ -1,62 +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" - -RRModePtr -xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced, - Bool interlaced) -{ - struct libxcvt_mode_info *libxcvt_mode_info; - char name[128]; - xRRModeInfo modeinfo; - - libxcvt_mode_info = - libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced); - - memset(&modeinfo, 0, sizeof modeinfo); - 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); - - 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-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c deleted file mode 100644 index b678eaa10..000000000 --- a/hw/xwayland/xwayland-glamor-eglstream.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* - * 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 - -#define MESA_EGL_NO_X11_HEADERS -#define EGL_NO_X11 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "xwayland-glamor.h" -#include "xwayland-pixmap.h" -#include "xwayland-screen.h" -#include "xwayland-window.h" - -#include "wayland-eglstream-client-protocol.h" -#include "wayland-eglstream-controller-client-protocol.h" -#include "linux-dmabuf-unstable-v1-client-protocol.h" - -struct xwl_eglstream_private { - EGLDeviceEXT egl_device; - struct wl_eglstream_display *display; - struct wl_eglstream_controller *controller; - uint32_t display_caps; - - EGLConfig config; - - Bool have_egl_damage; - Bool have_egl_stream_flush; - - GLint blit_prog; - GLuint blit_vao; - GLuint blit_vbo; - GLuint blit_is_rgba_pos; -}; - -enum xwl_pixmap_type { - XWL_PIXMAP_EGLSTREAM, /* Pixmaps created by glamor. */ - XWL_PIXMAP_DMA_BUF, /* Pixmaps allocated through DRI3. */ -}; - -struct xwl_pixmap { - enum xwl_pixmap_type type; - /* add any new <= 4-byte member here to avoid holes on 64-bit */ - struct xwl_screen *xwl_screen; - struct wl_buffer *buffer; - struct wl_callback *pending_cb; - Bool wait_for_buffer_release; - - /* XWL_PIXMAP_EGLSTREAM. */ - EGLStreamKHR stream; - EGLSurface surface; - - /* XWL_PIXMAP_DMA_BUF. */ - EGLImage image; -}; - -static DevPrivateKeyRec xwl_eglstream_private_key; - -static inline struct xwl_eglstream_private * -xwl_eglstream_get(struct xwl_screen *xwl_screen) -{ - return dixLookupPrivate(&xwl_screen->screen->devPrivates, - &xwl_eglstream_private_key); -} - -static GLint -xwl_eglstream_compile_glsl_prog(GLenum type, const char *source) -{ - GLint ok; - GLint prog; - - prog = glCreateShader(type); - glShaderSource(prog, 1, (const GLchar **) &source, NULL); - glCompileShader(prog); - glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); - if (!ok) { - GLchar *info; - GLint size; - - glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); - info = malloc(size); - if (info) { - glGetShaderInfoLog(prog, size, NULL, info); - ErrorF("Failed to compile %s: %s\n", - type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); - ErrorF("Program source:\n%s", source); - free(info); - } - else - ErrorF("Failed to get shader compilation info.\n"); - FatalError("GLSL compile failure\n"); - } - - return prog; -} - -static GLuint -xwl_eglstream_build_glsl_prog(GLuint vs, GLuint fs) -{ - GLint ok; - GLuint prog; - - prog = glCreateProgram(); - glAttachShader(prog, vs); - glAttachShader(prog, fs); - - glLinkProgram(prog); - glGetProgramiv(prog, GL_LINK_STATUS, &ok); - if (!ok) { - GLchar *info; - GLint size; - - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); - info = malloc(size); - - glGetProgramInfoLog(prog, size, NULL, info); - ErrorF("Failed to link: %s\n", info); - FatalError("GLSL link failure\n"); - } - - return prog; -} - -static void -xwl_eglstream_cleanup(struct xwl_screen *xwl_screen) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - - if (xwl_eglstream->display) - wl_eglstream_display_destroy(xwl_eglstream->display); - if (xwl_eglstream->controller) - wl_eglstream_controller_destroy(xwl_eglstream->controller); - if (xwl_eglstream->blit_prog) { - glDeleteProgram(xwl_eglstream->blit_prog); - glDeleteBuffers(1, &xwl_eglstream->blit_vbo); - } - - free(xwl_eglstream); -} - -static Bool -xwl_glamor_egl_supports_device_probing(void) -{ - return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base"); -} - -static void ** -xwl_glamor_egl_get_devices(int *num_devices) -{ - EGLDeviceEXT *devices, *tmp; - Bool ret; - int drm_dev_count = 0; - int i; - - if (!xwl_glamor_egl_supports_device_probing()) - return NULL; - - /* Get the number of devices */ - ret = eglQueryDevicesEXT(0, NULL, num_devices); - if (!ret || *num_devices < 1) - return NULL; - - devices = calloc(*num_devices, sizeof(EGLDeviceEXT)); - if (!devices) - return NULL; - - ret = eglQueryDevicesEXT(*num_devices, devices, num_devices); - if (!ret) - goto error; - - /* We're only ever going to care about devices that support - * EGL_EXT_device_drm, so filter out the ones that don't - */ - for (i = 0; i < *num_devices; i++) { - const char *extension_str = - eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS); - - if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm")) - continue; - - devices[drm_dev_count++] = devices[i]; - } - if (!drm_dev_count) - goto error; - - *num_devices = drm_dev_count; - tmp = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count); - if (!tmp) - goto error; - - devices = tmp; - - return devices; - -error: - free(devices); - - return NULL; -} - -static Bool -xwl_glamor_egl_device_has_egl_extensions(void *device, - const char **ext_list, size_t size) -{ - EGLDisplay egl_display; - int i; - Bool has_exts = TRUE; - - egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device); - if (!egl_display || !eglInitialize(egl_display, NULL, NULL)) - return FALSE; - - for (i = 0; i < size; i++) { - if (!epoxy_has_egl_extension(egl_display, ext_list[i])) { - has_exts = FALSE; - break; - } - } - - eglTerminate(egl_display); - return has_exts; -} - -static void -xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap) -{ - struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen; - - /* If we're using this stream in the current egl context, unbind it so the - * driver doesn't keep it around until the next eglMakeCurrent() - * don't have to keep it around until something else changes the surface - */ - xwl_glamor_egl_make_current(xwl_screen); - if (eglGetCurrentSurface(EGL_READ) == xwl_pixmap->surface || - eglGetCurrentSurface(EGL_DRAW) == xwl_pixmap->surface) { - eglMakeCurrent(xwl_screen->egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - xwl_screen->egl_context); - } - - if (xwl_pixmap->surface != EGL_NO_SURFACE) - eglDestroySurface(xwl_screen->egl_display, xwl_pixmap->surface); - - if (xwl_pixmap->stream != EGL_NO_STREAM_KHR) - eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream); - - if (xwl_pixmap->buffer) - wl_buffer_destroy(xwl_pixmap->buffer); - - if (xwl_pixmap->image != EGL_NO_IMAGE_KHR) - eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image); - - free(xwl_pixmap); -} - -static void -xwl_eglstream_destroy_pending_cb(PixmapPtr pixmap) -{ - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - - if (xwl_pixmap && xwl_pixmap->pending_cb) { - wl_callback_destroy(xwl_pixmap->pending_cb); - xwl_pixmap->pending_cb = NULL; - } -} - -static Bool -xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap) -{ - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - - if (xwl_pixmap && pixmap->refcnt == 1) { - xwl_eglstream_destroy_pending_cb(pixmap); - xwl_eglstream_destroy_pixmap_stream(xwl_pixmap); - xwl_pixmap_del_buffer_release_cb(pixmap); - } - return glamor_destroy_pixmap(pixmap); -} - -static struct wl_buffer * -xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap) -{ - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - - if (!xwl_pixmap) - return NULL; - - return xwl_pixmap->buffer; -} - -static const char * -xwl_eglstream_get_error_str(EGLint error) -{ - switch (error) { - case EGL_BAD_PARAMETER: - return "EGL_BAD_PARAMETER"; - case EGL_BAD_ATTRIBUTE: - return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_MATCH: - return "EGL_BAD_MATCH"; - case EGL_BAD_ACCESS: - return "EGL_BAD_ACCESS"; - case EGL_BAD_STATE_KHR: - return "EGL_BAD_STATE_KHR"; - case EGL_BAD_STREAM_KHR: - return "EGL_BAD_STREAM_KHR"; - case EGL_BAD_DISPLAY: - return "EGL_BAD_DISPLAY"; - case EGL_NOT_INITIALIZED: - return "EGL_NOT_INITIALIZED"; - default: - return "Unknown error"; - } -} - -static const char * -xwl_eglstream_get_stream_state_str(EGLint state) -{ - switch (state) { - case EGL_STREAM_STATE_CREATED_KHR: - return "EGL_STREAM_STATE_CREATED_KHR"; - case EGL_STREAM_STATE_CONNECTING_KHR: - return "EGL_STREAM_STATE_CONNECTING_KHR"; - case EGL_STREAM_STATE_EMPTY_KHR: - return "EGL_STREAM_STATE_EMPTY_KHR"; - case EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR: - return "EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR"; - case EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR: - return "EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR"; - case EGL_STREAM_STATE_DISCONNECTED_KHR: - return "EGL_STREAM_STATE_DISCONNECTED_KHR"; - default: - return "Unknown state"; - } -} - -static EGLint -xwl_eglstream_get_state(EGLDisplay egl_display, EGLStreamKHR egl_stream) -{ - EGLint state; - - eglQueryStreamKHR(egl_display, egl_stream, EGL_STREAM_STATE_KHR, &state); - if (!eglQueryStreamKHR(egl_display, egl_stream, - EGL_STREAM_STATE_KHR, &state)) { - EGLint state_error = eglGetError(); - ErrorF("eglstream: Failed to query state - error 0x%X: %s\n", - state_error, xwl_eglstream_get_error_str(state_error)); - return EGL_FALSE; - } - - return state; -} - - -static void -xwl_eglstream_print_error(EGLDisplay egl_display, - EGLStreamKHR egl_stream, EGLint error) -{ - ErrorF("eglstream: error 0x%X: %s\n", error, - xwl_eglstream_get_error_str(error)); - - if (error == EGL_BAD_STATE_KHR) { - EGLint state = xwl_eglstream_get_state(egl_display, egl_stream); - ErrorF("eglstream: stream state 0x%X: %s\n", state, - xwl_eglstream_get_stream_state_str(state)); - } -} - -static void -xwl_eglstream_consumer_ready_callback(void *data, - struct wl_callback *callback, - uint32_t time) -{ - PixmapPtr pixmap = data; - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen; - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - - xwl_eglstream_destroy_pending_cb(pixmap); - - xwl_glamor_egl_make_current(xwl_screen); - - xwl_pixmap->surface = eglCreateStreamProducerSurfaceKHR( - xwl_screen->egl_display, xwl_eglstream->config, - xwl_pixmap->stream, (int[]) { - EGL_WIDTH, pixmap->drawable.width, - EGL_HEIGHT, pixmap->drawable.height, - EGL_NONE - }); - - if (xwl_pixmap->surface == EGL_NO_SURFACE) { - ErrorF("eglstream: Failed to create EGLSurface for pixmap\n"); - xwl_eglstream_print_error(xwl_screen->egl_display, - xwl_pixmap->stream, eglGetError()); - } else { - DebugF("eglstream: completes eglstream for pixmap %p, congrats!\n", - pixmap); - } -} - -static const struct wl_callback_listener consumer_ready_listener = { - xwl_eglstream_consumer_ready_callback -}; - -static void -xwl_eglstream_buffer_release_callback(void *data) -{ - PixmapPtr pixmap = data; - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - - assert(xwl_pixmap); - - if (xwl_pixmap->wait_for_buffer_release) { - xwl_pixmap->wait_for_buffer_release = FALSE; - /* drop the reference we took in the ready callback, freeing if necessary */ - dixDestroyPixmap(pixmap, 0); - } -} - -static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = { - xwl_pixmap_buffer_release_cb, -}; - -static void -xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen, - WindowPtr window, PixmapPtr pixmap) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - struct xwl_pixmap *xwl_pixmap; - struct xwl_window *xwl_window = xwl_window_from_window(window); - struct wl_array stream_attribs; - int stream_fd = -1; - - xwl_pixmap = calloc(1, sizeof(*xwl_pixmap)); - if (!xwl_pixmap) - FatalError("Not enough memory to create pixmap\n"); - xwl_pixmap_set_private(pixmap, xwl_pixmap); - - xwl_pixmap->type = XWL_PIXMAP_EGLSTREAM; - xwl_pixmap->image = EGL_NO_IMAGE; - - xwl_glamor_egl_make_current(xwl_screen); - - xwl_pixmap->wait_for_buffer_release = FALSE; - xwl_pixmap->xwl_screen = xwl_screen; - xwl_pixmap->surface = EGL_NO_SURFACE; - xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL); - if (xwl_pixmap->stream == EGL_NO_STREAM_KHR) { - ErrorF("eglstream: Couldn't create EGL stream.\n"); - goto fail; - } - stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display, - xwl_pixmap->stream); - if (stream_fd == EGL_NO_FILE_DESCRIPTOR_KHR) { - ErrorF("eglstream: Couldn't get EGL stream file descriptor.\n"); - goto fail; - } - - wl_array_init(&stream_attribs); - xwl_pixmap->buffer = - wl_eglstream_display_create_stream(xwl_eglstream->display, - pixmap->drawable.width, - pixmap->drawable.height, - stream_fd, - WL_EGLSTREAM_HANDLE_TYPE_FD, - &stream_attribs); - if (!xwl_pixmap->buffer) { - ErrorF("eglstream: Failed to create buffer\n"); - goto fail; - } - - wl_buffer_add_listener(xwl_pixmap->buffer, - &xwl_eglstream_buffer_release_listener, - pixmap); - - xwl_pixmap_set_buffer_release_cb(pixmap, - xwl_eglstream_buffer_release_callback, - pixmap); - - wl_eglstream_controller_attach_eglstream_consumer( - xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer); - - xwl_pixmap->pending_cb = wl_display_sync(xwl_screen->display); - wl_callback_add_listener(xwl_pixmap->pending_cb, &consumer_ready_listener, - pixmap); -fail: - if (stream_fd >= 0) - close(stream_fd); -} - -static Bool -xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - PixmapPtr pixmap = - (*xwl_screen->screen->GetWindowPixmap)(xwl_window->window); - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - - if (xwl_pixmap) { - if (xwl_pixmap->pending_cb) { - /* Wait for the compositor to finish connecting the consumer for - * this eglstream */ - return FALSE; - } - - if (xwl_pixmap->surface != EGL_NO_SURFACE || - xwl_pixmap->type == XWL_PIXMAP_DMA_BUF) { - return TRUE; - } - - /* The pending stream got removed, we have a xwl_pixmap and - * yet we do not have a surface. - * So something went wrong with the surface creation, retry. - */ - xwl_eglstream_destroy_pixmap_stream(xwl_pixmap); - } - - /* Glamor pixmap has no backing stream yet; begin making one and disallow - * commits until then - */ - xwl_eglstream_create_pixmap_and_stream(xwl_screen, xwl_window->window, - pixmap); - - return FALSE; -} - -static Bool -xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window, - PixmapPtr pixmap, RegionPtr region) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); - BoxPtr box = RegionExtents(region); - EGLint egl_damage[] = { - box->x1, box->y1, - box->x2 - box->x1, box->y2 - box->y1 - }; - GLint saved_vao; - int status; - - if (xwl_pixmap->type != XWL_PIXMAP_EGLSTREAM) - /* This can happen if a client does X11 rendering on a - * flipping OpenGL or Vulkan window. In that case, we don't - * need to do the copy below. - */ - return TRUE; - - /* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we - * won't actually draw to it - */ - xwl_glamor_egl_make_current(xwl_screen); - glamor_set_alu(xwl_screen->screen, GXcopy); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (eglGetCurrentSurface(EGL_READ) != xwl_pixmap->surface || - eglGetCurrentSurface(EGL_DRAW) != xwl_pixmap->surface) - eglMakeCurrent(xwl_screen->egl_display, - xwl_pixmap->surface, xwl_pixmap->surface, - xwl_screen->egl_context); - - /* Save current GL state */ - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao); - - /* Setup our GL state */ - glUseProgram(xwl_eglstream->blit_prog); - glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); - glActiveTexture(GL_TEXTURE0); - glBindVertexArray(xwl_eglstream->blit_vao); - glBindTexture(GL_TEXTURE_2D, glamor_get_pixmap_texture(pixmap)); - - glUniform1i(xwl_eglstream->blit_is_rgba_pos, - pixmap->drawable.depth >= 32); - - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - ErrorF("eglstream: Framebuffer incomplete 0x%X, not posting damage\n", status); - status = FALSE; - goto out; - } - - /* Blit rendered image into EGLStream surface */ - glDrawBuffer(GL_BACK); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - if (xwl_eglstream->have_egl_damage) - status = eglSwapBuffersWithDamageKHR(xwl_screen->egl_display, - xwl_pixmap->surface, - egl_damage, 1); - else - status = eglSwapBuffers(xwl_screen->egl_display, - xwl_pixmap->surface); - - if (!status) { - ErrorF("eglstream: buffer swap failed, not posting damage\n"); - goto out; - } - -#ifdef EGL_NV_stream_flush - if (xwl_eglstream->have_egl_stream_flush) - /* block until stream state is updated on the compositor's side */ - eglStreamFlushNV(xwl_screen->egl_display, - xwl_pixmap->stream); -#endif - - if (!xwl_pixmap->wait_for_buffer_release) { - /* hang onto the pixmap until the compositor has released it */ - pixmap->refcnt++; - xwl_pixmap->wait_for_buffer_release = TRUE; - } - -out: - /* Restore previous state */ - glBindVertexArray(saved_vao); - glBindTexture(GL_TEXTURE_2D, 0); - - return status; -} - -static Bool -xwl_glamor_eglstream_check_flip(PixmapPtr pixmap) -{ - return xwl_pixmap_get(pixmap)->type == XWL_PIXMAP_DMA_BUF; -} - -static void -xwl_eglstream_display_handle_caps(void *data, - struct wl_eglstream_display *disp, - int32_t caps) -{ - xwl_eglstream_get(data)->display_caps = caps; -} - -static void -xwl_eglstream_display_handle_swapinterval_override(void *data, - struct wl_eglstream_display *disp, - int32_t swapinterval, - struct wl_buffer *stream) -{ -} - -const struct wl_eglstream_display_listener eglstream_display_listener = { - .caps = xwl_eglstream_display_handle_caps, - .swapinterval_override = xwl_eglstream_display_handle_swapinterval_override, -}; - -static Bool -xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, - struct wl_registry *wl_registry, - uint32_t id, const char *name, - uint32_t version) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - - if (strcmp(name, "wl_eglstream_display") == 0) { - xwl_eglstream->display = wl_registry_bind( - wl_registry, id, &wl_eglstream_display_interface, version); - - wl_eglstream_display_add_listener(xwl_eglstream->display, - &eglstream_display_listener, - xwl_screen); - return TRUE; - } else if (strcmp(name, "wl_eglstream_controller") == 0) { - xwl_eglstream->controller = wl_registry_bind( - wl_registry, id, &wl_eglstream_controller_interface, version); - return TRUE; - } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) { - xwl_screen_set_dmabuf_interface(xwl_screen, id, version); - return TRUE; - } - - /* no match */ - return FALSE; -} - -static Bool -xwl_glamor_eglstream_has_wl_interfaces(struct xwl_screen *xwl_screen) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - - if (xwl_eglstream->display == NULL) { - ErrorF("glamor: 'wl_eglstream_display' not supported\n"); - return FALSE; - } - - if (xwl_eglstream->controller == NULL) { - ErrorF("glamor: 'wl_eglstream_controller' not supported\n"); - return FALSE; - } - - return TRUE; -} - -static inline void -xwl_eglstream_init_shaders(struct xwl_screen *xwl_screen) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - GLint fs, vs, attrib; - GLuint vbo; - - const char *blit_vs_src = - "attribute vec2 texcoord;\n" - "attribute vec2 position;\n" - "varying vec2 t;\n" - "void main() {\n" - " t = texcoord;\n" - " gl_Position = vec4(position, 0, 1);\n" - "}"; - - const char *blit_fs_src = - "varying vec2 t;\n" - "uniform sampler2D s;\n" - "uniform bool is_rgba;\n" - "void main() {\n" - " if (is_rgba)\n" - " gl_FragColor = texture2D(s, t);\n" - " else\n" - " gl_FragColor = vec4(texture2D(s, t).rgb, 1.0);\n" - "}"; - - static const float position[] = { - /* position */ - -1, -1, - 1, -1, - 1, 1, - -1, 1, - /* texcoord */ - 0, 1, - 1, 1, - 1, 0, - 0, 0, - }; - - vs = xwl_eglstream_compile_glsl_prog(GL_VERTEX_SHADER, blit_vs_src); - fs = xwl_eglstream_compile_glsl_prog(GL_FRAGMENT_SHADER, blit_fs_src); - - xwl_eglstream->blit_prog = xwl_eglstream_build_glsl_prog(vs, fs); - glDeleteShader(vs); - glDeleteShader(fs); - - /* Create the blitter's vao */ - glGenVertexArrays(1, &xwl_eglstream->blit_vao); - glBindVertexArray(xwl_eglstream->blit_vao); - - /* Set the data for both position and texcoord in the vbo */ - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_STATIC_DRAW); - xwl_eglstream->blit_vbo = vbo; - - /* Define each shader attribute's data location in our vbo */ - attrib = glGetAttribLocation(xwl_eglstream->blit_prog, "position"); - glVertexAttribPointer(attrib, 2, GL_FLOAT, TRUE, 0, NULL); - glEnableVertexAttribArray(attrib); - - attrib = glGetAttribLocation(xwl_eglstream->blit_prog, "texcoord"); - glVertexAttribPointer(attrib, 2, GL_FLOAT, TRUE, 0, - (void*)(sizeof(float) * 8)); - glEnableVertexAttribArray(attrib); - - /* Save the location of uniforms we'll set later */ - xwl_eglstream->blit_is_rgba_pos = - glGetUniformLocation(xwl_eglstream->blit_prog, "is_rgba"); -} - -static int -xwl_dri3_open_client(ClientPtr client, - ScreenPtr screen, - RRProviderPtr provider, - int *pfd) -{ - /* Not supported with this backend. */ - return BadImplementation; -} - -static PixmapPtr -xwl_dri3_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) -{ - PixmapPtr pixmap; - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - struct xwl_pixmap *xwl_pixmap; - unsigned int texture; - EGLint image_attribs[48]; - uint32_t mod_hi = modifier >> 32, mod_lo = modifier & 0xffffffff, format; - int attrib = 0, i; - struct zwp_linux_buffer_params_v1 *params; - - format = wl_drm_format_for_depth(depth); - if (!xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) { - ErrorF("glamor: unsupported format modifier\n"); - return NULL; - } - - xwl_pixmap = calloc(1, sizeof (*xwl_pixmap)); - if (!xwl_pixmap) - return NULL; - xwl_pixmap->type = XWL_PIXMAP_DMA_BUF; - xwl_pixmap->xwl_screen = xwl_screen; - - xwl_pixmap->buffer = NULL; - xwl_pixmap->stream = EGL_NO_STREAM_KHR; - xwl_pixmap->surface = EGL_NO_SURFACE; - - params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf); - for (i = 0; i < num_fds; i++) { - zwp_linux_buffer_params_v1_add(params, fds[i], i, - offsets[i], strides[i], - mod_hi, mod_lo); - } - xwl_pixmap->buffer = - zwp_linux_buffer_params_v1_create_immed(params, width, height, - format, 0); - zwp_linux_buffer_params_v1_destroy(params); - - - image_attribs[attrib++] = EGL_WIDTH; - image_attribs[attrib++] = width; - image_attribs[attrib++] = EGL_HEIGHT; - image_attribs[attrib++] = height; - image_attribs[attrib++] = EGL_LINUX_DRM_FOURCC_EXT; - image_attribs[attrib++] = drm_format_for_depth(depth, bpp); - - if (num_fds > 0) { - image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_FD_EXT; - image_attribs[attrib++] = fds[0]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; - image_attribs[attrib++] = offsets[0]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - image_attribs[attrib++] = strides[0]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; - image_attribs[attrib++] = mod_hi; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; - image_attribs[attrib++] = mod_lo; - } - if (num_fds > 1) { - image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_FD_EXT; - image_attribs[attrib++] = fds[1]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; - image_attribs[attrib++] = offsets[1]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; - image_attribs[attrib++] = strides[1]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; - image_attribs[attrib++] = mod_hi; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; - image_attribs[attrib++] = mod_lo; - } - if (num_fds > 2) { - image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_FD_EXT; - image_attribs[attrib++] = fds[2]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; - image_attribs[attrib++] = offsets[2]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; - image_attribs[attrib++] = strides[2]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT; - image_attribs[attrib++] = mod_hi; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; - image_attribs[attrib++] = mod_lo; - } - if (num_fds > 3) { - image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_FD_EXT; - image_attribs[attrib++] = fds[3]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT; - image_attribs[attrib++] = offsets[3]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_PITCH_EXT; - image_attribs[attrib++] = strides[3]; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT; - image_attribs[attrib++] = mod_hi; - image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT; - image_attribs[attrib++] = mod_lo; - } - image_attribs[attrib++] = EGL_NONE; - - xwl_glamor_egl_make_current(xwl_screen); - - /* eglCreateImageKHR will close fds */ - xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - NULL, image_attribs); - if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) { - ErrorF("eglCreateImageKHR failed!\n"); - if (xwl_pixmap->buffer) - wl_buffer_destroy(xwl_pixmap->buffer); - free(xwl_pixmap); - return NULL; - } - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, 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); - glBindTexture(GL_TEXTURE_2D, 0); - - pixmap = glamor_create_pixmap(screen, width, height, depth, - GLAMOR_CREATE_PIXMAP_NO_TEXTURE); - glamor_set_pixmap_texture(pixmap, texture); - glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); - wl_buffer_add_listener(xwl_pixmap->buffer, - &xwl_eglstream_buffer_release_listener, - pixmap); - xwl_pixmap_set_private(pixmap, xwl_pixmap); - - return pixmap; -} - -static const dri3_screen_info_rec xwl_dri3_info = { - .version = 2, - .open = NULL, - .pixmap_from_fds = xwl_dri3_pixmap_from_fds, - .fds_from_pixmap = NULL, - .open_client = xwl_dri3_open_client, - .get_formats = xwl_glamor_get_formats, - .get_modifiers = xwl_glamor_get_modifiers, - .get_drawable_modifiers = glamor_get_drawable_modifiers, -}; - -static Bool -xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen) -{ - struct xwl_eglstream_private *xwl_eglstream = - xwl_eglstream_get(xwl_screen); - EGLConfig config; - const EGLint attrib_list[] = { - 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_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, - EGL_NONE - }; - const EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_STREAM_BIT_KHR, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_NONE, - }; - int n; - - xwl_screen->egl_display = glamor_egl_get_display( - EGL_PLATFORM_DEVICE_EXT, xwl_eglstream->egl_device); - if (!xwl_screen->egl_display) - goto error; - - if (!eglInitialize(xwl_screen->egl_display, NULL, NULL)) { - xwl_screen->egl_display = NULL; - goto error; - } - - if (!epoxy_has_egl_extension(xwl_screen->egl_display, - "EGL_IMG_context_priority")) { - ErrorF("EGL_IMG_context_priority not available\n"); - goto error; - } - - eglChooseConfig(xwl_screen->egl_display, config_attribs, &config, 1, &n); - if (!n) { - ErrorF("No acceptable EGL configs found\n"); - goto error; - } - - xwl_eglstream->config = config; -#if 0 - xwl_screen->formats = - XWL_FORMAT_RGB565 | XWL_FORMAT_XRGB8888 | XWL_FORMAT_ARGB8888; -#endif - - eglBindAPI(EGL_OPENGL_API); - xwl_screen->egl_context = eglCreateContext( - xwl_screen->egl_display, config, EGL_NO_CONTEXT, attrib_list); - if (xwl_screen->egl_context == EGL_NO_CONTEXT) { - ErrorF("Failed to create main EGL context: 0x%x\n", eglGetError()); - goto error; - } - - if (!eglMakeCurrent(xwl_screen->egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - xwl_screen->egl_context)) { - ErrorF("Failed to make EGL context current\n"); - goto error; - } - - xwl_eglstream->have_egl_damage = - epoxy_has_egl_extension(xwl_screen->egl_display, - "EGL_KHR_swap_buffers_with_damage"); - if (!xwl_eglstream->have_egl_damage) - ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance " - "will be affected\n"); - -#ifdef EGL_NV_stream_flush - xwl_eglstream->have_egl_stream_flush = - epoxy_has_egl_extension(xwl_screen->egl_display, - "EGL_NV_stream_flush"); -#else - xwl_eglstream->have_egl_stream_flush = FALSE; -#endif /* EGL_NV_stream_flush */ - - if (!xwl_eglstream->have_egl_stream_flush) - ErrorF("EGL_NV_stream_flush not available, " - "this may cause visible corruption.\n"); - - xwl_eglstream_init_shaders(xwl_screen); - - if (epoxy_has_gl_extension("GL_OES_EGL_image")) { - if (dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) - xwl_screen->glvnd_vendor = "nvidia"; - else - ErrorF("DRI3 initialization failed. Performance will be affected.\n"); - } else { - ErrorF("Driver lacks GL_OES_EGL_image, performance will be affected.\n"); - } - - return TRUE; -error: - xwl_eglstream_cleanup(xwl_screen); - return FALSE; -} - -static Bool -xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen) -{ - ScreenPtr screen = xwl_screen->screen; - - /* We can just let glamor handle CreatePixmap */ - screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap; - - return TRUE; -} - -static EGLDeviceEXT -xwl_eglstream_get_device(struct xwl_screen *xwl_screen) -{ - void **devices = NULL; - const char *exts[] = { - "EGL_KHR_stream", - "EGL_KHR_stream_producer_eglsurface", - }; - int num_devices, i; - EGLDeviceEXT device = EGL_NO_DEVICE_EXT; - - /* No device specified by the user, so find one ourselves */ - devices = xwl_glamor_egl_get_devices(&num_devices); - if (!devices) - goto out; - - for (i = 0; i < num_devices; i++) { - if (xwl_glamor_egl_device_has_egl_extensions(devices[i], exts, - ARRAY_SIZE(exts))) { - device = devices[i]; - break; - } - } - - free(devices); -out: - if (!device) - ErrorF("glamor: No eglstream capable devices found\n"); - return device; -} - -void -xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) -{ - struct xwl_eglstream_private *xwl_eglstream; - EGLDeviceEXT egl_device; - - xwl_screen->eglstream_backend.is_available = FALSE; - egl_device = xwl_eglstream_get_device(xwl_screen); - if (egl_device == EGL_NO_DEVICE_EXT) - return; - - if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0)) - return; - - xwl_eglstream = calloc(1, sizeof(*xwl_eglstream)); - if (!xwl_eglstream) { - ErrorF("Failed to allocate memory required to init EGLStream support\n"); - return; - } - - dixSetPrivate(&xwl_screen->screen->devPrivates, - &xwl_eglstream_private_key, xwl_eglstream); - - xwl_eglstream->egl_device = egl_device; - - xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl; - xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry; - xwl_screen->eglstream_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces; - xwl_screen->eglstream_backend.init_screen = xwl_glamor_eglstream_init_screen; - xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap; - xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage; - xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits; - xwl_screen->eglstream_backend.check_flip = xwl_glamor_eglstream_check_flip; - xwl_screen->eglstream_backend.is_available = TRUE; - xwl_screen->eglstream_backend.backend_flags = XWL_EGL_BACKEND_NO_FLAG; -} diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c deleted file mode 100644 index 12d820e44..000000000 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ /dev/null @@ -1,974 +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 -#include -#include - -#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-pixmap.h" -#include "xwayland-screen.h" - -#include "linux-dmabuf-unstable-v1-client-protocol.h" - -struct xwl_gbm_private { - char *device_name; - struct gbm_device *gbm; - struct wl_drm *drm; - int drm_fd; - int fd_render_node; - Bool drm_authenticated; - uint32_t capabilities; - int dmabuf_capable; -}; - -struct xwl_pixmap { - struct wl_buffer *buffer; - EGLImage image; - unsigned int texture; - struct gbm_bo *bo; -}; - -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); -} - -static uint32_t -gbm_format_for_depth(int depth) -{ - switch (depth) { - case 16: - return GBM_FORMAT_RGB565; - case 24: - 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) -{ - PixmapPtr pixmap; - struct xwl_pixmap *xwl_pixmap; - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - - 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->image = eglCreateImageKHR(xwl_screen->egl_display, - xwl_screen->egl_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(ScreenPtr screen, - int width, int height, int depth, - unsigned int hint) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); - struct gbm_bo *bo; - PixmapPtr pixmap = 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); - -#ifdef GBM_BO_WITH_MODIFIERS - if (xwl_gbm->dmabuf_capable) { - uint32_t num_modifiers; - uint64_t *modifiers = NULL; - - xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers); - bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height, - format, modifiers, num_modifiers); - free(modifiers); - } - else -#endif - { - bo = gbm_bo_create(xwl_gbm->gbm, width, height, format, - GBM_BO_USE_RENDERING); - } - - if (bo) { - pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); - - 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(screen, width, height, depth, hint); - - return pixmap; -} - -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); - free(xwl_pixmap); - } - - return glamor_destroy_pixmap(pixmap); -} - -static const struct wl_buffer_listener xwl_glamor_gbm_buffer_listener = { - xwl_pixmap_buffer_release_cb, -}; - -static struct wl_buffer * -xwl_glamor_gbm_get_wl_buffer_for_pixmap(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 prime_fd; - int num_planes; - 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); - - prime_fd = gbm_bo_get_fd(xwl_pixmap->bo); - if (prime_fd == -1) - return NULL; - -#ifdef GBM_BO_WITH_MODIFIERS - 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++) { - strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i); - offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i); - } -#else - num_planes = 1; - modifier = DRM_FORMAT_MOD_INVALID; - strides[0] = gbm_bo_get_stride(xwl_pixmap->bo); - offsets[0] = 0; -#endif - - 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_fd, 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) { - xwl_pixmap->buffer = - wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fd, width, height, - format, - 0, gbm_bo_get_stride(xwl_pixmap->bo), - 0, 0, - 0, 0); - } - - close(prime_fd); - - /* Add our listener now */ - 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->device_name) - free(xwl_gbm->device_name); - 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); - - 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; - } -} - -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; -} - -_X_EXPORT 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; - - 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); - 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); - bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD, &data, - GBM_BO_USE_RENDERING); - } else { - goto error; - } - - if (bo == NULL) - goto error; - - pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); - if (pixmap == NULL) { - gbm_bo_destroy(bo); - goto error; - } - - return pixmap; - -error: - return NULL; -} - -_X_EXPORT 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 - 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++) { - fds[i] = gbm_bo_get_fd(xwl_pixmap->bo); - 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); - 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 - */ -_X_EXPORT int -glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, - CARD16 *stride, CARD32 *size) -{ - return -1; -} - -static const 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 = glamor_get_drawable_modifiers, -}; - -static const char * -get_render_node_path_for_device(const drmDevicePtr drm_device, - const char *device_path) -{ - char *render_node_path = NULL; - char device_found = 0; - int i; - - for (i = 0; i < DRM_NODE_MAX; i++) { - if ((drm_device->available_nodes & (1 << i)) == 0) - continue; - - if (!strcmp (device_path, drm_device->nodes[i])) - device_found = 1; - - if (is_device_path_render_node(drm_device->nodes[i])) - render_node_path = drm_device->nodes[i]; - - if (device_found && render_node_path) - 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); - 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); - return; - } - - if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) { - xwl_gbm->fd_render_node = 1; - 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; -} - -static Bool -xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen, - struct wl_registry *wl_registry, - uint32_t id, const char *name, - uint32_t version) -{ - if (strcmp(name, "wl_drm") == 0) { - xwl_screen_set_drm_interface(xwl_screen, id, version); - return TRUE; - } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) { - xwl_screen_set_dmabuf_interface(xwl_screen, id, version); - return TRUE; - } - - /* no match */ - return FALSE; -} - -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")); -} - -static Bool -xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen) -{ - struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); - - if (xwl_gbm->drm == NULL) { - ErrorF("glamor: 'wl_drm' not supported\n"); - return FALSE; - } - - return TRUE; -} - -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; - - eglBindAPI(EGL_OPENGL_API); - - xwl_screen->egl_context = - eglCreateContext(xwl_screen->egl_display, NULL, - EGL_NO_CONTEXT, config_attribs_core); - - if (xwl_screen->egl_context == EGL_NO_CONTEXT) - xwl_screen->egl_context = - eglCreateContext(xwl_screen->egl_display, NULL, - 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, - }; - - eglBindAPI(EGL_OPENGL_ES_API); - - xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, NULL, - 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_egl(struct xwl_screen *xwl_screen) -{ - struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); - EGLint major, minor; - const GLubyte *renderer; - - 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, "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; - - 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; -} - -static Bool -xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen) -{ - struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); - - if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) { - ErrorF("Failed to initialize dri3\n"); - goto error; - } - - 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; -} - -void -xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) -{ - struct xwl_gbm_private *xwl_gbm; - - xwl_screen->gbm_backend.is_available = FALSE; - - if (!xwl_glamor_gbm_has_egl_extension()) - return; - - if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0)) - return; - - xwl_gbm = calloc(sizeof(*xwl_gbm), 1); - if (!xwl_gbm) { - ErrorF("glamor: Not enough memory to setup GBM, disabling\n"); - return; - } - - dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key, - xwl_gbm); - - xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry; - xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces; - xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl; - xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen; - xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap; - xwl_screen->gbm_backend.check_flip = NULL; - xwl_screen->gbm_backend.is_available = TRUE; - xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH | - XWL_EGL_BACKEND_NEEDS_N_BUFFERING; -} diff --git a/hw/xwayland/xwayland-glamor-xv.c b/hw/xwayland/xwayland-glamor-xv.c deleted file mode 100644 index 23e7100e4..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 = xnfcalloc(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 = xnfcalloc(NUM_PORTS, sizeof(XvPortRec)); - xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates, - xwlXvScreenPrivateKey); - xwlXvScreen->port_privates = xnfcalloc(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 = xnfcalloc(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 = xnfcalloc(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 = xnfcalloc(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 = xnfcalloc(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 2729e8747..000000000 --- a/hw/xwayland/xwayland-glamor.c +++ /dev/null @@ -1,491 +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 -#ifdef GLXEXT -#include "glx_extinit.h" -#endif - -#include "linux-dmabuf-unstable-v1-client-protocol.h" -#include "drm-client-protocol.h" -#include - -#include "xwayland-glamor.h" -#include "xwayland-glx.h" -#include "xwayland-screen.h" -#include "xwayland-window.h" - -static void -glamor_egl_make_current(struct glamor_context *glamor_ctx) -{ - eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (!eglMakeCurrent(glamor_ctx->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - glamor_ctx->ctx)) - FatalError("Failed to make EGL context current\n"); -} - -void -xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen) -{ - if (lastGLContext == xwl_screen->glamor_ctx) - return; - - lastGLContext = xwl_screen->glamor_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_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(PixmapPtr pixmap) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); - - if (!xwl_glamor_pixmap_get_wl_buffer(pixmap)) - return FALSE; - - if (xwl_screen->egl_backend->check_flip) - return xwl_screen->egl_backend->check_flip(pixmap); - - return TRUE; -} - -Bool -xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen, - uint32_t format, uint64_t modifier) -{ - struct xwl_format *xwl_format = NULL; - int i; - - for (i = 0; i < xwl_screen->num_formats; i++) { - if (xwl_screen->formats[i].format == format) { - xwl_format = &xwl_screen->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; -} - -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; - } -} - -Bool -xwl_glamor_get_formats(ScreenPtr screen, - CARD32 *num_formats, CARD32 **formats) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - int i; - - /* Explicitly zero the count as the caller may ignore the return value */ - *num_formats = 0; - - if (!xwl_screen->dmabuf) - return FALSE; - - if (xwl_screen->num_formats == 0) - return TRUE; - - *formats = calloc(xwl_screen->num_formats, sizeof(CARD32)); - if (*formats == NULL) - return FALSE; - - for (i = 0; i < xwl_screen->num_formats; i++) - (*formats)[i] = xwl_screen->formats[i].format; - *num_formats = xwl_screen->num_formats; - - return TRUE; -} - -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); - struct xwl_format *xwl_format = NULL; - int i; - - /* Explicitly zero the count as the caller may ignore the return value */ - *num_modifiers = 0; - - if (!xwl_screen->dmabuf) - return FALSE; - - if (xwl_screen->num_formats == 0) - return TRUE; - - for (i = 0; i < xwl_screen->num_formats; i++) { - if (xwl_screen->formats[i].format == format) { - xwl_format = &xwl_screen->formats[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 void -xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, - uint32_t format) -{ -} - -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; - struct xwl_format *xwl_format = NULL; - int i; - - for (i = 0; i < xwl_screen->num_formats; i++) { - if (xwl_screen->formats[i].format == format) { - xwl_format = &xwl_screen->formats[i]; - break; - } - } - - if (xwl_format == NULL) { - xwl_screen->num_formats++; - xwl_screen->formats = realloc(xwl_screen->formats, - xwl_screen->num_formats * sizeof(*xwl_format)); - if (!xwl_screen->formats) - return; - xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1]; - xwl_format->format = format; - xwl_format->num_modifiers = 0; - xwl_format->modifiers = NULL; - } - - xwl_format->num_modifiers++; - xwl_format->modifiers = realloc(xwl_format->modifiers, - xwl_format->num_modifiers * sizeof(uint64_t)); - if (!xwl_format->modifiers) - return; - xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo; - xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32; -} - -static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = { - .format = xwl_dmabuf_handle_format, - .modifier = xwl_dmabuf_handle_modifier -}; - -Bool -xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, - uint32_t id, uint32_t version) -{ - if (version < 3) - return FALSE; - - xwl_screen->dmabuf = - wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3); - zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen); - - 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 (xwl_screen->gbm_backend.is_available && - xwl_screen->gbm_backend.init_wl_registry(xwl_screen, - registry, - id, - interface, - version)) { - /* no-op */ - } else if (xwl_screen->eglstream_backend.is_available && - xwl_screen->eglstream_backend.init_wl_registry(xwl_screen, - registry, - id, - interface, - version)) { - /* no-op */ - } -} - -Bool -xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen, - struct xwl_egl_backend *xwl_egl_backend) -{ - return xwl_egl_backend->has_wl_interfaces(xwl_screen); -} - -struct wl_buffer * -xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); - - if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap) - return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap); - - return NULL; -} - -Bool -xwl_glamor_post_damage(struct xwl_window *xwl_window, - PixmapPtr pixmap, RegionPtr region) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - - if (xwl_screen->egl_backend->post_damage) - return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region); - - return TRUE; -} - -Bool -xwl_glamor_allow_commits(struct xwl_window *xwl_window) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - - if (xwl_screen->egl_backend->allow_commits) - return xwl_screen->egl_backend->allow_commits(xwl_window); - else - 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; -} - -Bool -xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen) -{ - if (!xwl_screen->glamor || !xwl_screen->egl_backend) - return FALSE; - - return (xwl_screen->egl_backend->backend_flags & - XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH); -} - -Bool -xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen) -{ - /* wl_shm benefits from n-buffering */ - if (!xwl_screen->glamor || !xwl_screen->egl_backend) - return TRUE; - - return (xwl_screen->egl_backend->backend_flags & - XWL_EGL_BACKEND_NEEDS_N_BUFFERING); -} - -void -xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream) -{ -#ifdef GLAMOR_HAS_GBM - xwl_glamor_init_gbm(xwl_screen); - if (!xwl_screen->gbm_backend.is_available && !use_eglstream) - ErrorF("xwayland glamor: GBM backend (default) is not available\n"); -#endif -#ifdef XWL_HAS_EGLSTREAM - xwl_glamor_init_eglstream(xwl_screen); - if (!xwl_screen->eglstream_backend.is_available && use_eglstream) - ErrorF("xwayland glamor: EGLStream backend requested but not available\n"); -#endif -} - -static Bool -xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen) -{ -#ifdef GLAMOR_HAS_GBM - if (xwl_screen->gbm_backend.is_available && - xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) { - xwl_screen->egl_backend = &xwl_screen->gbm_backend; - return TRUE; - } - else - ErrorF("Missing Wayland requirements for glamor GBM backend\n"); -#endif - - return FALSE; -} - -static Bool -xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen) -{ -#ifdef XWL_HAS_EGLSTREAM - if (xwl_screen->eglstream_backend.is_available && - xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) { - xwl_screen->egl_backend = &xwl_screen->eglstream_backend; - return TRUE; - } - else - ErrorF("Missing Wayland requirements for glamor EGLStream backend\n"); -#endif - - return FALSE; -} - -void -xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream) -{ - if (use_eglstream) { - if (!xwl_glamor_select_eglstream_backend(xwl_screen)) - xwl_glamor_select_gbm_backend(xwl_screen); - } - else { - if (!xwl_glamor_select_gbm_backend(xwl_screen)) - xwl_glamor_select_eglstream_backend(xwl_screen); - } -} - -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_screen->egl_backend->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_screen->egl_backend->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 cf3c4fba3..000000000 --- a/hw/xwayland/xwayland-glamor.h +++ /dev/null @@ -1,158 +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 "xwayland-types.h" - -typedef enum _xwl_egl_backend_flags { - XWL_EGL_BACKEND_NO_FLAG = 0, - XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0), - XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1), -} xwl_egl_backend_flags; - -struct xwl_egl_backend { - /* Set by the backend if available */ - Bool is_available; - - /* Features and requirements set by the backend */ - xwl_egl_backend_flags backend_flags; - - /* Called once for each interface in the global registry. Backends - * should use this to bind to any wayland interfaces they need. - */ - Bool (*init_wl_registry)(struct xwl_screen *xwl_screen, - struct wl_registry *wl_registry, - uint32_t id, const char *name, - uint32_t version); - - /* Check that the required Wayland interfaces are available. - */ - Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen); - - /* Called before glamor has been initialized. Backends should setup a - * valid, glamor compatible EGL context in this hook. - */ - Bool (*init_egl)(struct xwl_screen *xwl_screen); - - /* Called after glamor has been initialized, and after all of the - * common Xwayland DDX hooks have been connected. Backends should use - * this to setup any required wraps around X server callbacks like - * CreatePixmap. - */ - Bool (*init_screen)(struct xwl_screen *xwl_screen); - - /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for - * the given window/pixmap combo so that damage to the pixmap may be - * displayed on-screen. Backends should use this to create a new - * wl_buffer for a currently buffer-less pixmap, or simply return the - * pixmap they've prepared beforehand. - */ - struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap); - - /* Called by Xwayland to perform any pre-wl_surface damage routines - * that are required by the backend. If your backend is poorly - * designed and lacks the ability to render directly to a surface, - * you should implement blitting from the glamor pixmap to the wayland - * pixmap here. Otherwise, this callback is optional. - */ - Bool (*post_damage)(struct xwl_window *xwl_window, - PixmapPtr pixmap, RegionPtr region); - - /* Called by Xwayland to confirm with the egl backend that the given - * pixmap is completely setup and ready for display on-screen. This - * callback is optional. - */ - Bool (*allow_commits)(struct xwl_window *xwl_window); - - /* Called by Xwayland to check whether the given pixmap can be - * presented by xwl_present_flip. If not implemented, assumed TRUE. - */ - Bool (*check_flip)(PixmapPtr pixmap); -}; - -#ifdef XWL_HAS_GLAMOR - -void xwl_glamor_init_backends(struct xwl_screen *xwl_screen, - Bool use_eglstream); -void xwl_glamor_select_backend(struct xwl_screen *xwl_screen, - Bool use_eglstream); -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_dmabuf_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); -Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen, - struct xwl_egl_backend *xwl_egl_backend); -Bool xwl_glamor_post_damage(struct xwl_window *xwl_window, - PixmapPtr pixmap, RegionPtr region); -Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window); -void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen); -Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen); -Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen); -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_check_flip(PixmapPtr pixmap); - -#ifdef XV -/* glamor Xv Adaptor */ -Bool xwl_glamor_xv_init(ScreenPtr pScreen); -#endif /* XV */ - -#endif /* XWL_HAS_GLAMOR */ - -#ifdef GLAMOR_HAS_GBM -void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); -#else -static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) -{ -} -#endif - -#ifdef XWL_HAS_EGLSTREAM -void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); -#else -static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) -{ -} -#endif - -#endif /* XWAYLAND_GLAMOR_H */ diff --git a/hw/xwayland/xwayland-glx.c b/hw/xwayland/xwayland-glx.c deleted file mode 100644 index eba8946ab..000000000 --- a/hw/xwayland/xwayland-glx.c +++ /dev/null @@ -1,397 +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: - * Adam Jackson - */ - -/* - * Sets up GLX capabilities based on the EGL capabilities of the glamor - * renderer for the screen. Without this you will get whatever swrast - * can do, which often does not include things like multisample visuals. - */ - -#include - -#define MESA_EGL_NO_X11_HEADERS -#define EGL_NO_X11 -// #include -#include -#include "glxserver.h" -#include "glxutil.h" -#include "compint.h" -#include -#include "glamor_context.h" -#include "glamor.h" - -#include "xwayland-screen.h" - -/* Can't get these from since it pulls in client headers */ -#define GLX_RGBA_BIT 0x00000001 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 -#define GLX_SWAP_UNDEFINED_OML 0x8063 - -struct egl_config { - __GLXconfig base; - EGLConfig config; -}; - -struct egl_screen { - __GLXscreen base; - EGLDisplay display; - EGLConfig *configs; -}; - -static void -egl_screen_destroy(__GLXscreen *_screen) -{ - struct egl_screen *screen = (struct egl_screen *)_screen; - - /* XXX do we leak the fbconfig list? */ - - free(screen->configs); - __glXScreenDestroy(_screen); - free(_screen); -} - -static void -egl_drawable_destroy(__GLXdrawable *draw) -{ - free(draw); -} - -static GLboolean -egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw) -{ - return GL_FALSE; -} - -static void -egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h) -{ -} - -static void -egl_drawable_wait_x(__GLXdrawable *draw) -{ - glamor_block_handler(draw->pDraw->pScreen); -} - -static void -egl_drawable_wait_gl(__GLXdrawable *draw) -{ -} - -static __GLXdrawable * -egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen, - DrawablePtr draw, XID drawid, int type, - XID glxdrawid, __GLXconfig *modes) -{ - __GLXdrawable *ret; - - ret = calloc(1, sizeof *ret); - if (!ret) - return NULL; - - if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) { - free(ret); - return NULL; - } - - ret->destroy = egl_drawable_destroy; - ret->swapBuffers = egl_drawable_swap_buffers; - ret->copySubBuffer = egl_drawable_copy_sub_buffer; - ret->waitX = egl_drawable_wait_x; - ret->waitGL = egl_drawable_wait_gl; - - return ret; -} - -/* - * TODO: - * - * - figure out sRGB - * - bindToTextureTargets is suspicious - * - better channel mask setup - * - drawable type masks is suspicious - */ -static struct egl_config * -translate_eglconfig(struct egl_screen *screen, EGLConfig hc, - struct egl_config *chain, Bool direct_color, - Bool double_buffer, Bool duplicate_for_composite) -{ - EGLint value; - struct egl_config *c = calloc(1, sizeof *c); - - if (!c) - return chain; - - /* constants. changing these requires (at least) new EGL extensions */ - c->base.stereoMode = GL_FALSE; - c->base.numAuxBuffers = 0; - c->base.level = 0; - c->base.transparentAlpha = 0; - c->base.transparentIndex = 0; - c->base.transparentPixel = GLX_NONE; - c->base.visualSelectGroup = 0; - c->base.indexBits = 0; - c->base.optimalPbufferWidth = 0; - c->base.optimalPbufferHeight = 0; - c->base.bindToMipmapTexture = 0; - c->base.bindToTextureTargets = GLX_DONT_CARE; - c->base.sRGBCapable = 0; - c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; - - /* this is... suspect */ - c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; - - /* hmm */ - c->base.bindToTextureRgb = GL_TRUE; - c->base.bindToTextureRgba = GL_TRUE; - - /* - * glx conformance failure: there's no such thing as accumulation - * buffers in EGL. they should be emulable with shaders and fbos, - * but i'm pretty sure nobody's using this feature since it's - * entirely software. note that glx conformance merely requires - * that an accum buffer _exist_, not a minimum bitness. - */ - c->base.accumRedBits = 0; - c->base.accumGreenBits = 0; - c->base.accumBlueBits = 0; - c->base.accumAlphaBits = 0; - - /* parametric state */ - if (direct_color) - c->base.visualType = GLX_DIRECT_COLOR; - else - c->base.visualType = GLX_TRUE_COLOR; - - if (double_buffer) - c->base.doubleBufferMode = GL_TRUE; - else - c->base.doubleBufferMode = GL_FALSE; - - /* direct-mapped state */ -#define GET(attr, slot) \ - eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot) - GET(EGL_RED_SIZE, redBits); - GET(EGL_GREEN_SIZE, greenBits); - GET(EGL_BLUE_SIZE, blueBits); - GET(EGL_ALPHA_SIZE, alphaBits); - GET(EGL_BUFFER_SIZE, rgbBits); - GET(EGL_DEPTH_SIZE, depthBits); - GET(EGL_STENCIL_SIZE, stencilBits); - GET(EGL_TRANSPARENT_RED_VALUE, transparentRed); - GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen); - GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue); - GET(EGL_SAMPLE_BUFFERS, sampleBuffers); - GET(EGL_SAMPLES, samples); - if (c->base.renderType & GLX_PBUFFER_BIT) { - GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth); - GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight); - GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels); - } -#undef GET - - /* derived state: config caveats */ - eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value); - if (value == EGL_NONE) - c->base.visualRating = GLX_NONE; - else if (value == EGL_SLOW_CONFIG) - c->base.visualRating = GLX_SLOW_CONFIG; - else if (value == EGL_NON_CONFORMANT_CONFIG) - c->base.visualRating = GLX_NON_CONFORMANT_CONFIG; - /* else panic */ - - /* derived state: float configs */ - c->base.renderType = GLX_RGBA_BIT; - if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT, - &value) == EGL_TRUE) { - if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) { - c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB; - } - /* else panic */ - } - - /* map to the backend's config */ - c->config = hc; - - /* - * XXX do something less ugly - */ - if (c->base.renderType == GLX_RGBA_BIT) { - if (c->base.redBits == 5 && - (c->base.rgbBits == 15 || c->base.rgbBits == 16)) { - c->base.blueMask = 0x0000001f; - if (c->base.alphaBits) { - c->base.greenMask = 0x000003e0; - c->base.redMask = 0x00007c00; - c->base.alphaMask = 0x00008000; - } else { - c->base.greenMask = 0x000007e0; - c->base.redMask = 0x0000f800; - c->base.alphaMask = 0x00000000; - } - } - else if (c->base.redBits == 8 && - (c->base.rgbBits == 24 || c->base.rgbBits == 32)) { - c->base.blueMask = 0x000000ff; - c->base.greenMask = 0x0000ff00; - c->base.redMask = 0x00ff0000; - if (c->base.alphaBits) - /* assume all remaining bits are alpha */ - c->base.alphaMask = 0xff000000; - } - else if (c->base.redBits == 10 && - (c->base.rgbBits == 30 || c->base.rgbBits == 32)) { - c->base.blueMask = 0x000003ff; - c->base.greenMask = 0x000ffc00; - c->base.redMask = 0x3ff00000; - if (c->base.alphaBits) - /* assume all remaining bits are alpha */ - c->base.alphaMask = 0xc000000; - } - } - - /* - * Here we decide which fbconfigs will be duplicated for compositing. - * fgbconfigs marked with duplicatedForComp will be reserved for - * compositing visuals. - * It might look strange to do this decision this late when translation - * from an EGLConfig is already done, but using the EGLConfig - * accessor functions becomes worse both with respect to code complexity - * and CPU usage. - */ - if (duplicate_for_composite && - (c->base.renderType == GLX_RGBA_FLOAT_BIT_ARB || - c->base.rgbBits != 32 || - c->base.redBits != 8 || - c->base.greenBits != 8 || - c->base.blueBits != 8 || - c->base.visualRating != GLX_NONE || - c->base.sampleBuffers != 0)) { - free(c); - return chain; - } - c->base.duplicatedForComp = duplicate_for_composite; - - c->base.next = chain ? &chain->base : NULL; - return c; -} - -static __GLXconfig * -egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen) -{ - int i, j, k, nconfigs; - struct egl_config *c = NULL; - EGLConfig *host_configs = NULL; - - eglGetConfigs(screen->display, NULL, 0, &nconfigs); - if (!(host_configs = calloc(nconfigs, sizeof *host_configs))) - return NULL; - - eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs); - - /* We walk the EGL configs backwards to make building the - * ->next chain easier. - */ - for (i = nconfigs - 1; i > 0; i--) - for (j = 0; j < 3; j++) /* direct_color */ - for (k = 0; k < 2; k++) /* double_buffer */ - c = translate_eglconfig(screen, host_configs[i], c, - /* direct_color */ j == 1, - /* double_buffer */ k > 0, - /* duplicate_for_composite */ j == 0); - - screen->configs = host_configs; - return c ? &c->base : NULL; -} - -static __GLXscreen * -egl_screen_probe(ScreenPtr pScreen) -{ - struct egl_screen *screen; - struct xwl_screen *xwl_screen = xwl_screen_get(pScreen); - __GLXscreen *base; - - if (enableIndirectGLX) - return NULL; /* not implemented */ - - if (!(screen = calloc(1, sizeof *screen))) - return NULL; - - base = &screen->base; - base->destroy = egl_screen_destroy; - base->createDrawable = egl_create_glx_drawable; - /* base.swapInterval = NULL; */ - - screen->display = xwl_screen->glamor_ctx->display; - - __glXInitExtensionEnableBits(screen->base.glx_enable_bits); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control"); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context"); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error"); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile"); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness"); - __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context"); - __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); - __glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); - // __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control"); - - base->fbconfigs = egl_mirror_configs(pScreen, screen); - if (!base->fbconfigs) { - free(screen); - return NULL; - } - - if (!screen->base.glvnd && xwl_screen->glvnd_vendor) - screen->base.glvnd = strdup(xwl_screen->glvnd_vendor); - - if (!screen->base.glvnd) - screen->base.glvnd = strdup("mesa"); - - __glXScreenInit(base, pScreen); - __glXsetGetProcAddress(eglGetProcAddress); - - return base; -} - -__GLXprovider glamor_provider = { - egl_screen_probe, - "glamor", - NULL -}; diff --git a/hw/xwayland/xwayland-glx.h b/hw/xwayland/xwayland-glx.h deleted file mode 100644 index 62c9fb7ce..000000000 --- a/hw/xwayland/xwayland-glx.h +++ /dev/null @@ -1,37 +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: - * Adam Jackson - */ - -#ifndef XWAYLAND_GLX_H -#define XWAYLAND_GLX_H - -#include - -#ifdef GLXEXT -#include "glx_extinit.h" -extern __GLXprovider glamor_provider; -#endif - -#endif /* XWAYLAND_GLX_H */ diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c deleted file mode 100644 index 26b3630c7..000000000 --- a/hw/xwayland/xwayland-input.c +++ /dev/null @@ -1,3058 +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 "xwayland-cursor.h" -#include "xwayland-input.h" -#include "xwayland-window.h" -#include "xwayland-screen.h" - -#include "pointer-constraints-unstable-v1-client-protocol.h" -#include "relative-pointer-unstable-v1-client-protocol.h" -#include "tablet-unstable-v2-client-protocol.h" -#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h" - -struct axis_discrete_pending { - struct xorg_list l; - uint32_t axis; - int32_t discrete; -}; - -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 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[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL); - axes_labels[3] = 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, 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 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 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; - DeviceIntPtr dev = get_pointer_device(xwl_seat); - DeviceIntPtr master; - int i; - int sx = wl_fixed_to_int(sx_w); - int sy = wl_fixed_to_int(sy_w); - int dx, dy; - ScreenPtr pScreen = xwl_seat->xwl_screen->screen; - ValuatorMask mask; - - /* 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; - - 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->window->drawable.x; - dy = xwl_seat->focus_window->window->drawable.y; - - /* We just entered a new xwindow, forget about the old last xwindow */ - xwl_seat->last_xwindow = NullWindow; - - master = GetMaster(dev, POINTER_OR_FLOAT); - (*pScreen->SetCursorPosition) (dev, pScreen, dx + sx, dy + sy, TRUE); - - miPointerInvalidateSprite(master); - - CheckMotion(NULL, 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_seat->cursor.frame_cb) { - wl_callback_destroy(xwl_seat->cursor.frame_cb); - xwl_seat->cursor.frame_cb = NULL; - 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); - } -} - -static void -pointer_handle_leave(void *data, struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface) -{ - struct xwl_seat *xwl_seat = data; - DeviceIntPtr dev = get_pointer_device(xwl_seat); - - xwl_seat->xwl_screen->serial = serial; - - /* 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_xwindow = xwl_seat->focus_window->window; - xwl_seat->focus_window = NULL; - CheckMotion(NULL, GetMaster(dev, POINTER_OR_FLOAT)); - } -} - -static void -dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat) -{ - 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; - - 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) -{ - 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->window->drawable.x; - int drawable_y = xwl_seat->focus_window->window->drawable.y; - int x; - int y; - - if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) { - event_x *= xwl_seat->focus_window->scale_x; - event_y *= xwl_seat->focus_window->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) -{ - 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; - - 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_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); - } - - xwl_seat->pending_pointer_event.has_absolute = FALSE; - xwl_seat->pending_pointer_event.has_relative = 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; - int index; - const int divisor = 10; - ValuatorMask mask; - struct axis_discrete_pending *pending = NULL; - struct axis_discrete_pending *iter; - - switch (axis) { - case WL_POINTER_AXIS_VERTICAL_SCROLL: - index = 3; - break; - case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - index = 2; - break; - default: - return; - } - - xorg_list_for_each_entry(iter, &xwl_seat->axis_discrete_pending, l) { - if (iter->axis == axis) { - pending = iter; - break; - } - } - - valuator_mask_zero(&mask); - - if (pending) { - valuator_mask_set(&mask, index, pending->discrete); - xorg_list_del(&pending->l); - free(pending); - } else { - valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor); - } - - QueuePointerEvents(get_pointer_device(xwl_seat), - MotionNotify, 0, POINTER_RELATIVE, &mask); -} - -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) -{ -} - -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; - - struct axis_discrete_pending *pending = malloc(sizeof *pending); - if (!pending) - return; - - pending->axis = axis; - pending->discrete = discrete; - - xorg_list_add(&pending->l, &xwl_seat->axis_discrete_pending); -} - -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, -}; - -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 -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); -} - -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; - DeviceIntPtr master; - XkbDescPtr xkb; - XkbChangesRec changes = { 0 }; - - 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_SHARED, 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); - - if (xwl_seat->keyboard->key) - /* Keep the current controls */ - XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc); - - XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb); - - master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); - if (master) - XkbDeviceApplyKeymap(master, xkb); - - 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; - - xwl_seat->xwl_screen->serial = serial; - xwl_seat->keyboard_focus = surface; - - wl_array_copy(&xwl_seat->keys, keys); - wl_array_for_each(k, &xwl_seat->keys) - QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8); -} - -static void -keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, - uint32_t serial, struct wl_surface *surface) -{ - struct xwl_seat *xwl_seat = data; - uint32_t *k; - - xwl_seat->xwl_screen->serial = serial; - - wl_array_for_each(k, &xwl_seat->keys) - QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8); - - xwl_seat->keyboard_focus = NULL; -} - -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->locked_group = group & XkbAllGroupsMask; - new_state->base_mods = mods_depressed & XkbAllModifiersMask; - new_state->locked_mods = mods_locked & XkbAllModifiersMask; - XkbLatchModifiers(dev, XkbAllModifiersMask, - mods_latched & 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->window->drawable.x; - dy = xwl_touch->window->window->drawable.y; - - x = (dx + xwl_touch->x) * 0xFFFF / xwl_seat->xwl_screen->width; - y = (dy + xwl_touch->y) * 0xFFFF / xwl_seat->xwl_screen->height; - - 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_touch *xwl_touch; - - if (surface == NULL) - 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_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_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_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; - - /* Pick the first realized toplevel we find */ - if (*toplevel == NullWindow && window->realized && xwl_window_is_toplevel(window)) - *toplevel = window; -} - -static WindowPtr -xwl_keyboard_search_window(ClientPtr client) -{ - WindowPtr window = NullWindow; - - FindClientResourcesByType(client, RT_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; - - 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) -{ - 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); - } - - 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 -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_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); - } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->wl_pointer) { - release_pointer(xwl_seat); - release_relative_pointer(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); - } - - 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_cursor_release(struct xwl_cursor *xwl_cursor) -{ - wl_surface_destroy(xwl_cursor->surface); - if (xwl_cursor->frame_cb) - wl_callback_destroy(xwl_cursor->frame_cb); -} - -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; - - 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, 5)); - xwl_seat->id = id; - - 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->axis_discrete_pending); - 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; - struct axis_discrete_pending *ad, *ad_next; - - 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); - } - - xorg_list_for_each_entry_safe(ad, ad_next, &xwl_seat->axis_discrete_pending, l) { - xorg_list_del(&ad->l); - free(ad); - } - - 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; - - xwl_tablet_tool->proximity_in_serial = serial; - xwl_seat->tablet_focus_window = wl_surface_get_user_data(wl_surface); - - 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; - ValuatorMask mask; - - xwl_seat->xwl_screen->serial = serial; - - valuator_mask_zero(&mask); - QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask); -} - -static void -tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool) -{ - struct xwl_tablet_tool *xwl_tablet_tool = data; - ValuatorMask mask; - - valuator_mask_zero(&mask); - QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask); -} - -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; - 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; - - dx = xwl_seat->tablet_focus_window->window->drawable.x; - dy = xwl_seat->tablet_focus_window->window->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; - - 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); -} - -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_now; - 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 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); - - diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now; - released = diff & ~xwl_tablet_tool->buttons_now; - pressed = diff & xwl_tablet_tool->buttons_now; - - 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->buttons_prev = xwl_tablet_tool->buttons_now; - - 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 (pad == 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(sizeof *xwl_tablet, 1); - 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(sizeof *xwl_tablet_tool, 1); - 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(sizeof *xwl_tablet_pad, 1); - 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_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 -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") == 0 && version >= 3) { - create_input_device(xwl_screen, id, version); - xwl_screen->expecting_event++; - } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { - init_relative_pointer_manager(xwl_screen, id, version); - } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { - init_pointer_constraints(xwl_screen, id, version); - } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) { - init_tablet_manager(xwl_screen, id, version); - } else if (strcmp(interface, "zwp_xwayland_keyboard_grab_manager_v1") == 0) { - init_keyboard_grab(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) -{ -} - -static Bool -sprite_check_lost_focus(SpritePtr sprite, WindowPtr window) -{ - DeviceIntPtr device, master; - struct xwl_seat *xwl_seat; - - 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; - - master = GetMaster(device, POINTER_OR_FLOAT); - if (!master || !master->lastSlave) - return FALSE; - - /* 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 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_xwindow != NullWindow && - IsParent(xwl_seat->last_xwindow, window)) - return TRUE; - - return FALSE; -} - -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, WindowPtr 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->window == 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; - WindowPtr window; - int sx, sy; - - if (!warp_emulator->locked_pointer) - return; - - if (!warp_emulator->xwl_seat->focus_window) - return; - - window = warp_emulator->xwl_seat->focus_window->window; - if (x >= window->drawable.x || - y >= window->drawable.y || - x < (window->drawable.x + window->drawable.width) || - y < (window->drawable.y + window->drawable.height)) { - sx = x - window->drawable.x; - sy = y - window->drawable.y; - zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer, - wl_fixed_from_int(sx), - wl_fixed_from_int(sy)); - wl_surface_commit(warp_emulator->xwl_seat->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->window) - 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->window; - 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) -{ - /* 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_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(); - - 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); -} - -void -CloseInput(void) -{ - mieqFini(); -} diff --git a/hw/xwayland/xwayland-input.h b/hw/xwayland/xwayland-input.h deleted file mode 100644 index 0c6591b5e..000000000 --- a/hw/xwayland/xwayland-input.h +++ /dev/null @@ -1,197 +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 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 wl_keyboard *wl_keyboard; - struct wl_touch *wl_touch; - struct zwp_tablet_seat_v2 *tablet_seat; - struct wl_array keys; - struct xwl_window *focus_window; - struct xwl_window *tablet_focus_window; - uint32_t id; - uint32_t pointer_enter_serial; - struct xorg_list link; - CursorPtr x_cursor; - OsTimerPtr x_cursor_timer; - CursorPtr pending_x_cursor; - struct xwl_cursor cursor; - WindowPtr last_xwindow; - - struct xorg_list touches; - - size_t keymap_size; - char *keymap; - struct wl_surface *keyboard_focus; - - struct xorg_list axis_discrete_pending; - 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; - } pending_pointer_event; - - struct xorg_list tablets; - struct xorg_list tablet_tools; - struct xorg_list tablet_pads; - struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab; -}; - -struct xwl_tablet { - struct xorg_list link; - struct zwp_tablet_v2 *tablet; - struct xwl_seat *seat; -}; - -struct xwl_tablet_tool { - struct xorg_list link; - struct zwp_tablet_tool_v2 *tool; - struct xwl_seat *seat; - - DeviceIntPtr xdevice; - uint32_t proximity_in_serial; - double x; - double y; - uint32_t pressure; - double tilt_x; - double tilt_y; - double rotation; - double slider; - - uint32_t buttons_now, - buttons_prev; - - int32_t wheel_clicks; - - struct xwl_cursor cursor; -}; - -struct xwl_tablet_pad_ring { - unsigned int index; - struct xorg_list link; - struct xwl_tablet_pad_group *group; - struct zwp_tablet_pad_ring_v2 *ring; -}; - -struct xwl_tablet_pad_strip { - unsigned int index; - struct xorg_list link; - struct xwl_tablet_pad_group *group; - struct zwp_tablet_pad_strip_v2 *strip; -}; - -struct xwl_tablet_pad_group { - struct xorg_list link; - struct xwl_tablet_pad *pad; - struct zwp_tablet_pad_group_v2 *group; - - struct xorg_list pad_group_ring_list; - struct xorg_list pad_group_strip_list; -}; - -struct xwl_tablet_pad { - struct xorg_list link; - struct zwp_tablet_pad_v2 *pad; - struct xwl_seat *seat; - - DeviceIntPtr xdevice; - - unsigned int nbuttons; - struct xorg_list pad_group_list; -}; - -void xwl_seat_destroy(struct xwl_seat *xwl_seat); - -void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr 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 ef705bc01..000000000 --- a/hw/xwayland/xwayland-output.c +++ /dev/null @@ -1,881 +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 "xwayland-cvt.h" -#include "xwayland-output.h" -#include "xwayland-screen.h" -#include "xwayland-window.h" - -#include "xdg-output-unstable-v1-client-protocol.h" - -#define ALL_ROTATIONS (RR_Rotate_0 | \ - RR_Rotate_90 | \ - RR_Rotate_180 | \ - RR_Rotate_270 | \ - RR_Reflect_X | \ - RR_Reflect_Y) - -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; - - 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->x = x; - xwl_output->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->width = width; - xwl_output->height = height; - } - xwl_output->refresh = refresh; -} - -/** - * 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 output_width, output_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))) { - output_width = xwl_output->width; - output_height = xwl_output->height; - } else { - output_width = xwl_output->height; - output_height = xwl_output->width; - } - - if (*width < xwl_output->x + output_width) - *width = xwl_output->x + output_width; - - if (*height < xwl_output->y + output_height) - *height = xwl_output->y + output_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_output *xwl_output, int width, int height) -{ - struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - - 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->width = width; - xwl_screen->height = 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; - - 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->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] = { - /* 4:3 (1.33) */ - { 2048, 1536 }, - { 1920, 1440 }, - { 1600, 1200 }, - { 1440, 1080 }, - { 1400, 1050 }, - { 1280, 1024 }, /* 5:4 (1.25) */ - { 1280, 960 }, - { 1152, 864 }, - { 1024, 768 }, - { 800, 600 }, - { 640, 480 }, - { 320, 240 }, - /* 16:10 (1.6) */ - { 2560, 1600 }, - { 1920, 1200 }, - { 1680, 1050 }, - { 1440, 900 }, - { 1280, 800 }, - { 720, 480 }, /* 3:2 (1.5) */ - { 640, 400 }, - { 320, 200 }, - /* 16:9 (1.77) */ - { 5120, 2880 }, - { 4096, 2304 }, - { 3840, 2160 }, - { 3200, 1800 }, - { 2880, 1620 }, - { 2560, 1440 }, - { 2048, 1152 }, - { 1920, 1080 }, - { 1600, 900 }, - { 1368, 768 }, - { 1280, 720 }, - { 1024, 576 }, - { 864, 486 }, - { 720, 400 }, - { 640, 350 }, -}; - -/* 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) -{ - struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - RRModePtr *rr_modes; - int i; - - rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr)); - if (!rr_modes) - goto err; - - /* Add actual output mode */ - rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0); - if (!rr_modes[0]) - goto err; - - *count = 1; - - if (!xwl_screen_has_resolution_change_emulation(xwl_screen)) - return rr_modes; - - /* Add fake modes */ - for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) { - /* Skip actual output mode, already added */ - if (xwl_output_fake_modes[i][0] == width && - xwl_output_fake_modes[i][1] == height) - continue; - - /* Skip modes which are too big, avoid downscaling */ - if (xwl_output_fake_modes[i][0] > width || - xwl_output_fake_modes[i][1] > 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, which is idx 0 */ - if (width == -1 && height == -1 && output->modes) - 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->x; - prop->rects[index][1] = xwl_output->y; - prop->rects[index][2] = emulated_mode->width; - prop->rects[index][3] = emulated_mode->height; - 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, RT_WINDOW, - xwl_output_set_randr_emu_prop_callback, &prop); -} - -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) -{ - DebugF("XWAYLAND: xwl_output_set_emulated_mode from %s: %dx%d\n", - from_vidmode ? "vidmode" : "randr", - mode->mode.width, mode->mode.height); - - /* modes[0] is the actual (not-emulated) output mode */ - if (mode == xwl_output->randr_output->modes[0]) - 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); -} - -static void -apply_output_change(struct xwl_output *xwl_output) -{ - struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - struct xwl_output *it; - int mode_width, mode_height, count; - int width = 0, height = 0, has_this_output = 0; - RRModePtr *randr_modes; - - /* Clear out the "done" received flags */ - xwl_output->wl_output_done = FALSE; - xwl_output->xdg_output_done = FALSE; - - /* When we have received an xdg-output for the mode size we might need to - * rotate back the stored logical size it provided. - */ - if (xwl_output->xdg_output == NULL - || xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) { - mode_width = xwl_output->width; - mode_height = xwl_output->height; - } else { - mode_width = xwl_output->height; - mode_height = xwl_output->width; - } - - /* Build a fresh modes array using the current refresh rate */ - randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count); - RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); - RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], - xwl_output->x, xwl_output->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); - - 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, &width, &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, &width, &height); - - --xwl_screen->expecting_event; - } - - update_screen_size(xwl_output, width, height); -} - -static void -output_handle_done(void *data, struct wl_output *wl_output) -{ - struct xwl_output *xwl_output = data; - - xwl_output->wl_output_done = TRUE; - /* 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) -{ -} - -static const struct wl_output_listener output_listener = { - output_handle_geometry, - output_handle_mode, - output_handle_done, - output_handle_scale -}; - -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->x = x; - xwl_output->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->width = width; - xwl_output->height = height; -} - -static void -xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) -{ - struct xwl_output *xwl_output = data; - - xwl_output->xdg_output_done = TRUE; - 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) -{ -} - -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, -}; - -struct xwl_output * -xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) -{ - struct xwl_output *xwl_output; - static int serial; - char name[256]; - - 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, 2); - 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); - - snprintf(name, sizeof name, "XWAYLAND%d", serial++); - - 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); - - xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name, - strlen(name), xwl_output); - 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); - RRTellChanged(xwl_screen->screen); - - /* 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); - --xwl_screen->expecting_event; - - 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->xdg_output) - zxdg_output_v1_destroy(xwl_output->xdg_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; - int width = 0, height = 0; - - xorg_list_del(&xwl_output->link); - - xorg_list_for_each_entry(it, &xwl_screen->output_list, link) - output_get_new_size(it, &width, &height); - update_screen_size(xwl_output, width, height); - - RRCrtcDestroy(xwl_output->randr_crtc); - 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 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) -{ - 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; - - 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->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 - - return TRUE; -} - -static void -xwl_output_get_xdg_output(struct xwl_output *xwl_output) -{ - struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - - 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 02b983108..000000000 --- a/hw/xwayland/xwayland-output.h +++ /dev/null @@ -1,82 +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" - -struct xwl_output { - struct xorg_list link; - struct wl_output *output; - struct zxdg_output_v1 *xdg_output; - uint32_t server_output_id; - struct xwl_screen *xwl_screen; - RROutputPtr randr_output; - RRCrtcPtr randr_crtc; - int32_t x, y, width, height, refresh; - Rotation rotation; - Bool wl_output_done; - Bool xdg_output_done; -}; - -/* Per client per output emulated randr/vidmode resolution info. */ -struct xwl_emulated_mode { - uint32_t server_output_id; - int32_t width; - int32_t height; - Bool from_vidmode; -}; - -Bool xwl_screen_init_output(struct xwl_screen *xwl_screen); - -struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen, - uint32_t id); - -void xwl_output_destroy(struct xwl_output *xwl_output); - -void xwl_output_remove(struct xwl_output *xwl_output); - -struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client( - struct xwl_output *xwl_output, ClientPtr client); - -RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output, - int32_t width, int32_t height); -void xwl_output_set_emulated_mode(struct xwl_output *xwl_output, - ClientPtr client, RRModePtr mode, - Bool from_vidmode); -void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen, - WindowPtr window); - -void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); - -#endif /* XWAYLAND_OUTPUT_H */ diff --git a/hw/xwayland/xwayland-pixmap.c b/hw/xwayland/xwayland-pixmap.c deleted file mode 100644 index 6e797a34c..000000000 --- a/hw/xwayland/xwayland-pixmap.c +++ /dev/null @@ -1,123 +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" - -#include "xwayland-types.h" -#include "xwayland-pixmap.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); -} - -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 06ee4898a..000000000 --- a/hw/xwayland/xwayland-pixmap.h +++ /dev/null @@ -1,47 +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); -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); - -#endif /* XWAYLAND_PIXMAP_H */ diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c deleted file mode 100644 index c9cf8c2f5..000000000 --- a/hw/xwayland/xwayland-present.c +++ /dev/null @@ -1,965 +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 -#include - -#include "xwayland-present.h" -#include "xwayland-screen.h" -#include "xwayland-window.h" -#include "xwayland-pixmap.h" -#include "glamor.h" - - -#define XWL_PRESENT_CAPS PresentCapabilityAsync - - -/* - * 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->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); - - 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(uint64_t event_id) -{ - return (struct xwl_present_event*)(uintptr_t)event_id; -} - -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; -} - -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); -} - -static void -xwl_present_reset_timer(struct xwl_present_window *xwl_present_window) -{ - if (xwl_present_has_pending_events(xwl_present_window)) { - CARD32 timeout; - - if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list)) - timeout = TIMER_LEN_FLIP; - else - timeout = TIMER_LEN_COPY; - - 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 uint32_t -xwl_present_query_capabilities(present_screen_priv_ptr screen_priv) -{ - return XWL_PRESENT_CAPS; -} - -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; -} - -/* - * 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) -{ - uint64_t ust = 0, crtc_msc = 0; - - (void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc); - 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) -{ - present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); - xwl_present_free_event(xwl_present_event_from_id((uintptr_t)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) { - xwl_present_free_idle_vblank(xwl_present_window->flip_active); - 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; - struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); - - 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_id((uintptr_t)xwl_present_window->flip_active); - - if (!event->pixmap) - 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; - - present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, 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; - } - - /* 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); - - /* 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; - 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(); - - 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(event_id); - - event->vblank.exec_msc = msc; - - xorg_list_del(&event->vblank.event_queue); - xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list); - - /* If there's a pending frame callback, use that */ - if (xwl_window && xwl_window->frame_callback && - 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) -{ - glamor_block_handler(window->drawable.pScreen); -} - -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; - - if (reason) - *reason = PRESENT_FLIP_REASON_UNKNOWN; - - if (!xwl_window) - return FALSE; - - 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 window */ - if (present_window->drawable.width != pixmap->drawable.width || - present_window->drawable.height != pixmap->drawable.height) - 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; - - if (!xwl_glamor_check_flip(pixmap)) - 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->window) != screen->GetWindowPixmap(present_window)) - 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->window->winSize, &present_window->winSize)) - return FALSE; - - 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(WindowPtr present_window, - RRCrtcPtr crtc, - uint64_t event_id, - PixmapPtr pixmap, - Bool sync_flip, - RegionPtr damage) -{ - 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_id(event_id); - - if (!xwl_window) - return FALSE; - - buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap); - if (!buffer) { - ErrorF("present: Error getting buffer\n"); - return FALSE; - } - - damage_box = RegionExtents(damage); - - pixmap->refcnt++; - - event->pixmap = pixmap; - - xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event); - - /* We can flip directly to the main surface (full screen window without clips) */ - wl_surface_attach(xwl_window->surface, buffer, 0, 0); - - if (!xwl_window->frame_callback) - xwl_window_create_frame_callback(xwl_window); - - 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); - } - - /* Realign timer */ - xwl_present_reset_timer(xwl_present_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); - - wl_surface_commit(xwl_window->surface); - - if (!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); - xwl_window->present_flipped = TRUE; - return TRUE; -} - -/* - * 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); - - xorg_list_del(&vblank->event_queue); - - if (present_execute_wait(vblank, crtc_msc)) - return; - - if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) { - DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n", - vblank->event_id, vblank, flip_pending)); - xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue); - vblank->flip_ready = TRUE; - return; - } - - vblank->queued = FALSE; - - if (vblank->pixmap && vblank->window) { - ScreenPtr screen = window->drawable.pScreen; - - 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->window, vblank->crtc, vblank->event_id, - vblank->pixmap, vblank->sync_flip, damage)) { - WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->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); - vblank->pixmap->refcnt++; - dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id); - - /* Report damage */ - DamageDamageRegion(&vblank->window->drawable, damage); - RegionDestroy(damage); - - /* Put pending flip at the flip queue head */ - xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue); - return; - } - - vblank->flip = FALSE; - } - 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); - - if (xwl_present_queue_vblank(screen, window, vblank->crtc, - vblank->event_id, crtc_msc + 1) - == Success) { - /* Clear the pixmap field, so this will fall through to present_execute_post next time */ - dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id); - vblank->pixmap = NULL; - 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, - uint32_t options, - uint64_t target_window_msc, - uint64_t divisor, - uint64_t remainder, - present_notify_ptr notifies, - int num_notifies) -{ - uint64_t ust = 0; - uint64_t target_msc; - uint64_t crtc_msc = 0; - int ret; - present_vblank_ptr vblank, tmp; - 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_present_event *event; - - if (!window_priv) - return BadAlloc; - - 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); - - /* - * Look for a matching presentation already on the list... - */ - - if (!update && pixmap) { - xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) { - - if (!vblank->pixmap) - continue; - - if (!vblank->queued) - continue; - - if (vblank->target_msc != target_msc) - continue; - - present_vblank_scrap(vblank); - if (vblank->flip_ready) - xwl_present_re_execute(vblank); - } - } - - 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, options, XWL_PRESENT_CAPS, - notifies, num_notifies, target_msc, crtc_msc)) { - present_vblank_destroy(vblank); - return BadAlloc; - } - - vblank->event_id = (uintptr_t)event; - - /* Xwayland presentations always complete (at least) one frame after they - * are executed - */ - vblank->exec_msc = vblank->target_msc - 1; - - 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); - xwl_present_reset_timer(xwl_present_window); -} - -Bool -xwl_present_init(ScreenPtr screen) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - present_screen_priv_ptr screen_priv; - - if (!xwl_screen->glamor || !xwl_screen->egl_backend) - return FALSE; - - 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; - - 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->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 d3eff73f4..000000000 --- a/hw/xwayland/xwayland-present.h +++ /dev/null @@ -1,67 +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" - -#ifdef GLAMOR_HAS_GBM -struct xwl_present_window { - struct xorg_list frame_callback_list; - - uint64_t msc; - uint64_t ust; - - OsTimerPtr frame_timer; - - struct wl_callback *sync_callback; - - struct xorg_list wait_list; - struct xorg_list flip_queue; - struct xorg_list idle_queue; - - present_vblank_ptr flip_active; -}; - -struct xwl_present_event { - present_vblank_rec vblank; - - PixmapPtr pixmap; -}; - -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); - -#endif /* GLAMOR_HAS_GBM */ - -#endif /* XWAYLAND_PRESENT_H */ diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c deleted file mode 100644 index bb18e5c94..000000000 --- a/hw/xwayland/xwayland-screen.c +++ /dev/null @@ -1,751 +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 - -#ifdef XWL_HAS_GLAMOR -#include -#endif - -#include -#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 MITSHM -#include "shmint.h" -#endif - -#include "xdg-output-unstable-v1-client-protocol.h" -#include "viewporter-client-protocol.h" -#include "xdg-shell-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->x == 0 && xwl_output->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); -} - -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); -} - -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; - - DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen); - - xorg_list_for_each_entry_safe(xwl_output, next_xwl_output, - &xwl_screen->output_list, link) - xwl_output_destroy(xwl_output); - - xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat, - &xwl_screen->seat_list, link) - xwl_seat_destroy(xwl_seat); - - xwl_screen_release_tablet_manager(xwl_screen); - - RemoveNotifyFd(xwl_screen->wayland_fd); - - wl_display_disconnect(xwl_screen->display); - - screen->CloseScreen = xwl_screen->CloseScreen; - free(xwl_screen); - - return screen->CloseScreen(screen); -} - -static struct xwl_seat * -xwl_screen_get_default_seat(struct xwl_screen *xwl_screen) -{ - 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->window; - - /* Warps on non wl_surface backed Windows are only allowed - * as long as the pointer stays within the focus window. - */ - if (x >= focus->drawable.x && - y >= focus->drawable.y && - x < focus->drawable.x + focus->drawable.width && - y < focus->drawable.y + focus->drawable.height) { - if (!window) { - DebugF("Warp relative to pointer, assuming pointer focus\n"); - xwl_window = xwl_seat->focus_window; - } else if (window == screen->root) { - DebugF("Warp on root window, assuming pointer focus\n"); - xwl_window = xwl_seat->focus_window; - } - } - } - if (!xwl_window) - return; - - xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y); -} - -static 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->window->drawable.x || - window->drawable.x + window->drawable.width > - xwl_window->window->drawable.x + xwl_window->window->drawable.width || - window->drawable.y < xwl_window->window->drawable.y || - window->drawable.y + window->drawable.height > - xwl_window->window->drawable.y + xwl_window->window->drawable.height) - continue; - - if (xwl_window->window->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 (!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; - -#ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window)) - continue; -#endif - - 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_glamor_needs_buffer_flush(xwl_screen)) - 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") == 0) { - uint32_t request_version = 1; - - 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") == 0) { - xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); - } - else if (strcmp(interface, "xdg_wm_base") == 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") == 0 && version >= 2) { - if (xwl_output_create(xwl_screen, id)) - xwl_screen->expecting_event++; - } - else if (strcmp(interface, "zxdg_output_manager_v1") == 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_viewporter") == 0) { - xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_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; - - 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; - } - } -} - -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); -} - -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; - - xwl_read_events (xwl_screen); -} - -static void -wakeup_handler(void *data, int err) -{ -} - -static void -block_handler(void *data, void *timeout) -{ - struct xwl_screen *xwl_screen = data; - - xwl_screen_post_damage(xwl_screen); - xwl_dispatch_events (xwl_screen); -} - -void -xwl_sync_events (struct xwl_screen *xwl_screen) -{ - xwl_dispatch_events (xwl_screen); - xwl_read_events (xwl_screen); -} - -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; - - ret = wl_display_roundtrip(xwl_screen->display); - while (ret >= 0 && xwl_screen->expecting_event) - ret = wl_display_roundtrip(xwl_screen->display); - - if (ret < 0) - xwl_give_up("could not connect to wayland server\n"); -} - -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; -#ifdef XWL_HAS_GLAMOR - Bool use_eglstreams = FALSE; -#endif - - xwl_screen = calloc(1, sizeof *xwl_screen); - if (xwl_screen == NULL) - return 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; - - dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen); - xwl_screen->screen = pScreen; - -#ifdef XWL_HAS_GLAMOR - xwl_screen->glamor = 1; -#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 = 0; - } - else if (strcmp(argv[i], "-eglstream") == 0) { -#ifdef XWL_HAS_EGLSTREAM - use_eglstreams = TRUE; -#else - ErrorF("xwayland glamor: this build does not have EGLStream support\n"); -#endif - } - } - -#ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor) - xwl_glamor_init_backends(xwl_screen, use_eglstreams); -#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); - xwl_screen->depth = 24; - - if (!monitorResolution) - monitorResolution = DEFAULT_DPI; - - xwl_screen->display = wl_display_connect(NULL); - if (xwl_screen->display == NULL) { - ErrorF("could not connect to wayland server\n"); - return FALSE; - } - - if (!xwl_screen_init_output(xwl_screen)) - return FALSE; - - xwl_screen->expecting_event = 0; - xwl_screen->registry = wl_display_get_registry(xwl_screen->display); - wl_registry_add_listener(xwl_screen->registry, - ®istry_listener, xwl_screen); - xwl_screen_roundtrip(xwl_screen); - - 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->width, xwl_screen->height, - 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 - - 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_select_backend(xwl_screen, use_eglstreams); - - if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) { - ErrorF("Failed to initialize glamor, falling back to sw\n"); - xwl_screen->glamor = 0; - } - } - - if (xwl_screen->glamor && xwl_screen->rootless) - xwl_screen->present = xwl_present_init(pScreen); -#endif - - if (!xwl_screen->glamor) { - xwl_screen->CreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = xwl_shm_create_screen_resources; - pScreen->CreatePixmap = xwl_shm_create_pixmap; - pScreen->DestroyPixmap = xwl_shm_destroy_pixmap; - } - - xwl_screen->RealizeWindow = pScreen->RealizeWindow; - pScreen->RealizeWindow = xwl_realize_window; - - xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow; - pScreen->UnrealizeWindow = xwl_unrealize_window; - - xwl_screen->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->ResizeWindow = pScreen->ResizeWindow; - pScreen->ResizeWindow = xwl_resize_window; - - xwl_screen->MoveWindow = pScreen->MoveWindow; - pScreen->MoveWindow = xwl_move_window; - - if (xwl_screen->rootless) { - xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap; - pScreen->SetWindowPixmap = xwl_window_set_window_pixmap; - } - - 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); - - 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 b965dddd7..000000000 --- a/hw/xwayland/xwayland-screen.h +++ /dev/null @@ -1,138 +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-output.h" -#include "xwayland-glamor.h" - -struct xwl_format { - uint32_t format; - int num_modifiers; - uint64_t *modifiers; -}; - -struct xwl_screen { - int width; - int height; - int depth; - ScreenPtr screen; - int wm_client_id; - int expecting_event; - enum RootClipMode root_clip_mode; - - int rootless; - int glamor; - int present; - - CreateScreenResourcesProcPtr CreateScreenResources; - CloseScreenProcPtr CloseScreen; - RealizeWindowProcPtr RealizeWindow; - UnrealizeWindowProcPtr UnrealizeWindow; - DestroyWindowProcPtr DestroyWindow; - XYToWindowProcPtr XYToWindow; - SetWindowPixmapProcPtr SetWindowPixmap; - ChangeWindowAttributesProcPtr ChangeWindowAttributes; - ResizeWindowProcPtr ResizeWindow; - MoveWindowProcPtr MoveWindow; - - struct xorg_list output_list; - struct xorg_list seat_list; - struct xorg_list damage_window_list; - struct xorg_list window_list; - - 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_xwayland_keyboard_grab_manager_v1 *wp_grab; - struct zwp_linux_dmabuf_v1 *dmabuf; - struct zxdg_output_manager_v1 *xdg_output_manager; - struct wp_viewporter *viewporter; - 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 xwl_egl_backend gbm_backend; - struct xwl_egl_backend eglstream_backend; - /* pointer to the current backend for creating pixmaps on wayland */ - struct xwl_egl_backend *egl_backend; - - struct glamor_context *glamor_ctx; - - Atom allow_commits_prop; - - /* The preferred GLVND vendor. If NULL, "mesa" is assumed. */ - const char *glvnd_vendor; -}; - -/* 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); -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); - -#endif /* XWAYLAND_SCREEN_H */ diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c deleted file mode 100644 index cf7e97ca3..000000000 --- a/hw/xwayland/xwayland-shm.c +++ /dev/null @@ -1,339 +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 "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 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 || - (!xwl_screen->rootless && hint != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) || - (width == 0 && height == 0) || depth < 15) - return fbCreatePixmap(screen, width, height, depth, hint); - - 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; - - stride = PixmapBytePad(width, depth); - size = stride * height; - 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) -{ - return xwl_pixmap_get(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 da80ff98e..000000000 --- a/hw/xwayland/xwayland-types.h +++ /dev/null @@ -1,34 +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_egl_backend; - -#endif /* XWAYLAND_TYPES_H */ diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c deleted file mode 100644 index 87e9c3d73..000000000 --- a/hw/xwayland/xwayland-vidmode.c +++ /dev/null @@ -1,492 +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_screen_get_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_output *xwl_output = xwl_screen_get_first_output(xwl_screen); - struct xwl_emulated_mode *emulated_mode; - - 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 = xwl_screen_get_first_output(xwl_screen); - VidModePtr pVidMode; - DisplayModePtr pMod; - intptr_t index; - - pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey); - pVidMode = VidModeGetPtr(pScreen); - if (xwl_output == NULL || 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_screen_get_first_output(xwl_screen); - - if (!xwl_output) - return FALSE; - - /* Support only default viewport */ - return (x == xwl_output->x && y == xwl_output->y); -} - -static Bool -xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(pScreen); - struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen); - - if (!xwl_output) - return FALSE; - - *x = xwl_output->x; - *y = xwl_output->y; - - return TRUE; -} - -static Bool -xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(pScreen); - struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen); - RRModePtr rrmode; - - if (!xwl_output) - return FALSE; - - rrmode = xwl_output_find_mode(xwl_output, mode->HDisplay, mode->VDisplay); - if (rrmode == NULL) - return FALSE; - - xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), rrmode, TRUE); - 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_screen_get_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 f04c79a8a..000000000 --- a/hw/xwayland/xwayland-window-buffers.c +++ /dev/null @@ -1,367 +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-window-buffers.h" - -#define BUFFER_TIMEOUT 1 * 1000 /* ms */ - -struct xwl_window_buffer { - struct xwl_window *xwl_window; - PixmapPtr pixmap; - RegionPtr damage_region; - Bool recycle_on_release; - int refcnt; - uint32_t time; - struct xorg_list link_buffer; -}; - -static Bool -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) { - ValidateGC(&dst_pixmap->drawable, pGC); - (void) (*pGC->ops->CopyArea) (&src_pixmap->drawable, - &dst_pixmap->drawable, - pGC, - x, y, - width, height, - x, y); - FreeScratchGC(pGC); - - return TRUE; - } - - return FALSE; -} - -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_append(&xwl_window_buffer->link_buffer, - &xwl_window->window_buffers_available); - - 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 Bool -xwl_window_buffer_dispose(struct xwl_window_buffer *xwl_window_buffer) -{ - assert(xwl_window_buffer->refcnt > 0); - - if (--xwl_window_buffer->refcnt) - return FALSE; - - RegionDestroy(xwl_window_buffer->damage_region); - - if (xwl_window_buffer->pixmap) - xwl_window_buffer_destroy_pixmap (xwl_window_buffer); - - xorg_list_del(&xwl_window_buffer->link_buffer); - free(xwl_window_buffer); - - return TRUE; -} - -static void -xwl_window_buffer_recycle(struct xwl_window_buffer *xwl_window_buffer) -{ - RegionEmpty(xwl_window_buffer->damage_region); - xwl_window_buffer->recycle_on_release = FALSE; - - if (xwl_window_buffer->pixmap) - xwl_window_buffer_destroy_pixmap (xwl_window_buffer); -} - -static void -xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window, - RegionPtr damage_region) -{ - 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, - damage_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, - damage_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 xwl_window_buffer_new(xwl_window); - - 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_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_dispose(xwl_window_buffer)) - return; - - if (xwl_window_buffer->recycle_on_release) - xwl_window_buffer_recycle(xwl_window_buffer); - - /* 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_buffers_init(struct xwl_window *xwl_window) -{ - xorg_list_init(&xwl_window->window_buffers_available); - xorg_list_init(&xwl_window->window_buffers_unavailable); -} - -void -xwl_window_buffers_recycle(struct xwl_window *xwl_window) -{ - struct xwl_window_buffer *xwl_window_buffer, *tmp; - - /* Dispose available buffers */ - xorg_list_for_each_entry_safe(xwl_window_buffer, tmp, - &xwl_window->window_buffers_available, - link_buffer) { - xwl_window_buffer_dispose(xwl_window_buffer); - } - - if (xwl_window->window_buffers_timer) - TimerCancel(xwl_window->window_buffers_timer); - - /* Mark the others for recycle on release */ - xorg_list_for_each_entry(xwl_window_buffer, - &xwl_window->window_buffers_unavailable, - link_buffer) { - xwl_window_buffer->recycle_on_release = TRUE; - } -} - -void -xwl_window_buffers_dispose(struct xwl_window *xwl_window) -{ - 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_dispose(xwl_window_buffer); - } - - 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_dispose(xwl_window_buffer); - } - - if (xwl_window->window_buffers_timer) { - TimerFree(xwl_window->window_buffers_timer); - xwl_window->window_buffers_timer = 0; - } -} - -PixmapPtr -xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window, - RegionPtr damage_region) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - struct xwl_window_buffer *xwl_window_buffer; - PixmapPtr window_pixmap; - RegionPtr full_damage; - - window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); - -#ifdef XWL_HAS_GLAMOR - if (!xwl_glamor_needs_n_buffering(xwl_screen)) - return window_pixmap; -#endif /* XWL_HAS_GLAMOR */ - - xwl_window_buffer = xwl_window_buffer_get_available(xwl_window); - if (!xwl_window_buffer) - return window_pixmap; - - xwl_window_buffer_add_damage_region(xwl_window, damage_region); - - full_damage = xwl_window_buffer->damage_region; - - if (xwl_window_buffer->pixmap) { - BoxPtr pBox = RegionRects(full_damage); - int nBox = RegionNumRects(full_damage); - while (nBox--) { - if (!copy_pixmap_area(window_pixmap, - xwl_window_buffer->pixmap, - pBox->x1 + xwl_window->window->borderWidth, - pBox->y1 + xwl_window->window->borderWidth, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1)) - return window_pixmap; - - pBox++; - } - } else { - xwl_window_buffer->pixmap = - (*xwl_screen->screen->CreatePixmap) (window_pixmap->drawable.pScreen, - window_pixmap->drawable.width, - window_pixmap->drawable.height, - window_pixmap->drawable.depth, - CREATE_PIXMAP_USAGE_BACKING_PIXMAP); - - if (!xwl_window_buffer->pixmap) - return window_pixmap; - - if (!copy_pixmap_area(window_pixmap, - xwl_window_buffer->pixmap, - 0, 0, - window_pixmap->drawable.width, - window_pixmap->drawable.height)) { - xwl_window_buffer_recycle(xwl_window_buffer); - return window_pixmap; - } - } - - RegionEmpty(xwl_window_buffer->damage_region); - - /* Hold a reference on the buffer until it's released by the compositor */ - xwl_window_buffer->refcnt++; - xwl_pixmap_set_buffer_release_cb(xwl_window_buffer->pixmap, - xwl_window_buffer_release_callback, - xwl_window_buffer); - - xorg_list_del(&xwl_window_buffer->link_buffer); - 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 8031f24d5..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" -#include "regionstr.h" - -void xwl_window_buffers_init(struct xwl_window *xwl_window); -void xwl_window_buffers_recycle(struct xwl_window *xwl_window); -void xwl_window_buffers_dispose(struct xwl_window *xwl_window); -PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window, - RegionPtr damage_region); - -#endif /* XWAYLAND_WINDOW_BUFFERS_H */ diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c deleted file mode 100644 index 00f161eda..000000000 --- a/hw/xwayland/xwayland-window.c +++ /dev/null @@ -1,858 +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 "compositeext.h" -#include "compint.h" -#include "inputstr.h" -#include "propertyst.h" - -#include "xwayland-types.h" -#include "xwayland-input.h" -#include "xwayland-present.h" -#include "xwayland-screen.h" -#include "xwayland-window.h" -#include "xwayland-window-buffers.h" -#include "xwayland-shm.h" - -#include "viewporter-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -static DevPrivateKeyRec xwl_window_private_key; -static DevPrivateKeyRec xwl_damage_private_key; - -static void -xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow, - const char *debug_msg) -{ - xwl_window->allow_commits = allow; - DebugF("xwayland: win %d allow_commits = %d (%s)\n", - xwl_window->window->drawable.id, allow, debug_msg); -} - -static void -xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window, - PropertyPtr prop) -{ - static Bool warned = FALSE; - CARD32 *propdata; - - if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop) - FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__); - - if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) { - /* Not properly set, so fall back to safe and glitchy */ - xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault"); - - if (!warned) { - 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"); -} - -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); -} - -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; -} - -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 -damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) -{ - WindowPtr window = data; - struct xwl_window *xwl_window = xwl_window_get(window); - struct xwl_screen *xwl_screen; - - if (!xwl_window) - return; - - xwl_screen = xwl_window->xwl_screen; - -#ifdef GLAMOR_HAS_GBM - if (xwl_window->present_flipped) { - /* This damage is from a Present flip, which already committed a new - * buffer for the surface, so we don't need to do anything in response - */ - RegionEmpty(DamageRegion(pDamage)); - xorg_list_del(&xwl_window->link_damage); - xwl_window->present_flipped = FALSE; - return; - } -#endif - - xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); -} - -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); - DamageSetReportAfterOp(damage, TRUE); - - 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); -} - -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; -} - -static void -xwl_window_enable_viewport(struct xwl_window *xwl_window, - struct xwl_output *xwl_output, - struct xwl_emulated_mode *emulated_mode) -{ - if (!xwl_window_has_viewport_enabled(xwl_window)) { - DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n", - emulated_mode->width, emulated_mode->height, - xwl_output->width, xwl_output->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(emulated_mode->width), - wl_fixed_from_int(emulated_mode->height)); - wp_viewport_set_destination(xwl_window->viewport, - xwl_output->width, - xwl_output->height); - - xwl_window->scale_x = (float)emulated_mode->width / xwl_output->width; - xwl_window->scale_y = (float)emulated_mode->height / xwl_output->height; -} - -static Bool -window_is_wm_window(WindowPtr window) -{ - struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen); - - return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id; -} - -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 first *and only* child of the decoration/wrapper window. - */ - while (window_is_wm_window(window)) { - if (!window->firstChild || window->firstChild != window->lastChild) - return NULL; /* Should never happen, skip resolution emulation */ - - window = window->firstChild; - } - - return window; -} - -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_resolution_change_emulation(xwl_screen)) - return FALSE; - - window = window_get_client_toplevel(xwl_window->window); - 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) { - emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner); - if (!emulated_mode) - continue; - - if (drawable->x == xwl_output->x && - drawable->y == xwl_output->y && - drawable->width == emulated_mode->width && - drawable->height == emulated_mode->height) { - - *emulated_mode_ret = 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->window->overrideRedirect && - emulated_mode && emulated_mode->from_vidmode && - drawable->x == 0 && drawable->y == 0 && - drawable->width == xwl_screen->width && - drawable->height == xwl_screen->height) { - - *emulated_mode_ret = emulated_mode; - *xwl_output_ret = xwl_output; - return TRUE; - } - - return FALSE; -} - -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(xwl_window, xwl_output, emulated_mode); - 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_is_wm_window(window)) - return FALSE; - - /* CSD and override-redirect toplevel windows */ - if (window_get_damage(window)) - return TRUE; - - /* Normal toplevel client windows, reparented to a window-manager window */ - return window->parent && 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->window, - xwl_window->xwl_screen->allow_commits_prop, - serverClient, DixReadAccess); - if (ret == Success && prop) - xwl_window_set_allow_commits_from_property(xwl_window, prop); - else - xwl_window_set_allow_commits(xwl_window, TRUE, "no property"); -} - -static void -send_surface_id_event(struct xwl_window *xwl_window) -{ - static const char atom_name[] = "WL_SURFACE_ID"; - static Atom type_atom; - DeviceIntPtr dev; - xEvent e; - - if (type_atom == None) - type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE); - - e.u.u.type = ClientMessage; - e.u.u.detail = 32; - e.u.clientMessage.window = xwl_window->window->drawable.id; - e.u.clientMessage.u.l.type = type_atom; - e.u.clientMessage.u.l.longs0 = - wl_proxy_get_id((struct wl_proxy *) xwl_window->surface); - e.u.clientMessage.u.l.longs1 = 0; - e.u.clientMessage.u.l.longs2 = 0; - e.u.clientMessage.u.l.longs3 = 0; - e.u.clientMessage.u.l.longs4 = 0; - - dev = PickPointer(serverClient); - DeliverEventsToWindow(dev, xwl_window->xwl_screen->screen->root, - &e, 1, SubstructureRedirectMask, NullGrab); -} - -static void -xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, - uint32_t serial) -{ - xdg_surface_ack_configure(xdg_surface, serial); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - xdg_surface_handle_configure, -}; - -static Bool -ensure_surface_for_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - struct wl_region *region; - WindowPtr toplevel; - - if (xwl_window_from_window(window)) - return TRUE; - - xwl_screen = xwl_screen_get(screen); - - if (xwl_screen->rootless) { - if (window->redirectDraw != RedirectDrawManual) - return TRUE; - } - else { - if (window->parent) - return TRUE; - } - - xwl_window = calloc(1, sizeof *xwl_window); - if (xwl_window == NULL) - return FALSE; - - xwl_window->xwl_screen = xwl_screen; - xwl_window->window = window; - xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor); - if (xwl_window->surface == NULL) { - ErrorF("wl_display_create_surface failed\n"); - goto err; - } - - if (!xwl_screen->rootless) { - xwl_window->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; - } - - xdg_surface_add_listener(xwl_window->xdg_surface, - &xdg_surface_listener, xwl_window); - - xdg_surface_get_toplevel(xwl_window->xdg_surface); - - wl_surface_commit(xwl_window->surface); - - region = wl_compositor_create_region(xwl_screen->compositor); - if (region == NULL) { - ErrorF("Failed creating region\n"); - goto err_surf; - } - - wl_region_add(region, 0, 0, - window->drawable.width, window->drawable.height); - wl_surface_set_opaque_region(xwl_window->surface, region); - wl_region_destroy(region); - } - - wl_display_flush(xwl_screen->display); - - send_surface_id_event(xwl_window); - - wl_surface_set_user_data(xwl_window->surface, xwl_window); - - 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); - -#ifdef GLAMOR_HAS_GBM - xorg_list_init(&xwl_window->frame_callback_list); -#endif - - xwl_window_buffers_init(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 (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); - } - - return TRUE; - -err_surf: - if (xwl_window->xdg_surface) - xdg_surface_destroy(xwl_window->xdg_surface); - wl_surface_destroy(xwl_window->surface); -err: - free(xwl_window); - return FALSE; -} - -Bool -xwl_realize_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - 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 && !window->parent) { - BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height }; - - RegionReset(&window->winSize, &box); - RegionNull(&window->clipList); - RegionNull(&window->borderClip); - } - - if (xwl_screen->rootless ? - (window->drawable.class == InputOutput && - window->parent == window->drawable.pScreen->root) : - !window->parent) { - if (!register_damage(window)) - return FALSE; - } - - return ensure_surface_for_window(window); -} - -Bool -xwl_unrealize_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - struct xwl_seat *xwl_seat; - Bool ret; - - xwl_screen = xwl_screen_get(screen); - - xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { - if (xwl_seat->focus_window && xwl_seat->focus_window->window == window) - xwl_seat->focus_window = NULL; - if (xwl_seat->tablet_focus_window && xwl_seat->tablet_focus_window->window == window) - xwl_seat->tablet_focus_window = NULL; - if (xwl_seat->last_xwindow == window) - xwl_seat->last_xwindow = NullWindow; - if (xwl_seat->cursor_confinement_window && - xwl_seat->cursor_confinement_window->window == window) - xwl_seat_unconfine_pointer(xwl_seat); - if (xwl_seat->pointer_warp_emulator && - xwl_seat->pointer_warp_emulator->locked_window && - xwl_seat->pointer_warp_emulator->locked_window->window == window) - xwl_seat_destroy_pointer_warp_emulator(xwl_seat); - xwl_seat_clear_touch(xwl_seat, window); - } - - compUnredirectWindow(serverClient, window, CompositeRedirectManual); - - screen->UnrealizeWindow = xwl_screen->UnrealizeWindow; - ret = (*screen->UnrealizeWindow) (window); - xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; - screen->UnrealizeWindow = xwl_unrealize_window; - - xwl_window = xwl_window_get(window); - if (!xwl_window) - return ret; - - if (xwl_window_has_viewport_enabled(xwl_window)) - xwl_window_disable_viewport(xwl_window); - - wl_surface_destroy(xwl_window->surface); - xorg_list_del(&xwl_window->link_damage); - xorg_list_del(&xwl_window->link_window); - unregister_damage(window); - - xwl_window_buffers_dispose(xwl_window); - - if (xwl_window->frame_callback) - wl_callback_destroy(xwl_window->frame_callback); - -#ifdef GLAMOR_HAS_GBM - if (xwl_screen->present) { - struct xwl_present_window *xwl_present_window, *tmp; - - xorg_list_for_each_entry_safe(xwl_present_window, tmp, - &xwl_window->frame_callback_list, - frame_callback_list) { - xwl_present_unrealize_window(xwl_present_window); - } - } -#endif - - free(xwl_window); - dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); - - 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; - - ensure_surface_for_window(window); - - if (old_pixmap->drawable.width == pixmap->drawable.width && - old_pixmap->drawable.height == pixmap->drawable.height) - return; - - xwl_window = xwl_window_get(window); - if (xwl_window) - xwl_window_buffers_recycle(xwl_window); -} - -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_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 && (xwl_window_get(window) || xwl_window_is_toplevel(window))) - xwl_window_check_resolution_change_emulation(xwl_window); -} - -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; - -#ifdef GLAMOR_HAS_GBM - if (xwl_window->xwl_screen->present) { - struct xwl_present_window *xwl_present_window, *tmp; - - xorg_list_for_each_entry_safe(xwl_present_window, tmp, - &xwl_window->frame_callback_list, - frame_callback_list) { - xwl_present_frame_callback(xwl_present_window); - } - } -#endif -} - -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); -} - -Bool -xwl_destroy_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen = xwl_screen_get(screen); - Bool ret; - -#ifdef GLAMOR_HAS_GBM - if (xwl_screen->present) - xwl_present_cleanup(window); -#endif - - 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; -} - -void -xwl_window_post_damage(struct xwl_window *xwl_window) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - RegionPtr region; - BoxPtr box; - struct wl_buffer *buffer; - PixmapPtr pixmap; - int i; - - assert(!xwl_window->frame_callback); - - region = DamageRegion(window_get_damage(xwl_window->window)); - pixmap = xwl_window_buffers_get_pixmap(xwl_window, region); - -#ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor) - buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap); - else -#endif - buffer = xwl_shm_pixmap_get_wl_buffer(pixmap); - - if (!buffer) { - ErrorF("Error getting buffer\n"); - return; - } - -#ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor) { - if (!xwl_glamor_post_damage(xwl_window, pixmap, region)) { - ErrorF("glamor: Failed to post damage\n"); - return; - } - } -#endif - - wl_surface_attach(xwl_window->surface, buffer, 0, 0); - - /* Arbitrary limit to try to avoid flooding the Wayland - * connection. If we flood it too much anyway, this could - * abort in libwayland-client. - */ - if (RegionNumRects(region) > 256) { - box = RegionExtents(region); - xwl_surface_damage(xwl_screen, xwl_window->surface, - box->x1 + xwl_window->window->borderWidth, - box->y1 + xwl_window->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 + xwl_window->window->borderWidth, - box->y1 + xwl_window->window->borderWidth, - box->x2 - box->x1, box->y2 - box->y1); - } - } - - xwl_window_create_frame_callback(xwl_window); - DamageEmpty(window_get_damage(xwl_window->window)); -} - -Bool -xwl_window_init(void) -{ - if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) - 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 d94f07204..000000000 --- a/hw/xwayland/xwayland-window.h +++ /dev/null @@ -1,86 +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 "xwayland-types.h" - -struct xwl_window { - struct xwl_screen *xwl_screen; - struct wl_surface *surface; - struct wp_viewport *viewport; - float scale_x, scale_y; - struct xdg_surface *xdg_surface; - WindowPtr window; - 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; -#ifdef GLAMOR_HAS_GBM - struct xorg_list frame_callback_list; - Bool present_flipped; -#endif -}; - -struct xwl_window *xwl_window_get(WindowPtr window); -struct xwl_window *xwl_window_from_window(WindowPtr window); - -void xwl_window_update_property(struct xwl_window *xwl_window, - PropertyStateRec *propstate); -Bool xwl_window_has_viewport_enabled(struct xwl_window *xwl_window); -Bool xwl_window_is_toplevel(WindowPtr window); -void xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window); - -void xwl_window_set_window_pixmap(WindowPtr window, PixmapPtr pixmap); -Bool xwl_realize_window(WindowPtr window); -Bool xwl_unrealize_window(WindowPtr window); -Bool xwl_change_window_attributes(WindowPtr window, unsigned long mask); -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); -Bool xwl_window_init(void); - -#endif /* XWAYLAND_WINDOW_H */ diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c deleted file mode 100644 index 801af38aa..000000000 --- a/hw/xwayland/xwayland.c +++ /dev/null @@ -1,294 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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("-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"); -#ifdef XWL_HAS_EGLSTREAM - ErrorF("-eglstream use eglstream backend for nvidia GPUs\n"); -#endif - ErrorF("-shm use shared memory for passing buffers\n"); - ErrorF("-verbose [n] verbose startup messages\n"); - ErrorF("-version show the server version and exit\n"); - ErrorF("-noTouchPointerEmulation disable touch pointer emulation\n"); -} - -static int init_fd = -1; -static int wm_fd = -1; -static int listen_fds[5] = { -1, -1, -1, -1, -1 }; -static int listen_fd_count = 0; -static int verbosity = 0; - -static void -xwl_show_version(void) -{ - ErrorF("%s Xwayland %s (%d)\n", VENDOR_NAME, VENDOR_MAN_VERSION, VENDOR_RELEASE); - ErrorF("X Protocol Version %d, Revision %d\n", X_PROTOCOL, X_PROTOCOL_REVISION); -#if defined(BUILDERSTRING) - if (strlen(BUILDERSTRING)) - ErrorF("%s\n", BUILDERSTRING); -#endif -} - -static void -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; - } - else if (strcmp(argv[i], "-verbose") == 0) { - if (++i < argc && argv[i]) { - char *end; - long val; - - val = strtol(argv[i], &end, 0); - if (*end == '\0') { - verbosity = val; - LogSetParameter(XLOG_VERBOSITY, verbosity); - return 2; - } - } - LogSetParameter(XLOG_VERBOSITY, ++verbosity); - return 1; - } - else if (strcmp(argv[i], "-eglstream") == 0) { - return 1; - } - else if (strcmp(argv[i], "-version") == 0) { - xwl_show_version(); - exit(0); - } - else if (strcmp(argv[i], "-noTouchPointerEmulation") == 0) { - touchEmulatePointer = FALSE; - } - - 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); -} - -_X_NORETURN -static void _X_ATTRIBUTE_PRINTF(1, 0) -xwl_log_handler(const char *format, va_list args) -{ - char msg[256]; - - vsnprintf(msg, sizeof msg, format, args); - FatalError("%s", msg); -} - -static const ExtensionModule xwayland_extensions[] = { -#ifdef XF86VIDMODE - { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, -#endif -}; - -void -InitOutput(ScreenInfo * screen_info, int argc, char **argv) -{ - int depths[] = { 1, 4, 8, 15, 16, 24, 32 }; - int bpp[] = { 1, 8, 8, 16, 16, 32, 32 }; - int i; - - for (i = 0; i < ARRAY_SIZE(depths); i++) { - screen_info->formats[i].depth = depths[i]; - screen_info->formats[i].bitsPerPixel = bpp[i]; - screen_info->formats[i].scanlinePad = BITMAP_SCANLINE_PAD; - } - - screen_info->imageByteOrder = IMAGE_BYTE_ORDER; - screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - screen_info->bitmapBitOrder = BITMAP_BIT_ORDER; - screen_info->numPixmapFormats = ARRAY_SIZE(depths); - - if (serverGeneration == 1) - 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/hw/xwayland/xwayland.pc.in b/hw/xwayland/xwayland.pc.in deleted file mode 100644 index 9d727b002..000000000 --- a/hw/xwayland/xwayland.pc.in +++ /dev/null @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ - -Name: Xwayland -Description: X Server for Wayland -Version: @PACKAGE_VERSION@ -xwayland=@xwayland_path@/Xwayland -have_glamor=@have_glamor@ -have_eglstream=@have_eglstream@ -have_initfd=true -have_listenfd=true -have_verbose=true -have_terminate_delay=true -have_no_touch_pointer_emulation=true diff --git a/include/Makefile.am b/include/Makefile.am index a1f241263..56e0b24fe 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -81,7 +81,6 @@ EXTRA_DIST = \ vidmodestr.h \ xorg-config.h.meson.in \ xorg-server.h.meson.in \ - xwayland-config.h.meson.in \ xwin-config.h.meson.in \ xsha1.h diff --git a/include/meson.build b/include/meson.build index 4d2c4e075..1fab731c3 100644 --- a/include/meson.build +++ b/include/meson.build @@ -412,14 +412,6 @@ configure_file(output : 'xwin-config.h', input : 'xwin-config.h.meson.in', configuration : xwin_data) -xwayland_data = configuration_data() -xwayland_data.set('XWL_HAS_GLAMOR', build_glamor and (gbm_dep.found() or build_eglstream) ? '1' : false) -xwayland_data.set('XWL_HAS_EGLSTREAM', build_eglstream ? '1' : false) - -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.in b/include/xwayland-config.h.in deleted file mode 100644 index 9695aae6b..000000000 --- a/include/xwayland-config.h.in +++ /dev/null @@ -1,13 +0,0 @@ -/* xwayland-config.h.in: not at all generated. */ -#ifndef _XWAYLAND_CONFIG_H_ -#define _XWAYLAND_CONFIG_H_ - -#include - -/* Build glamor support for Xwayland */ -#undef XWL_HAS_GLAMOR - -/* Build eglstream support for Xwayland */ -#undef XWL_HAS_EGLSTREAM - -#endif /* _XWAYLAND_CONFIG_H_ */ diff --git a/include/xwayland-config.h.meson.in b/include/xwayland-config.h.meson.in deleted file mode 100644 index 0943ff57d..000000000 --- a/include/xwayland-config.h.meson.in +++ /dev/null @@ -1,11 +0,0 @@ -/* xwayland-config.h.meson.in: not at all generated */ - -#pragma once - -#include - -/* Build glamor support for Xwayland */ -#mesondefine XWL_HAS_GLAMOR - -/* Build eglstream support for Xwayland */ -#mesondefine XWL_HAS_EGLSTREAM diff --git a/meson.build b/meson.build index 9201428a8..b55ee696a 100644 --- a/meson.build +++ b/meson.build @@ -196,39 +196,6 @@ endif xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg') libxcvt_dep = dependency('libxcvt', required: build_xorg) -build_xwayland = false -if (host_machine.system() != 'darwin' and - host_machine.system() != 'windows') - if 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', required: xwayland_required), - ] - - if build_glamor - 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 -endif - build_xnest = false if (host_machine.system() != 'darwin' and host_machine.system() != 'windows') @@ -326,7 +293,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 @@ -338,21 +305,6 @@ if build_glamor epoxy_dep = dependency('epoxy', required: false) endif -eglstream_option = get_option('xwayland_eglstream') -if build_xwayland and build_glamor - eglstream_dep = dependency('wayland-eglstream-protocols', required:false) - if eglstream_option == 'auto' - build_eglstream = eglstream_dep.found() - else - build_eglstream = eglstream_option == 'true' - if build_eglstream and not eglstream_dep.found() - error('glamor EGLStream support requested, but wayland-eglstream-protocols not found') - endif - endif -else - build_eglstream = 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 93e13f9ef..906f13c48 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_eglstream', type: 'combo', choices: ['true', 'false', 'auto'], - value: 'auto', description: 'Enable EGLStream support for glamor 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, @@ -128,8 +124,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('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 0892fd807..78716e441 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 +if build_dri3 srcs_miext_sync += 'misyncshm.c' endif diff --git a/test/Makefile.am b/test/Makefile.am index 1f797530c..ce07c3551 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -25,14 +25,9 @@ endif endif endif -if XWAYLAND -XWAYLAND_TESTS = scripts/xwayland-piglit.sh -endif - SCRIPT_TESTS = \ $(XVFB_TESTS) \ $(XEPHYR_GLAMOR_TESTS) \ - $(XWAYLAND_TESTS) \ $(NULL) TESTS = tests \ @@ -193,7 +188,6 @@ EXTRA_DIST = \ scripts/xvfb-piglit.sh \ scripts/xephyr-glamor-piglit.sh \ scripts/xinit-piglit-session.sh \ - scripts/xwayland-piglit.sh \ scripts/run-piglit.sh \ $(NULL) diff --git a/test/meson.build b/test/meson.build index 4a79394e4..beeeaf840 100644 --- a/test/meson.build +++ b/test/meson.build @@ -100,19 +100,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 f0bb9727b..000000000 --- a/test/scripts/xwayland-piglit.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -e - -# 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-$$ - -# Wait for weston to initialize before starting Xwayland -timeout --preserve-status 60s bash -c 'while ! weston-info &>/dev/null; do sleep 1; done' - -# 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" - -export PIGLIT_ARGS - -$XSERVER_DIR/test/scripts/run-piglit.sh -PIGLIT_STATUS=$? - -kill $WESTON_PID -exit $PIGLIT_STATUS