diff options
97 files changed, 1530 insertions, 1285 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d66bb0b62..117744496 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,13 +1,104 @@ -image: docker:latest -services: - - docker:dind +# IMAGE_TAG is the tag of the docker image used for the build jobs. If the +# image doesn't exist yet, the docker-image stage generates it. +# +# In order to generate a new image, one should generally change the tag. +# While removing the image from the registry would also work, that's not +# recommended except for ephemeral images during development: Replacing an +# image after a significant amount of time might pull in newer versions of +# gcc/clang or other packages, which might break the build with older commits +# using the same tag. +# +# After merging a change resulting in generating a new image to the main +# repository, it's recommended to remove the image from the source repository's +# container registry, so that the image from the main repository's registry +# will be used there as well. +variables: + IMAGE_TAG: "debian-testing-20190219" + IMAGE_LOCAL: "$CI_REGISTRY_IMAGE:$IMAGE_TAG" + IMAGE_MAIN: "registry.freedesktop.org/xorg/xserver:$IMAGE_TAG" -before_script: - - echo FROM nwnk/xserver-travis-rawhide:v5 > Dockerfile - - echo ADD . /root >> Dockerfile - - echo WORKDIR /root >> Dockerfile - - docker build -t withgit . +stages: + - docker-image + - build-and-test -job: +debian-testing: + stage: docker-image + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [""] script: - - docker run --volume $HOME/.ccache:/root/.ccache withgit ./test/scripts/build-travis-deps.sh + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json + - mkdir kaniko-context + - | + echo "FROM $IMAGE_LOCAL" > kaniko-context/Dockerfile + # If the image exists in the local registry, skip to the build-and-test job + set +e + set -x + /kaniko/executor --context kaniko-context --no-push && exit 0 + set +x + set -e + - | + echo "FROM $IMAGE_MAIN" > kaniko-context/Dockerfile + # Try to re-use the image from the main repository's registry, and if + # that fails, generate a local image from scratch + set +e + set -x + /kaniko/executor --context kaniko-context --destination $IMAGE_LOCAL && exit 0 + set +x + set -e + - /kaniko/executor --context $CI_PROJECT_DIR/.gitlab-ci --destination $IMAGE_LOCAL + +.common-build-and-test: + stage: build-and-test + image: $IMAGE_LOCAL + artifacts: + when: on_failure + paths: + - build/test/piglit-results/ + cache: + paths: + - ccache/ + variables: + LC_ALL: C.UTF-8 + before_script: + - export CCACHE_BASEDIR="$PWD" + - export CCACHE_DIR="$PWD/ccache" + - export CCACHE_COMPILERCHECK=content + - export PATH="/usr/lib/ccache:$PATH" + - ccache --zero-stats + - ccache --show-stats + after_script: + - CCACHE_DIR="$PWD/ccache" ccache --show-stats + +autotools-build-and-test: + extends: .common-build-and-test + script: + - mkdir build/ + - cd build/ + - ../autogen.sh --prefix=/usr + - make -j$(nproc) distcheck + - | + export PIGLIT_DIR=/root/piglit XTEST_DIR=/root/xts + set +e + set -x + make -j$(nproc) check + status=$? + cat test/piglit-results/xvfb/long-summary || : + exit $status + +meson-build-and-test: + extends: .common-build-and-test + variables: + PIGLIT_DIR: /root/piglit + XTEST_DIR: /root/xts + script: + - meson -Dprefix=/usr build/ + - | + ninja -C build/ install + set +e + set -x + ninja -C build/ test + status=$? + cat build/meson-logs/testlog.txt + cat build/test/piglit-results/xvfb/long-summary || : + exit $status diff --git a/.gitlab-ci/Dockerfile b/.gitlab-ci/Dockerfile new file mode 100644 index 000000000..4c66ad0d4 --- /dev/null +++ b/.gitlab-ci/Dockerfile @@ -0,0 +1,35 @@ +FROM debian:testing-slim + +WORKDIR /tmp + +RUN export DEBIAN_FRONTEND=noninteractive; \ + echo 'path-exclude=/usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft && \ + echo 'path-exclude=/usr/share/locale/*' >> /etc/dpkg/dpkg.cfg.d/99-exclude-cruft && \ + echo 'path-exclude=/usr/share/man/*' >> /etc/dpkg/dpkg.cfg.d/99-exclude-cruft && \ + echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf && \ + echo '#!/bin/sh' > /usr/sbin/policy-rc.d && \ + echo 'exit 101' >> /usr/sbin/policy-rc.d && \ + chmod +x /usr/sbin/policy-rc.d && \ + echo 'deb-src https://deb.debian.org/debian testing main' >/etc/apt/sources.list.d/deb-src.list && \ + apt-get update && \ + apt-get install -y meson git ca-certificates ccache cmake automake autoconf libtool libwaffle-dev \ + libxkbcommon-dev python3-mako python3-numpy python3-six x11-utils x11-xserver-utils xauth xvfb && \ + apt-get build-dep -y xorg-server && \ + \ + cd /root && \ + git clone https://gitlab.freedesktop.org/mesa/piglit.git && cd piglit && \ + cmake -G Ninja -DPIGLIT_BUILD_GL_TESTS=OFF -DPIGLIT_BUILD_GLES1_TESTS=OFF \ + -DPIGLIT_BUILD_GLES2_TESTS=OFF -DPIGLIT_BUILD_GLES3_TESTS=OFF \ + -DPIGLIT_BUILD_DMA_BUF_TESTS=OFF -DPIGLIT_BUILD_GLX_TESTS=OFF && \ + ninja && \ + cd .. && \ + git clone https://gitlab.freedesktop.org/xorg/test/xts && \ + cd xts && ./autogen.sh && xvfb-run make -j$(nproc) && \ + cd .. && rm -rf piglit/.git xts/.git && \ + echo '[xts]' > piglit/piglit.conf && echo 'path=/root/xts' >> piglit/piglit.conf && \ + find -name \*.a -o -name \*.o | xargs rm && \ + \ + apt-get purge -y git cmake libwaffle-dev libxkbcommon-dev \ + x11-utils x11-xserver-utils xauth xvfb && \ + apt-get autoremove -y --purge && apt-get clean && \ + rm -f /var/lib/apt/lists/deb.debian.org_debian_dists_testing_* diff --git a/.travis.yml b/.travis.yml index 5fbb29b68..15677891b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,24 +6,13 @@ branches: matrix: include: - - os: linux - dist: trusty - services: docker - env: DISTRO=rawhide:v5 - os: osx osx_image: xcode9.2 env: DISTRO=xcode9.2 install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install ccache ; fi - -before_script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull nwnk/xserver-travis-$DISTRO ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM nwnk/xserver-travis-$DISTRO > Dockerfile ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit . ; fi + - HOMEBREW_NO_AUTO_UPDATE=1 brew install ccache script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run --volume $HOME/.ccache:/root/.ccache withgit /bin/sh -c "cd /root && ./test/scripts/build-travis-deps.sh" ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./test/scripts/build-travis-osx.sh ; fi + - ./test/scripts/build-travis-osx.sh - ccache -s diff --git a/Makefile.am b/Makefile.am index 32d4d21e7..19511f765 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,7 +72,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = xorg-server.pc endif -EXTRA_DIST = xorg-server.pc.in xorg-server.m4 autogen.sh +EXTRA_DIST = xorg-server.pc.in xorg-server.m4 autogen.sh README.md DISTCHECK_CONFIGURE_FLAGS=\ --with-xkb-path=$(XKB_BASE_DIRECTORY) \ @@ -1,4 +1,5 @@ - X Server +X Server +-------- The X server accepts requests from client applications to create windows, which are (normally rectangular) "virtual screens" that the client program @@ -16,29 +17,19 @@ https://en.wikipedia.org/wiki/X_server All questions regarding this software should be directed at the Xorg mailing list: - https://lists.freedesktop.org/mailman/listinfo/xorg - -Please submit bug reports to the Xorg bugzilla: - - https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + https://lists.freedesktop.org/mailman/listinfo/xorg The master development code repository can be found at: - git://anongit.freedesktop.org/git/xorg/xserver - - https://cgit.freedesktop.org/xorg/xserver + https://gitlab.freedesktop.org/xorg/xserver For patch submission instructions, see: - https://www.x.org/wiki/Development/Documentation/SubmittingPatches - -For more information on the git code manager, see: - - https://wiki.x.org/wiki/GitPage + https://www.x.org/wiki/Development/Documentation/SubmittingPatches As with other projects hosted on freedesktop.org, X.Org follows its Code of Conduct, based on the Contributor Covenant. Please conduct yourself in a respectful and civilized manner when using the above mailing lists, bug trackers, etc: - https://www.freedesktop.org/wiki/CodeOfConduct + https://www.freedesktop.org/wiki/CodeOfConduct diff --git a/Xext/dpms.c b/Xext/dpms.c index efa715428..e43a37974 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -45,9 +45,9 @@ Equipment Corporation. CARD16 DPMSPowerLevel = 0; Bool DPMSDisabledSwitch = FALSE; -CARD32 DPMSStandbyTime; -CARD32 DPMSSuspendTime; -CARD32 DPMSOffTime; +CARD32 DPMSStandbyTime = -1; +CARD32 DPMSSuspendTime = -1; +CARD32 DPMSOffTime = -1; Bool DPMSEnabled; Bool @@ -432,7 +432,15 @@ DPMSCloseDownExtension(ExtensionEntry *e) void DPMSExtensionInit(void) { - DPMSStandbyTime = DPMSSuspendTime = DPMSOffTime = ScreenSaverTime; +#define CONDITIONALLY_SET_DPMS_TIMEOUT(_timeout_value_) \ + if (_timeout_value_ == -1) { /* not yet set from config */ \ + _timeout_value_ = ScreenSaverTime; \ + } + + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSStandbyTime) + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSSuspendTime) + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSOffTime) + DPMSPowerLevel = DPMSModeOn; DPMSEnabled = DPMSSupported(); diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c index 844ea49ce..bd9c45b03 100644 --- a/Xext/panoramiX.c +++ b/Xext/panoramiX.c @@ -751,11 +751,7 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth) PanoramiXNumDepths, sizeof(DepthRec)); PanoramiXDepths[j].depth = pDepth->depth; PanoramiXDepths[j].numVids = 0; - /* XXX suboptimal, should grow these dynamically */ - if (pDepth->numVids) - PanoramiXDepths[j].vids = xallocarray(pDepth->numVids, sizeof(VisualID)); - else - PanoramiXDepths[j].vids = NULL; + PanoramiXDepths[j].vids = NULL; } static void @@ -796,6 +792,9 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual) for (k = 0; k < PanoramiXNumDepths; k++) { if (PanoramiXDepths[k].depth == pVisual->nplanes) { + PanoramiXDepths[k].vids = reallocarray(PanoramiXDepths[k].vids, + PanoramiXDepths[k].numVids + 1, + sizeof(VisualID)); PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; PanoramiXDepths[k].numVids++; break; diff --git a/Xext/shm.c b/Xext/shm.c index fc8441c43..589ed0b4d 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -834,6 +834,19 @@ ProcPanoramiXShmGetImage(ClientPtr client) return BadMatch; } + if (format == ZPixmap) { + widthBytesLine = PixmapBytePad(w, pDraw->depth); + length = widthBytesLine * h; + } + else { + widthBytesLine = PixmapBytePad(w, 1); + lenPer = widthBytesLine * h; + plane = ((Mask) 1) << (pDraw->depth - 1); + length = lenPer * Ones(planemask & (plane | (plane - 1))); + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); + drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); if (!drawables) return BadAlloc; @@ -856,18 +869,6 @@ ProcPanoramiXShmGetImage(ClientPtr client) .depth = pDraw->depth }; - if (format == ZPixmap) { - widthBytesLine = PixmapBytePad(w, pDraw->depth); - length = widthBytesLine * h; - } - else { - widthBytesLine = PixmapBytePad(w, 1); - lenPer = widthBytesLine * h; - plane = ((Mask) 1) << (pDraw->depth - 1); - length = lenPer * Ones(planemask & (plane | (plane - 1))); - } - - VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); xgi.size = length; if (length == 0) { /* nothing to do */ @@ -1302,9 +1303,14 @@ static int ProcShmDispatch(ClientPtr client) { REQUEST(xReq); - switch (stuff->data) { - case X_ShmQueryVersion: + + if (stuff->data == X_ShmQueryVersion) return ProcShmQueryVersion(client); + + if (!client->local) + return BadRequest; + + switch (stuff->data) { case X_ShmAttach: return ProcShmAttach(client); case X_ShmDetach: @@ -1461,9 +1467,14 @@ static int _X_COLD SProcShmDispatch(ClientPtr client) { REQUEST(xReq); - switch (stuff->data) { - case X_ShmQueryVersion: + + if (stuff->data == X_ShmQueryVersion) return SProcShmQueryVersion(client); + + if (!client->local) + return BadRequest; + + switch (stuff->data) { case X_ShmAttach: return SProcShmAttach(client); case X_ShmDetach: diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c index d0be70135..1926762ad 100644 --- a/Xi/xibarriers.c +++ b/Xi/xibarriers.c @@ -611,7 +611,9 @@ CreatePointerBarrierClient(ClientPtr client, } pbd->deviceid = dev->id; + input_lock(); xorg_list_add(&pbd->entry, &ret->per_device); + input_unlock(); } ret->id = stuff->barrier; @@ -626,7 +628,9 @@ CreatePointerBarrierClient(ClientPtr client, ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX); if (barrier_is_vertical(&ret->barrier)) ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY); + input_lock(); xorg_list_add(&ret->entry, &cs->barriers); + input_unlock(); *client_out = ret; return Success; @@ -689,7 +693,9 @@ BarrierFreeBarrier(void *data, XID id) mieqEnqueue(dev, (InternalEvent *) &ev); } + input_lock(); xorg_list_del(&c->entry); + input_unlock(); FreePointerBarrierClient(c); return Success; @@ -709,7 +715,9 @@ static void add_master_func(void *res, XID id, void *devid) pbd = AllocBarrierDevice(); pbd->deviceid = *deviceid; + input_lock(); xorg_list_add(&pbd->entry, &barrier->per_device); + input_unlock(); } static void remove_master_func(void *res, XID id, void *devid) @@ -752,7 +760,9 @@ static void remove_master_func(void *res, XID id, void *devid) mieqEnqueue(dev, (InternalEvent *) &ev); } + input_lock(); xorg_list_del(&pbd->entry); + input_unlock(); free(pbd); } diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c index aa965e46f..65d5870f6 100644 --- a/Xi/xipassivegrab.c +++ b/Xi/xipassivegrab.c @@ -88,7 +88,7 @@ ProcXIPassiveGrabDevice(ClientPtr client) }; int i, ret = Success; uint32_t *modifiers; - xXIGrabModifierInfo *modifiers_failed; + xXIGrabModifierInfo *modifiers_failed = NULL; GrabMask mask = { 0 }; GrabParameters param; void *tmp; @@ -232,8 +232,8 @@ ProcXIPassiveGrabDevice(ClientPtr client) if (rep.num_modifiers) WriteToClient(client, rep.length * 4, modifiers_failed); - free(modifiers_failed); out: + free(modifiers_failed); xi2mask_free(&mask.xi2mask); return ret; } diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index c0000f909..fbb51fe81 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -238,6 +238,18 @@ SizeDeviceClasses(DeviceIntPtr dev) } /** + * Get pointers to button information areas holding button mask and labels. + */ +static void +ButtonInfoData(xXIButtonInfo *info, int *mask_words, unsigned char **mask, + Atom **atoms) +{ + *mask_words = bytes_to_int32(bits_to_bytes(info->num_buttons)); + *mask = (unsigned char*) &info[1]; + *atoms = (Atom*) ((*mask) + (*mask_words) * 4); +} + +/** * Write button information into info. * @return Number of bytes written into info. */ @@ -245,21 +257,20 @@ int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) { unsigned char *bits; + Atom *labels; int mask_len; int i; if (!dev || !dev->button) return 0; - mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); - info->type = ButtonClass; info->num_buttons = dev->button->numButtons; + ButtonInfoData(info, &mask_len, &bits, &labels); info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + info->num_buttons + mask_len; info->sourceid = dev->button->sourceid; - bits = (unsigned char *) &info[1]; memset(bits, 0, mask_len * 4); if (reportState) @@ -267,8 +278,7 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) if (BitIsOn(dev->button->down, i)) SetBit(bits, i); - bits += mask_len * 4; - memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); + memcpy(labels, dev->button->labels, dev->button->numButtons * sizeof(Atom)); return info->length * 4; } @@ -277,13 +287,17 @@ static void SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info) { Atom *btn; + int mask_len; + unsigned char *mask; + int i; + ButtonInfoData(info, &mask_len, &mask, &btn); swaps(&info->type); swaps(&info->length); swaps(&info->sourceid); - for (i = 0, btn = (Atom *) &info[1]; i < info->num_buttons; i++, btn++) + for (i = 0 ; i < info->num_buttons; i++, btn++) swapl(btn); swaps(&info->num_buttons); @@ -369,6 +383,9 @@ SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo * info) swapl(&info->min.frac); swapl(&info->max.integral); swapl(&info->max.frac); + swapl(&info->value.integral); + swapl(&info->value.frac); + swapl(&info->resolution); swaps(&info->number); swaps(&info->sourceid); } diff --git a/composite/compalloc.c b/composite/compalloc.c index 433dc820a..3e2f14fb0 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -47,24 +47,18 @@ #include "compint.h" -static void -compScreenUpdate(ScreenPtr pScreen) -{ - compCheckTree(pScreen); - compPaintChildrenToWindow(pScreen->root); -} - -static void -compBlockHandler(ScreenPtr pScreen, void *pTimeout) +static Bool +compScreenUpdate(ClientPtr pClient, void *closure) { + ScreenPtr pScreen = closure; CompScreenPtr cs = GetCompScreen(pScreen); - pScreen->BlockHandler = cs->BlockHandler; - compScreenUpdate(pScreen); - (*pScreen->BlockHandler) (pScreen, pTimeout); + compCheckTree(pScreen); + compPaintChildrenToWindow(pScreen->root); - /* Next damage will restore the block handler */ - cs->BlockHandler = NULL; + /* Next damage will restore the worker */ + cs->pendingScreenUpdate = FALSE; + return TRUE; } void @@ -87,9 +81,9 @@ compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) CompScreenPtr cs = GetCompScreen(pScreen); CompWindowPtr cw = GetCompWindow(pWin); - if (!cs->BlockHandler) { - cs->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = compBlockHandler; + if (!cs->pendingScreenUpdate) { + QueueWorkProc(compScreenUpdate, serverClient, pScreen); + cs->pendingScreenUpdate = TRUE; } cw->damaged = TRUE; diff --git a/composite/compinit.c b/composite/compinit.c index 2590aa46d..6ea33ea4e 100644 --- a/composite/compinit.c +++ b/composite/compinit.c @@ -387,6 +387,8 @@ compScreenInit(ScreenPtr pScreen) cs->pOverlayWin = NULL; cs->pOverlayClients = NULL; + cs->pendingScreenUpdate = FALSE; + cs->numAlternateVisuals = 0; cs->alternateVisuals = NULL; cs->numImplicitRedirectExceptions = 0; @@ -442,8 +444,6 @@ compScreenInit(ScreenPtr pScreen) cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; pScreen->ChangeWindowAttributes = compChangeWindowAttributes; - cs->BlockHandler = NULL; - cs->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = compCloseScreen; diff --git a/composite/compint.h b/composite/compint.h index 89f6507b9..d501bad65 100644 --- a/composite/compint.h +++ b/composite/compint.h @@ -156,7 +156,8 @@ typedef struct _CompScreen { */ ChangeWindowAttributesProcPtr ChangeWindowAttributes; - ScreenBlockHandlerProcPtr BlockHandler; + Bool pendingScreenUpdate; + CloseScreenProcPtr CloseScreen; int numAlternateVisuals; VisualID *alternateVisuals; diff --git a/configure.ac b/configure.ac index 4ed23a6f6..8c134ba11 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.20.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2018-05-10" -RELEASE_NAME="Avocado Toast" +AC_INIT([xorg-server], 1.20.5, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server) +RELEASE_DATE="2019-05-30" +RELEASE_NAME="Red Lentil Dal" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -1916,9 +1916,6 @@ if test "x$XORG" = xyes; then XORG_OS_SUBDIR="linux" linux_acpi="no" case $host_cpu in - alpha*) - linux_alpha=yes - ;; i*86|amd64*|x86_64*|ia64*) linux_acpi=$enable_linux_acpi ;; @@ -2083,7 +2080,6 @@ AM_CONDITIONAL([XORG], [test "x$XORG" = xyes]) AM_CONDITIONAL([XORG_BUS_PCI], [test "x$PCI" = xyes]) AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes]) AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes]) -AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes]) AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes]) AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes]) AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) diff --git a/dix/devices.c b/dix/devices.c index 4a628afb0..1b18b168e 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1177,6 +1177,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent) flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); ret = Success; + break; } } @@ -1193,6 +1194,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent) prev->next = next; ret = Success; + break; } } diff --git a/dix/dixutils.c b/dix/dixutils.c index 540023cbd..2983174a1 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -508,6 +508,19 @@ WorkQueuePtr workQueue; static WorkQueuePtr *workQueueLast = &workQueue; void +ClearWorkQueue(void) +{ + WorkQueuePtr q, *p; + + p = &workQueue; + while ((q = *p)) { + *p = q->next; + free(q); + } + workQueueLast = p; +} + +void ProcessWorkQueue(void) { WorkQueuePtr q, *p; diff --git a/dix/getevents.c b/dix/getevents.c index d8955969a..f83dac709 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -331,9 +331,6 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to, static void updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) { - int i; - DeviceIntPtr lastSlave; - /* master->last.valuators[0]/[1] is in desktop-wide coords and the actual * position of the pointer */ pDev->last.valuators[0] = master->last.valuators[0]; @@ -358,27 +355,7 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) screenInfo.height); } - /* calculate the other axis as well based on info from the old - * slave-device. If the old slave had less axes than this one, - * last.valuators is reset to 0. - */ - if ((lastSlave = master->last.slave) && lastSlave->valuator) { - for (i = 2; i < pDev->valuator->numAxes; i++) { - if (i >= lastSlave->valuator->numAxes) { - pDev->last.valuators[i] = 0; - valuator_mask_set_double(pDev->last.scroll, i, 0); - } - else { - double val = pDev->last.valuators[i]; - - val = rescaleValuatorAxis(val, lastSlave->valuator->axes + i, - pDev->valuator->axes + i, 0, 0); - pDev->last.valuators[i] = val; - valuator_mask_set_double(pDev->last.scroll, i, val); - } - } - } - + /* other axes are left as-is */ } /** diff --git a/dix/inpututils.c b/dix/inpututils.c index 6bff9efab..c51c83547 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -282,7 +282,7 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, else if (!IsFloating(dev) && GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) { /* If this fails, expect the results to be weird. */ - if (check_modmap_change(client, dev->master, modmap)) + if (check_modmap_change(client, dev->master, modmap) == Success) do_modmap_change(client, dev->master, modmap); } diff --git a/dix/main.c b/dix/main.c index f98643aa5..b228d9c28 100644 --- a/dix/main.c +++ b/dix/main.c @@ -342,6 +342,8 @@ dix_main(int argc, char *argv[], char *envp[]) DeleteCallbackManager(); + ClearWorkQueue(); + if (dispatchException & DE_TERMINATE) { CloseWellKnownConnections(); } diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c index e34bebedb..958877efa 100644 --- a/dri3/dri3_request.c +++ b/dri3/dri3_request.c @@ -135,7 +135,7 @@ proc_dri3_open(ClientPtr client) REQUEST_SIZE_MATCH(xDRI3OpenReq); - status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess); + status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); if (status != Success) return status; @@ -365,7 +365,7 @@ proc_dri3_get_supported_modifiers(ClientPtr client) REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq); - status = dixLookupWindow(&window, stuff->window, client, DixReadAccess); + status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); if (status != Success) return status; pScreen = window->drawable.pScreen; diff --git a/exa/exa_render.c b/exa/exa_render.c index 50a9a659e..9fbfdfca2 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -291,7 +291,8 @@ exaTryDriverSolidFill(PicturePtr pSrc, pixel = exaGetPixmapFirstPixel(pSrcPix); } else - miRenderColorToPixel(pSrc->pFormat, + miRenderColorToPixel(PictureMatchFormat(pDst->pDrawable->pScreen, 32, + pSrc->format), &pSrc->pSourcePict->solidFill.fullcolor, &pixel); diff --git a/fb/fboverlay.c b/fb/fboverlay.c index a028a8de1..d47a7c67b 100644 --- a/fb/fboverlay.c +++ b/fb/fboverlay.c @@ -279,11 +279,11 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen, (&fbOverlayScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) return FALSE; - pScrPriv = malloc(sizeof(FbOverlayScrPrivRec)); - if (!pScrPriv) + if (bpp1 == 24 || bpp2 == 24) return FALSE; - if (bpp1 == 24 || bpp2 == 24) + pScrPriv = malloc(sizeof(FbOverlayScrPrivRec)); + if (!pScrPriv) return FALSE; if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1, diff --git a/glamor/glamor.c b/glamor/glamor.c index 86935ed98..b1c7d9f13 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -136,6 +136,9 @@ glamor_get_pixmap_texture(PixmapPtr pixmap) if (!pixmap_priv) return 0; + if (!pixmap_priv->fbo) + return 0; + if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY) return 0; @@ -563,6 +566,14 @@ glamor_init(ScreenPtr screen, unsigned int flags) if (!glamor_check_instruction_count(gl_version)) goto fail; + + /* Glamor rendering assumes that platforms with GLSL 130+ + * have instanced arrays, but this is not always the case. + * etnaviv offers GLSL 140 with OpenGL 2.1. + */ + if (glamor_priv->glsl_version >= 130 && + !epoxy_has_gl_extension("GL_ARB_instanced_arrays")) + glamor_priv->glsl_version = 120; } else { if (gl_version < 20) { ErrorF("Require Open GLES2.0 or later.\n"); @@ -818,56 +829,66 @@ glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format, return TRUE; } -_X_EXPORT int -glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, - uint32_t *strides, uint32_t *offsets, - uint64_t *modifier) +static int +_glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, + uint32_t *strides, uint32_t *offsets, + CARD32 *size, uint64_t *modifier) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); if (!glamor_priv->dri3_enabled) - return -1; + return 0; switch (pixmap_priv->type) { case GLAMOR_TEXTURE_DRM: case GLAMOR_TEXTURE_ONLY: if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ? GL_RGB10_A2 : GL_RGBA, 0)) - return -1; - return glamor_egl_fds_from_pixmap(screen, pixmap, fds, - strides, offsets, - modifier); + return 0; + + if (modifier) { + return glamor_egl_fds_from_pixmap(screen, pixmap, fds, + strides, offsets, + modifier); + } else { + CARD16 stride; + + fds[0] = glamor_egl_fd_from_pixmap(screen, pixmap, &stride, size); + strides[0] = stride; + + return fds[0] >= 0; + } default: break; } - return -1; + return 0; +} + +_X_EXPORT int +glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, + uint32_t *strides, uint32_t *offsets, + uint64_t *modifier) +{ + return _glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, + NULL, modifier); } _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { + int fd; int ret; - int fds[4]; - uint32_t strides[4], offsets[4]; - uint64_t modifier; - - ret = glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, - &modifier); + uint32_t stride32; - /* Pixmaps with multi-planes/modifier are not supported in this interface */ - if (ret > 1) { - while (ret > 0) - close(fds[--ret]); + ret = _glamor_fds_from_pixmap(screen, pixmap, &fd, &stride32, NULL, size, + NULL); + if (ret != 1) return -1; - } - - ret = fds[0]; - *stride = strides[0]; - *size = pixmap->drawable.height * *stride; - return ret; + *stride = stride32; + return fd; } _X_EXPORT int diff --git a/glamor/glamor.h b/glamor/glamor.h index 06e11506f..09e9c895c 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -141,7 +141,7 @@ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back); -/* The DDX is not supposed to call these three functions */ +/* The DDX is not supposed to call these four functions */ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen); extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *, uint32_t *, uint32_t *, @@ -150,6 +150,7 @@ extern _X_EXPORT int glamor_egl_fd_name_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen); +extern _X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); /* @glamor_supports_pixmap_import_export: Returns whether * glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 123e9f28d..d3c678d6b 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -99,8 +99,18 @@ glamor_get_flink_name(int fd, int handle, int *name) struct drm_gem_flink flink; flink.handle = handle; - if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) - return FALSE; + if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + + /* + * Assume non-GEM kernels have names identical to the handle + */ + if (errno == ENODEV) { + *name = handle; + return TRUE; + } else { + return FALSE; + } + } *name = flink.name; return TRUE; } @@ -402,7 +412,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, #endif } -static int +_X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { @@ -882,6 +892,7 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { struct glamor_egl_screen_private *glamor_egl; + const GLubyte *renderer; glamor_egl = calloc(sizeof(*glamor_egl), 1); if (glamor_egl == NULL) @@ -976,6 +987,19 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) "Failed to make EGL context current\n"); goto error; } + + renderer = glGetString(GL_RENDERER); + if (!renderer) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "glGetString() returned NULL, your GL is broken\n"); + goto error; + } + if (strstr((const char *)renderer, "llvmpipe")) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Refusing to try glamor on llvmpipe\n"); + goto error; + } + /* * Force the next glamor_make_current call to set the right context * (in case of multiple GPUs using glamor) @@ -989,7 +1013,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) } xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n", - glGetString(GL_RENDERER)); + renderer); #ifdef GBM_BO_WITH_MODIFIERS if (epoxy_has_egl_extension(glamor_egl->display, diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c index aae909e9f..91ab9a7ae 100644 --- a/glamor/glamor_egl_stubs.c +++ b/glamor/glamor_egl_stubs.c @@ -51,3 +51,10 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, { return 0; } + +int +glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ + return -1; +} diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 4e864cd79..eef078860 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -38,7 +38,7 @@ #define RADIAL_SMALL_STOPS (6 + 2) #define RADIAL_LARGE_STOPS (16 + 2) -static const char * +static char * _glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count, int use_array) { @@ -310,7 +310,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, "}\n"\ "\n"\ "%s\n" /* fs_getcolor_source */ - const char *fs_getcolor_source; + char *fs_getcolor_source; glamor_priv = glamor_get_screen_private(screen); @@ -343,6 +343,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); free(gradient_fs); + free(fs_getcolor_source); glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, fs_prog); @@ -493,7 +494,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, "}\n"\ "\n"\ "%s" /* fs_getcolor_source */ - const char *fs_getcolor_source; + char *fs_getcolor_source; glamor_priv = glamor_get_screen_private(screen); @@ -522,6 +523,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); free(gradient_fs); + free(fs_getcolor_source); glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, fs_prog); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 0417df4e6..d5737018f 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -766,18 +766,27 @@ glamor_set_normalize_tcoords_generic(PixmapPtr pixmap, * * We could support many more formats by using GL_ARB_texture_view to * parse the same bits as different formats. For now, we only support - * tweaking whether we sample the alpha bits of an a8r8g8b8, or just - * force them to 1. + * tweaking whether we sample the alpha bits, or just force them to 1. */ static Bool -glamor_render_format_is_supported(PictFormatShort format) +glamor_render_format_is_supported(PicturePtr picture) { - switch (format) { + PictFormatShort storage_format; + + /* Source-only pictures should always work */ + if (!picture->pDrawable) + return TRUE; + + storage_format = format_for_depth(picture->pDrawable->depth); + + switch (picture->format) { case PICT_x2r10g10b10: + return storage_format == PICT_x2r10g10b10; case PICT_a8r8g8b8: case PICT_x8r8g8b8: + return storage_format == PICT_a8r8g8b8 || storage_format == PICT_x8r8g8b8; case PICT_a8: - return TRUE; + return storage_format == PICT_a8; default: return FALSE; } @@ -815,7 +824,7 @@ glamor_composite_choose_shader(CARD8 op, goto fail; } - if (!glamor_render_format_is_supported(dest->format)) { + if (!glamor_render_format_is_supported(dest)) { glamor_fallback("Unsupported dest picture format.\n"); goto fail; } @@ -978,7 +987,7 @@ glamor_composite_choose_shader(CARD8 op, goto fail; } } else { - if (source && !glamor_render_format_is_supported(source->format)) { + if (source && !glamor_render_format_is_supported(source)) { glamor_fallback("Unsupported source picture format.\n"); goto fail; } @@ -990,7 +999,7 @@ glamor_composite_choose_shader(CARD8 op, goto fail; } } else if (mask) { - if (!glamor_render_format_is_supported(mask->format)) { + if (!glamor_render_format_is_supported(mask)) { glamor_fallback("Unsupported mask picture format.\n"); goto fail; } diff --git a/glx/createcontext.c b/glx/createcontext.c index 7d09c3a1c..24b02ddfb 100644 --- a/glx/createcontext.c +++ b/glx/createcontext.c @@ -28,6 +28,7 @@ #include "glxserver.h" #include "glxext.h" #include "indirect_dispatch.h" +#include "opaque.h" #define ALL_VALID_FLAGS \ (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \ @@ -320,6 +321,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc) err = BadAlloc; } else { + /* Only allow creating indirect GLX contexts if allowed by + * server command line. Indirect GLX is of limited use (since + * it's only GL 1.4), it's slower than direct contexts, and + * it's a massive attack surface for buffer overflow type + * errors. + */ + if (!enableIndirectGLX) { + client->errorValue = req->isDirect; + return BadValue; + } + ctx = glxScreen->createContext(glxScreen, config, shareCtx, req->numAttribs, (uint32_t *) attribs, &err); diff --git a/glx/vndcmds.c b/glx/vndcmds.c index 493e2bfc0..f0779d14a 100644 --- a/glx/vndcmds.c +++ b/glx/vndcmds.c @@ -50,7 +50,7 @@ typedef struct GlxVendorPrivDispatchRec { static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {}; static HashTable vendorPrivHash = NULL; static HtGenericHashSetupRec vendorPrivSetup = { - .keySize = sizeof(void*) + .keySize = sizeof(CARD32) }; static int DispatchBadRequest(ClientPtr client) @@ -386,10 +386,6 @@ static int dispatch_GLXVendorPriv(ClientPtr client) // Note that even if none of the vendors provides a dispatch stub, // we'll still add an entry to the dispatch table, so that we don't // have to look it up again later. - disp = (GlxVendorPrivDispatch *) malloc(sizeof(GlxVendorPrivDispatch)); - if (disp == NULL) { - return BadAlloc; - } disp->proc = GetVendorDispatchFunc(stuff->glxCode, GlxCheckSwap(client, diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 57c8b8dd4..9aeaea1a6 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -108,14 +108,14 @@ endif install-exec-hook: (cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) Xorg$(EXEEXT) X) if INSTALL_SETUID - chown root $(DESTDIR)$(bindir)/Xorg + chown 0 $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg endif if SUID_WRAPPER $(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR) mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg ${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg - -chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap + -chown 0 $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap endif uninstall-local: diff --git a/hw/xfree86/common/compiler.h b/hw/xfree86/common/compiler.h index eea29dfb5..7144c6a27 100644 --- a/hw/xfree86/common/compiler.h +++ b/hw/xfree86/common/compiler.h @@ -986,33 +986,64 @@ inl(unsigned PORT_SIZE port) #endif #ifdef __alpha__ -/* entry points for Mmio memory access routines */ -extern _X_EXPORT int (*xf86ReadMmio8) (void *, unsigned long); -extern _X_EXPORT int (*xf86ReadMmio16) (void *, unsigned long); -extern _X_EXPORT int (*xf86ReadMmio32) (void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio8) (int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio16) (int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio32) (int, void *, unsigned long); +static inline int +xf86ReadMmio8(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD8 *) ((unsigned long) Base + (Offset)); +} + +static inline int +xf86ReadMmio16(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD16 *) ((unsigned long) Base + (Offset)); +} + +static inline int +xf86ReadMmio32(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD32 *) ((unsigned long) Base + (Offset)); +} + +static inline void +xf86WriteMmio8(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD8 *) ((unsigned long) Base + (Offset)) = Value; +} + +static inline void +xf86WriteMmio16(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD16 *) ((unsigned long) Base + (Offset)) = Value; +} + +static inline void +xf86WriteMmio32(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD32 *) ((unsigned long) Base + (Offset)) = Value; +} + extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int); extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); /* Some macros to hide the system dependencies for MMIO accesses */ /* Changed to kill noise generated by gcc's -Wcast-align */ -#define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) -#define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) -#define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) - -#define MMIO_OUT32(base, offset, val) \ - do { \ - write_mem_barrier(); \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \ - } while (0) +#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) +#define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) +#define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) #define MMIO_OUT8(base, offset, val) \ - (*xf86WriteMmio8)((CARD8)(val), base, offset) + xf86WriteMmio8((CARD8)(val), base, offset) #define MMIO_OUT16(base, offset, val) \ - (*xf86WriteMmio16)((CARD16)(val), base, offset) + xf86WriteMmio16((CARD16)(val), base, offset) +#define MMIO_OUT32(base, offset, val) \ + xf86WriteMmio32((CARD32)(val), base, offset) #elif defined(__powerpc__) || defined(__sparc__) /* diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 2c1d335dc..e31030d63 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -939,10 +939,12 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) from = X_CMDLINE; i = -1; if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) { - if (i != 64 && i != 128 && i != 256 && i != 512) - ErrorF("MaxClients must be one of 64, 128, 256 or 512\n"); - from = X_CONFIG; - LimitClients = i; + if (Ones(i) != 1 || i < 64 || i > 2048) { + ErrorF("MaxClients must be one of 64, 128, 256, 512, 1024, or 2048\n"); + } else { + from = X_CONFIG; + LimitClients = i; + } } xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n", LimitClients, RESOURCE_ID_MASK); diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index e890f05c2..7cc7401a2 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -53,6 +53,8 @@ DevPrivateKeyRec xf86ScreenKeyRec; ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */ ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */ +int xf86DRMMasterFd = -1; /* Command line argument for DRM master file descriptor */ + const unsigned char byte_reversed[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 3c5cc7097..cabf8716b 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -1027,14 +1027,18 @@ ddxProcessArgument(int argc, char **argv, int i) /* First the options that are not allowed with elevated privileges */ if (!strcmp(argv[i], "-modulepath")) { CHECK_FOR_REQUIRED_ARGUMENT(); - xf86CheckPrivs(argv[i], argv[i + 1]); + if (xf86PrivsElevated()) + FatalError("\nInvalid argument -modulepath " + "with elevated privileges\n"); xf86ModulePath = argv[i + 1]; xf86ModPathFrom = X_CMDLINE; return 2; } if (!strcmp(argv[i], "-logfile")) { CHECK_FOR_REQUIRED_ARGUMENT(); - xf86CheckPrivs(argv[i], argv[i + 1]); + if (xf86PrivsElevated()) + FatalError("\nInvalid argument -logfile " + "with elevated privileges\n"); xf86LogFile = argv[i + 1]; xf86LogFileFrom = X_CMDLINE; return 2; diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 4fe2b5f33..393af3900 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -93,6 +93,7 @@ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */ extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */ extern int xf86NumGPUScreens; +extern _X_EXPORT int xf86DRMMasterFd; /* Command line argument for DRM master file descriptor */ #ifndef DEFAULT_VERBOSE #define DEFAULT_VERBOSE 0 #endif diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 0718cdcb0..6575c4ec8 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1190,7 +1190,7 @@ xf86VideoPtrToDriverList(struct pci_device *dev, XF86MatchedDrivers *md) { int idx = 0; -#ifdef __linux__ +#if defined(__linux__) || defined(__NetBSD__) driverList[idx++] = "nouveau"; #endif driverList[idx++] = "nv"; diff --git a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h index 82e4a549e..1ef1a0edf 100644 --- a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h +++ b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h @@ -174,6 +174,7 @@ CHIPSET(0x3EA4, cfl_gt1, "Intel(R) HD Graphics (Coffeelake 2x6 GT1)") CHIPSET(0x3E91, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)") CHIPSET(0x3E92, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)") CHIPSET(0x3E96, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") +CHIPSET(0x3E98, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)") CHIPSET(0x3E9A, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") CHIPSET(0x3E9B, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)") CHIPSET(0x3E94, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") diff --git a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h index 20c15837a..2ec8a1e24 100644 --- a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h +++ b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h @@ -205,3 +205,33 @@ CHIPSET(0x67CF, POLARIS10_, POLARIS10) CHIPSET(0x67DF, POLARIS10_, POLARIS10) CHIPSET(0x98E4, STONEY_, STONEY) + +CHIPSET(0x6980, POLARIS12_, POLARIS12) +CHIPSET(0x6981, POLARIS12_, POLARIS12) +CHIPSET(0x6985, POLARIS12_, POLARIS12) +CHIPSET(0x6986, POLARIS12_, POLARIS12) +CHIPSET(0x6987, POLARIS12_, POLARIS12) +CHIPSET(0x6995, POLARIS12_, POLARIS12) +CHIPSET(0x6997, POLARIS12_, POLARIS12) +CHIPSET(0x699F, POLARIS12_, POLARIS12) + +CHIPSET(0x694C, VEGAM_, VEGAM) +CHIPSET(0x694E, VEGAM_, VEGAM) + +CHIPSET(0x6860, VEGA10_, VEGA10) +CHIPSET(0x6861, VEGA10_, VEGA10) +CHIPSET(0x6862, VEGA10_, VEGA10) +CHIPSET(0x6863, VEGA10_, VEGA10) +CHIPSET(0x6864, VEGA10_, VEGA10) +CHIPSET(0x6867, VEGA10_, VEGA10) +CHIPSET(0x6868, VEGA10_, VEGA10) +CHIPSET(0x687F, VEGA10_, VEGA10) +CHIPSET(0x686C, VEGA10_, VEGA10) + +CHIPSET(0x69A0, VEGA12_, VEGA12) +CHIPSET(0x69A1, VEGA12_, VEGA12) +CHIPSET(0x69A2, VEGA12_, VEGA12) +CHIPSET(0x69A3, VEGA12_, VEGA12) +CHIPSET(0x69AF, VEGA12_, VEGA12) + +CHIPSET(0x15DD, RAVEN_, RAVEN) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 5d8906d63..8d29b130f 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -36,6 +36,7 @@ #include <unistd.h> #include <fcntl.h> #include "xf86.h" +#include "xf86Priv.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" @@ -195,17 +196,30 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn) } static int +get_passed_fd(void) +{ + if (xf86DRMMasterFd >= 0) { + xf86DrvMsg(-1, X_INFO, "Using passed DRM master file descriptor %d\n", xf86DRMMasterFd); + return dup(xf86DRMMasterFd); + } + return -1; +} + +static int open_hw(const char *dev) { int fd; + if ((fd = get_passed_fd()) != -1) + return fd; + if (dev) - fd = open(dev, O_RDWR, 0); + fd = open(dev, O_RDWR | O_CLOEXEC, 0); else { dev = getenv("KMSDEVICE"); - if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { + if ((NULL == dev) || ((fd = open(dev, O_RDWR | O_CLOEXEC, 0)) == -1)) { dev = "/dev/dri/card0"; - fd = open(dev, O_RDWR, 0); + fd = open(dev, O_RDWR | O_CLOEXEC, 0); } } if (fd == -1) @@ -626,19 +640,21 @@ ms_dirty_update(ScreenPtr screen, int *timeout) xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { region = DamageRegion(ent->damage); if (RegionNotEmpty(region)) { - msPixmapPrivPtr ppriv = - msGetPixmapPriv(&ms->drmmode, ent->slave_dst); + if (!screen->isGPU) { + msPixmapPrivPtr ppriv = + msGetPixmapPriv(&ms->drmmode, ent->slave_dst->master_pixmap); - if (ppriv->notify_on_damage) { - ppriv->notify_on_damage = FALSE; + if (ppriv->notify_on_damage) { + ppriv->notify_on_damage = FALSE; - ent->slave_dst->drawable.pScreen-> - SharedPixmapNotifyDamage(ent->slave_dst); - } + ent->slave_dst->drawable.pScreen-> + SharedPixmapNotifyDamage(ent->slave_dst); + } - /* Requested manual updating */ - if (ppriv->defer_dirty_update) - continue; + /* Requested manual updating */ + if (ppriv->defer_dirty_update) + continue; + } redisplay_dirty(screen, ent, timeout); DamageEmpty(ent->damage); @@ -818,6 +834,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn) return TRUE; } + ms->fd_passed = FALSE; + if ((ms->fd = get_passed_fd()) >= 0) { + ms->fd_passed = TRUE; + return TRUE; + } + #ifdef XSERVER_PLATFORM_BUS if (pEnt->location.type == BUS_PLATFORM) { #ifdef XF86_PDEV_SERVER_FD @@ -878,8 +900,6 @@ PreInit(ScrnInfoPtr pScrn, int flags) if (pScrn->numEntities != 1) return FALSE; - pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (flags & PROBE_DETECT) { return FALSE; } @@ -888,6 +908,8 @@ PreInit(ScrnInfoPtr pScrn, int flags) if (!GetRec(pScrn)) return FALSE; + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + ms = modesettingPTR(pScrn); ms->SaveGeneration = -1; ms->pEnt = pEnt; @@ -920,7 +942,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) "Using 24bpp hw front buffer with 32bpp shadow\n"); defaultbpp = 32; } else { - ms->drmmode.kbpp = defaultbpp; + ms->drmmode.kbpp = 0; } bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; @@ -941,6 +963,8 @@ PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } xf86PrintDepthBpp(pScrn); + if (!ms->drmmode.kbpp) + ms->drmmode.kbpp = pScrn->bitsPerPixel; /* Process the options */ xf86CollectOptions(pScrn, NULL); @@ -1014,8 +1038,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) #endif } - ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - ret |= drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); + ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); ms->atomic_modeset = (ret == 0); ms->kms_has_modifiers = FALSE; @@ -1230,8 +1253,8 @@ msStartFlippingPixmapTracking(RRCrtcPtr crtc, DrawablePtr src, ScreenPtr pScreen = src->pScreen; modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); - msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), - ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); + msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1->master_pixmap), + ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2->master_pixmap); if (!PixmapStartDirtyTracking(src, slave_dst1, x, y, dst_x, dst_y, rotation)) { @@ -1259,10 +1282,10 @@ msStartFlippingPixmapTracking(RRCrtcPtr crtc, DrawablePtr src, static Bool msPresentSharedPixmap(PixmapPtr slave_dst) { - ScreenPtr pScreen = slave_dst->drawable.pScreen; + ScreenPtr pScreen = slave_dst->master_pixmap->drawable.pScreen; modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); - msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, slave_dst); + msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, slave_dst->master_pixmap); RegionPtr region = DamageRegion(ppriv->dirty->damage); @@ -1283,8 +1306,8 @@ msStopFlippingPixmapTracking(DrawablePtr src, ScreenPtr pScreen = src->pScreen; modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); - msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), - ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); + msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1->master_pixmap), + ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2->master_pixmap); Bool ret = TRUE; @@ -1450,7 +1473,7 @@ msRequestSharedPixmapNotifyDamage(PixmapPtr ppix) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); - msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, ppix); + msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, ppix->master_pixmap); ppriv->notify_on_damage = TRUE; @@ -1502,6 +1525,9 @@ SetMaster(ScrnInfoPtr pScrn) return TRUE; #endif + if (ms->fd_passed) + return TRUE; + ret = drmSetMaster(ms->fd); if (ret) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", @@ -1754,7 +1780,8 @@ LeaveVT(ScrnInfoPtr pScrn) return; #endif - drmDropMaster(ms->fd); + if (!ms->fd_passed) + drmDropMaster(ms->fd); } /* @@ -1813,8 +1840,6 @@ CloseScreen(ScreenPtr pScreen) ms->drmmode.shadow_fb2 = NULL; } - drmmode_terminate_leases(pScrn, &ms->drmmode); - drmmode_uevent_fini(pScrn, &ms->drmmode); drmmode_free_bos(pScrn, &ms->drmmode); diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index 55f3400e2..c8db4b8a4 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -84,6 +84,7 @@ struct ms_drm_queue { typedef struct _modesettingRec { int fd; + Bool fd_passed; int Chipset; EntityInfoPtr pEnt; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 859a21a9d..336f7686e 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -398,7 +398,6 @@ drmmode_prop_info_copy(drmmode_prop_info_ptr dst, err: while (i--) free(dst[i].enum_values); - free(dst); return FALSE; } @@ -604,6 +603,8 @@ drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y) drmmode_ptr drmmode = drmmode_crtc->drmmode; int ret; + *fb_id = 0; + if (drmmode_crtc->prime_pixmap) { if (!drmmode->reverse_prime_offload_mode) { msPixmapPrivPtr ppriv = @@ -695,18 +696,21 @@ drmmode_output_disable(xf86OutputPtr output) { modesettingPtr ms = modesettingPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; + xf86CrtcPtr crtc = drmmode_output->current_crtc; drmModeAtomicReq *req = drmModeAtomicAlloc(); uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; - int ret; + int ret = 0; assert(ms->atomic_modeset); if (!req) return 1; - /* XXX Can we disable all outputs without disabling CRTC right away? */ - ret = connector_add_prop(req, drmmode_output, - DRMMODE_CONNECTOR_CRTC_ID, 0); + ret |= connector_add_prop(req, drmmode_output, + DRMMODE_CONNECTOR_CRTC_ID, 0); + if (crtc) + ret |= crtc_add_dpms_props(req, crtc, DPMSModeOff, NULL); + if (ret == 0) ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); @@ -990,7 +994,7 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo, } #endif return drmModeAddFB(drmmode->fd, bo->width, bo->height, - drmmode->scrn->depth, drmmode->scrn->bitsPerPixel, + drmmode->scrn->depth, drmmode->kbpp, drmmode_bo_get_pitch(bo), drmmode_bo_get_handle(bo), fb_id); } @@ -1350,13 +1354,19 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) { modesettingPtr ms = modesettingPTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; /* XXX Check if DPMS mode is already the right one */ drmmode_crtc->dpms_mode = mode; - if (ms->atomic_modeset && mode != DPMSModeOn && !ms->pending_modeset) - drmmode_crtc_disable(crtc); + if (ms->atomic_modeset) { + if (mode != DPMSModeOn && !ms->pending_modeset) + drmmode_crtc_disable(crtc); + } else if (crtc->enabled == FALSE) { + drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + 0, 0, 0, NULL, 0, NULL); + } } #ifdef GLAMOR_HAS_GBM @@ -1794,11 +1804,8 @@ drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } - ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, - drmmode->kbpp, - drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), - drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), - &drmmode_crtc->rotate_fb_id); + ret = drmmode_bo_import(drmmode, &drmmode_crtc->rotate_bo, + &drmmode_crtc->rotate_fb_id); if (ret) { ErrorF("failed to add rotate fb\n"); @@ -2833,7 +2840,7 @@ static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, if (len + 1> 5) return -1; memcpy(conn_id, blob_data + 4, len); - conn_id[len + 1] = '\0'; + conn_id[len] = '\0'; id = strtoul(conn_id, NULL, 10); *conn_base_id = id; @@ -3251,6 +3258,9 @@ drmmode_create_lease(RRLeasePtr lease, int *fd) nobjects = ncrtc + noutput; + if (ms->atomic_modeset) + nobjects += ncrtc; /* account for planes as well */ + if (nobjects == 0) return BadValue; @@ -3267,12 +3277,14 @@ drmmode_create_lease(RRLeasePtr lease, int *fd) i = 0; - /* Add CRTC ids */ + /* Add CRTC and plane ids */ for (c = 0; c < ncrtc; c++) { xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; objects[i++] = drmmode_crtc->mode_crtc->crtc_id; + if (ms->atomic_modeset) + objects[i++] = drmmode_crtc->plane_id; } /* Add connector ids */ @@ -3320,23 +3332,6 @@ drmmode_terminate_lease(RRLeasePtr lease) } } -void -drmmode_terminate_leases(ScrnInfoPtr pScrn, drmmode_ptr drmmode) -{ - ScreenPtr screen = xf86ScrnToScreen(pScrn); - rrScrPrivPtr scr_priv = rrGetScrPriv(screen); - RRLeasePtr lease, next; - - xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) { - drmmode_lease_private_ptr lease_private = lease->devPrivate; - drmModeRevokeLease(drmmode->fd, lease_private->lessee_id); - free(lease_private); - lease->devPrivate = NULL; - RRLeaseTerminated(lease); - RRLeaseFree(lease); - } -} - static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { .resize = drmmode_xf86crtc_resize, .create_lease = drmmode_create_lease, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index e46a292d3..cde661450 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -272,8 +272,6 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); -extern void drmmode_terminate_leases(ScrnInfoPtr scrn, drmmode_ptr drmmode); - Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); void *drmmode_map_front_bo(drmmode_ptr drmmode); Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); diff --git a/hw/xfree86/drivers/modesetting/modesetting.man b/hw/xfree86/drivers/modesetting/modesetting.man index d90352380..d530d7c4c 100644 --- a/hw/xfree86/drivers/modesetting/modesetting.man +++ b/hw/xfree86/drivers/modesetting/modesetting.man @@ -14,10 +14,13 @@ modesetting \- video driver for framebuffer device .fi .SH DESCRIPTION .B modesetting -is an @xservername@ driver for KMS devices. This is a non-accelerated -driver, the following framebuffer depths are supported: 8, 15, 16, 24. -All visual types are supported for depth 8, and TrueColor visual is -supported for the other depths. RandR 1.2 is supported. +is an @xservername@ driver for KMS devices. This driver supports +TrueColor visuals at framebuffer depths of 15, 16, 24, and 30. RandR +1.2 is supported for multi-head configurations. Acceleration is available +through glamor for devices supporting at least OpenGL ES 2.0 or OpenGL 2.1. +If glamor is not enabled, a shadow framebuffer is configured based on the +KMS drivers' preference (unless the framebuffer is 24 bits per pixel, in +which case the shadow framebuffer is always used). .SH SUPPORTED HARDWARE The .B modesetting @@ -51,8 +54,18 @@ The framebuffer device to use. Default: /dev/dri/card0. .BI "Option \*qShadowFB\*q \*q" boolean \*q Enable or disable use of the shadow framebuffer layer. Default: on. .TP +.BI "Option \*qDoubleShadow\*q \*q" boolean \*q +Double-buffer shadow updates. When enabled, the driver will keep two copies of +the shadow framebuffer. When the shadow framebuffer is flushed, the old and new +versions of the shadow are compared, and only tiles that have actually changed +are uploaded to the device. This is an optimization for server-class GPUs with +a remote display function (typically VNC), where remote updates are triggered +by any framebuffer write, so minimizing the amount of data uploaded is crucial. +This defaults to enabled for ASPEED and Matrox G200 devices, and disabled +otherwise. +.TP .BI "Option \*qAccelMethod\*q \*q" string \*q -One of \*qglamor\*q or \*qnone\*q. Default: glamor +One of \*qglamor\*q or \*qnone\*q. Default: glamor. .TP .BI "Option \*qPageFlip\*q \*q" boolean \*q Enable DRI3 page flipping. The default is diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c index 0bd77df87..95089515c 100644 --- a/hw/xfree86/fbdevhw/fbdevhw.c +++ b/hw/xfree86/fbdevhw/fbdevhw.c @@ -329,6 +329,22 @@ fbdev_open(int scrnIndex, const char *dev, char **namep) return -1; } + /* only touch non-PCI devices on this path */ + { + char buf[PATH_MAX]; + char *sysfs_path = NULL; + char *node = strrchr(dev, '/') + 1; + + if (asprintf(&sysfs_path, "/sys/class/graphics/%s", node) < 0 || + readlink(sysfs_path, buf, sizeof(buf)) < 0 || + strstr(buf, "devices/pci")) { + free(sysfs_path); + close(fd); + return -1; + } + free(sysfs_path); + } + if (namep) { if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, (void *) (&fix))) { *namep = NULL; diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 4aa77a244..37a45bb3a 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -174,6 +174,32 @@ xf86CrtcInUse(xf86CrtcPtr crtc) return FALSE; } +/** + * Return whether the crtc is leased by a client + */ + +static Bool +xf86CrtcIsLeased(xf86CrtcPtr crtc) +{ + /* If the DIX structure hasn't been created, it can't have been leased */ + if (!crtc->randr_crtc) + return FALSE; + return RRCrtcIsLeased(crtc->randr_crtc); +} + +/** + * Return whether the output is leased by a client + */ + +static Bool +xf86OutputIsLeased(xf86OutputPtr output) +{ + /* If the DIX structure hasn't been created, it can't have been leased */ + if (!output->randr_output) + return FALSE; + return RROutputIsLeased(output->randr_output); +} + void xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen) { @@ -254,7 +280,7 @@ xf86CrtcSetModeTransform(xf86CrtcPtr crtc, DisplayModePtr mode, RRTransformRec saved_transform; Bool saved_transform_present; - crtc->enabled = xf86CrtcInUse(crtc) && !RRCrtcIsLeased(crtc->randr_crtc);; + crtc->enabled = xf86CrtcInUse(crtc) && !xf86CrtcIsLeased(crtc); /* We only hit this if someone explicitly sends a "disabled" modeset. */ if (!crtc->enabled) { @@ -412,7 +438,7 @@ xf86CrtcSetOrigin(xf86CrtcPtr crtc, int x, int y) crtc->x = x; crtc->y = y; - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) return; if (crtc->funcs->set_origin) { @@ -734,14 +760,11 @@ xf86CrtcCloseScreen(ScreenPtr screen) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o, c; - screen->CloseScreen = config->CloseScreen; - - xf86RotateCloseScreen(screen); - - xf86RandR12CloseScreen(screen); - - screen->CloseScreen(screen); - + /* The randr_output and randr_crtc pointers are already invalid as + * the DIX resources were freed when the associated resources were + * freed. Clear them now; referencing through them during the rest + * of the CloseScreen sequence will not end well. + */ for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -752,6 +775,15 @@ xf86CrtcCloseScreen(ScreenPtr screen) crtc->randr_crtc = NULL; } + + screen->CloseScreen = config->CloseScreen; + + xf86RotateCloseScreen(screen); + + xf86RandR12CloseScreen(screen); + + screen->CloseScreen(screen); + /* detach any providers */ if (config->randr_provider) { RRProviderDestroy(config->randr_provider); @@ -2656,7 +2688,7 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) static void xf86DisableCrtc(xf86CrtcPtr crtc) { - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) return; crtc->funcs->dpms(crtc, DPMSModeOff); @@ -2677,7 +2709,7 @@ xf86PrepareOutputs(ScrnInfoPtr scrn) for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; - if (RROutputIsLeased(output->randr_output)) + if (xf86OutputIsLeased(output)) continue; #if RANDR_GET_CRTC_INTERFACE @@ -2703,7 +2735,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn) uint32_t desired_outputs = 0, current_outputs = 0; int o; - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) continue; for (o = 0; o < config->num_output; o++) { @@ -2726,7 +2758,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn) if (desired_outputs != current_outputs || !desired_outputs) xf86DisableCrtc(crtc); #else - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) continue; xf86DisableCrtc(crtc); @@ -2964,7 +2996,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; - if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) + if (!xf86OutputIsLeased(output) && output->crtc != NULL) (*output->funcs->dpms) (output, mode); } } @@ -2980,7 +3012,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; - if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) + if (!xf86OutputIsLeased(output) && output->crtc != NULL) (*output->funcs->dpms) (output, mode); } } diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index b49d4c789..34f2652bf 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -2019,7 +2019,7 @@ xf86RandR12ChangeGamma(ScrnInfoPtr pScrn, Gamma gamma) RRCrtcPtr randr_crtc = xf86CompatRRCrtc(pScrn); int size; - if (!randr_crtc) + if (!randr_crtc || pScrn->LoadPalette == xf86RandR12LoadPalette) return Success; size = max(0, randr_crtc->gammaSize); diff --git a/hw/xfree86/os-support/bsd/Makefile.am b/hw/xfree86/os-support/bsd/Makefile.am index b01ea5bca..66ac83805 100644 --- a/hw/xfree86/os-support/bsd/Makefile.am +++ b/hw/xfree86/os-support/bsd/Makefile.am @@ -26,8 +26,7 @@ endif if ALPHA_VIDEO # Cheat here and piggyback other alpha bits on ALPHA_VIDEO. ARCH_SOURCES = \ - alpha_video.c \ - bsd_ev56.c + alpha_video.c endif if ARM_VIDEO diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am index 26e40bb93..9b4535b53 100644 --- a/hw/xfree86/os-support/linux/Makefile.am +++ b/hw/xfree86/os-support/linux/Makefile.am @@ -1,13 +1,5 @@ noinst_LTLIBRARIES = liblinux.la -if LINUX_ALPHA -noinst_LTLIBRARIES += liblinuxev56.la - -liblinuxev56_la_CFLAGS = $(AM_CFLAGS) -mcpu=ev56 - -liblinuxev56_la_SOURCES = lnx_ev56.c -endif - if LNXACPI ACPI_SRCS = lnx_acpi.c if !LNXAPM @@ -39,7 +31,3 @@ liblinux_la_SOURCES = linux.h lnx_init.c lnx_video.c \ AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES) AM_CPPFLAGS = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS) - -if LINUX_ALPHA -liblinux_la_LIBADD = liblinuxev56.la -endif diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index a00002464..039dc4a4d 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -346,6 +346,13 @@ xf86CloseConsole(void) close(xf86Info.consoleFd); /* make the vt-manager happy */ } +#define CHECK_FOR_REQUIRED_ARGUMENT() \ + if (((i + 1) >= argc) || (!argv[i + 1])) { \ + ErrorF("Required argument to %s not specified\n", argv[i]); \ + UseMsg(); \ + FatalError("Required argument to %s not specified\n", argv[i]); \ + } + int xf86ProcessArgument(int argc, char *argv[], int i) { @@ -366,6 +373,19 @@ xf86ProcessArgument(int argc, char *argv[], int i) } return 1; } + + if (!strcmp(argv[i], "-masterfd")) { + CHECK_FOR_REQUIRED_ARGUMENT(); + if (xf86PrivsElevated()) + FatalError("\nCannot specify -masterfd when server is setuid/setgid\n"); + if (sscanf(argv[++i], "%d", &xf86DRMMasterFd) != 1) { + UseMsg(); + xf86DRMMasterFd = -1; + return 0; + } + return 2; + } + return 0; } @@ -375,4 +395,5 @@ xf86UseMsg(void) ErrorF("vtXX use the specified VT number\n"); ErrorF("-keeptty "); ErrorF("don't detach controlling tty (for debugging only)\n"); + ErrorF("-masterfd <fd> use the specified fd as the DRM master fd (not if setuid/gid)\n"); } diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 11af52c46..70374ace8 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -43,7 +43,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) } if (fd == -1) - fd = open(path, O_RDWR, O_CLOEXEC); + fd = open(path, O_RDWR | O_CLOEXEC, 0); if (fd == -1) return FALSE; diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c index c09d71947..04e45092a 100644 --- a/hw/xfree86/os-support/linux/lnx_video.c +++ b/hw/xfree86/os-support/linux/lnx_video.c @@ -166,30 +166,3 @@ xf86DisableIO(void) ExtendedEnabled = FALSE; } - -#if defined (__alpha__) - -extern int readDense8(void *Base, register unsigned long Offset); -extern int readDense16(void *Base, register unsigned long Offset); -extern int readDense32(void *Base, register unsigned long Offset); -extern void - writeDense8(int Value, void *Base, register unsigned long Offset); -extern void - writeDense16(int Value, void *Base, register unsigned long Offset); -extern void - writeDense32(int Value, void *Base, register unsigned long Offset); - -void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset) - = writeDense8; -void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset) - = writeDense16; -void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset) - = writeDense32; -int (*xf86ReadMmio8) (void *Base, unsigned long Offset) - = readDense8; -int (*xf86ReadMmio16) (void *Base, unsigned long Offset) - = readDense16; -int (*xf86ReadMmio32) (void *Base, unsigned long Offset) - = readDense32; - -#endif /* __alpha__ */ diff --git a/hw/xfree86/os-support/meson.build b/hw/xfree86/os-support/meson.build index 901422786..b6e5c975d 100644 --- a/hw/xfree86/os-support/meson.build +++ b/hw/xfree86/os-support/meson.build @@ -100,7 +100,6 @@ elif host_machine.system().endswith('bsd') srcs_xorg_os_support += 'shared/ioperm_noop.c' elif host_machine.cpu_family() == 'alpha' srcs_xorg_os_support += 'bsd/alpha_video.c' - srcs_xorg_os_support += 'bsd/bsd_ev56.c' endif if host_machine.system() == 'freebsd' diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c index 6768d290b..0cb9788cc 100644 --- a/hw/xfree86/os-support/shared/posix_tty.c +++ b/hw/xfree86/os-support/shared/posix_tty.c @@ -188,7 +188,7 @@ xf86SetSerial(int fd, XF86OptionPtr options) { struct termios t; int val; - const char *s; + char *s; int baud, r; if (fd < 0) @@ -264,8 +264,10 @@ xf86SetSerial(int fd, XF86OptionPtr options) } else { xf86Msg(X_ERROR, "Invalid Option Parity value: %s\n", s); + free(s); return -1; } + free(s); } if ((val = xf86SetIntOption(options, "Vmin", -1)) != -1) { @@ -291,8 +293,10 @@ xf86SetSerial(int fd, XF86OptionPtr options) } else { xf86Msg(X_ERROR, "Invalid Option FlowControl value: %s\n", s); + free(s); return -1; } + free(s); } if ((xf86SetBoolOption(options, "ClearDTR", FALSE))) { diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am index a0f9e9fe4..b2c446af8 100644 --- a/hw/xquartz/mach-startup/Makefile.am +++ b/hw/xquartz/mach-startup/Makefile.am @@ -76,6 +76,8 @@ nodist_Xquartz_SOURCES = \ Xquartz_LDFLAGS = \ -Wl,-framework,CoreServices +if XQUARTZ + BUILT_SOURCES = \ mach_startupServer.c \ mach_startupUser.c \ @@ -88,6 +90,8 @@ CLEANFILES = \ $(BUILT_SOURCES): $(srcdir)/mach_startup.defs mig -sheader mach_startupServer.h $(srcdir)/mach_startup.defs +endif + EXTRA_DIST = \ launchd_fd.h \ mach_startup.defs \ diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c index 8dd1cc304..c62c0d2ac 100644 --- a/hw/xwayland/xwayland-glamor-eglstream.c +++ b/hw/xwayland/xwayland-glamor-eglstream.c @@ -187,6 +187,89 @@ xwl_eglstream_cleanup(struct xwl_screen *xwl_screen) 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_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap) { @@ -229,8 +312,6 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap) static struct wl_buffer * xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created) { /* XXX created? */ @@ -559,11 +640,11 @@ const struct wl_eglstream_display_listener eglstream_display_listener = { .swapinterval_override = xwl_eglstream_display_handle_swapinterval_override, }; -static void +static Bool xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, struct wl_registry *wl_registry, - const char *name, - uint32_t id, uint32_t version) + uint32_t id, const char *name, + uint32_t version) { struct xwl_eglstream_private *xwl_eglstream = xwl_eglstream_get(xwl_screen); @@ -575,10 +656,34 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, 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; } + + /* 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 @@ -691,6 +796,12 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen) 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"); @@ -740,14 +851,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen) xwl_eglstream_get(xwl_screen); ScreenPtr screen = xwl_screen->screen; - if (!xwl_eglstream->controller) { - ErrorF("No eglstream controller was exposed in the wayland registry. " - "This means your version of nvidia's EGL wayland libraries " - "are too old, as we require support for this.\n"); - xwl_eglstream_cleanup(xwl_screen); - return FALSE; - } - /* We can just let glamor handle CreatePixmap */ screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap; @@ -792,23 +895,24 @@ out: return device; } -Bool +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 FALSE; + return; if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0)) - return FALSE; + return; xwl_eglstream = calloc(sizeof(*xwl_eglstream), 1); if (!xwl_eglstream) { - ErrorF("Failed to allocate memory required to init eglstream support\n"); - return FALSE; + ErrorF("Failed to allocate memory required to init EGLStream support\n"); + return; } dixSetPrivate(&xwl_screen->screen->devPrivates, @@ -817,14 +921,12 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) xwl_eglstream->egl_device = egl_device; xorg_list_init(&xwl_eglstream->pending_streams); - xwl_screen->egl_backend.init_egl = xwl_glamor_eglstream_init_egl; - xwl_screen->egl_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry; - xwl_screen->egl_backend.init_screen = xwl_glamor_eglstream_init_screen; - xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap; - xwl_screen->egl_backend.post_damage = xwl_glamor_eglstream_post_damage; - xwl_screen->egl_backend.allow_commits = xwl_glamor_eglstream_allow_commits; - - ErrorF("glamor: Using nvidia's eglstream interface, direct rendering impossible.\n"); - ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n"); - return TRUE; + 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.is_available = TRUE; } diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index 29325adac..a211e0915 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -124,6 +124,22 @@ is_fd_render_node(int fd) return 0; } +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 = is_fd_render_node(fd); + close(fd); + + return is_render_node; +} + static PixmapPtr xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth) @@ -230,13 +246,13 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap) static struct wl_buffer * xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created) { 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; int prime_fd; int num_planes; uint32_t strides[4]; @@ -244,6 +260,9 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, uint64_t modifier; int i; + if (xwl_pixmap == NULL) + return NULL; + if (xwl_pixmap->buffer) { /* Buffer already exists. Return it and inform caller if interested. */ if (created) @@ -272,7 +291,7 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, #else num_planes = 1; modifier = DRM_FORMAT_MOD_INVALID; - strides[0] = gbm_go_get_stride(xwl_pixmap->bo); + strides[0] = gbm_bo_get_stride(xwl_pixmap->bo); offsets[0] = 0; #endif @@ -494,6 +513,9 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, xwl_pixmap = xwl_pixmap_get(pixmap); + if (xwl_pixmap == NULL) + return 0; + if (!xwl_pixmap->bo) return 0; @@ -517,6 +539,16 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, #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; +} + _X_EXPORT Bool glamor_get_formats(ScreenPtr screen, CARD32 *num_formats, CARD32 **formats) @@ -595,14 +627,80 @@ static const dri3_screen_info_rec xwl_dri3_info = { .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); - xwl_gbm->device_name = strdup(device); if (!xwl_gbm->device_name) { xwl_glamor_gbm_cleanup(xwl_screen); return; @@ -734,16 +832,42 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, return TRUE; } -static void +static Bool xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen, struct wl_registry *wl_registry, - const char *name, - uint32_t id, uint32_t version) + uint32_t id, const char *name, + uint32_t version) { - if (strcmp(name, "wl_drm") == 0) + if (strcmp(name, "wl_drm") == 0) { xwl_screen_set_drm_interface(xwl_screen, id, version); - else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) + 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 @@ -761,6 +885,7 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen) GLAMOR_GL_CORE_VER_MINOR, EGL_NONE }; + const GLubyte *renderer; if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) { ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n"); @@ -807,8 +932,20 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen) goto error; } - if (!epoxy_has_gl_extension("GL_OES_EGL_image")) + 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") && @@ -835,11 +972,16 @@ error: 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"); @@ -852,6 +994,7 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen) goto error; } +skip_drm_auth: xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap; xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap; @@ -861,27 +1004,32 @@ error: return FALSE; } -Bool +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 FALSE; + return; xwl_gbm = calloc(sizeof(*xwl_gbm), 1); if (!xwl_gbm) { ErrorF("glamor: Not enough memory to setup GBM, disabling\n"); - return FALSE; + return; } dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key, xwl_gbm); - xwl_screen->egl_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry; - xwl_screen->egl_backend.init_egl = xwl_glamor_gbm_init_egl; - xwl_screen->egl_backend.init_screen = xwl_glamor_gbm_init_screen; - xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap; - - return TRUE; + 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.is_available = TRUE; } diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index cdca072ed..7ea6def61 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -52,88 +52,12 @@ xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen) xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx); } -Bool -xwl_glamor_egl_supports_device_probing(void) -{ - return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base"); -} - -void ** -xwl_glamor_egl_get_devices(int *num_devices) -{ -#ifdef XWL_HAS_EGLSTREAM - EGLDeviceEXT *devices; - Bool ret; - int drm_dev_count = 0; - int i; - - /* 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; - devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count); - - return devices; - -error: - free(devices); -#endif - return NULL; -} - -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; -} - 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; @@ -148,24 +72,36 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen, uint32_t id, const char *interface, uint32_t version) { - if (xwl_screen->egl_backend.init_wl_registry) - xwl_screen->egl_backend.init_wl_registry(xwl_screen, registry, - interface, id, 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, - unsigned short width, - unsigned short height, Bool *created) { 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, - width, - height, - created); + if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap) + return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap, + created); return NULL; } @@ -176,8 +112,8 @@ xwl_glamor_post_damage(struct xwl_window *xwl_window, { struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - if (xwl_screen->egl_backend.post_damage) - xwl_screen->egl_backend.post_damage(xwl_window, pixmap, region); + if (xwl_screen->egl_backend->post_damage) + xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region); } Bool @@ -185,8 +121,8 @@ 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); + if (xwl_screen->egl_backend->allow_commits) + return xwl_screen->egl_backend->allow_commits(xwl_window); else return TRUE; } @@ -228,6 +164,68 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen, return 0; } +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)) { + ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n"); + ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n"); + 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) { @@ -240,7 +238,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) return FALSE; } - if (!xwl_screen->egl_backend.init_egl(xwl_screen)) { + if (!xwl_screen->egl_backend->init_egl(xwl_screen)) { ErrorF("EGL setup failed, disabling glamor\n"); return FALSE; } @@ -250,7 +248,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) return FALSE; } - if (!xwl_screen->egl_backend.init_screen(xwl_screen)) { + if (!xwl_screen->egl_backend->init_screen(xwl_screen)) { ErrorF("EGL backend init_screen() failed, disabling glamor\n"); return FALSE; } diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 0a37f97bd..fbbcb39cc 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -37,6 +37,12 @@ #include <misc.h> #include "tablet-unstable-v2-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; @@ -565,6 +571,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer, 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: @@ -577,8 +585,22 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer, return; } + xorg_list_for_each_entry(iter, &xwl_seat->axis_discrete_pending, l) { + if (iter->axis == axis) { + pending = iter; + break; + } + } + valuator_mask_zero(&mask); - valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor); + + 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(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask); } @@ -608,6 +630,16 @@ 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 = { @@ -1337,6 +1369,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version 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); } @@ -1345,6 +1378,7 @@ 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) { @@ -1357,6 +1391,11 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) 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); @@ -1565,8 +1604,8 @@ tablet_tool_motion(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; int32_t dx, dy; - int sx = wl_fixed_to_int(x); - int sy = wl_fixed_to_int(y); + double sx = wl_fixed_to_double(x); + double sy = wl_fixed_to_double(y); if (!xwl_seat->tablet_focus_window) return; @@ -1574,8 +1613,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool, dx = xwl_seat->tablet_focus_window->window->drawable.x; dy = xwl_seat->tablet_focus_window->window->drawable.y; - xwl_tablet_tool->x = dx + sx; - xwl_tablet_tool->y = dy + sy; + xwl_tablet_tool->x = (double) dx + sx; + xwl_tablet_tool->y = (double) dy + sy; } static void @@ -1733,15 +1772,15 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) int button; valuator_mask_zero(&mask); - valuator_mask_set(&mask, 0, xwl_tablet_tool->x); - valuator_mask_set(&mask, 1, xwl_tablet_tool->y); + 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(&mask, 3, xwl_tablet_tool->tilt_x); - valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); - valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); + 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_SCREEN, &mask); + POINTER_ABSOLUTE | POINTER_DESKTOP, &mask); valuator_mask_zero(&mask); diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 48faeb142..cc68f0340 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -38,6 +38,8 @@ 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) { @@ -211,6 +213,7 @@ 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; int width = 0, height = 0, has_this_output = 0; RRModePtr randr_mode; Bool need_rotate; @@ -222,7 +225,16 @@ apply_output_change(struct xwl_output *xwl_output) /* xdg-output sends output size in compositor space. so already rotated */ need_rotate = (xwl_output->xdg_output == NULL); - randr_mode = xwayland_cvt(xwl_output->width, xwl_output->height, + /* We need to rotate back the logical size for the mode */ + if (need_rotate || 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; + } + + randr_mode = xwayland_cvt(mode_width, mode_height, xwl_output->refresh / 1000.0, 0, 0); RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); RRCrtcNotify(xwl_output->randr_crtc, randr_mode, @@ -392,14 +404,15 @@ xwl_output_remove(struct xwl_output *xwl_output) int width = 0, height = 0; Bool need_rotate = (xwl_output->xdg_output == NULL); - RRCrtcDestroy(xwl_output->randr_crtc); - RROutputDestroy(xwl_output->randr_output); xorg_list_del(&xwl_output->link); xorg_list_for_each_entry(it, &xwl_screen->output_list, link) output_get_new_size(it, need_rotate, &height, &width); update_screen_size(xwl_output, width, height); + RRCrtcDestroy(xwl_output->randr_crtc); + RROutputDestroy(xwl_output->randr_output); + xwl_output_destroy(xwl_output); } @@ -435,7 +448,7 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen) return TRUE; } -void +static void xwl_output_get_xdg_output(struct xwl_output *xwl_output) { struct xwl_screen *xwl_screen = xwl_output->xwl_screen; diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index b5ae80dcf..2937d9c97 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -85,28 +85,23 @@ xwl_present_timer_callback(OsTimerPtr timer, static inline Bool xwl_present_has_events(struct xwl_present_window *xwl_present_window) { - return !xorg_list_is_empty(&xwl_present_window->event_list) || - !xorg_list_is_empty(&xwl_present_window->release_queue); -} - -static inline Bool -xwl_present_is_flipping(WindowPtr window, struct xwl_window *xwl_window) -{ - return xwl_window && xwl_window->present_window == window; + return !!xwl_present_window->sync_flip || + !xorg_list_is_empty(&xwl_present_window->event_list); } static void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window) { if (xwl_present_has_events(xwl_present_window)) { - WindowPtr present_window = xwl_present_window->window; - Bool is_flipping = xwl_present_is_flipping(present_window, - xwl_window_from_window(present_window)); + CARD32 timeout; + + if (xwl_present_window->frame_callback) + timeout = TIMER_LEN_FLIP; + else + timeout = TIMER_LEN_COPY; xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer, - 0, - is_flipping ? TIMER_LEN_FLIP : - TIMER_LEN_COPY, + 0, timeout, &xwl_present_timer_callback, xwl_present_window); } else { @@ -117,21 +112,22 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window) void xwl_present_cleanup(WindowPtr window) { - struct xwl_window *xwl_window = xwl_window_from_window(window); struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); struct xwl_present_event *event, *tmp; if (!xwl_present_window) return; - if (xwl_window && xwl_window->present_window == window) - xwl_window->present_window = NULL; - if (xwl_present_window->frame_callback) { wl_callback_destroy(xwl_present_window->frame_callback); xwl_present_window->frame_callback = NULL; } + 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, &xwl_present_window->event_list, list) { xorg_list_del(&event->list); @@ -139,6 +135,16 @@ xwl_present_cleanup(WindowPtr window) } /* Clear remaining buffer releases and inform Present about free ressources */ + event = xwl_present_window->sync_flip; + xwl_present_window->sync_flip = NULL; + if (event) { + if (event->buffer_released) { + free(event); + } else { + event->pending = FALSE; + event->abort = TRUE; + } + } xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) { xorg_list_del(&event->list); event->abort = TRUE; @@ -147,6 +153,11 @@ xwl_present_cleanup(WindowPtr window) /* 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); } @@ -187,11 +198,31 @@ static const struct wl_buffer_listener xwl_present_release_listener = { }; static void -xwl_present_events_notify(struct xwl_present_window *xwl_present_window) +xwl_present_msc_bump(struct xwl_present_window *xwl_present_window) { - uint64_t msc = xwl_present_window->msc; + uint64_t msc = ++xwl_present_window->msc; struct xwl_present_event *event, *tmp; + xwl_present_window->ust = GetTimeInMicros(); + + event = xwl_present_window->sync_flip; + xwl_present_window->sync_flip = NULL; + if (event) { + event->pending = FALSE; + + present_wnmd_event_notify(xwl_present_window->window, event->event_id, + xwl_present_window->ust, msc); + + if (event->buffer_released) { + /* If the buffer was already released, clean up now */ + present_wnmd_event_notify(xwl_present_window->window, event->event_id, + xwl_present_window->ust, msc); + free(event); + } else { + xorg_list_add(&event->list, &xwl_present_window->release_queue); + } + } + xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) { @@ -211,24 +242,13 @@ xwl_present_timer_callback(OsTimerPtr timer, void *arg) { struct xwl_present_window *xwl_present_window = arg; - WindowPtr present_window = xwl_present_window->window; - struct xwl_window *xwl_window = xwl_window_from_window(present_window); xwl_present_window->frame_timer_firing = TRUE; - xwl_present_window->msc++; - xwl_present_window->ust = GetTimeInMicros(); - xwl_present_events_notify(xwl_present_window); + xwl_present_msc_bump(xwl_present_window); + xwl_present_reset_timer(xwl_present_window); - if (xwl_present_has_events(xwl_present_window)) { - /* Still events, restart timer */ - return xwl_present_is_flipping(present_window, xwl_window) ? TIMER_LEN_FLIP : - TIMER_LEN_COPY; - } else { - /* No more events, do not restart timer and delete it instead */ - xwl_present_free_timer(xwl_present_window); - return 0; - } + return 0; } static void @@ -246,10 +266,7 @@ xwl_present_frame_callback(void *data, return; } - xwl_present_window->msc++; - xwl_present_window->ust = GetTimeInMicros(); - - xwl_present_events_notify(xwl_present_window); + xwl_present_msc_bump(xwl_present_window); /* we do not need the timer anymore for this frame, * reset it for potentially the next one @@ -269,6 +286,9 @@ xwl_present_sync_callback(void *data, struct xwl_present_event *event = data; struct xwl_present_window *xwl_present_window = event->xwl_present_window; + wl_callback_destroy(xwl_present_window->sync_callback); + xwl_present_window->sync_callback = NULL; + event->pending = FALSE; if (event->abort) { @@ -284,12 +304,14 @@ xwl_present_sync_callback(void *data, xwl_present_window->ust, xwl_present_window->msc); - if (event->buffer_released) + if (event->buffer_released) { /* If the buffer was already released, send the event now again */ present_wnmd_event_notify(xwl_present_window->window, event->event_id, xwl_present_window->ust, xwl_present_window->msc); + xwl_present_free_event(event); + } } static const struct wl_callback_listener xwl_present_sync_listener = { @@ -306,6 +328,10 @@ xwl_present_get_crtc(WindowPtr present_window) return NULL; rr_private = rrGetScrPriv(present_window->drawable.pScreen); + + if (rr_private->numCrtcs == 0) + return NULL; + return rr_private->crtcs[0]; } @@ -332,17 +358,9 @@ xwl_present_queue_vblank(WindowPtr present_window, uint64_t event_id, uint64_t msc) { - struct xwl_window *xwl_window = xwl_window_from_window(present_window); struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window); struct xwl_present_event *event; - if (!xwl_window) - return BadMatch; - - if (xwl_window->present_window && - xwl_window->present_window != present_window) - return BadMatch; - event = malloc(sizeof *event); if (!event) return BadAlloc; @@ -412,13 +430,6 @@ xwl_present_check_flip2(RRCrtcPtr crtc, return FALSE; /* - * Do not flip if there is already another child window doing flips. - */ - if (xwl_window->present_window && - xwl_window->present_window != 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. @@ -440,7 +451,7 @@ xwl_present_flip(WindowPtr present_window, { 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 present_box, damage_box; + BoxPtr damage_box; Bool buffer_created; struct wl_buffer *buffer; struct xwl_present_event *event; @@ -448,29 +459,28 @@ xwl_present_flip(WindowPtr present_window, if (!xwl_window) return FALSE; - present_box = RegionExtents(&present_window->winSize); damage_box = RegionExtents(damage); event = malloc(sizeof *event); if (!event) return FALSE; - xwl_window->present_window = present_window; - - buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, - present_box->x2 - present_box->x1, - present_box->y2 - present_box->y1, - &buffer_created); + buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created); event->event_id = event_id; event->xwl_present_window = xwl_present_window; event->buffer = buffer; - event->target_msc = xwl_present_window->msc; + event->target_msc = target_msc; event->pending = TRUE; event->abort = FALSE; event->buffer_released = FALSE; - xorg_list_add(&event->list, &xwl_present_window->release_queue); + if (sync_flip) { + xorg_list_init(&event->list); + xwl_present_window->sync_flip = event; + } else { + xorg_list_add(&event->list, &xwl_present_window->release_queue); + } if (buffer_created) wl_buffer_add_listener(buffer, &xwl_present_release_listener, NULL); @@ -479,13 +489,6 @@ xwl_present_flip(WindowPtr present_window, /* We can flip directly to the main surface (full screen window without clips) */ wl_surface_attach(xwl_window->surface, buffer, 0, 0); - if (!xwl_present_window->frame_timer || - xwl_present_window->frame_timer_firing) { - /* Realign timer */ - xwl_present_window->frame_timer_firing = FALSE; - xwl_present_reset_timer(xwl_present_window); - } - if (!xwl_present_window->frame_callback) { xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface); wl_callback_add_listener(xwl_present_window->frame_callback, @@ -493,35 +496,51 @@ xwl_present_flip(WindowPtr present_window, xwl_present_window); } + /* Realign timer */ + xwl_present_window->frame_timer_firing = FALSE; + xwl_present_reset_timer(xwl_present_window); + wl_surface_damage(xwl_window->surface, 0, 0, damage_box->x2 - damage_box->x1, damage_box->y2 - damage_box->y1); wl_surface_commit(xwl_window->surface); - 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); + 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); + } wl_display_flush(xwl_window->xwl_screen->display); + xwl_window->present_flipped = TRUE; return TRUE; } static void xwl_present_flips_stop(WindowPtr window) { - struct xwl_window *xwl_window = xwl_window_from_window(window); struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); - if (!xwl_window) - return; + /* Change back to the fast refresh rate */ + xwl_present_reset_timer(xwl_present_window); +} - assert(xwl_window->present_window == window); +void +xwl_present_unrealize_window(WindowPtr window) +{ + struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); - xwl_window->present_window = NULL; + if (!xwl_present_window || !xwl_present_window->frame_callback) + return; - /* Change back to the fast refresh rate */ + /* The pending frame callback may never be called, so drop it and shorten + * the frame timer interval. + */ + wl_callback_destroy(xwl_present_window->frame_callback); + xwl_present_window->frame_callback = NULL; xwl_present_reset_timer(xwl_present_window); } @@ -547,10 +566,9 @@ xwl_present_init(ScreenPtr screen) struct xwl_screen *xwl_screen = xwl_screen_get(screen); /* - * doesn't work with the streams backend. we don't have an explicit - * boolean for that, but we do know gbm doesn't fill in this hook... + * doesn't work with the EGLStream backend. */ - if (xwl_screen->egl_backend.post_damage != NULL) + if (xwl_screen->egl_backend == &xwl_screen->eglstream_backend) return FALSE; if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0)) diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 1d6b49979..7e6e0ab25 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -96,9 +96,7 @@ ddxUseMsg(void) ErrorF("-rootless run rootless, requires wm support\n"); ErrorF("-wm fd create X client for wm on given fd\n"); ErrorF("-listen fd add give fd as a listen socket\n"); -#ifdef XWL_HAS_EGLSTREAM ErrorF("-eglstream use eglstream backend for nvidia GPUs\n"); -#endif } int @@ -117,11 +115,9 @@ ddxProcessArgument(int argc, char *argv[], int i) else if (strcmp(argv[i], "-shm") == 0) { return 1; } -#ifdef XWL_HAS_EGLSTREAM else if (strcmp(argv[i], "-eglstream") == 0) { return 1; } -#endif return 0; } @@ -374,6 +370,18 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) struct xwl_window *xwl_window = data; struct xwl_screen *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); } @@ -601,6 +609,11 @@ xwl_unrealize_window(WindowPtr window) xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; screen->UnrealizeWindow = xwl_unrealize_window; +#ifdef GLAMOR_HAS_GBM + if (xwl_screen->present) + xwl_present_unrealize_window(window); +#endif + xwl_window = xwl_window_get(window); if (!xwl_window) return ret; @@ -682,8 +695,6 @@ xwl_window_post_damage(struct xwl_window *xwl_window) #ifdef XWL_HAS_GLAMOR if (xwl_screen->glamor) buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, - pixmap->drawable.width, - pixmap->drawable.height, NULL); else #endif @@ -727,11 +738,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) xorg_list_for_each_entry_safe(xwl_window, next_xwl_window, &xwl_screen->damage_window_list, link_damage) { -#ifdef GLAMOR_HAS_GBM - /* Present on the main surface. So don't commit here as well. */ - if (xwl_window->present_window) - continue; -#endif /* If we're waiting on a frame callback from the server, * don't attach a new buffer. */ if (xwl_window->frame_callback) @@ -741,7 +747,7 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) continue; #ifdef XWL_HAS_GLAMOR - if (!xwl_glamor_allow_commits(xwl_window)) + if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window)) continue; #endif @@ -943,9 +949,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) struct xwl_screen *xwl_screen; Pixel red_mask, blue_mask, green_mask; int ret, bpc, green_bpc, i; -#ifdef XWL_HAS_EGLSTREAM Bool use_eglstreams = FALSE; -#endif xwl_screen = calloc(1, sizeof *xwl_screen); if (xwl_screen == NULL) @@ -988,28 +992,18 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) else if (strcmp(argv[i], "-shm") == 0) { xwl_screen->glamor = 0; } -#ifdef XWL_HAS_EGLSTREAM 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) { -#ifdef XWL_HAS_EGLSTREAM - if (use_eglstreams) { - if (!xwl_glamor_init_eglstream(xwl_screen)) { - ErrorF("xwayland glamor: failed to setup eglstream backend, falling back to swaccel\n"); - xwl_screen->glamor = 0; - } - } else -#endif - if (!xwl_glamor_init_gbm(xwl_screen)) { - ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n"); - xwl_screen->glamor = 0; - } - } + 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 @@ -1095,9 +1089,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) return FALSE; #ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) { - ErrorF("Failed to initialize glamor, falling back to sw\n"); - xwl_screen->glamor = 0; + 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) @@ -1134,6 +1132,10 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); + wl_display_roundtrip(xwl_screen->display); + while (xwl_screen->expecting_event) + wl_display_roundtrip(xwl_screen->display); + return ret; } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 25112e2cb..463622669 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -57,6 +57,60 @@ struct xwl_format { struct xwl_pixmap; struct xwl_window; +struct xwl_screen; + +struct xwl_egl_backend { + /* Set by the backend if available */ + Bool is_available; + + /* 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, + Bool *created); + + /* 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. + */ + void (*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); +}; struct xwl_screen { int width; @@ -109,55 +163,10 @@ struct xwl_screen { struct xwl_format *formats; void *egl_display, *egl_context; - /* the current backend for creating pixmaps on wayland */ - struct { - /* Called once for each interface in the global registry. Backends - * should use this to bind to any wayland interfaces they need. This - * callback is optional. - */ - void (*init_wl_registry)(struct xwl_screen *xwl_screen, - struct wl_registry *wl_registry, - const char *name, uint32_t id, - uint32_t version); - - /* 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, - unsigned short width, - unsigned short height, - Bool *created); - - /* 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. - */ - void (*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); - } egl_backend; + 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; @@ -173,12 +182,15 @@ struct xwl_window { struct xorg_list link_damage; struct wl_callback *frame_callback; Bool allow_commits; - WindowPtr present_window; +#ifdef GLAMOR_HAS_GBM + Bool present_flipped; +#endif }; #ifdef GLAMOR_HAS_GBM struct xwl_present_window { struct xwl_screen *xwl_screen; + struct xwl_present_event *sync_flip; WindowPtr window; struct xorg_list link; @@ -263,6 +275,7 @@ struct xwl_seat { 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; @@ -301,13 +314,13 @@ struct xwl_tablet_tool { DeviceIntPtr xdevice; uint32_t proximity_in_serial; - uint32_t x; - uint32_t y; + double x; + double y; uint32_t pressure; - float tilt_x; - float tilt_y; - float rotation; - float slider; + double tilt_x; + double tilt_y; + double rotation; + double slider; uint32_t buttons_now, buttons_prev; @@ -414,7 +427,11 @@ PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height, Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap); struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(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, @@ -422,58 +439,52 @@ Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, 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, - unsigned short width, - unsigned short height, Bool *created); 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); void 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); #ifdef GLAMOR_HAS_GBM Bool xwl_present_init(ScreenPtr screen); void xwl_present_cleanup(WindowPtr window); -#endif - -void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); - -void xwl_output_get_xdg_output(struct xwl_output *xwl_output); -void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); - -void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen); -Bool xwl_glamor_egl_supports_device_probing(void); -void **xwl_glamor_egl_get_devices(int *num_devices); -Bool xwl_glamor_egl_device_has_egl_extensions(void *device, - const char **ext_list, - size_t size); +void xwl_present_unrealize_window(WindowPtr window); +#endif /* GLAMOR_HAS_GBM */ #ifdef XV /* glamor Xv Adaptor */ Bool xwl_glamor_xv_init(ScreenPtr pScreen); -#endif +#endif /* XV */ + +#endif /* XWL_HAS_GLAMOR */ + +void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); + +void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); #ifdef XF86VIDMODE void xwlVidModeExtensionInit(void); #endif #ifdef GLAMOR_HAS_GBM -Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); +void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); #else -static inline Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) +static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) { - return FALSE; } #endif #ifdef XWL_HAS_EGLSTREAM -Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); +void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); #else -static inline Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) +static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) { - return FALSE; } #endif diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am index 160bef5b0..ae9debe5c 100644 --- a/hw/xwin/glx/Makefile.am +++ b/hw/xwin/glx/Makefile.am @@ -55,9 +55,10 @@ generated_gl_thunks.ic: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml generated_gl_thunks.def: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml $(KHRONOS_SPEC_DIR)/reg.py $(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/gl.xml -thunkdefs $(GENGLWRAPPERSOPTS) -outfile $@ -endif BUILT_SOURCES = generated_gl_shim.ic generated_gl_thunks.ic generated_gl_thunks.def generated_wgl_wrappers.ic CLEANFILES = $(BUILT_SOURCES) +endif + EXTRA_DIST = gen_gl_wrappers.py diff --git a/include/Makefile.am b/include/Makefile.am index 0ce7faa6e..9c22ce113 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -79,5 +79,8 @@ EXTRA_DIST = \ swapreq.h \ systemd-logind.h \ 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/dix.h b/include/dix.h index 476559842..b6e2bcfde 100644 --- a/include/dix.h +++ b/include/dix.h @@ -240,6 +240,8 @@ extern _X_EXPORT void RemoveBlockAndWakeupHandlers(ServerBlockHandlerProcPtr blo extern _X_EXPORT void InitBlockAndWakeupHandlers(void); +extern _X_EXPORT void ClearWorkQueue(void); + extern _X_EXPORT void ProcessWorkQueue(void); extern _X_EXPORT void ProcessWorkQueueZombies(void); diff --git a/include/meson.build b/include/meson.build index f76f557be..dfca3c340 100644 --- a/include/meson.build +++ b/include/meson.build @@ -153,10 +153,10 @@ conf_data.set('BUSFAULT', conf_data.get('HAVE_SIGACTION')) conf_data.set('_XTYPEDEF_POINTER', '1') conf_data.set('_XITYPEDEF_POINTER', '1') +conf_data.set('LISTEN_TCP', get_option('listen_tcp')) +conf_data.set('LISTEN_UNIX', get_option('listen_unix')) +conf_data.set('LISTEN_LOCAL', get_option('listen_local')) # XXX: Configurable? -conf_data.set('LISTEN_TCP', '1') -conf_data.set('LISTEN_UNIX', '1') -conf_data.set('LISTEN_LOCAL', '1') conf_data.set('XTRANS_SEND_FDS', '1') conf_data.set('TCPCONN', '1') diff --git a/include/xserver_poll.h b/include/xserver_poll.h index 5a42307df..0f3a37c73 100644 --- a/include/xserver_poll.h +++ b/include/xserver_poll.h @@ -24,7 +24,7 @@ #define _XSERVER_POLL_H_ #ifndef _DIX_CONFIG_H_ -#error must inclue dix-config.h to use xserver_poll.h +#error must include dix-config.h to use xserver_poll.h #endif #ifdef HAVE_POLL diff --git a/meson.build b/meson.build index 5a5a6a5e0..d99882324 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project('xserver', 'c', 'buildtype=debugoptimized', 'c_std=gnu99', ], - version: '1.20.0', + version: '1.20.5', meson_version: '>= 0.47.0', ) add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c') diff --git a/meson_options.txt b/meson_options.txt index 86fca4668..3453b8df5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -45,6 +45,13 @@ option('vendor_name_short', type: 'string', value: 'X.Org') option('vendor_web', type: 'string', value: 'http://wiki.x.org') option('os_vendor', type: 'string', value: '') +option('listen_tcp', type: 'boolean', value: false, + description: 'Listen on TCP by default') +option('listen_unix', type: 'boolean', value: true, + description: 'Listen on Unix by default') +option('listen_local', type: 'boolean', value: true, + description: 'Listen on local by default') + option('int10', type: 'combo', choices: ['stub', 'x86emu', 'vm86', 'auto', 'false'], value: 'auto', description: 'Xorg int10 backend (default: usually x86emu)') diff --git a/mi/mibitblt.c b/mi/mibitblt.c index 2de5bf8fd..43d9bd917 100644 --- a/mi/mibitblt.c +++ b/mi/mibitblt.c @@ -141,6 +141,8 @@ miCopyArea(DrawablePtr pSrcDrawable, free(ordering); free(pwidthFirst); free(pptFirst); + if (realSrcClip) + RegionDestroy(prgnSrcClip); return NULL; } diff --git a/mi/miinitext.c b/mi/miinitext.c index 5596e212f..b7c702127 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -190,7 +190,7 @@ EnableDisableExtension(const char *name, Bool enable) for (i = 0; i < ARRAY_SIZE(staticExtensions); i++) { ext = &staticExtensions[i]; - if (strcmp(name, ext->name) == 0) { + if (strcasecmp(name, ext->name) == 0) { if (ext->disablePtr != NULL) { *ext->disablePtr = !enable; return TRUE; diff --git a/miext/damage/damage.c b/miext/damage/damage.c index de14d5cc8..f3ae4ebbc 100644 --- a/miext/damage/damage.c +++ b/miext/damage/damage.c @@ -829,16 +829,36 @@ damagePolyPoint(DrawablePtr pDrawable, /* this could be slow if the points were spread out */ - while (--nptTmp) { - pptTmp++; - if (box.x1 > pptTmp->x) - box.x1 = pptTmp->x; - else if (box.x2 < pptTmp->x) - box.x2 = pptTmp->x; - if (box.y1 > pptTmp->y) - box.y1 = pptTmp->y; - else if (box.y2 < pptTmp->y) - box.y2 = pptTmp->y; + if (mode == CoordModePrevious) { + int x = box.x1; + int y = box.y1; + + while (--nptTmp) { + pptTmp++; + x += pptTmp->x; + y += pptTmp->y; + if (box.x1 > x) + box.x1 = x; + else if (box.x2 < x) + box.x2 = x; + if (box.y1 > y) + box.y1 = y; + else if (box.y2 < y) + box.y2 = y; + } + } + else { + while (--nptTmp) { + pptTmp++; + if (box.x1 > pptTmp->x) + box.x1 = pptTmp->x; + else if (box.x2 < pptTmp->x) + box.x2 = pptTmp->x; + if (box.y1 > pptTmp->y) + box.y1 = pptTmp->y; + else if (box.y2 < pptTmp->y) + box.y2 = pptTmp->y; + } } box.x2++; diff --git a/os/WaitFor.c b/os/WaitFor.c index 7c7b1d2d4..dc33c1648 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -190,10 +190,11 @@ WaitForSomething(Bool are_ready) /* deal with any blocked jobs */ if (workQueue) { ProcessWorkQueue(); - are_ready = clients_are_ready(); } timeout = check_timers(); + are_ready = clients_are_ready(); + if (are_ready) timeout = 0; @@ -42,6 +42,7 @@ from The Open Group. #include "dixstruct.h" #include <sys/types.h> #include <sys/stat.h> +#include <errno.h> #ifdef WIN32 #include <X11/Xw32defs.h> #endif @@ -119,9 +120,15 @@ LoadAuthorization(void) if (!authorization_file) return 0; + errno = 0; f = Fopen(authorization_file, "r"); - if (!f) + if (!f) { + LogMessageVerb(X_ERROR, 0, + "Failed to open authorization file \"%s\": %s\n", + authorization_file, + errno != 0 ? strerror(errno) : "Unknown error"); return -1; + } while ((auth = XauReadAuth(f)) != 0) { for (i = 0; i < NUM_AUTHORIZATION; i++) { @@ -194,6 +194,8 @@ LogFilePrep(const char *fname, const char *backup, const char *idstring) { char *logFileName = NULL; + /* the format string below is controlled by the user, + this code should never be called with elevated privileges */ if (asprintf(&logFileName, fname, idstring) == -1) FatalError("Cannot allocate space for the log file name\n"); diff --git a/os/meson.build b/os/meson.build index f9b19d7a0..4c49d0964 100644 --- a/os/meson.build +++ b/os/meson.build @@ -56,9 +56,13 @@ endif rpc_dep = [] if get_option('secure-rpc') - # prefer libtirpc (if available), otherwise assume RPC functions are + # prefer libtirpc (if available), otherwise ensure RPC functions are # provided by libc. rpc_dep = dependency('libtirpc', required: false) + if not (rpc_dep.found() or cc.has_header('rpc/rpc.h')) + error('secure-rpc requested, but neither libtirpc or libc RPC support were found') + endif + srcs_os += 'rpcauth.c' endif diff --git a/os/utils.c b/os/utils.c index eb2c3b8e8..7764418f0 100644 --- a/os/utils.c +++ b/os/utils.c @@ -486,14 +486,15 @@ GetTimeInMicros(void) struct timeval tv; #ifdef MONOTONIC_CLOCK struct timespec tp; + static clockid_t uclockid; - if (!clockid) { + if (!uclockid) { if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) - clockid = CLOCK_MONOTONIC; + uclockid = CLOCK_MONOTONIC; else - clockid = ~0L; + uclockid = ~0L; } - if (clockid != ~0L && clock_gettime(clockid, &tp) == 0) + if (uclockid != ~0L && clock_gettime(uclockid, &tp) == 0) return (CARD64) tp.tv_sec * (CARD64)1000000 + tp.tv_nsec / 1000; #endif diff --git a/os/xdmcp.c b/os/xdmcp.c index d8c81fbf8..62adead84 100644 --- a/os/xdmcp.c +++ b/os/xdmcp.c @@ -569,10 +569,9 @@ XdmcpRegisterDisplayClass(const char *name, int length) } static void -xdmcp_start(void) +xdmcp_reset(void) { timeOutRtx = 0; - get_xdmcp_sock(); if (xdmcpSocket >= 0) SetNotifyFd(xdmcpSocket, XdmcpSocketNotify, X_NOTIFY_READ, NULL); #if defined(IPv6) && defined(AF_INET6) @@ -583,6 +582,13 @@ xdmcp_start(void) send_packet(); } +static void +xdmcp_start(void) +{ + get_xdmcp_sock(); + xdmcp_reset(); +} + /* * initialize XDMCP; create the socket, compute the display * number, set up the state machine @@ -611,7 +617,7 @@ XdmcpReset(void) { state = XDM_INIT_STATE; if (state != XDM_OFF) - xdmcp_start(); + xdmcp_reset(); } /* diff --git a/present/present.c b/present/present.c index 37cbf0720..3eddb7434 100644 --- a/present/present.c +++ b/present/present.c @@ -108,7 +108,7 @@ present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct pr if (present_fence) present_fence_set_triggered(present_fence); if (window) { - DebugPresent(("\ti %08lx\n", pixmap ? pixmap->drawable.id : 0)); + DebugPresent(("\ti %08" PRIx32 "\n", pixmap ? pixmap->drawable.id : 0)); present_send_idle_notify(window, serial, pixmap, present_fence); } } diff --git a/present/present_priv.h b/present/present_priv.h index f62456755..5849b9e0b 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -34,6 +34,7 @@ #include <syncsrv.h> #include <xfixes.h> #include <randrstr.h> +#include <inttypes.h> #if 0 #define DebugPresent(x) ErrorF x diff --git a/present/present_scmd.c b/present/present_scmd.c index 0803a0c0b..3b7fbd832 100644 --- a/present/present_scmd.c +++ b/present/present_scmd.c @@ -78,7 +78,7 @@ present_check_flip(RRCrtcPtr crtc, PresentFlipReason *reason) { ScreenPtr screen = window->drawable.pScreen; - PixmapPtr window_pixmap; + PixmapPtr screen_pixmap, window_pixmap; WindowPtr root = screen->root; present_screen_priv_ptr screen_priv = present_screen_priv(screen); @@ -99,8 +99,9 @@ present_check_flip(RRCrtcPtr crtc, return FALSE; /* Make sure the window hasn't been redirected with Composite */ + screen_pixmap = screen->GetScreenPixmap(screen); window_pixmap = screen->GetWindowPixmap(window); - if (window_pixmap != screen->GetScreenPixmap(screen) && + if (window_pixmap != screen_pixmap && window_pixmap != screen_priv->flip_pixmap && window_pixmap != present_flip_pending_pixmap(screen)) return FALSE; @@ -126,19 +127,20 @@ present_check_flip(RRCrtcPtr crtc, window->drawable.x != pixmap->screen_x || window->drawable.y != pixmap->screen_y || #endif window->drawable.width != pixmap->drawable.width || - window->drawable.height != pixmap->drawable.height) { + window->drawable.height != pixmap->drawable.height || + pixmap->devKind != screen_pixmap->devKind) { return FALSE; } /* Ask the driver for permission */ if (screen_priv->info->version >= 1 && screen_priv->info->check_flip2) { if (!(*screen_priv->info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) { - DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); + DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); return FALSE; } } else if (screen_priv->info->check_flip) { if (!(*screen_priv->info->check_flip) (crtc, window, pixmap, sync_flip)) { - DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); + DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); return FALSE; } } @@ -351,7 +353,7 @@ present_unflip(ScreenPtr screen) present_restore_screen_pixmap(screen); screen_priv->unflip_event_id = ++present_event_id; - DebugPresent(("u %lld\n", screen_priv->unflip_event_id)); + DebugPresent(("u %" PRIu64 "\n", screen_priv->unflip_event_id)); (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id); } @@ -361,7 +363,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) ScreenPtr screen = vblank->screen; present_screen_priv_ptr screen_priv = present_screen_priv(screen); - DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n", + DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", vblank->event_id, vblank, vblank->target_msc, vblank->pixmap ? vblank->pixmap->drawable.id : 0, vblank->window ? vblank->window->drawable.id : 0)); @@ -402,7 +404,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc) if (!event_id) return; - DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc)); + DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc)); xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) { int64_t match = event_id - vblank->event_id; if (match == 0) { @@ -425,7 +427,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc) present_screen_priv_ptr screen_priv = present_screen_priv(screen); if (event_id == screen_priv->unflip_event_id) { - DebugPresent(("\tun %lld\n", event_id)); + DebugPresent(("\tun %" PRIu64 "\n", event_id)); screen_priv->unflip_event_id = 0; present_flip_idle(screen); present_flip_try_ready(screen); @@ -547,7 +549,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (vblank->flip && vblank->pixmap && vblank->window) { if (screen_priv->flip_pending || screen_priv->unflip_event_id) { - DebugPresent(("\tr %lld %p (pending %p unflip %lld)\n", + DebugPresent(("\tr %" PRIu64 " %p (pending %p unflip %" PRIu64 ")\n", vblank->event_id, vblank, screen_priv->flip_pending, screen_priv->unflip_event_id)); xorg_list_del(&vblank->event_queue); @@ -565,7 +567,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (vblank->flip) { - DebugPresent(("\tf %lld %p %8lld: %08lx -> %08lx\n", + DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", vblank->event_id, vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); @@ -609,7 +611,8 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) screen_priv->flip_pending = NULL; vblank->flip = FALSE; } - DebugPresent(("\tc %p %8lld: %08lx -> %08lx\n", vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); + DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", + vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); if (screen_priv->flip_pending) { /* Check pending flip @@ -713,7 +716,7 @@ present_scmd_pixmap(WindowPtr window, if (vblank->crtc != target_crtc || vblank->target_msc != target_msc) continue; - DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n", + DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n", vblank->event_id, vblank, vblank->target_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id, vblank->crtc)); diff --git a/present/present_vblank.c b/present/present_vblank.c index f93a1afa9..2c124f4bb 100644 --- a/present/present_vblank.c +++ b/present/present_vblank.c @@ -138,7 +138,7 @@ present_vblank_create(WindowPtr window, } if (pixmap) - DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n", + DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n", vblank->event_id, vblank, *target_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id, target_crtc, vblank->flip, vblank->sync_flip, vblank->serial)); @@ -153,7 +153,7 @@ no_mem: void present_vblank_scrap(present_vblank_ptr vblank) { - DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n", + DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n", vblank->event_id, vblank, vblank->target_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id, vblank->crtc)); @@ -175,7 +175,7 @@ present_vblank_destroy(present_vblank_ptr vblank) /* Also make sure vblank is removed from event queue (wnmd) */ xorg_list_del(&vblank->event_queue); - DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n", + DebugPresent(("\td %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", vblank->event_id, vblank, vblank->target_msc, vblank->pixmap ? vblank->pixmap->drawable.id : 0, vblank->window ? vblank->window->drawable.id : 0)); diff --git a/present/present_wnmd.c b/present/present_wnmd.c index 80ffb014e..9d0b147cc 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -168,7 +168,7 @@ present_wnmd_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_ WindowPtr window = vblank->window; present_window_priv_ptr window_priv = present_window_priv(window); - DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n", + DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", vblank->event_id, vblank, vblank->target_msc, vblank->pixmap ? vblank->pixmap->drawable.id : 0, vblank->window ? vblank->window->drawable.id : 0)); @@ -188,10 +188,11 @@ present_wnmd_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_ window_priv->flip_active = vblank; window_priv->flip_pending = NULL; + present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc); + if (vblank->abort_flip) present_wnmd_flips_stop(window); - present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc); present_wnmd_flip_try_ready(window); } @@ -212,7 +213,7 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin return; } - DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc)); + DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc)); xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) { if (event_id == vblank->event_id) { present_wnmd_execute(vblank, ust, msc); @@ -269,8 +270,8 @@ present_wnmd_check_flip(RRCrtcPtr crtc, if (!screen_priv->wnmd_info->flip) return FALSE; - /* Don't flip redirected windows */ - if (window->redirectDraw != RedirectDrawNone) + /* Can't flip redirected child windows */ + if (screen->GetWindowPixmap(window) != screen->GetWindowPixmap(toplvl_window)) return FALSE; /* Source pixmap must align with window exactly */ @@ -291,7 +292,8 @@ present_wnmd_check_flip(RRCrtcPtr crtc, /* Ask the driver for permission */ if (screen_priv->wnmd_info->check_flip2) { if (!(*screen_priv->wnmd_info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) { - DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); + DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", + window->drawable.id, pixmap ? pixmap->drawable.id : 0)); return FALSE; } } @@ -353,7 +355,7 @@ present_wnmd_flip(WindowPtr window, Bool sync_flip, RegionPtr damage) { - ScreenPtr screen = crtc->pScreen; + ScreenPtr screen = window->drawable.pScreen; present_screen_priv_ptr screen_priv = present_screen_priv(screen); return (*screen_priv->wnmd_info->flip) (window, @@ -424,7 +426,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (vblank->flip && vblank->pixmap && vblank->window) { if (window_priv->flip_pending) { - DebugPresent(("\tr %lld %p (pending %p)\n", + DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n", vblank->event_id, vblank, window_priv->flip_pending)); xorg_list_del(&vblank->event_queue); @@ -443,7 +445,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (vblank->flip) { RegionPtr damage; - DebugPresent(("\tf %lld %p %8lld: %08lx -> %08lx\n", + DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", vblank->event_id, vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); @@ -469,6 +471,10 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) 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); @@ -484,7 +490,8 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) window_priv->flip_pending = NULL; vblank->flip = FALSE; } - DebugPresent(("\tc %p %8lld: %08lx -> %08lx\n", vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); + DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n", + vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id)); present_wnmd_cancel_flip(window); diff --git a/randr/randr.c b/randr/randr.c index feb54bcc8..5db8b5ced 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -89,8 +89,12 @@ RRCloseScreen(ScreenPtr pScreen) { rrScrPriv(pScreen); int j; + RRLeasePtr lease, next; unwrap(pScrPriv, pScreen, CloseScreen); + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) + RRTerminateLease(lease); for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) RRCrtcDestroy(pScrPriv->crtcs[j]); for (j = pScrPriv->numOutputs - 1; j >= 0; j--) diff --git a/randr/randrstr.h b/randr/randrstr.h index f94174b54..2cede92e3 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -829,6 +829,9 @@ RRCrtcIsLeased(RRCrtcPtr crtc); extern _X_EXPORT Bool RROutputIsLeased(RROutputPtr output); +void +RRTerminateLease(RRLeasePtr lease); + Bool RRLeaseInit(void); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index d7d937e80..a851aebcc 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -534,6 +534,7 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, width, height, depth, x, y, rotation); if (spix_front == NULL) { + ErrorF("randr: failed to create shared pixmap\n"); return FALSE; } @@ -701,8 +702,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen, if (new_height < screen_pixmap->drawable.height) new_height = screen_pixmap->drawable.height; - if (new_width == screen_pixmap->drawable.width && - new_height == screen_pixmap->drawable.height) { + if (new_width <= screen_pixmap->drawable.width && + new_height <= screen_pixmap->drawable.height) { } else { pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0); } @@ -871,6 +872,17 @@ RRCrtcDestroyResource(void *value, XID pid) if (pScreen) { rrScrPriv(pScreen); int i; + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) { + int c; + for (c = 0; c < lease->numCrtcs; c++) { + if (lease->crtcs[c] == crtc) { + RRTerminateLease(lease); + break; + } + } + } for (i = 0; i < pScrPriv->numCrtcs; i++) { if (pScrPriv->crtcs[i] == crtc) { diff --git a/randr/rrlease.c b/randr/rrlease.c index b4a8827cc..e25d9ca99 100644 --- a/randr/rrlease.c +++ b/randr/rrlease.c @@ -169,7 +169,7 @@ RRLeaseFree(RRLeasePtr lease) * finished, which may be some time after this function returns * if the driver operation is asynchronous */ -static void +void RRTerminateLease(RRLeasePtr lease) { ScreenPtr screen = lease->screen; diff --git a/randr/rroutput.c b/randr/rroutput.c index 33300e1cc..e52ad7671 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -379,6 +379,17 @@ RROutputDestroyResource(void *value, XID pid) if (pScreen) { rrScrPriv(pScreen); int i; + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) { + int o; + for (o = 0; o < lease->numOutputs; o++) { + if (lease->outputs[o] == output) { + RRTerminateLease(lease); + break; + } + } + } if (pScrPriv->primaryOutput == output) pScrPriv->primaryOutput = NULL; diff --git a/test/scripts/build-travis-deps.sh b/test/scripts/build-travis-deps.sh deleted file mode 100755 index f52587dd5..000000000 --- a/test/scripts/build-travis-deps.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -export PREFIX=/usr -export TRAVIS_BUILD_DIR=/root -export PIGLIT_DIR=$TRAVIS_BUILD_DIR/piglit -export XTEST_DIR=$TRAVIS_BUILD_DIR/xts - -cat > "$PIGLIT_DIR"/piglit.conf << _EOF_ -[xts] -path=$XTEST_DIR -_EOF_ - -# awful -cp test/tetexec.cfg $XTEST_DIR/xts5 - -set -x - -meson setup build/ -meson configure -Dprefix=$PREFIX build/ -ninja -C build/ install -ninja -C build/ test - -status=$? - -cat build/meson-logs/testlog.txt -cat build/test/piglit-results/xvfb/long-summary || : -# there should be a better way of extracting results, but: -# find build/test/piglit-results/xvfb/ | grep setfontpath | xargs cat -# isn't the worst thing ever - -exit $status diff --git a/test/scripts/run-piglit.sh b/test/scripts/run-piglit.sh index b999c2598..8b9fda1a4 100755 --- a/test/scripts/run-piglit.sh +++ b/test/scripts/run-piglit.sh @@ -46,8 +46,8 @@ $XSERVER_BUILDDIR/test/simple-xinit \ # Write out piglit-summaries. SHORT_SUMMARY=$PIGLIT_RESULTS_DIR/summary LONG_SUMMARY=$PIGLIT_RESULTS_DIR/long-summary -$PIGLIT_DIR/piglit-summary.py -s $PIGLIT_RESULTS_DIR > $SHORT_SUMMARY -$PIGLIT_DIR/piglit-summary.py $PIGLIT_RESULTS_DIR > $LONG_SUMMARY +$PIGLIT_DIR/piglit summary console -s $PIGLIT_RESULTS_DIR > $SHORT_SUMMARY +$PIGLIT_DIR/piglit summary console $PIGLIT_RESULTS_DIR > $LONG_SUMMARY # Write the short summary to make check's log file. cat $SHORT_SUMMARY @@ -66,7 +66,7 @@ if ! grep "^ *crash: *0$" $SHORT_SUMMARY > /dev/null; then status=1 fi -$PIGLIT_DIR/piglit-summary-html.py \ +$PIGLIT_DIR/piglit summary html \ --overwrite \ $PIGLIT_RESULTS_DIR/html \ $PIGLIT_RESULTS_DIR diff --git a/test/scripts/xinit-piglit-session.sh b/test/scripts/xinit-piglit-session.sh index c26735d49..b495c96d6 100755 --- a/test/scripts/xinit-piglit-session.sh +++ b/test/scripts/xinit-piglit-session.sh @@ -24,15 +24,6 @@ fi cd $PIGLIT_DIR -# Write the piglit.conf we'll use for our testing. Don't use the -# default piglit.conf name because that may overwrite a local -# piglit.conf. -PIGLITCONF=piglit-xserver-test.conf -cat <<EOF > $PIGLITCONF -[xts] -path=$XTEST_DIR -EOF - # Skip some tests that are failing at the time of importing the script. # "REPORT: min_bounds, rbearing was 0, expecting 2" PIGLIT_ARGS="$PIGLIT_ARGS -x xlistfontswithinfo@3" @@ -41,4 +32,4 @@ PIGLIT_ARGS="$PIGLIT_ARGS -x xloadqueryfont@1" PIGLIT_ARGS="$PIGLIT_ARGS -x xqueryfont@1" PIGLIT_ARGS="$PIGLIT_ARGS -x xqueryfont@2" -exec ./piglit-run.py xts-render -f $PIGLITCONF $PIGLIT_ARGS $PIGLIT_RESULTS_DIR +exec ./piglit run xts-render $PIGLIT_ARGS $PIGLIT_RESULTS_DIR diff --git a/test/tetexec.cfg b/test/tetexec.cfg deleted file mode 100644 index dd919900d..000000000 --- a/test/tetexec.cfg +++ /dev/null @@ -1,497 +0,0 @@ -# -# Copyright (c) 2005 X.Org Foundation L.L.C. -# -# 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 -# 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. -# -# Copyright (c) Applied Testing and Technology, Inc. 1995 -# All Rights Reserved. -# -# Project: VSW5 -# -# File: tetexec.cfg -# -# Description: -# Execute configuration file for VSW5 -# -# Modifications: -# $Log: tetexec.cfg,v $ -# Revision 1.2 2005-11-03 08:42:00 jmichael -# clean up all vsw5 paths to use xts5 instead. -# -# Revision 1.1.1.2 2005/04/15 14:05:06 anderson -# Reimport of the base with the legal name in the copyright fixed. -# -# Revision 8.0 1998/12/23 23:39:36 mar -# Branch point for Release 5.0.2 -# -# Revision 7.0 1998/10/30 23:02:43 mar -# Branch point for Release 5.0.2b1 -# -# Revision 6.0 1998/03/02 05:30:36 tbr -# Branch point for Release 5.0.1 -# -# Revision 5.1 1998/02/24 03:36:35 andy -# Added the XT_COVERAGE variable. -# -# Revision 5.0 1998/01/26 03:27:10 tbr -# Branch point for Release 5.0.1b1 -# -# Revision 4.2 1998/01/23 00:37:47 tbr -# Fix XT_FONTSET typo. Add some variable descriptions. -# -# Revision 4.1 1998/01/22 05:28:25 tbr -# req.4.W.00029 vswsr126 vswsr125 vswsr124 vswsr122 vswsr127 -# Added new fonts and modified XT_FONTSET to select those fonts -# and realigned the data files associated with certain tests -# to match the expected results when using the new fonts -# -# Revision 4.0 1995/12/15 09:26:02 tbr -# Branch point for Release 5.0.0 -# -# Revision 3.1 1995/12/15 00:33:13 andy -# Prepare for GA Release -# - -# Portions of this software are based on Xlib and X Protocol Test Suite. -# We have used this material under the terms of its copyright, which grants -# free use, subject to the conditions below. Note however that those -# portions of this software that are based on the original Test Suite have -# been significantly revised and that all such revisions are copyright (c) -# 1995 Applied Testing and Technology, Inc. Insomuch as the proprietary -# revisions cannot be separated from the freely copyable material, the net -# result is that use of this software is governed by the ApTest copyright. -# -# Copyright (c) 1990, 1991 X Consortium -# -# 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 -# X CONSORTIUM 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 X Consortium 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 X Consortium. -# -# Copyright 1990, 1991 by UniSoft Group Limited. -# -# 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 and UniSoft not be -# used in advertising or publicity pertaining to distribution of the -# software without specific, written prior permission. and UniSoft -# makes no representations about the suitability of this software for any -# purpose. It is provided "as is" without express or implied warranty. -# -# $XConsortium: tetexec.cfg,v 1.27 94/04/17 20:59:59 rws Exp $ -# -########################################################################### -# This file contains run-time parameters for the test suite. -# They are accessed with the tet_getvar() function. -########################################################################### - -############################################## -# Configuration parameters defined by the TET -############################################## - -# TET_EXEC_IN_PLACE - Setting this variable to False indicates that -# files will be executed in a temporary execution directory. -# Use of a temporary execution directory for each test enables -# parallel execution of the test suite against multiple servers. -# Setting this variable to True will give you improved performance if -# you are not attempting parallel execution of the test suite against -# multiple servers. -TET_EXEC_IN_PLACE=True - -# TET_EXEC_LOCK - Indicate whether file locking should be used. Setting -# this variable to True means that a "tet_lock" file will be created in -# the execution directory of the test program. When this file exists, -# tcc will skip that test. -TET_EXEC_LOCK=False - -# TET_SAVE_FILES - This indicates which files generated during execution of -# tests are to be saved for later examination. -# This line should not be altered. -TET_SAVE_FILES=Err*.err,*.sav - -########################################################### -# General configuration parameters -########################################################### - -# XT_COVERAGE - There are three different levels of coverage that can be -# tested. They are largely identical but effect a few tests which -# are in a transitional state in terms of consistency of the specification, -# test suite, and sample code. The value of this variable determines -# whether these tests are run, or return results of UNTESTED. -# -# 0 - All tests are run. This level is intended for use only by -# developers of the sample code and the test suite as -# it enables execution of tests which are under investigation. -# 1 - All tests which should pass are run. At present this -# is as of R6.4gamma of the sample code. This value -# must be used to brand implementations derived from the -# sample code at this revision or above. Otherwise see value 2. -# 2 - This value may be used in the branding of implementations -# which are derived from revisions of the sample code earlier -# than R6.4gamma. -# -# Please see Section 4.1.2 of the User's Guide for additional information. -XT_COVERAGE=1 - -# XT_ALT_SCREEN - If the display supports more than one screen then -# this parameter should be set to one that is not under test. -# Set to the string UNSUPPORTED if only one screen is available. -XT_ALT_SCREEN=UNSUPPORTED - -# XT_FONTPATH - -# This should be set to a comma separated list that is a valid font path -# for the X server. -# It should include at least the components of the default font path -# for the X server enabling the cursor font to be accessed. -# One of the entries in the list must be the directory in which -# the test fonts were installed. -XT_FONTPATH=/root/xts/xts5/fonts,catalogue:/etc/X11/fontpath.d,built-ins - -# XT_SPEEDFACTOR - Specifies a multiplier used for timing. -# This should be set >= 1. -# This is a speedfactor which should be set to reflect the relative delay -# in response of the underlying operating system and X server combined. -# Co-operating processes which must synchronize allow a time delay in -# proportion to this speedfactor, to account for scheduling delays in the -# underlying operating system and X server. -# There should be no need to change the default unless the round trip -# time to the X server can be very long ( >15 seconds); in this case set this -# parameter to a value larger than the maximum round trip time divided -# by 3. -XT_SPEEDFACTOR=1 - -# XT_RESET_DELAY - Specifies a delay time in seconds. -# Set this to be a time which is greater than or equal to the maximum time -# required by your server to reset when the last client is closed. -# The test suite pauses for this time whenever a connection is about to be -# opened and the server may be resetting. -# The server may be resetting when the test case is entered (in startup()) -# as a result of closing the last connection in the previous test case. -# The server also resets in a few places in the test for XCloseDisplay(). -XT_RESET_DELAY=1 - -# XT_EXTENSIONS - Specifies whether you wish to test the extended assertions -# which require the XTEST extension. -# Set this to Yes if the XTEST extension is available on your system, -# and you have configured the test suite to use the XTEST extension, -# and you want to execute these tests, otherwise set to No. -XT_EXTENSIONS=Yes - -########################################################### -# Configuration parameters for specific tests -########################################################### - -# XT_VISUAL_CLASSES - A space separated list of the visual classes that -# are supported for the screen given by DISPLAY. Each visual class -# is followed by a list of depths at which the class is supported -# (enclosed by brackets and separated by commas with no spaces). -# Visual classes and depths that are supported only by other screens -# should not be included. -# Note - this parameter is used to check the correctness of the information -# returned by XMatchVisualInfo and XGetVisualInfo. Other tests which loop -# over visuals obtain the visuals by calling these functions. -# Example values are: -XT_VISUAL_CLASSES=DirectColor(24) TrueColor(24) TrueColor(32) - -# XT_FONTCURSOR_GOOD - This specifies the number of a glyph in the -# default cursor font known to exist. -# XT_FONTCURSOR_GOOD+2 should also be a glyph in the default cursor font. -# Neither of these should be the same as the X server's default cursor. -XT_FONTCURSOR_GOOD=2 - -# XT_FONTCURSOR_BAD - This specifies the number of a glyph in the -# default cursor font known not to exist. If there is no such -# number then set this parameter to UNSUPPORTED. -XT_FONTCURSOR_BAD=9999 - -# XT_FONTPATH_GOOD - -# This should be set to a comma separated list that is a valid font path -# for the X server. It should be different to the list specified by -# XT_FONTPATH. It need not contain the test fonts. -XT_FONTPATH_GOOD=catalogue:/etc/X11/fontpath.d,built-ins - -# XT_FONTPATH_BAD - This should be set to a comma separated list that -# is an invalid font path for the X server. -XT_FONTPATH_BAD=/no-such-path-name - -# XT_BAD_FONT_NAME - This should be set to a non-existent font name. -XT_BAD_FONT_NAME=non-existent-font-name - -# XT_GOOD_COLORNAME - This should be set to the name of a colour -# which exists in the colour database for the X server. -XT_GOOD_COLORNAME=red - -# XT_BAD_COLORNAME - This should be set to the name of a colour -# which does not exist in the colour database for the X server. -XT_BAD_COLORNAME=nosuchcolor - -# XT_DISPLAYMOTIONBUFFERSIZE - specifies size of pointer motion buffer -# This should be set to a non-zero value (the value returned by -# XDisplayMotionBufferSize) if the X server supports a more complete -# history of pointer motion than that provided by event notification, or -# zero otherwise. -XT_DISPLAYMOTIONBUFFERSIZE=256 - -########################################################### -# Configuration parameters for Display functions -########################################################### - -# XT_SCREEN_COUNT - This parameter should be set to the number of screens -# available on the display, as returned by XScreenCount. -XT_SCREEN_COUNT=1 - -# XT_PIXMAP_DEPTHS - A space separated list of depths supported by -# the specified screen of the display that can be used for pixmaps. -XT_PIXMAP_DEPTHS=24 1 4 8 15 16 32 - -# XT_BLACK_PIXEL - This parameter should be set to the black pixel value -# of the specified screen of the display. -XT_BLACK_PIXEL=0 - -# XT_WHITE_PIXEL - This parameter should be set to the white pixel value -# of the specified screen of the display. -XT_WHITE_PIXEL=16777215 - -# XT_HEIGHT_MM - This parameter should be set to the height in millimeters -# of the specified screen of the display. -XT_HEIGHT_MM=476 - -# XT_WIDTH_MM - This parameter should be set to the width in millimeters -# of the specified screen of the display. -XT_WIDTH_MM=846 - -# XT_PROTOCOL_VERSION - This should be set to the major version number (11) -# of the X protocol as returned by XProtocolVersion. -XT_PROTOCOL_VERSION=11 - -# XT_PROTOCOL_REVISION - This should be set to the minor protocol -# revision number as returned by XProtocolRevision. -XT_PROTOCOL_REVISION=0 - -# XT_SERVER_VENDOR - This should be set to the X server vendor string -# as returned by XServerVendor. -XT_SERVER_VENDOR=Fedora Project - -# XT_VENDOR_RELEASE - This should be set to the X server vendor's release -# number as returned by XVendorRelease. -XT_VENDOR_RELEASE=11999902 - -# XT_DOES_SAVE_UNDERS - Set this to Yes if the specified screen of the display -# supports save unders (indicated by XDoesSaveUnders returning True) -# otherwise set to No. -XT_DOES_SAVE_UNDERS=No - -# XT_DOES_BACKING_STORE - Set this to the following value: -# - 0 if the way the specified screen supports backing store is NotUseful -# - 1 if the way the specified screen supports backing store is WhenMapped -# - 2 if the way the specified screen supports backing store is Always -# The way the specified screen supports backing store is indicated by the -# return value of XDoesBackingStore. -XT_DOES_BACKING_STORE=0 - -########################################################### -# Configuration parameters for connection tests -########################################################### - -# XT_POSIX_SYSTEM - This may be set to Yes to indicate that the -# underlying operating system is a POSIX system. If this parameter is -# set to Yes, some extended assertions which describe implementation -# dependent functionality will be tested assuming POSIX concepts. -XT_POSIX_SYSTEM=Yes - -# XT_TCP - Set this to yes if clients can connect to the X server under -# test using TCP streams. This will be used (on a POSIX system) -# in the tests for XOpenDisplay. -XT_TCP=No - -# XT_DISPLAYHOST - Set this to the hostname of the machine on which -# the display is physically attached. This will be used instead of -# DISPLAY (on a POSIX system) in the tests for XOpenDisplay which -# specifically test the hostname component of the display name. -# Note that this may not be the same as the machine on which the -# test suite clients execute (XTESTHOST). -XT_DISPLAYHOST= - -# XT_LOCAL - Set this to yes if clients can connect to a local X server -# without passing a hostname to XOpenDisplay. This will be used -# (on a POSIX system) in the tests for XOpenDisplay. -# This is usually the case when the X server under test is running on the -# same platform as the X test suite. -# When a hostname is omitted, the Xlib implementation of XOpenDisplay -# can use the fastest available transport mechanism to make local connections. -XT_LOCAL=Yes - - -########################################################################### -# The following variables are options which do not affect test results. -# They only alter the accompanying output from the test suite. -# They are accessed with the tet_getvar() function. -########################################################################### - -# XT_SAVE_SERVER_IMAGE - When set to Yes, the image produced by the server -# that is compared with the known good image is dumped to a file -# with suffix .sav. -XT_SAVE_SERVER_IMAGE=No - -# XT_OPTION_NO_CHECK - This may be set to Yes to suppress the journal file -# records containing CHECK keywords. -XT_OPTION_NO_CHECK=Yes - -# XT_OPTION_NO_TRACE - This may be set to Yes to suppress the journal file -# records containing TRACE keywords. -XT_OPTION_NO_TRACE=Yes - -########################################################################### -# The following variables are intended for use in debugging. They should -# not be used when running verification tests. -# They are accessed with the tet_getvar() function. -########################################################################### - -# XT_DEBUG - This may be set to a debugging level between 0 and 9. -# A higher level produces more debugging output. Output is only -# produced by the test suite at levels 1, 2 and 3 at present. So setting -# this variable to 0 produces no debug output. -XT_DEBUG=0 - -# XT_DEBUG_OVERRIDE_REDIRECT - When set to Yes, windows are created with -# override_redirect set. Otherwise windows are not created with -# override_redirect set. This enables tests to be run more easily with a -# window manager running on the same screen. -# This should not be set to Yes for verification tests. -XT_DEBUG_OVERRIDE_REDIRECT=No - -# XT_DEBUG_PAUSE_AFTER - When set to Yes, the test pauses before calls to -# the function being tested, until Carriage Return is entered. -# This should not be set to Yes for verification tests. -XT_DEBUG_PAUSE_AFTER=No - -# XT_DEBUG_PIXMAP_ONLY - When set to Yes, tests which would normally loop over -# both windows and pixmaps are restricted to loop over just pixmaps. -# This should not be set to Yes for verification tests. -# If XT_DEBUG_WINDOW_ONLY is also set, some tests will report UNRESOLVED due -# to the fact that nothing has been tested. -XT_DEBUG_PIXMAP_ONLY=No - -# XT_DEBUG_WINDOW_ONLY - When set to Yes, tests which would normally loop over -# both windows and pixmaps are restricted to loop over just windows. -# This should not be set to Yes for verification tests. -# If XT_DEBUG_PIXMAP_ONLY is also set, some tests will report UNRESOLVED due -# to the fact that nothing has been tested. -XT_DEBUG_WINDOW_ONLY=No - -# XT_DEBUG_DEFAULT_DEPTHS - When set to Yes, tests which would normally loop -# over multiple depths are restricted to test just the first visual -# returned by XGetVisualInfo and/or the first pixmap depth returned by -# XListDepths (depending on whether XT_DEBUG_PIXMAP_ONLY or -# XT_DEBUG_WINDOW_ONLY is also set). -# This should not be set to Yes for verification tests. -# Note that the first visual returned by XGetVisualInfo may not be -# the default visual for the screen. -XT_DEBUG_DEFAULT_DEPTHS=No - -# XT_DEBUG_VISUAL_IDS - When set to a non-empty string, tests which would -# normally loop over multiple depths are restricted to test just the -# visuals ID's listed. Note that visual ID's for visuals on more than -# one screen may be entered, but those used will depend on whether the test -# being executed uses visuals on the default screen or alternate screen. -# The visuals ID's should be entered in decimal, octal or hexadecimal -# and separated with commas and with no intervening spaces. -# This should not be set to a non-empty string for verification tests. -XT_DEBUG_VISUAL_IDS= - -# XT_DEBUG_NO_PIXCHECK - When set to Yes, tests which would normally -# perform pixmap verification omit this (all other processing is -# performed in those tests as normal). -# Pixmap verification is a scheme which compares the image produced by -# the X server with a known good image file which is part of the test -# suite. -# This should not be set to Yes for verification tests. -XT_DEBUG_NO_PIXCHECK=No - -# XT_DEBUG_BYTE_SEX - When set to NATIVE, REVERSE, MSB or LSB, -# the X Protocol tests will only be executed with the specified byte sex. -# When set to BOTH, the X Protocol tests make connections to the X server using -# both the native and reversed byte sex. -XT_DEBUG_BYTE_SEX=BOTH - -# XT_DEBUG_VISUAL_CHECK - When set to a non-zero value, the X Protocol tests -# will pause for the specified time interval (in seconds) to enable a visual -# check to be performed on the displayed screen contents. -XT_DEBUG_VISUAL_CHECK=0 - -########################################################################### -# The following variables are intended for use only in generating known good -# image files. -########################################################################### - -# XT_FONTDIR - The directory in which the VSW5 fonts are supplied (before -# being installed). -# This must be set such that appending a string gives a valid file name. -# This is normally set to $TET_ROOT/xts5/fonts/ -# This is only used by the PV library which is not part of the test suite. -XT_FONTDIR= - -############################################## -# The following variables are used in xim tests -############################################## -# - -# -# XT_LOCALE - The locales in which input method tests are run -# -XT_LOCALE=C - -# -# XT_FONTSET - The base font name list used to select fonts when font -# sets are generated. -# -XT_FONTSET=-vsw-*-*-r-normal--*-120-75-75-*-*-*-*,-vsw-*-*-r-normal--*-180-75-75-*-*-*-* - -# -# XT_LOCALE_MODIFIERS - Used to verify that XSetLocaleModifiers works -# properly. -# -XT_LOCALE_MODIFIERS=@im=none - -# -# XT_SAVE_IM - Used for developing and debugging input method tests. -# -XT_SAVE_IM=No - -# Undocumented variables: - -DISPLAY=:0 diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c index b91692f55..8cd85dd05 100644 --- a/test/xi2/protocol-common.c +++ b/test/xi2/protocol-common.c @@ -259,6 +259,7 @@ init_simple(void) screen.DeviceCursorInitialize = device_cursor_init; screen.DeviceCursorCleanup = device_cursor_cleanup; screen.SetCursorPosition = set_cursor_pos; + screen.root = &root; dixResetPrivates(); InitAtoms(); diff --git a/test/xtest.c b/test/xtest.c index 05d7ec1d3..fc5e43368 100644 --- a/test/xtest.c +++ b/test/xtest.c @@ -29,6 +29,7 @@ #include "input.h" #include "inputstr.h" #include "scrnintstr.h" +#include "windowstr.h" #include "exevents.h" #include "extinit.h" #include "xkbsrv.h" @@ -58,11 +59,15 @@ device_cursor_cleanup(DeviceIntPtr dev, ScreenPtr screen) static void xtest_init_devices(void) { - ScreenRec screen; - ClientRec server_client; + ScreenRec screen = {0}; + ClientRec server_client = {0}; + WindowRec root = {0}; + WindowOptRec optional = {0}; /* random stuff that needs initialization */ - memset(&screen, 0, sizeof(screen)); + root.drawable.id = 0xab; + root.optional = &optional; + screen.root = &root; screenInfo.numScreens = 1; screenInfo.screens[0] = &screen; screen.myNum = 0; @@ -2570,7 +2570,7 @@ _XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values) first = last = 0; if (change.map.num_modmap_keys > 0) { firstMM = change.map.first_modmap_key; - lastMM = first + change.map.num_modmap_keys - 1; + lastMM = firstMM + change.map.num_modmap_keys - 1; } else firstMM = lastMM = 0; |