diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2020-08-25 17:57:24 +0100 |
---|---|---|
committer | Jon Turney <jon.turney@dronecode.org.uk> | 2020-08-25 17:57:24 +0100 |
commit | ffb70dce4ec24d66d682a2ea3d2743f3eb384f95 (patch) | |
tree | e2b6a61164c23033f377fc32775a5cc596fa790a | |
parent | 8b3c91f306ad808a3c948cc57eb222a0e39edbda (diff) | |
parent | afb77415e1fb862c322754230f63bb70fd596943 (diff) |
Merge tag 'xorg-server-1.20.9' into cygwin-release-1.20
xorg-server-1.20.9
120 files changed, 1683 insertions, 614 deletions
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c index f31b1e054..32424fcbd 100644 --- a/Xext/panoramiXprocs.c +++ b/Xext/panoramiXprocs.c @@ -1105,6 +1105,10 @@ PanoramiXCopyArea(ClientPtr client) DixGetAttrAccess); if (rc != Success) return rc; + drawables[j]->pScreen->SourceValidate(drawables[j], 0, 0, + drawables[j]->width, + drawables[j]->height, + IncludeInferiors); } pitch = PixmapBytePad(width, drawables[0]->depth); @@ -2007,6 +2011,12 @@ PanoramiXGetImage(ClientPtr client) if (rc != Success) return rc; } + FOR_NSCREENS_FORWARD(i) { + drawables[i]->pScreen->SourceValidate(drawables[i], 0, 0, + drawables[i]->width, + drawables[i]->height, + IncludeInferiors); + } xgi = (xGetImageReply) { .type = X_Reply, diff --git a/Xext/shm.c b/Xext/shm.c index 589ed0b4d..24c6b1087 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -35,6 +35,9 @@ in this Software without prior written authorization from The Open Group. #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> +#ifdef HAVE_MEMFD_CREATE +#include <sys/mman.h> +#endif #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> @@ -652,6 +655,9 @@ ProcShmGetImage(ClientPtr client) visual = wVisual(((WindowPtr) pDraw)); if (pDraw->type == DRAWABLE_WINDOW) pVisibleRegion = &((WindowPtr) pDraw)->borderClip; + pDraw->pScreen->SourceValidate(pDraw, stuff->x, stuff->y, + stuff->width, stuff->height, + IncludeInferiors); } else { if (stuff->x < 0 || @@ -860,6 +866,12 @@ ProcPanoramiXShmGetImage(ClientPtr client) return rc; } } + FOR_NSCREENS_FORWARD(i) { + drawables[i]->pScreen->SourceValidate(drawables[i], 0, 0, + drawables[i]->width, + drawables[i]->height, + IncludeInferiors); + } xgi = (xShmGetImageReply) { .type = X_Reply, @@ -1194,36 +1206,55 @@ ProcShmAttachFd(ClientPtr client) static int shm_tmpfile(void) { -#ifdef SHMDIR - int fd; - char template[] = SHMDIR "/shmfd-XXXXXX"; + const char *shmdirs[] = { + "/run/shm", + "/var/tmp", + "/tmp", + }; + int fd; + +#ifdef HAVE_MEMFD_CREATE + fd = memfd_create("xorg", MFD_CLOEXEC|MFD_ALLOW_SEALING); + if (fd != -1) { + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK); + DebugF ("Using memfd_create\n"); + return fd; + } +#endif + #ifdef O_TMPFILE - fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); - if (fd >= 0) { - DebugF ("Using O_TMPFILE\n"); - return fd; - } - ErrorF ("Not using O_TMPFILE\n"); + for (int i = 0; i < ARRAY_SIZE(shmdirs); i++) { + fd = open(shmdirs[i], O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); + if (fd >= 0) { + DebugF ("Using O_TMPFILE\n"); + return fd; + } + } + ErrorF ("Not using O_TMPFILE\n"); #endif + + for (int i = 0; i < ARRAY_SIZE(shmdirs); i++) { + char template[PATH_MAX]; + snprintf(template, ARRAY_SIZE(template), "%s/shmfd-XXXXXX", shmdirs[i]); #ifdef HAVE_MKOSTEMP - fd = mkostemp(template, O_CLOEXEC); + fd = mkostemp(template, O_CLOEXEC); #else - fd = mkstemp(template); + fd = mkstemp(template); #endif - if (fd < 0) - return -1; - unlink(template); + if (fd < 0) + continue; + unlink(template); #ifndef HAVE_MKOSTEMP - int flags = fcntl(fd, F_GETFD); - if (flags != -1) { - flags |= FD_CLOEXEC; - (void) fcntl(fd, F_SETFD, &flags); - } -#endif - return fd; -#else - return -1; + int flags = fcntl(fd, F_GETFD); + if (flags != -1) { + flags |= FD_CLOEXEC; + (void) fcntl(fd, F_SETFD, &flags); + } #endif + return fd; + } + + return -1; } static int diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c index 68a7a9bee..334c2784a 100644 --- a/Xext/sleepuntil.c +++ b/Xext/sleepuntil.c @@ -125,8 +125,7 @@ ClientSleepUntil(ClientPtr client, static void ClientAwaken(ClientPtr client, void *closure) { - if (!client->clientGone) - AttendClient(client); + AttendClient(client); } static int diff --git a/Xext/sync.c b/Xext/sync.c index 8f22a865b..fd2ceb042 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -881,18 +881,21 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, return Success; } -static SyncObject * +SyncObject * SyncCreate(ClientPtr client, XID id, unsigned char type) { SyncObject *pSync; + RESTYPE resType; switch (type) { case SYNC_COUNTER: pSync = malloc(sizeof(SyncCounter)); + resType = RTCounter; break; case SYNC_FENCE: pSync = (SyncObject *) dixAllocateObjectWithPrivates(SyncFence, PRIVATE_SYNC_FENCE); + resType = RTFence; break; default: return NULL; @@ -901,6 +904,11 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) if (!pSync) return NULL; + pSync->initialized = FALSE; + + if (!AddResource(id, resType, (void *) pSync)) + return NULL; + pSync->client = client; pSync->id = id; pSync->pTriglist = NULL; @@ -923,13 +931,10 @@ SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered); if (status != Success) { - dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); + FreeResource(pFence->sync.id, RT_NONE); return status; } - if (!AddResource(id, RTFence, (void *) pFence)) - return BadAlloc; - return Success; #else return BadImplementation; @@ -957,8 +962,7 @@ SyncCreateCounter(ClientPtr client, XSyncCounter id, int64_t initialvalue) pCounter->value = initialvalue; pCounter->pSysCounterInfo = NULL; - if (!AddResource(id, RTCounter, (void *) pCounter)) - return NULL; + pCounter->sync.initialized = TRUE; return pCounter; } @@ -1137,21 +1141,26 @@ static int FreeCounter(void *env, XID id) { SyncCounter *pCounter = (SyncCounter *) env; - SyncTriggerList *ptl, *pnext; pCounter->sync.beingDestroyed = TRUE; - /* tell all the counter's triggers that the counter has been destroyed */ - for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { - (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); - pnext = ptl->next; - free(ptl); /* destroy the trigger list as we go */ - } - if (IsSystemCounter(pCounter)) { - xorg_list_del(&pCounter->pSysCounterInfo->entry); - free(pCounter->pSysCounterInfo->name); - free(pCounter->pSysCounterInfo->private); - free(pCounter->pSysCounterInfo); + + if (pCounter->sync.initialized) { + SyncTriggerList *ptl, *pnext; + + /* tell all the counter's triggers that counter has been destroyed */ + for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { + (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); + pnext = ptl->next; + free(ptl); /* destroy the trigger list as we go */ + } + if (IsSystemCounter(pCounter)) { + xorg_list_del(&pCounter->pSysCounterInfo->entry); + free(pCounter->pSysCounterInfo->name); + free(pCounter->pSysCounterInfo->private); + free(pCounter->pSysCounterInfo); + } } + free(pCounter); return Success; } @@ -1889,9 +1898,6 @@ ProcSyncCreateFence(ClientPtr client) miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered); - if (!AddResource(stuff->fid, RTFence, (void *) pFence)) - return BadAlloc; - return Success; } diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h index f1b99d010..c88285cb1 100644 --- a/Xext/syncsdk.h +++ b/Xext/syncsdk.h @@ -29,6 +29,9 @@ extern _X_EXPORT int SyncVerifyFence(SyncFence ** ppFence, XID fid, ClientPtr client, Mask mode); +extern _X_EXPORT SyncObject* + SyncCreate(ClientPtr client, XID id, unsigned char type); + #define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ do { \ int rc; \ diff --git a/Xi/exevents.c b/Xi/exevents.c index 17d751e31..659816a46 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1293,14 +1293,21 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, int rc; InputClients *iclients = NULL; *mask = NULL; + *grab = NULL; if (listener->type == LISTENER_GRAB || listener->type == LISTENER_POINTER_GRAB) { - *grab = listener->grab; BUG_RETURN_VAL(!*grab, FALSE); + } + else if (ti->emulate_pointer && dev->deviceGrab.grab && + !dev->deviceGrab.fromPassiveGrab) { + /* There may be an active pointer grab on the device */ + *grab = dev->deviceGrab.grab; + } + if (*grab) { *client = rClient(*grab); *win = (*grab)->window; *mask = (*grab)->xi2mask; @@ -1357,8 +1364,6 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, /* if owner selected, oclients is NULL */ *client = oclients ? rClient(oclients) : wClient(*win); } - - *grab = NULL; } return TRUE; @@ -1498,16 +1503,6 @@ DeliverEmulatedMotionEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, &mask)) return; - /* There may be a pointer grab on the device */ - if (!grab) { - grab = dev->deviceGrab.grab; - if (grab) { - win = grab->window; - mask = grab->xi2mask; - client = rClient(grab); - } - } - DeliverTouchEmulatedEvent(dev, ti, (InternalEvent*)&motion, &ti->listeners[0], client, win, grab, mask); } diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index cbdd91258..504defe56 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -423,7 +423,7 @@ ProcXIChangeHierarchy(ClientPtr client) if (!stuff->num_changes) return rc; - len = ((size_t)stuff->length << 2) - sizeof(xXIChangeHierarchyReq); + len = ((size_t)client->req_len << 2) - sizeof(xXIChangeHierarchyReq); any = (xXIAnyHierarchyChangeInfo *) &stuff[1]; while (stuff->num_changes--) { diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c index 65d5870f6..d30f51f3c 100644 --- a/Xi/xipassivegrab.c +++ b/Xi/xipassivegrab.c @@ -203,8 +203,14 @@ ProcXIPassiveGrabDevice(ClientPtr client) ¶m, XI2, &mask); break; case XIGrabtypeKeycode: - status = GrabKey(client, dev, mod_dev, stuff->detail, - ¶m, XI2, &mask); + /* XI2 allows 32-bit keycodes but thanks to XKB we can never + * implement this. Just return an error for all keycodes that + * cannot work anyway */ + if (stuff->detail > 255) + status = XIAlreadyGrabbed; + else + status = GrabKey(client, dev, mod_dev, stuff->detail, + ¶m, XI2, &mask); break; case XIGrabtypeEnter: case XIGrabtypeFocusIn: diff --git a/config/udev.c b/config/udev.c index 3a73189e2..b00d90237 100644 --- a/config/udev.c +++ b/config/udev.c @@ -56,7 +56,7 @@ static struct udev_monitor *udev_monitor; #ifdef CONFIG_UDEV_KMS static void -config_udev_odev_setup_attribs(const char *path, const char *syspath, +config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback); #endif @@ -128,7 +128,7 @@ device_added(struct udev_device *udev_device) LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path); - config_udev_odev_setup_attribs(path, syspath, major(devnum), + config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum), minor(devnum), NewGPUDeviceRequest); return; } @@ -322,7 +322,7 @@ device_removed(struct udev_device *device) LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n", syspath, path); - config_udev_odev_setup_attribs(path, syspath, major(devnum), + config_udev_odev_setup_attribs(device, path, syspath, major(devnum), minor(devnum), DeleteGPUDeviceRequest); /* Retry vtenter after a drm node removal */ systemd_logind_vtenter(); @@ -464,18 +464,50 @@ config_udev_fini(void) #ifdef CONFIG_UDEV_KMS +/* Find the last occurrence of the needle in haystack */ +static char *strrstr(const char *haystack, const char *needle) +{ + char *prev, *last, *tmp; + + prev = strstr(haystack, needle); + if (!prev) + return NULL; + + last = prev; + tmp = prev + 1; + + while (tmp) { + last = strstr(tmp, needle); + if (!last) + return prev; + else { + prev = last; + tmp = prev + 1; + } + } + + return last; +} + static void -config_udev_odev_setup_attribs(const char *path, const char *syspath, +config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback) { struct OdevAttributes *attribs = config_odev_allocate_attributes(); + const char *value, *str; attribs->path = XNFstrdup(path); attribs->syspath = XNFstrdup(syspath); attribs->major = major; attribs->minor = minor; + value = udev_device_get_property_value(udev_device, "ID_PATH"); + if (value && (str = strrstr(value, "pci-"))) { + attribs->busid = XNFstrdup(str); + attribs->busid[3] = ':'; + } + /* ownership of attribs is passed to probe layer */ probe_callback(attribs); } @@ -516,7 +548,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback) else if (!check_seat(udev_device)) goto no_probe; - config_udev_odev_setup_attribs(path, syspath, major(devnum), + config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum), minor(devnum), probe_callback); no_probe: udev_device_unref(udev_device); diff --git a/configure.ac b/configure.ac index 8c134ba11..68d1dc9e6 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.5, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server) -RELEASE_DATE="2019-05-30" -RELEASE_NAME="Red Lentil Dal" +AC_INIT([xorg-server], 1.20.9, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server) +RELEASE_DATE="2020-08-25" +RELEASE_NAME="Chicken Parmigiana" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -169,7 +169,7 @@ dnl Checks for library functions. AC_CHECK_FUNCS([backtrace geteuid getuid issetugid getresuid \ getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \ mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \ - walkcontext setitimer poll epoll_create1 mkostemp]) + walkcontext setitimer poll epoll_create1 mkostemp memfd_create isastream]) AC_CONFIG_LIBOBJ_DIR([os]) AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup\ timingsafe_memcmp]) @@ -773,7 +773,7 @@ LIBDRI="dri >= 7.8.0" LIBDRM="libdrm >= 2.4.89" LIBEGL="egl" LIBGBM="gbm >= 10.2.0" -LIBGL="gl >= 7.1.0" +LIBGL="gl >= 1.2" LIBXEXT="xext >= 1.0.99.4" LIBXFONT="xfont2 >= 2.0.0" LIBXI="xi >= 1.2.99.1" @@ -1124,55 +1124,12 @@ case "$DRI2,$HAVE_DRI2PROTO" in yes,yes | auto,yes) AC_DEFINE(DRI2, 1, [Build DRI2 extension]) DRI2=yes - LIBGL="gl >= 9.2.0" + LIBGL="gl >= 1.2" SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $DRI2PROTO" ;; esac AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) -dnl -dnl Locate a suitable tmp file system for creating shared memeory files -dnl - -AC_ARG_WITH(shared-memory-dir, AS_HELP_STRING([--with-shared-memory-dir=PATH], [Path to directory in a world-writable temporary directory for anonymous shared memory (default: auto)]), -[], -[with_shared_memory_dir=yes]) - -shmdirs="/run/shm /var/tmp /tmp" - -case x"$with_shared_memory_dir" in -xyes) - for dir in $shmdirs; do - case x"$with_shared_memory_dir" in - xyes) - echo Checking temp dir "$dir" - if test -d "$dir"; then - with_shared_memory_dir="$dir" - fi - ;; - esac - done - ;; -x/*) - ;; -xno) - ;; -*) - AC_MSG_ERROR([Invalid directory specified for --with-shared-memory-dir: $with_shared_memory_dir]) - ;; -esac - -case x"$with_shared_memory_dir" in -xyes) - AC_MSG_ERROR([No directory found for shared memory temp files.]) - ;; -xno) - ;; -*) - AC_DEFINE_UNQUOTED(SHMDIR, ["$with_shared_memory_dir"], [Directory for shared memory temp files]) - ;; -esac - AC_ARG_ENABLE(xtrans-send-fds, AS_HELP_STRING([--disable-xtrans-send-fds], [Use Xtrans support for fd passing (default: auto)]), [XTRANS_SEND_FDS=$enableval], [XTRANS_SEND_FDS=auto]) case "x$XTRANS_SEND_FDS" in @@ -1289,7 +1246,7 @@ esac AM_CONDITIONAL(DRI3, test "x$DRI3" = xyes) -if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "x$CONFIG_UDEV_KMS" = xyes; then +if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "x$CONFIG_UDEV_KMS" = xyes || test "x$XORG" = xyes; then if test "x$DRM" = xyes; then AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support]) PKG_CHECK_MODULES([LIBDRM], $LIBDRM) @@ -2104,6 +2061,10 @@ if test "x$GLAMOR" = xyes; then [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DMABUF, 1, [Have GLAMOR_HAS_EGL_QUERY_DMABUF])], []) + PKG_CHECK_EXISTS(epoxy >= 1.5.4, + [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DRIVER, 1, [Have GLAMOR_HAS_EGL_QUERY_DRIVER])], + []) + PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) if test "x$GBM" = xyes; then AC_DEFINE(GLAMOR_HAS_GBM, 1, diff --git a/dix/devices.c b/dix/devices.c index 1b18b168e..00c453980 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2656,7 +2656,7 @@ GetPairedDevice(DeviceIntPtr dev) if (!IsMaster(dev) && !IsFloating(dev)) dev = GetMaster(dev, MASTER_ATTACHED); - return dev->spriteInfo->paired; + return dev->spriteInfo? dev->spriteInfo->paired: NULL; } /** diff --git a/dix/dispatch.c b/dix/dispatch.c index 0befd61c0..f64fe6b1c 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -2200,8 +2200,11 @@ DoGetImage(ClientPtr client, int format, Drawable drawable, return BadAlloc; WriteReplyToClient(client, sizeof(xGetImageReply), &xgi); - if (pDraw->type == DRAWABLE_WINDOW) + if (pDraw->type == DRAWABLE_WINDOW) { pVisibleRegion = &((WindowPtr) pDraw)->borderClip; + pDraw->pScreen->SourceValidate(pDraw, x, y, width, height, + IncludeInferiors); + } if (linesPerBuf == 0) { /* nothing to do */ diff --git a/dix/dixutils.c b/dix/dixutils.c index 2983174a1..331ccfb96 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -662,14 +662,7 @@ ClientWakeup(ClientPtr client) if (q->client == client) { *prev = q->next; free(q); - if (client->clientGone) - /* Oops -- new zombie cleanup code ensures this only - * happens from inside CloseDownClient; don't want to - * recurse here... - */ - /* CloseDownClient(client) */ ; - else - AttendClient(client); + AttendClient(client); break; } prev = &q->next; diff --git a/dix/events.c b/dix/events.c index d3a33ea3f..427b891ae 100644 --- a/dix/events.c +++ b/dix/events.c @@ -597,6 +597,8 @@ XineramaConfineCursorToWindow(DeviceIntPtr pDev, int x, y, off_x, off_y, i; + assert(!noPanoramiXExtension); + if (!XineramaSetWindowPntrs(pDev, pWin)) return; @@ -1530,7 +1532,9 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, mouse->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); } - DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); + if (! (grabinfo->grab && oldWin == grabinfo->grab->window + && oldWin == grab->window)) + DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; @@ -1640,7 +1644,9 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, oldWin = keybd->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; - if (oldWin) + if (oldWin && + ! (grabinfo->grab && oldWin == grabinfo->grab->window + && oldWin == grab->window)) DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; diff --git a/dix/pixmap.c b/dix/pixmap.c index 81ac5e2d8..061bd421d 100644 --- a/dix/pixmap.c +++ b/dix/pixmap.c @@ -32,6 +32,7 @@ from The Open Group. #include <X11/X.h> #include "scrnintstr.h" +#include "mi.h" #include "misc.h" #include "os.h" #include "windowstr.h" @@ -116,7 +117,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) if (pScreen->totalPixmapSize > ((size_t) - 1) - pixDataSize) return NullPixmap; - pPixmap = malloc(pScreen->totalPixmapSize + pixDataSize); + pPixmap = calloc(1, pScreen->totalPixmapSize + pixDataSize); if (!pPixmap) return NullPixmap; @@ -395,7 +396,7 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty) * leaves the software cursor in place */ SourceValidate = pScreen->SourceValidate; - pScreen->SourceValidate = NULL; + pScreen->SourceValidate = miSourceValidate; RegionTranslate(&pixregion, dirty->x, dirty->y); RegionIntersect(&pixregion, &pixregion, region); diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml index 3dde65178..0ac2224e9 100644 --- a/doc/Xserver-spec.xml +++ b/doc/Xserver-spec.xml @@ -2930,8 +2930,8 @@ The sample server implementation is in Xserver/fb/fbscreen.c.</para> unsigned int subWindowMode; </programlisting></blockquote> -SourceValidate should be called by CopyArea/CopyPlane primitives when -the SourceValidate function pointer in the screen is non-null. If you know that +SourceValidate should be called by any primitive that reads from pDrawable. +If you know that you will never need SourceValidate, you can avoid this check. Currently, SourceValidate is used by the mi software cursor code to remove the cursor from the screen when the source rectangle overlaps the cursor position. diff --git a/doc/dtrace/Xserver-DTrace.xml b/doc/dtrace/Xserver-DTrace.xml index 91ca254d7..ee594ac7c 100644 --- a/doc/dtrace/Xserver-DTrace.xml +++ b/doc/dtrace/Xserver-DTrace.xml @@ -15,8 +15,8 @@ </affiliation> </author> <releaseinfo>X Server Version &xserver.version;</releaseinfo> - <copyright><year>2005</year><year>2006</year><year>2007</year><year>2010</year> - <holder>Oracle and/or its affiliates. All rights reserved.</holder> + <copyright><year>2005</year><year>2006</year><year>2007</year><year>2010</year><year>2020</year> + <holder>Oracle and/or its affiliates.</holder> </copyright> <legalnotice id="copyright"> <para> @@ -46,9 +46,9 @@ DEALINGS IN THE SOFTWARE. <title>Introduction</title> <para> This page provides details on a - <ulink url="http://wikis.sun.com/display/DTrace/Statically+Defined+Tracing+for+User+Applications">statically defined user application tracing provider</ulink> + <ulink url="http://dtrace.org/guide/chp-usdt.html">statically defined user application tracing provider</ulink> for the - <ulink url="http://hub.opensolaris.org/bin/view/Community+Group+dtrace/">DTrace</ulink> + <ulink url="http://dtrace.org/blogs/about/">DTrace</ulink> facility in <productname>Solaris</productname> 10, <productname>MacOS X</productname> 10.5, and later releases. This provider instruments various points in the X server, to allow @@ -235,9 +235,9 @@ DEALINGS IN THE SOFTWARE. <para> To access data in arguments of type <type>string</type>, you will need - to use <ulink url="http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyinstr}}"><function>copyinstr()</function></ulink>. + to use <ulink url="http://dtrace.org/guide/chp-actsub.html#chp-actsub-copyinstr"><function>copyinstr()</function></ulink>. To access data buffers referenced via <type>uintptr_t</type>'s, you will - need to use <ulink url="http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyin}}"><function>copyin()</function></ulink>. + need to use <ulink url="http://dtrace.org/guide/chp-actsub.html#chp-actsub-copyin"><function>copyin()</function></ulink>. <table id="Probe_Arguments"> <title>Probe Arguments</title> @@ -286,7 +286,7 @@ DEALINGS IN THE SOFTWARE. <entry><type>uintptr_t</type></entry> <entry>Pointer to buffer containing X event - decode using structures in - <<ulink url="http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>> + <<ulink url="https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/blob/master/include/X11/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>> and similar headers for each extension</entry> </row> <row> @@ -325,7 +325,7 @@ DEALINGS IN THE SOFTWARE. <entry><type>uintptr_t</type></entry> <entry>Pointer to buffer containing X request - decode using structures in - <<ulink url="http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>> + <<ulink url="https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/blob/master/include/X11/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>> and similar headers for each extension</entry> </row> <row> diff --git a/exa/exa_accel.c b/exa/exa_accel.c index b26d5c804..41fcb129f 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -1037,7 +1037,7 @@ exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, if (pExaPixmap->pDamage && pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP && pDrawable->width == 1 && pDrawable->height == 1 && - pDrawable->bitsPerPixel != 24) { + pDrawable->bitsPerPixel != 24 && alu == GXcopy) { RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); switch (pDrawable->bitsPerPixel) { diff --git a/glamor/glamor.c b/glamor/glamor.c index b1c7d9f13..abefef614 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -128,6 +128,21 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex) glamor_pixmap_attach_fbo(pixmap, fbo); } +_X_EXPORT void +glamor_clear_pixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv; + glamor_pixmap_private *pixmap_priv; + + glamor_priv = glamor_get_screen_private(screen); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + assert(pixmap_priv->fbo != NULL); + + glamor_pixmap_clear_fbo(glamor_priv, pixmap_priv->fbo); +} + uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap) { @@ -624,6 +639,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_NV_pack_subimage"); glamor_priv->has_dual_blend = + glamor_priv->glsl_version >= 130 && epoxy_has_gl_extension("GL_ARB_blend_func_extended"); glamor_priv->can_copyplane = (gl_version >= 30); diff --git a/glamor/glamor.h b/glamor/glamor.h index 09e9c895c..be04bf858 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -115,6 +115,9 @@ extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type); + +extern _X_EXPORT void glamor_clear_pixmap(PixmapPtr pixmap); + extern _X_EXPORT void glamor_block_handler(ScreenPtr screen); extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, @@ -395,6 +398,8 @@ extern _X_EXPORT Bool struct gbm_bo *bo, Bool used_modifiers); +extern _X_EXPORT const char *glamor_egl_get_driver_name(ScreenPtr screen); + #endif extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen, diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c index e050c0220..1ab2be6c0 100644 --- a/glamor/glamor_copy.c +++ b/glamor/glamor_copy.c @@ -221,7 +221,9 @@ glamor_copy_cpu_fbo(DrawablePtr src, goto bail; glamor_make_current(glamor_priv); - glamor_prepare_access(src, GLAMOR_ACCESS_RO); + + if (!glamor_prepare_access(src, GLAMOR_ACCESS_RO)) + goto bail; glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); @@ -309,7 +311,9 @@ glamor_copy_fbo_cpu(DrawablePtr src, goto bail; glamor_make_current(glamor_priv); - glamor_prepare_access(dst, GLAMOR_ACCESS_RW); + + if (!glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) + goto bail; glamor_get_drawable_deltas(src, src_pixmap, &src_xoff, &src_yoff); diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index d3c678d6b..ce8cbfaf4 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -355,8 +355,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok) return TRUE; } -struct gbm_bo * -glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) +static struct gbm_bo * +glamor_gbm_bo_from_pixmap_internal(ScreenPtr screen, PixmapPtr pixmap) { struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); @@ -370,6 +370,15 @@ glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) pixmap_priv->image, 0); } +struct gbm_bo * +glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) +{ + if (!glamor_make_pixmap_exportable(pixmap, TRUE)) + return NULL; + + return glamor_gbm_bo_from_pixmap_internal(screen, pixmap); +} + int glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, @@ -385,7 +394,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, if (!glamor_make_pixmap_exportable(pixmap, TRUE)) return 0; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return 0; @@ -423,7 +432,7 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, if (!glamor_make_pixmap_exportable(pixmap, FALSE)) return -1; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return -1; @@ -452,7 +461,7 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen, if (!glamor_make_pixmap_exportable(pixmap, FALSE)) goto failure; - bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) goto failure; @@ -679,6 +688,22 @@ glamor_get_modifiers(ScreenPtr screen, uint32_t format, #endif } +_X_EXPORT const char * +glamor_egl_get_driver_name(ScreenPtr screen) +{ +#ifdef GLAMOR_HAS_EGL_QUERY_DRIVER + struct glamor_egl_screen_private *glamor_egl; + + glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); + + if (epoxy_has_egl_extension(glamor_egl->display, "EGL_MESA_query_driver")) + return eglGetDisplayDriverName(glamor_egl->display); +#endif + + return NULL; +} + + static Bool glamor_egl_destroy_pixmap(PixmapPtr pixmap) { diff --git a/glamor/glamor_egl.h b/glamor/glamor_egl.h index 2f7566b24..8f6ed7840 100644 --- a/glamor/glamor_egl.h +++ b/glamor/glamor_egl.h @@ -28,6 +28,7 @@ #define GLAMOR_EGL_H #define MESA_EGL_NO_X11_HEADERS +#define EGL_NO_X11 #include <epoxy/gl.h> #include <epoxy/egl.h> #include <glamor_egl_ext.h> diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index e8c4330b3..f939a6c2f 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -239,6 +239,18 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv, return NULL; } +void +glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) +{ + glamor_make_current(glamor_priv); + + assert(fbo->fb != 0 && fbo->tex != 0); + + glamor_set_destination_pixmap_fbo(glamor_priv, fbo, 0, 0, fbo->width, fbo->height); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); +} + glamor_pixmap_fbo * glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv) { diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index 84a33ad6a..685d8d618 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -340,8 +340,10 @@ glamor_upload_picture_to_texture(PicturePtr picture) else iformat = format; - if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO)) + if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO)) { + ret = FALSE; goto fail; + } glPixelStorei(GL_UNPACK_ALIGNMENT, 4); diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c index 5a73e6c7d..835c4ebea 100644 --- a/glamor/glamor_prepare.c +++ b/glamor/glamor_prepare.c @@ -88,11 +88,29 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) gl_usage = GL_STREAM_READ; + glamor_priv->suppress_gl_out_of_memory_logging = true; + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo); glBufferData(GL_PIXEL_PACK_BUFFER, pixmap->devKind * pixmap->drawable.height, NULL, gl_usage); - } else { + + glamor_priv->suppress_gl_out_of_memory_logging = false; + + if (glGetError() == GL_OUT_OF_MEMORY) { + if (!glamor_priv->logged_any_pbo_allocation_failure) { + LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %d " + "bytes PBO due to GL_OUT_OF_MEMORY.\n", + pixmap->devKind * pixmap->drawable.height); + glamor_priv->logged_any_pbo_allocation_failure = true; + } + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glDeleteBuffers(1, &priv->pbo); + priv->pbo = 0; + } + } + + if (!priv->pbo) { pixmap->devPrivate.ptr = xallocarray(pixmap->devKind, pixmap->drawable.height); if (!pixmap->devPrivate.ptr) @@ -106,7 +124,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) RegionUninit(®ion); - if (glamor_priv->has_rw_pbo) { + if (priv->pbo) { if (priv->map_access == GLAMOR_ACCESS_RW) gl_access = GL_READ_WRITE; else @@ -128,8 +146,6 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) static void glamor_fini_pixmap(PixmapPtr pixmap) { - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) @@ -138,7 +154,7 @@ glamor_fini_pixmap(PixmapPtr pixmap) if (!priv->prepared) return; - if (glamor_priv->has_rw_pbo) { + if (priv->pbo) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); pixmap->devPrivate.ptr = NULL; @@ -153,7 +169,7 @@ glamor_fini_pixmap(PixmapPtr pixmap) RegionUninit(&priv->prepare_region); - if (glamor_priv->has_rw_pbo) { + if (priv->pbo) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteBuffers(1, &priv->pbo); priv->pbo = 0; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 7d9a7d4fb..4353a99f1 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -40,6 +40,7 @@ #include <epoxy/gl.h> #ifdef GLAMOR_HAS_GBM #define MESA_EGL_NO_X11_HEADERS +#define EGL_NO_X11 #include <epoxy/egl.h> #endif @@ -288,6 +289,7 @@ typedef struct glamor_screen_private { Bool suppress_gl_out_of_memory_logging; Bool logged_any_fbo_allocation_failure; + Bool logged_any_pbo_allocation_failure; /* xv */ glamor_program xv_prog; @@ -537,6 +539,7 @@ void glamor_destroy_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo); void glamor_pixmap_destroy_fbo(PixmapPtr pixmap); Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap); +void glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo); /* Return whether 'picture' is alpha-only */ static inline Bool glamor_picture_is_alpha(PicturePtr picture) diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 54d452e58..75e42823c 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -574,10 +574,8 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId, /* Look up old context. If we have one, it must be in a usable state. */ if (tag != 0) { prevglxc = glxServer.getContextTagPrivate(client, tag); - if (!prevglxc) - return __glXError(GLXBadContextTag); - if (prevglxc->renderMode != GL_RENDER) { + if (prevglxc && prevglxc->renderMode != GL_RENDER) { /* Oops. Not in render mode render. */ client->errorValue = prevglxc->id; return __glXError(GLXBadContextState); diff --git a/glx/glxdri2.c b/glx/glxdri2.c index d402ca860..822515a86 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -295,7 +295,7 @@ __glXDRIcontextWait(__GLXcontext * baseContext, } if (ret) { - *error = -1; + *error = cl->client->noClientException; return TRUE; } diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index 2858312de..c57d80db7 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -324,6 +324,7 @@ swrastGetImage(__DRIdrawable * draw, ScreenPtr pScreen = pDraw->pScreen; __GLXcontext *cx = lastGLContext; + pScreen->SourceValidate(pDraw, x, y, w, h, IncludeInferiors); pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data); if (cx != lastGLContext) { lastGLContext = cx; diff --git a/glx/meson.build b/glx/meson.build index 69d558e78..559b1feda 100644 --- a/glx/meson.build +++ b/glx/meson.build @@ -39,7 +39,7 @@ if build_glx common_dep, dl_dep, dependency('glproto', version: '>= 1.4.17'), - dependency('gl', version: '>= 9.2.0'), + dependency('gl', version: '>= 1.2'), ], c_args: [ glx_align64, @@ -74,7 +74,7 @@ if build_glx common_dep, dl_dep, dependency('glproto', version: '>= 1.4.17'), - dependency('gl', version: '>= 9.2.0'), + dependency('gl', version: '>= 1.2'), ], ) diff --git a/glx/vndcmds.c b/glx/vndcmds.c index f0779d14a..21c6fef9e 100644 --- a/glx/vndcmds.c +++ b/glx/vndcmds.c @@ -468,15 +468,24 @@ void GlxDispatchReset(void) int GlxDispatchRequest(ClientPtr client) { REQUEST(xReq); + int result; + if (GlxExtensionEntry->base == 0) return BadRequest; + + GlxSetRequestClient(client); + if (stuff->data < OPCODE_ARRAY_LEN) { if (dispatchFuncs[stuff->data] == NULL) { // Try to find a dispatch stub. dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0); } - return dispatchFuncs[stuff->data](client); + result = dispatchFuncs[stuff->data](client); } else { - return dispatch_GLXSingle(client); + result = dispatch_GLXSingle(client); } + + GlxSetRequestClient(NULL); + + return result; } diff --git a/glx/vndext.c b/glx/vndext.c index d7936467b..0513733b6 100644 --- a/glx/vndext.c +++ b/glx/vndext.c @@ -139,8 +139,17 @@ GlxGetClientData(ClientPtr client) { GlxClientPriv *cl = xglvGetClientPrivate(client); if (cl == NULL) { - cl = calloc(1, sizeof(GlxClientPriv)); + cl = calloc(1, sizeof(GlxClientPriv) + + screenInfo.numScreens * sizeof(GlxServerVendor *)); if (cl != NULL) { + int i; + + cl->vendors = (GlxServerVendor **) (cl + 1); + for (i=0; i<screenInfo.numScreens; i++) + { + cl->vendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]); + } + xglvSetClientPrivate(client, cl); } } @@ -295,8 +304,8 @@ GlxFreeServerImports(GlxServerImports *imports) } _X_EXPORT const GlxServerExports glxServer = { - .majorVersion = 0, - .minorVersion = 0, + .majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION, + .minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION, .extensionInitCallback = &vndInitCallbackListPtr, @@ -315,6 +324,7 @@ _X_EXPORT const GlxServerExports glxServer = { .getContextTagPrivate = GlxGetContextTagPrivate, .getVendorForScreen = GlxGetVendorForScreen, .forwardRequest = GlxForwardRequest, + .setClientScreenVendor = GlxSetClientScreenVendor, }; const GlxServerExports * diff --git a/glx/vndserver.h b/glx/vndserver.h index a175656ae..772b458a1 100644 --- a/glx/vndserver.h +++ b/glx/vndserver.h @@ -57,6 +57,11 @@ typedef struct GlxContextTagInfoRec { typedef struct GlxClientPrivRec { GlxContextTagInfo *contextTags; unsigned int contextTagCount; + + /** + * The vendor handles for each screen. + */ + GlxServerVendor **vendors; } GlxClientPriv; extern int GlxErrorBase; @@ -90,11 +95,19 @@ Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor); GlxServerVendor * GlxGetXIDMap(XID id); void GlxRemoveXIDMap(XID id); +/** + * Records the client that sent the current request. This is needed in + * GlxGetXIDMap to know which client's (screen -> vendor) mapping to use for a + * regular X window. + */ +void GlxSetRequestClient(ClientPtr client); + GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor); GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag); void GlxFreeContextTag(GlxContextTagInfo *tagInfo); Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor); +Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor); GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen); GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen); diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c index fd3be92d9..04788ffbd 100644 --- a/glx/vndservermapping.c +++ b/glx/vndservermapping.c @@ -33,6 +33,13 @@ #include "vndservervendor.h" +static ClientPtr requestClient = NULL; + +void GlxSetRequestClient(ClientPtr client) +{ + requestClient = client; +} + static GlxServerVendor *LookupXIDMapResource(XID id) { void *ptr = NULL; @@ -59,10 +66,7 @@ GlxServerVendor *GlxGetXIDMap(XID id) DixGetAttrAccess); if (rv == Success && ptr != NULL) { DrawablePtr draw = (DrawablePtr) ptr; - GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen); - if (screenPriv != NULL) { - vendor = screenPriv->vendor; - } + vendor = GlxGetVendorForScreen(requestClient, draw->pScreen); } } return vendor; @@ -185,12 +189,44 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor) return TRUE; } +Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor) +{ + GlxClientPriv *cl; + + if (screen == NULL || screen->isGPU) { + return FALSE; + } + + cl = GlxGetClientData(client); + if (cl == NULL) { + return FALSE; + } + + if (vendor != NULL) { + cl->vendors[screen->myNum] = vendor; + } else { + cl->vendors[screen->myNum] = GlxGetVendorForScreen(NULL, screen); + } + return TRUE; +} + GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen) { - GlxScreenPriv *priv = GlxGetScreen(screen); - if (priv != NULL) { - return priv->vendor; + // Note that the client won't be sending GPU screen numbers, so we don't + // need per-client mappings for them. + if (client != NULL && !screen->isGPU) { + GlxClientPriv *cl = GlxGetClientData(client); + if (cl != NULL) { + return cl->vendors[screen->myNum]; + } else { + return NULL; + } } else { - return NULL; + GlxScreenPriv *priv = GlxGetScreen(screen); + if (priv != NULL) { + return priv->vendor; + } else { + return NULL; + } } } diff --git a/hw/dmx/config/dmxconfig.c b/hw/dmx/config/dmxconfig.c index c1a9e1cf3..85bc0dbe4 100644 --- a/hw/dmx/config/dmxconfig.c +++ b/hw/dmx/config/dmxconfig.c @@ -72,7 +72,7 @@ typedef struct DMXConfigCmdStruct { DMXConfigList *xinputs; } DMXConfigCmd, *DMXConfigCmdPtr; -DMXConfigEntryPtr dmxConfigEntry; +extern DMXConfigEntryPtr dmxConfigEntry; static DMXConfigCmd dmxConfigCmd; static int dmxDisplaysFromCommandLine; diff --git a/hw/dmx/config/xdmxconfig.c b/hw/dmx/config/xdmxconfig.c index 49e4b5459..05d839688 100644 --- a/hw/dmx/config/xdmxconfig.c +++ b/hw/dmx/config/xdmxconfig.c @@ -65,7 +65,7 @@ extern FILE *yyin; #define DMX_CANVAS_WIDTH 400 #define DMX_CANVAS_HEIGHT 500 -DMXConfigEntryPtr dmxConfigEntry; +extern DMXConfigEntryPtr dmxConfigEntry; static DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual; static DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay; static int dmxConfigGrabbed, dmxConfigGrabbedFine; diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 07154d648..ddb331090 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -838,6 +838,15 @@ ddxGiveUp(enum ExitCode error) AbortDDX(error); } +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif + /** This function is called in Xserver/os/osinit.c from \a OsInit(). */ void OsVendorInit(void) diff --git a/hw/dmx/glxProxy/glxext.c b/hw/dmx/glxProxy/glxext.c index 49848bbff..ca9780f99 100644 --- a/hw/dmx/glxProxy/glxext.c +++ b/hw/dmx/glxProxy/glxext.c @@ -47,8 +47,6 @@ #include "extinit.h" #include "glx_extinit.h" -int noGlxExtension; - /* ** Forward declarations. */ diff --git a/hw/dmx/man/Xdmx.man b/hw/dmx/man/Xdmx.man index ef62a02f5..2ca9fb59f 100644 --- a/hw/dmx/man/Xdmx.man +++ b/hw/dmx/man/Xdmx.man @@ -729,4 +729,4 @@ Portions of are based on code from The XFree86 Project .RI ( http://www.xfree86.org ) and X.Org -.RI ( http://www.x.org ). +.RI ( https://www.x.org ). diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index abc35dfca..47bd97ade 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -100,6 +100,15 @@ CloseInput(void) KdCloseInput(); } +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif + #ifdef DDXBEFORERESET void ddxBeforeReset(void) diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c index 407f2afcd..d9f23f360 100644 --- a/hw/vfb/InitOutput.c +++ b/hw/vfb/InitOutput.c @@ -232,6 +232,15 @@ ddxBeforeReset(void) } #endif +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif + void ddxUseMsg(void) { diff --git a/hw/xfree86/common/compiler.h b/hw/xfree86/common/compiler.h index 7144c6a27..2b2008b3f 100644 --- a/hw/xfree86/common/compiler.h +++ b/hw/xfree86/common/compiler.h @@ -758,36 +758,6 @@ inl(unsigned short port) return xf86ReadMmio32Le((void *) ioBase, port); } -#elif defined(__arm__) && defined(__linux__) - -/* for Linux on ARM, we use the LIBC inx/outx routines */ -/* note that the appropriate setup via "ioperm" needs to be done */ -/* *before* any inx/outx is done. */ - -#include <sys/io.h> - -static __inline__ void -xf_outb(unsigned short port, unsigned char val) -{ - outb(val, port); -} - -static __inline__ void -xf_outw(unsigned short port, unsigned short val) -{ - outw(val, port); -} - -static __inline__ void -xf_outl(unsigned short port, unsigned int val) -{ - outl(val, port); -} - -#define outb xf_outb -#define outw xf_outw -#define outl xf_outl - #elif defined(__nds32__) /* diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index cabf8716b..2ec6b2f8b 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -682,36 +682,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0)) FatalError("Cannot register DDX private keys"); - for (i = 0; i < xf86NumGPUScreens; i++) { - ScrnInfoPtr pScrn = xf86GPUScreens[i]; - xf86VGAarbiterLock(pScrn); - - /* - * Almost everything uses these defaults, and many of those that - * don't, will wrap them. - */ - pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; -#ifdef XFreeXDGA - pScrn->SetDGAMode = xf86SetDGAMode; -#endif - pScrn->DPMSSet = NULL; - pScrn->LoadPalette = NULL; - pScrn->SetOverscan = NULL; - pScrn->DriverFunc = NULL; - pScrn->pScreen = NULL; - scr_index = AddGPUScreen(xf86ScreenInit, argc, argv); - xf86VGAarbiterUnlock(pScrn); - if (scr_index == i) { - dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates, - xf86ScreenKey, xf86GPUScreens[i]); - pScrn->pScreen = screenInfo.gpuscreens[scr_index]; - /* The driver should set this, but make sure it is set anyway */ - pScrn->vtSema = TRUE; - } else { - FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index); - } - } - for (i = 0; i < xf86NumScreens; i++) { xf86VGAarbiterLock(xf86Screens[i]); /* @@ -767,6 +737,36 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) xf86EnsureRANDR(xf86Screens[i]->pScreen); } + for (i = 0; i < xf86NumGPUScreens; i++) { + ScrnInfoPtr pScrn = xf86GPUScreens[i]; + xf86VGAarbiterLock(pScrn); + + /* + * Almost everything uses these defaults, and many of those that + * don't, will wrap them. + */ + pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; +#ifdef XFreeXDGA + pScrn->SetDGAMode = xf86SetDGAMode; +#endif + pScrn->DPMSSet = NULL; + pScrn->LoadPalette = NULL; + pScrn->SetOverscan = NULL; + pScrn->DriverFunc = NULL; + pScrn->pScreen = NULL; + scr_index = AddGPUScreen(xf86ScreenInit, argc, argv); + xf86VGAarbiterUnlock(pScrn); + if (scr_index == i) { + dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates, + xf86ScreenKey, xf86GPUScreens[i]); + pScrn->pScreen = screenInfo.gpuscreens[scr_index]; + /* The driver should set this, but make sure it is set anyway */ + pScrn->vtSema = TRUE; + } else { + FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index); + } + } + for (i = 0; i < xf86NumGPUScreens; i++) AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen); @@ -1444,3 +1444,13 @@ ddxBeforeReset(void) { } #endif + +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ + xf86OSInputThreadInit(); +} +#endif diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index dd4d5f958..00aa84ae2 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -74,7 +74,7 @@ * mask is 0xFFFF0000. */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(24, 0) +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(24, 1) #define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 1) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0) diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index 750e4270b..b884d8212 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -262,6 +262,10 @@ #define MAX_H (_MAX_H(c) + _MAX_H_OFFSET(c)) #define _MAX_CLOCK(x) x[9] #define MAX_CLOCK _MAX_CLOCK(c) +#define _DEFAULT_GTF(x) (x[10] == 0x00) +#define DEFAULT_GTF _DEFAULT_GTF(c) +#define _RANGE_LIMITS_ONLY(x) (x[10] == 0x01) +#define RANGE_LIMITS_ONLY _RANGE_LIMITS_ONLY(c) #define _HAVE_2ND_GTF(x) (x[10] == 0x02) #define HAVE_2ND_GTF _HAVE_2ND_GTF(c) #define _F_2ND_GTF(x) (x[12] * 2) @@ -477,6 +481,16 @@ struct detailed_timings { #define DS_VENDOR 0x101 #define DS_VENDOR_MAX 0x110 +/* + * Display range limit Descriptor of EDID version1, reversion 4 + */ +typedef enum { + DR_DEFAULT_GTF, + DR_LIMITS_ONLY, + DR_SECONDARY_GTF, + DR_CVT_SUPPORTED = 4, +} DR_timing_flags; + struct monitor_ranges { int min_v; int max_v; @@ -495,6 +509,7 @@ struct monitor_ranges { char supported_blanking; char supported_scaling; int preferred_refresh; /* in hz */ + DR_timing_flags display_range_timing_flags; }; struct whitePoints { @@ -524,7 +539,7 @@ struct detailed_monitor_section { Uchar serial[13]; Uchar ascii_data[13]; Uchar name[13]; - struct monitor_ranges ranges; /* 56 */ + struct monitor_ranges ranges; /* 60 */ struct std_timings std_t[5]; /* 80 */ struct whitePoints wp[2]; /* 32 */ /* color management data */ diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 17a8f81c0..19630471c 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -672,6 +672,9 @@ get_monitor_ranges(Uchar * c, struct monitor_ranges *r) r->max_clock = 0; if (MAX_CLOCK != 0xff) /* is specified? */ r->max_clock = MAX_CLOCK * 10 + 5; + + r->display_range_timing_flags = c[10]; + if (HAVE_2ND_GTF) { r->gtf_2nd_f = F_2ND_GTF; r->gtf_2nd_c = C_2ND_GTF; @@ -751,6 +754,30 @@ validate_version(int scrnIndex, struct edid_version *r) return TRUE; } +Bool +gtf_supported(xf86MonPtr mon) +{ + int i; + + if (!mon) + return FALSE; + + if ((mon->ver.version == 1) && (mon->ver.revision < 4)) { + if (mon->features.msc & 0x1) + return TRUE; + } else { + for (i = 0; i < DET_TIMINGS; i++) { + struct detailed_monitor_section *det_timing_des = &(mon->det_mon[i]); + if (det_timing_des && (det_timing_des->type == DS_RANGES) && + (det_timing_des->section.ranges.display_range_timing_flags == DR_DEFAULT_GTF + || det_timing_des->section.ranges.display_range_timing_flags == DR_SECONDARY_GTF)) + return TRUE; + } + } + + return FALSE; +} + /* * Returns true if HDMI, false if definitely not or unknown. */ diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h index 7d81ab911..6eb2f0ba2 100644 --- a/hw/xfree86/ddc/xf86DDC.h +++ b/hw/xfree86/ddc/xf86DDC.h @@ -48,6 +48,9 @@ extern _X_EXPORT Bool xf86SetDDCproperties(ScrnInfoPtr pScreen, xf86MonPtr DDC); extern _X_EXPORT Bool xf86MonitorIsHDMI(xf86MonPtr mon); +extern _X_EXPORT Bool +gtf_supported(xf86MonPtr mon); + extern _X_EXPORT DisplayModePtr FindDMTMode(int hsize, int vsize, int refresh, Bool rb); diff --git a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h index 1ef1a0edf..646df447b 100644 --- a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h +++ b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h @@ -1,3 +1,4 @@ +#ifndef IRIS CHIPSET(0x29A2, i965, "Intel(R) 965G") CHIPSET(0x2992, i965, "Intel(R) 965Q") CHIPSET(0x2982, i965, "Intel(R) 965G") @@ -91,6 +92,11 @@ CHIPSET(0x0F32, byt, "Intel(R) Bay Trail") CHIPSET(0x0F33, byt, "Intel(R) Bay Trail") CHIPSET(0x0157, byt, "Intel(R) Bay Trail") CHIPSET(0x0155, byt, "Intel(R) Bay Trail") +CHIPSET(0x22B0, chv, "Intel(R) HD Graphics (Cherrytrail)") +CHIPSET(0x22B1, chv, "Intel(R) HD Graphics XXX (Braswell)") /* Overridden in brw_get_renderer_string */ +CHIPSET(0x22B2, chv, "Intel(R) HD Graphics (Cherryview)") +CHIPSET(0x22B3, chv, "Intel(R) HD Graphics (Cherryview)") +#endif CHIPSET(0x1602, bdw_gt1, "Intel(R) Broadwell GT1") CHIPSET(0x1606, bdw_gt1, "Intel(R) Broadwell GT1") CHIPSET(0x160A, bdw_gt1, "Intel(R) Broadwell GT1") @@ -109,10 +115,6 @@ CHIPSET(0x162A, bdw_gt3, "Intel(R) Iris Pro P6300 (Broadwell GT3e)") CHIPSET(0x162B, bdw_gt3, "Intel(R) Iris 6100 (Broadwell GT3)") CHIPSET(0x162D, bdw_gt3, "Intel(R) Broadwell GT3") CHIPSET(0x162E, bdw_gt3, "Intel(R) Broadwell GT3") -CHIPSET(0x22B0, chv, "Intel(R) HD Graphics (Cherrytrail)") -CHIPSET(0x22B1, chv, "Intel(R) HD Graphics XXX (Braswell)") /* Overridden in brw_get_renderer_string */ -CHIPSET(0x22B2, chv, "Intel(R) HD Graphics (Cherryview)") -CHIPSET(0x22B3, chv, "Intel(R) HD Graphics (Cherryview)") CHIPSET(0x1902, skl_gt1, "Intel(R) HD Graphics 510 (Skylake GT1)") CHIPSET(0x1906, skl_gt1, "Intel(R) HD Graphics 510 (Skylake GT1)") CHIPSET(0x190A, skl_gt1, "Intel(R) Skylake GT1") @@ -156,7 +158,6 @@ CHIPSET(0x5912, kbl_gt2, "Intel(R) HD Graphics 630 (Kaby Lake GT2)") CHIPSET(0x5916, kbl_gt2, "Intel(R) HD Graphics 620 (Kaby Lake GT2)") CHIPSET(0x591A, kbl_gt2, "Intel(R) HD Graphics P630 (Kaby Lake GT2)") CHIPSET(0x591B, kbl_gt2, "Intel(R) HD Graphics 630 (Kaby Lake GT2)") -CHIPSET(0x591C, kbl_gt2, "Intel(R) Kaby Lake GT2") CHIPSET(0x591D, kbl_gt2, "Intel(R) HD Graphics P630 (Kaby Lake GT2)") CHIPSET(0x591E, kbl_gt2, "Intel(R) HD Graphics 615 (Kaby Lake GT2)") CHIPSET(0x5921, kbl_gt2, "Intel(R) Kabylake GT2F") @@ -164,13 +165,15 @@ CHIPSET(0x5923, kbl_gt3, "Intel(R) Kabylake GT3") CHIPSET(0x5926, kbl_gt3, "Intel(R) Iris Plus Graphics 640 (Kaby Lake GT3e)") CHIPSET(0x5927, kbl_gt3, "Intel(R) Iris Plus Graphics 650 (Kaby Lake GT3e)") CHIPSET(0x593B, kbl_gt4, "Intel(R) Kabylake GT4") +CHIPSET(0x591C, kbl_gt2, "Intel(R) Amber Lake (Kabylake) GT2") +CHIPSET(0x87C0, kbl_gt2, "Intel(R) Amber Lake (Kabylake) GT2") +CHIPSET(0x87CA, cfl_gt2, "Intel(R) Amber Lake (Coffeelake) GT2") CHIPSET(0x3184, glk, "Intel(R) UHD Graphics 605 (Geminilake)") CHIPSET(0x3185, glk_2x6, "Intel(R) UHD Graphics 600 (Geminilake 2x6)") CHIPSET(0x3E90, cfl_gt1, "Intel(R) UHD Graphics 610 (Coffeelake 2x6 GT1)") CHIPSET(0x3E93, cfl_gt1, "Intel(R) UHD Graphics 610 (Coffeelake 2x6 GT1)") CHIPSET(0x3E99, cfl_gt1, "Intel(R) HD Graphics (Coffeelake 2x6 GT1)") -CHIPSET(0x3EA1, cfl_gt1, "Intel(R) HD Graphics (Coffeelake 2x6 GT1)") -CHIPSET(0x3EA4, cfl_gt1, "Intel(R) HD Graphics (Coffeelake 2x6 GT1)") +CHIPSET(0x3E9C, 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)") @@ -178,14 +181,34 @@ 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)") -CHIPSET(0x3EA0, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") -CHIPSET(0x3EA3, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") CHIPSET(0x3EA9, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)") -CHIPSET(0x3EA2, cfl_gt3, "Intel(R) HD Graphics (Coffeelake 3x8 GT3)") CHIPSET(0x3EA5, cfl_gt3, "Intel(R) HD Graphics (Coffeelake 3x8 GT3)") CHIPSET(0x3EA6, cfl_gt3, "Intel(R) HD Graphics (Coffeelake 3x8 GT3)") CHIPSET(0x3EA7, cfl_gt3, "Intel(R) HD Graphics (Coffeelake 3x8 GT3)") CHIPSET(0x3EA8, cfl_gt3, "Intel(R) HD Graphics (Coffeelake 3x8 GT3)") +CHIPSET(0x3EA1, cfl_gt1, "Intel(R) HD Graphics (Whiskey Lake 2x6 GT1)") +CHIPSET(0x3EA4, cfl_gt1, "Intel(R) HD Graphics (Whiskey Lake 3x8 GT1)") +CHIPSET(0x3EA0, cfl_gt2, "Intel(R) HD Graphics (Whiskey Lake 3x8 GT2)") +CHIPSET(0x3EA3, cfl_gt2, "Intel(R) HD Graphics (Whiskey Lake 3x8 GT2)") +CHIPSET(0x3EA2, cfl_gt3, "Intel(R) HD Graphics (Whiskey Lake 3x8 GT3)") +CHIPSET(0x9B21, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BA0, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BA2, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BA4, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BA5, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BA8, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BAA, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BAB, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9BAC, cfl_gt1, "Intel(R) HD Graphics (Comet Lake 2x6 GT1)") +CHIPSET(0x9B41, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BC0, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BC2, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BC4, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BC5, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BC8, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BCA, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BCB, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") +CHIPSET(0x9BCC, cfl_gt2, "Intel(R) HD Graphics (Comet Lake 3x8 GT2)") CHIPSET(0x5A49, cnl_2x8, "Intel(R) HD Graphics (Cannonlake 2x8 GT0.5)") CHIPSET(0x5A4A, cnl_2x8, "Intel(R) HD Graphics (Cannonlake 2x8 GT0.5)") CHIPSET(0x5A41, cnl_3x8, "Intel(R) HD Graphics (Cannonlake 3x8 GT1)") @@ -201,8 +224,18 @@ CHIPSET(0x5A54, cnl_5x8, "Intel(R) HD Graphics (Cannonlake 5x8 GT2)") CHIPSET(0x8A50, icl_8x8, "Intel(R) HD Graphics (Ice Lake 8x8 GT2)") CHIPSET(0x8A51, icl_8x8, "Intel(R) HD Graphics (Ice Lake 8x8 GT2)") CHIPSET(0x8A52, icl_8x8, "Intel(R) HD Graphics (Ice Lake 8x8 GT2)") +CHIPSET(0x8A53, icl_8x8, "Intel(R) HD Graphics (Ice Lake 8x8 GT2)") +CHIPSET(0x8A54, icl_6x8, "Intel(R) HD Graphics (Ice Lake 6x8 GT1.5)") +CHIPSET(0x8A56, icl_4x8, "Intel(R) HD Graphics (Ice Lake 4x8 GT1)") +CHIPSET(0x8A57, icl_6x8, "Intel(R) HD Graphics (Ice Lake 6x8 GT1.5)") +CHIPSET(0x8A58, icl_4x8, "Intel(R) HD Graphics (Ice Lake 4x8 GT1)") +CHIPSET(0x8A59, icl_6x8, "Intel(R) HD Graphics (Ice Lake 6x8 GT1.5)") CHIPSET(0x8A5A, icl_6x8, "Intel(R) HD Graphics (Ice Lake 6x8 GT1.5)") CHIPSET(0x8A5B, icl_4x8, "Intel(R) HD Graphics (Ice Lake 4x8 GT1)") CHIPSET(0x8A5C, icl_6x8, "Intel(R) HD Graphics (Ice Lake 6x8 GT1.5)") CHIPSET(0x8A5D, icl_4x8, "Intel(R) HD Graphics (Ice Lake 4x8 GT1)") CHIPSET(0x8A71, icl_1x8, "Intel(R) HD Graphics (Ice Lake 1x8 GT0.5)") +CHIPSET(0x4500, ehl_4x8, "Intel(R) HD Graphics (Elkhart Lake 4x8)") +CHIPSET(0x4571, ehl_4x8, "Intel(R) HD Graphics (Elkhart Lake 4x8)") +CHIPSET(0x4551, ehl_4x4, "Intel(R) HD Graphics (Elkhart Lake 4x4)") +CHIPSET(0x4541, ehl_2x4, "Intel(R) HD Graphics (Elkhart Lake 2x4)") diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am index e0411ef51..961c57408 100644 --- a/hw/xfree86/drivers/modesetting/Makefile.am +++ b/hw/xfree86/drivers/modesetting/Makefile.am @@ -24,6 +24,8 @@ # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +include $(top_srcdir)/manpages.am + AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(LIBDRM_CFLAGS) $(UDEV_CFLAGS) $(CWARNFLAGS) AM_CPPFLAGS = \ @@ -62,9 +64,3 @@ driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@) EXTRA_DIST = modesetting.man CLEANFILES = $(driverman_DATA) - -# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure -SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man - -.man.$(DRIVER_MAN_SUFFIX): - $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c index 96eaaaaf7..c0799896c 100644 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ b/hw/xfree86/drivers/modesetting/dri2.c @@ -586,6 +586,7 @@ can_flip(ScrnInfoPtr scrn, DrawablePtr draw, return draw->type == DRAWABLE_WINDOW && ms->drmmode.pageflip && + !ms->drmmode.sprites_visible && !ms->drmmode.present_flipping && scrn->vtSema && DRI2CanFlip(draw) && can_exchange(scrn, draw, front, back); @@ -1033,6 +1034,7 @@ ms_dri2_screen_init(ScreenPtr screen) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); DRI2InfoRec info; + const char *driver_names[2] = { NULL, NULL }; if (!glamor_supports_pixmap_import_export(screen)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1071,9 +1073,30 @@ ms_dri2_screen_init(ScreenPtr screen) info.DestroyBuffer2 = ms_dri2_destroy_buffer2; info.CopyRegion2 = ms_dri2_copy_region2; - /* These two will be filled in by dri2.c */ - info.numDrivers = 0; - info.driverNames = NULL; + /* Ask Glamor to obtain the DRI driver name via EGL_MESA_query_driver. */ + driver_names[0] = glamor_egl_get_driver_name(screen); + + if (driver_names[0]) { + /* There is no VDPAU driver for Intel, fallback to the generic + * OpenGL/VAAPI va_gl backend to emulate VDPAU. Otherwise, + * guess that the DRI and VDPAU drivers have the same name. + */ + if (strcmp(driver_names[0], "i965") == 0 || + strcmp(driver_names[0], "iris") == 0) { + driver_names[1] = "va_gl"; + } else { + driver_names[1] = driver_names[0]; + } + + info.numDrivers = 2; + info.driverNames = driver_names; + } else { + /* EGL_MESA_query_driver was unavailable; let dri2.c select the + * driver and fill in these fields for us. + */ + info.numDrivers = 0; + info.driverNames = NULL; + } return DRI2ScreenInit(screen, &info); } diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 8d29b130f..2aaea5f7d 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -41,6 +41,7 @@ #include "compiler.h" #include "xf86Pci.h" #include "mipointer.h" +#include "mipointrst.h" #include "micmap.h" #include <X11/extensions/randr.h> #include "fb.h" @@ -131,6 +132,7 @@ static const OptionInfoRec Options[] = { {OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE}, {OPTION_DOUBLE_SHADOW, "DoubleShadow", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ATOMIC, "Atomic", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -1038,8 +1040,12 @@ PreInit(ScrnInfoPtr pScrn, int flags) #endif } - ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); - ms->atomic_modeset = (ret == 0); + if (xf86ReturnOptValBool(ms->drmmode.Options, OPTION_ATOMIC, FALSE)) { + ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); + ms->atomic_modeset = (ret == 0); + } else { + ms->atomic_modeset = FALSE; + } ms->kms_has_modifiers = FALSE; ret = drmGetCap(ms->fd, DRM_CAP_ADDFB2_MODIFIERS, &value); @@ -1332,7 +1338,6 @@ static Bool CreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap; Bool ret; @@ -1398,10 +1403,14 @@ CreateScreenResources(ScreenPtr pScreen) } } - pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping; - pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping; + if (dixPrivateKeyRegistered(rrPrivKey)) { + rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); + + pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping; + pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping; - pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking; + pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking; + } return ret; } @@ -1648,6 +1657,21 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) xf86SetSilkenMouse(pScreen); miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + /* If pageflip is enabled hook the screen's cursor-sprite (swcursor) funcs. + * So that we can disabe page-flipping on fallback to a swcursor. */ + if (ms->drmmode.pageflip) { + miPointerScreenPtr PointPriv = + dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + if (!dixRegisterScreenPrivateKey(&ms->drmmode.spritePrivateKeyRec, + pScreen, PRIVATE_DEVICE, + sizeof(msSpritePrivRec))) + return FALSE; + + ms->SpriteFuncs = PointPriv->spriteFuncs; + PointPriv->spriteFuncs = &drmmode_sprite_funcs; + } + /* Need to extend HWcursor support to handle mask interleave */ if (!ms->drmmode.sw_cursor) xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height, @@ -1844,6 +1868,14 @@ CloseScreen(ScreenPtr pScreen) drmmode_free_bos(pScrn, &ms->drmmode); + if (ms->drmmode.pageflip) { + miPointerScreenPtr PointPriv = + dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + if (PointPriv->spriteFuncs == &drmmode_sprite_funcs) + PointPriv->spriteFuncs = ms->SpriteFuncs; + } + if (pScrn->vtSema) { LeaveVT(pScrn); } diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index c8db4b8a4..f2e7889db 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -51,6 +51,7 @@ typedef enum { OPTION_PAGEFLIP, OPTION_ZAPHOD_HEADS, OPTION_DOUBLE_SHADOW, + OPTION_ATOMIC, } modesettingOpts; typedef struct @@ -96,6 +97,7 @@ typedef struct _modesettingRec { CreateScreenResourcesProcPtr createScreenResources; ScreenBlockHandlerProcPtr BlockHandler; + miPointerSpriteFuncPtr SpriteFuncs; void *driver; drmmode_rec drmmode; @@ -147,6 +149,7 @@ void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq); Bool ms_crtc_on(xf86CrtcPtr crtc); xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw); +RRCrtcPtr ms_randr_crtc_covering_drawable(DrawablePtr pDraw); int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc); diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 336f7686e..9dd8c5573 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -34,8 +34,10 @@ #include <sys/mman.h> #include <unistd.h> #include "dumb_bo.h" +#include "inputstr.h" #include "xf86str.h" #include "X11/Xatom.h" +#include "mi.h" #include "micmap.h" #include "xf86cmap.h" #include "xf86DDC.h" @@ -754,6 +756,7 @@ drmmode_crtc_set_mode(xf86CrtcPtr crtc, Bool test_only) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; + ScreenPtr screen = crtc->scrn->pScreen; drmModeModeInfo kmode; int output_count = 0; uint32_t *output_ids = NULL; @@ -764,6 +767,12 @@ drmmode_crtc_set_mode(xf86CrtcPtr crtc, Bool test_only) if (!drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y)) return 1; +#ifdef GLAMOR_HAS_GBM + /* Make sure any pending drawing will be visible in a new scanout buffer */ + if (drmmode->glamor) + glamor_finish(screen); +#endif + if (ms->atomic_modeset) { drmModeAtomicReq *req = drmModeAtomicAlloc(); Bool active; @@ -1452,8 +1461,6 @@ drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) FreeScratchGC(gc); - glamor_finish(pScreen); - pScreen->canDoBGNoneRoot = TRUE; if (drmmode->fbcon_pixmap) @@ -1790,6 +1797,19 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) &drmmode_crtc->prime_pixmap); } +static void +drmmode_clear_pixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + GCPtr gc; + + gc = GetScratchGC(pixmap->drawable.depth, screen); + if (gc) { + miClearDrawable(&pixmap->drawable, gc); + FreeScratchGC(gc); + } +} + static void * drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { @@ -2419,7 +2439,7 @@ drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes) int max_x = 0, max_y = 0; float max_vrefresh = 0.0; - if (mon && GTF_SUPPORTED(mon->features.msc)) + if (mon && gtf_supported(mon)) return Modes; if (!has_panel_fitter(output)) @@ -3174,6 +3194,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) if (!drmmode_glamor_handle_new_screen_pixmap(drmmode)) goto fail; + drmmode_clear_pixmap(ppix); + for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; @@ -3184,10 +3206,10 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) crtc->rotation, crtc->x, crtc->y); } - if (old_fb_id) { + if (old_fb_id) drmModeRmFB(drmmode->fd, old_fb_id); - drmmode_bo_destroy(drmmode, &old_front); - } + + drmmode_bo_destroy(drmmode, &old_front); return TRUE; @@ -3206,13 +3228,19 @@ static void drmmode_validate_leases(ScrnInfoPtr scrn) { ScreenPtr screen = scrn->pScreen; - rrScrPrivPtr scr_priv = rrGetScrPriv(screen); + rrScrPrivPtr scr_priv; modesettingPtr ms = modesettingPTR(scrn); drmmode_ptr drmmode = &ms->drmmode; drmModeLesseeListPtr lessees; RRLeasePtr lease, next; int l; + /* Bail out if RandR wasn't initialized. */ + if (!dixPrivateKeyRegistered(rrPrivKey)) + return; + + scr_priv = rrGetScrPriv(screen); + /* We can't talk to the kernel about leases when VT switched */ if (!scrn->vtSema) return; @@ -3650,7 +3678,7 @@ drmmode_handle_uevents(int fd, void *closure) goto out; if (mode_res->count_crtcs != config->num_crtc) { - ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc); + /* this triggers with Zaphod mode where we don't currently support connector hotplug or MST. */ goto out_free_res; } @@ -3699,15 +3727,16 @@ drmmode_handle_uevents(int fd, void *closure) drmmode_output_init(scrn, drmmode, mode_res, i, TRUE, 0); } - /* Check to see if a lessee has disappeared */ - drmmode_validate_leases(scrn); - if (changed) { RRSetChanged(xf86ScrnToScreen(scrn)); RRTellChanged(xf86ScrnToScreen(scrn)); } out_free_res: + + /* Check to see if a lessee has disappeared */ + drmmode_validate_leases(scrn); + drmModeFreeResources(mode_res); out: RRGetInfo(xf86ScrnToScreen(scrn), TRUE); @@ -3910,3 +3939,102 @@ drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int *depth, drmModeFreeResources(mode_res); return; } + +/* + * We hook the screen's cursor-sprite (swcursor) functions to see if a swcursor + * is active. When a swcursor is active we disabe page-flipping. + */ + +static void drmmode_sprite_do_set_cursor(msSpritePrivPtr sprite_priv, + ScrnInfoPtr scrn, int x, int y) +{ + modesettingPtr ms = modesettingPTR(scrn); + CursorPtr cursor = sprite_priv->cursor; + Bool sprite_visible = sprite_priv->sprite_visible; + + if (cursor) { + x -= cursor->bits->xhot; + y -= cursor->bits->yhot; + + sprite_priv->sprite_visible = + x < scrn->virtualX && y < scrn->virtualY && + (x + cursor->bits->width > 0) && + (y + cursor->bits->height > 0); + } else { + sprite_priv->sprite_visible = FALSE; + } + + ms->drmmode.sprites_visible += sprite_priv->sprite_visible - sprite_visible; +} + +static void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + msSpritePrivPtr sprite_priv = msGetSpritePriv(pDev, ms, pScreen); + + sprite_priv->cursor = pCursor; + drmmode_sprite_do_set_cursor(sprite_priv, scrn, x, y); + + ms->SpriteFuncs->SetCursor(pDev, pScreen, pCursor, x, y); +} + +static void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + msSpritePrivPtr sprite_priv = msGetSpritePriv(pDev, ms, pScreen); + + drmmode_sprite_do_set_cursor(sprite_priv, scrn, x, y); + + ms->SpriteFuncs->MoveCursor(pDev, pScreen, x, y); +} + +static Bool drmmode_sprite_realize_realize_cursor(DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + + return ms->SpriteFuncs->RealizeCursor(pDev, pScreen, pCursor); +} + +static Bool drmmode_sprite_realize_unrealize_cursor(DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + + return ms->SpriteFuncs->UnrealizeCursor(pDev, pScreen, pCursor); +} + +static Bool drmmode_sprite_device_cursor_initialize(DeviceIntPtr pDev, + ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + + return ms->SpriteFuncs->DeviceCursorInitialize(pDev, pScreen); +} + +static void drmmode_sprite_device_cursor_cleanup(DeviceIntPtr pDev, + ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(scrn); + + ms->SpriteFuncs->DeviceCursorCleanup(pDev, pScreen); +} + +miPointerSpriteFuncRec drmmode_sprite_funcs = { + .RealizeCursor = drmmode_sprite_realize_realize_cursor, + .UnrealizeCursor = drmmode_sprite_realize_unrealize_cursor, + .SetCursor = drmmode_sprite_set_cursor, + .MoveCursor = drmmode_sprite_move_cursor, + .DeviceCursorInitialize = drmmode_sprite_device_cursor_initialize, + .DeviceCursorCleanup = drmmode_sprite_device_cursor_cleanup, +}; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index cde661450..4142607fb 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -111,6 +111,9 @@ typedef struct { void *shadow_fb2; DevPrivateKeyRec pixmapPrivateKeyRec; + DevScreenPrivateKeyRec spritePrivateKeyRec; + /* Number of SW cursors currently visible on this screen */ + int sprites_visible; Bool reverse_prime_offload_mode; @@ -242,6 +245,15 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec; #define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec)) +typedef struct _msSpritePriv { + CursorPtr cursor; + Bool sprite_visible; +} msSpritePrivRec, *msSpritePrivPtr; + +#define msGetSpritePriv(dev, ms, screen) dixLookupScreenPrivate(&(dev)->devPrivates, &(ms)->drmmode.spritePrivateKeyRec, screen) + +extern miPointerSpriteFuncRec drmmode_sprite_funcs; + Bool drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, uint64_t modifier); int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo, diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c index dda7cc064..009a0790c 100644 --- a/hw/xfree86/drivers/modesetting/present.c +++ b/hw/xfree86/drivers/modesetting/present.c @@ -59,8 +59,7 @@ struct ms_present_vblank_event { static RRCrtcPtr ms_present_get_crtc(WindowPtr window) { - xf86CrtcPtr xf86_crtc = ms_dri2_crtc_covering_drawable(&window->drawable); - return xf86_crtc ? xf86_crtc->randr_crtc : NULL; + return ms_randr_crtc_covering_drawable(&window->drawable); } static int @@ -209,13 +208,17 @@ ms_present_flip_abort(modesettingPtr ms, void *data) /* * Test to see if page flipping is possible on the target crtc + * + * We ignore sw-cursors when *disabling* flipping, we may very well be + * returning to scanning out the normal framebuffer *because* we just + * switched to sw-cursor mode and check_flip just failed because of that. */ static Bool -ms_present_check_flip(RRCrtcPtr crtc, - WindowPtr window, - PixmapPtr pixmap, - Bool sync_flip, - PresentFlipReason *reason) +ms_present_check_unflip(RRCrtcPtr crtc, + WindowPtr window, + PixmapPtr pixmap, + Bool sync_flip, + PresentFlipReason *reason) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -282,6 +285,23 @@ ms_present_check_flip(RRCrtcPtr crtc, return TRUE; } +static Bool +ms_present_check_flip(RRCrtcPtr crtc, + WindowPtr window, + PixmapPtr pixmap, + Bool sync_flip, + PresentFlipReason *reason) +{ + ScreenPtr screen = window->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); + + if (ms->drmmode.sprites_visible > 0) + return FALSE; + + return ms_present_check_unflip(crtc, window, pixmap, sync_flip, reason); +} + /* * Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true, * then wait for vblank. Otherwise, flip immediately @@ -344,7 +364,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id) event->event_id = event_id; event->unflip = TRUE; - if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE, NULL) && + if (ms_present_check_unflip(NULL, screen->root, pixmap, TRUE, NULL) && ms_do_pageflip(screen, pixmap, event, -1, FALSE, ms_present_flip_handler, ms_present_flip_abort)) { return; diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c index 561229f30..50d2fd3a4 100644 --- a/hw/xfree86/drivers/modesetting/vblank.c +++ b/hw/xfree86/drivers/modesetting/vblank.c @@ -77,6 +77,28 @@ static void ms_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; } +static void ms_randr_crtc_box(RRCrtcPtr crtc, BoxPtr crtc_box) +{ + if (crtc->mode) { + crtc_box->x1 = crtc->x; + crtc_box->y1 = crtc->y; + switch (crtc->rotation) { + case RR_Rotate_0: + case RR_Rotate_180: + default: + crtc_box->x2 = crtc->x + crtc->mode->mode.width; + crtc_box->y2 = crtc->y + crtc->mode->mode.height; + break; + case RR_Rotate_90: + case RR_Rotate_270: + crtc_box->x2 = crtc->x + crtc->mode->mode.height; + crtc_box->y2 = crtc->y + crtc->mode->mode.width; + break; + } + } else + crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; +} + static int ms_box_area(BoxPtr box) { return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1); @@ -91,12 +113,45 @@ ms_crtc_on(xf86CrtcPtr crtc) } /* + * Return the first output which is connected to an active CRTC on this screen. + * + * RRFirstOutput() will return an output from a slave screen if it is primary, + * which is not the behavior that ms_covering_crtc() wants. + */ + +static RROutputPtr ms_first_output(ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; + + if (!pScrPriv) + return NULL; + + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc && + (pScrPriv->primaryOutput->pScreen == pScreen)) { + return pScrPriv->primaryOutput; + } + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + for (j = 0; j < pScrPriv->numOutputs; j++) { + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; + } + } + return NULL; +} + +/* * Return the crtc covering 'box'. If two crtcs cover a portion of * 'box', then prefer the crtc with greater coverage. */ static xf86CrtcPtr -ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) +ms_covering_xf86_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -108,6 +163,10 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) best_crtc = NULL; best_coverage = 0; + + if (!xf86_config) + return NULL; + for (c = 0; c < xf86_config->num_crtc; c++) { crtc = xf86_config->crtc[c]; @@ -135,7 +194,7 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) ScreenPtr slave; if (dixPrivateKeyRegistered(rrPrivKey)) - primary_output = RRFirstOutput(scrn->pScreen); + primary_output = ms_first_output(scrn->pScreen); if (!primary_output || !primary_output->crtc) return NULL; @@ -147,7 +206,79 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) if (!slave->is_output_slave) continue; - if (ms_covering_crtc(slave, box, FALSE)) { + if (ms_covering_xf86_crtc(slave, box, FALSE)) { + /* The drawable is on a slave output, return primary crtc */ + return crtc; + } + } + } + + return best_crtc; +} + +static RRCrtcPtr +ms_covering_randr_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc, best_crtc; + int coverage, best_coverage; + int c; + BoxRec crtc_box, cover_box; + Bool crtc_on; + + best_crtc = NULL; + best_coverage = 0; + + if (!dixPrivateKeyRegistered(rrPrivKey)) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) + return NULL; + + for (c = 0; c < pScrPriv->numCrtcs; c++) { + crtc = pScrPriv->crtcs[c]; + + if (screen_is_ms) { + crtc_on = ms_crtc_on((xf86CrtcPtr) crtc->devPrivate); + } else { + crtc_on = !!crtc->mode; + } + + /* If the CRTC is off, treat it as not covering */ + if (!crtc_on) + continue; + + ms_randr_crtc_box(crtc, &crtc_box); + ms_box_intersect(&cover_box, &crtc_box, box); + coverage = ms_box_area(&cover_box); + if (coverage > best_coverage) { + best_crtc = crtc; + best_coverage = coverage; + } + } + + /* Fallback to primary crtc for drawable's on slave outputs */ + if (best_crtc == NULL && !pScreen->isGPU) { + RROutputPtr primary_output = NULL; + ScreenPtr slave; + + if (dixPrivateKeyRegistered(rrPrivKey)) + primary_output = ms_first_output(scrn->pScreen); + if (!primary_output || !primary_output->crtc) + return NULL; + + crtc = primary_output->crtc; + if (!ms_crtc_on((xf86CrtcPtr) crtc->devPrivate)) + return NULL; + + xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) { + if (!slave->is_output_slave) + continue; + + if (ms_covering_randr_crtc(slave, box, FALSE)) { /* The drawable is on a slave output, return primary crtc */ return crtc; } @@ -168,7 +299,21 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw) box.x2 = box.x1 + pDraw->width; box.y2 = box.y1 + pDraw->height; - return ms_covering_crtc(pScreen, &box, TRUE); + return ms_covering_xf86_crtc(pScreen, &box, TRUE); +} + +RRCrtcPtr +ms_randr_crtc_covering_drawable(DrawablePtr pDraw) +{ + ScreenPtr pScreen = pDraw->pScreen; + BoxRec box; + + box.x1 = pDraw->x; + box.y1 = pDraw->y; + box.x2 = box.x1 + pDraw->width; + box.y2 = box.y1 + pDraw->height; + + return ms_covering_randr_crtc(pScreen, &box, TRUE); } static Bool diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man index 13a9dc3b3..888e87b53 100644 --- a/hw/xfree86/man/Xorg.man +++ b/hw/xfree86/man/Xorg.man @@ -557,7 +557,7 @@ vesa(@drivermansuffix@), vmware(@drivermansuffix@), .br Web site -.IR <http://www.x.org> . +.IR <https://www.x.org> . .SH AUTHORS Xorg has many contributors world wide. The names of most of them @@ -610,9 +610,9 @@ Orest Zborowski \fIorestz@eskimo.com\fP .PP Xorg source is available from the FTP server \fI<ftp://ftp.x.org/>\fP, and from the X.Org -server \fI<http://gitweb.freedesktop.org/>\fP. Documentation and other +server \fI<https://gitlab.freedesktop.org/xorg/>\fP. Documentation and other information can be found from the X.Org web site -\fI<http://www.x.org/>\fP. +\fI<https://www.x.org/>\fP. .SH LEGAL .PP @@ -622,7 +622,7 @@ and redistribution in source and binary form without fee. .B Xorg is copyright by numerous authors and contributors from around the world. Licensing information can be found at -.IR <http://www.x.org> . +.IR <https://www.x.org> . Refer to the source code for specific copyright notices. .PP .B XFree86(TM) diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man index 958926243..80215ead6 100644 --- a/hw/xfree86/man/xorg.conf.man +++ b/hw/xfree86/man/xorg.conf.man @@ -2500,7 +2500,7 @@ section for a dual headed configuration with two mice: This optional section is used to provide some information for the Direct Rendering Infrastructure. Details about the format of this section can be found on-line at -.IR <http://dri.freedesktop.org/> . +.IR <https://dri.freedesktop.org/> . .SH "VENDOR SECTION" The optional .B Vendor diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 37a45bb3a..17d4ef103 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1719,11 +1719,10 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY) if (edid_monitor) { struct det_monrec_parameter p; - struct disp_features *features = &edid_monitor->features; struct cea_data_block *hdmi_db; /* if display is not continuous-frequency, don't add default modes */ - if (!GTF_SUPPORTED(features->msc)) + if (!gtf_supported(edid_monitor)) add_default_modes = FALSE; p.mon_rec = &mon_rec; diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 34f2652bf..f220ef192 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -2226,6 +2226,7 @@ xf86CrtcLeaseTerminated(RRLeasePtr lease) { int c; int o; + ScrnInfoPtr scrn = xf86ScreenToScrn(lease->screen); RRLeaseTerminated(lease); /* @@ -2256,6 +2257,10 @@ xf86CrtcLeaseTerminated(RRLeasePtr lease) xf86CrtcCheckReset(crtc); } } + + /* Power off if necessary */ + xf86DisableUnusedFunctions(scrn); + RRLeaseFree(lease); } diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index 85ab9b8c7..5415ed97c 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -28,7 +28,7 @@ #include <stddef.h> #include <string.h> #include <stdio.h> - +#include "mi.h" #include "xf86.h" #include "xf86DDC.h" #include "windowstr.h" @@ -176,7 +176,7 @@ xf86RotateRedisplay(ScreenPtr pScreen) DamagePtr damage = xf86_config->rotation_damage; RegionPtr region; - if (!damage) + if (!damage || !pScreen->root) return FALSE; xf86RotatePrepare(pScreen); region = DamageRegion(damage); @@ -191,7 +191,7 @@ xf86RotateRedisplay(ScreenPtr pScreen) * leaves the software cursor in place */ SourceValidate = pScreen->SourceValidate; - pScreen->SourceValidate = NULL; + pScreen->SourceValidate = miSourceValidate; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; @@ -485,6 +485,9 @@ xf86CrtcRotate(xf86CrtcPtr crtc) if (damage) xf86CrtcDamageShadow(crtc); + else if (crtc->rotatedData && !crtc->rotatedPixmap) + /* Make sure the new rotate buffer has valid transformed contents */ + xf86RotateRedisplay(pScreen); /* All done */ return TRUE; diff --git a/hw/xfree86/os-support/bsd/bsd_init.c b/hw/xfree86/os-support/bsd/bsd_init.c index 75a719fc2..6fdf6d4e6 100644 --- a/hw/xfree86/os-support/bsd/bsd_init.c +++ b/hw/xfree86/os-support/bsd/bsd_init.c @@ -661,3 +661,9 @@ xf86UseMsg() ErrorF("don't detach controlling tty (for debugging only)\n"); return; } + +void +xf86OSInputThreadInit(void) +{ + return; +} diff --git a/hw/xfree86/os-support/hurd/hurd_init.c b/hw/xfree86/os-support/hurd/hurd_init.c index fe1a76413..c1b632f19 100644 --- a/hw/xfree86/os-support/hurd/hurd_init.c +++ b/hw/xfree86/os-support/hurd/hurd_init.c @@ -87,3 +87,9 @@ xf86CloseConsole() close(xf86Info.consoleFd); return; } + +void +xf86OSInputThreadInit(void) +{ + return; +} diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index 039dc4a4d..011d8da4f 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -397,3 +397,9 @@ xf86UseMsg(void) 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"); } + +void +xf86OSInputThreadInit(void) +{ + return; +} diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 70374ace8..e62306219 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -23,13 +23,13 @@ static Bool get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) { - drmSetVersion sv; drmVersionPtr v; - char *buf; int fd; int err = 0; Bool paused, server_fd = FALSE; + LogMessage(X_INFO, "Platform probe for %s\n", attribs->syspath); + fd = systemd_logind_take_fd(attribs->major, attribs->minor, path, &paused); if (fd != -1) { if (paused) { @@ -48,18 +48,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) if (fd == -1) return FALSE; - sv.drm_di_major = 1; - sv.drm_di_minor = 4; - sv.drm_dd_major = -1; /* Don't care */ - sv.drm_dd_minor = -1; /* Don't care */ - - err = drmSetInterfaceVersion(fd, &sv); - if (err) { - xf86Msg(X_ERROR, "%s: failed to set DRM interface version 1.4: %s\n", - path, strerror(-err)); - goto out; - } - /* for a delayed probe we've already added the device */ if (delayed_index == -1) { xf86_add_platform_device(attribs, FALSE); @@ -69,10 +57,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) if (server_fd) xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD; - buf = drmGetBusid(fd); - xf86_platform_odev_attributes(delayed_index)->busid = XNFstrdup(buf); - drmFreeBusid(buf); - v = drmGetVersion(fd); if (!v) { xf86Msg(X_ERROR, "%s: failed to query DRM version\n", path); diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index 884a71c61..247bec708 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -208,7 +208,8 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure) } } #endif -#ifdef I_SETSIG /* System V Streams - used on Solaris for input devices */ +#if defined(I_SETSIG) && defined(HAVE_ISASTREAM) + /* System V Streams - used on Solaris for input devices */ if (!installed && isastream(fd)) { if (ioctl(fd, I_SETSIG, S_INPUT | S_ERROR | S_HANGUP) == -1) { xf86Msg(X_WARNING, "fcntl(%d, I_SETSIG): %s\n", @@ -279,7 +280,7 @@ xf86RemoveSIGIOHandler(int fd) #ifdef O_ASYNC fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_ASYNC); #endif -#ifdef I_SETSIG +#if defined(I_SETSIG) && defined(HAVE_ISASTREAM) if (isastream(fd)) { if (ioctl(fd, I_SETSIG, 0) == -1) { xf86Msg(X_WARNING, "fcntl(%d, I_SETSIG, 0): %s\n", diff --git a/hw/xfree86/os-support/solaris/sun_vid.c b/hw/xfree86/os-support/solaris/sun_vid.c index 25f76181c..2b48e66b0 100644 --- a/hw/xfree86/os-support/solaris/sun_vid.c +++ b/hw/xfree86/os-support/solaris/sun_vid.c @@ -73,22 +73,24 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem) /* I/O Permissions section */ /***************************************************************************/ -#if defined(__i386__) || defined(__i386) || defined(__x86) -static Bool ExtendedEnabled = FALSE; -#endif +void +xf86OSInputThreadInit(void) +{ + /* + * Need to enable in input thread as well, as Solaris kernel tracks + * IOPL per-thread and doesn't inherit when creating a new thread. + */ + xf86EnableIO(); +} Bool xf86EnableIO(void) { #if defined(__i386__) || defined(__i386) || defined(__x86) - if (ExtendedEnabled) - return TRUE; - if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) { xf86Msg(X_WARNING, "xf86EnableIOPorts: Failed to set IOPL for I/O\n"); return FALSE; } - ExtendedEnabled = TRUE; #endif /* i386 */ return TRUE; } @@ -97,11 +99,6 @@ void xf86DisableIO(void) { #if defined(__i386__) || defined(__i386) || defined(__x86) - if (!ExtendedEnabled) - return; - sysi86(SI86V86, V86SC_IOPL, 0); - - ExtendedEnabled = FALSE; #endif /* i386 */ } diff --git a/hw/xfree86/os-support/stub/stub_init.c b/hw/xfree86/os-support/stub/stub_init.c index d3e0c3f29..f0d9039b9 100644 --- a/hw/xfree86/os-support/stub/stub_init.c +++ b/hw/xfree86/os-support/stub/stub_init.c @@ -24,3 +24,9 @@ void xf86UseMsg(void) { } + +void +xf86OSInputThreadInit(void) +{ + return; +} diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h index 99ca90249..17607b04b 100644 --- a/hw/xfree86/os-support/xf86_OSproc.h +++ b/hw/xfree86/os-support/xf86_OSproc.h @@ -136,6 +136,7 @@ extern _X_EXPORT int xf86GetSerialModemState(int fd); extern _X_EXPORT int xf86SerialModemSetBits(int fd, int bits); extern _X_EXPORT int xf86SerialModemClearBits(int fd, int bits); extern _X_EXPORT int xf86LoadKernelModule(const char *pathname); +extern _X_EXPORT void xf86OSInputThreadInit(void); /* AGP GART interface */ diff --git a/hw/xfree86/ramdac/xf86CursorRD.c b/hw/xfree86/ramdac/xf86CursorRD.c index afcce5353..ee1d98916 100644 --- a/hw/xfree86/ramdac/xf86CursorRD.c +++ b/hw/xfree86/ramdac/xf86CursorRD.c @@ -212,7 +212,7 @@ xf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable) xf86CursorScreenKey); if (!enable && ScreenPriv->CurrentCursor != NullCursor) { - CursorPtr currentCursor = ScreenPriv->CurrentCursor; + CursorPtr currentCursor = RefCursor(ScreenPriv->CurrentCursor); xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y); @@ -231,6 +231,7 @@ xf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable) */ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor, ScreenPriv->x, ScreenPriv->y); + UnrefCursor(ScreenPriv->SavedCursor); ScreenPriv->SavedCursor = NULL; } } diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index b45685216..c3afadf8c 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -169,3 +169,12 @@ ddxBeforeReset(void) return; } #endif + +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c index 30c6a4623..ac01c248c 100644 --- a/hw/xnest/Screen.c +++ b/hw/xnest/Screen.c @@ -263,7 +263,6 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) pScreen->SaveScreen = xnestSaveScreen; pScreen->GetImage = xnestGetImage; pScreen->GetSpans = xnestGetSpans; - pScreen->SourceValidate = NULL; /* Window Procedures */ diff --git a/hw/xquartz/man/Xquartz.man b/hw/xquartz/man/Xquartz.man index df7ab25aa..65a75d584 100644 --- a/hw/xquartz/man/Xquartz.man +++ b/hw/xquartz/man/Xquartz.man @@ -136,7 +136,7 @@ instead of -d. .PP X(@miscmansuffix@), Xserver(1), xdm(1), xinit(1), syslog(1), syslogd(8) .PP -http://xquartz.macosforge.org +https://www.xquartz.org/ .PP .SH AUTHORS / HISTORY X11 was originally ported to Mac OS X Server by John Carmack. Dave diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c index cf8395f1d..66720bcc0 100644 --- a/hw/xwayland/xwayland-cursor.c +++ b/hw/xwayland/xwayland-cursor.c @@ -188,6 +188,8 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, xwl_tablet_tool->proximity_in_serial, NULL, 0, 0); + clear_cursor_frame_callback(xwl_cursor); + xwl_cursor->needs_update = FALSE; return; } diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c index c62c0d2ac..36b749aaf 100644 --- a/hw/xwayland/xwayland-glamor-eglstream.c +++ b/hw/xwayland/xwayland-glamor-eglstream.c @@ -33,6 +33,7 @@ #include "wayland-eglstream-controller-client-protocol.h" #define MESA_EGL_NO_X11_HEADERS +#define EGL_NO_X11 #include <glamor_egl.h> #include <glamor.h> #include <glamor_transform.h> diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index a211e0915..ebff70a00 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -36,6 +36,7 @@ #include <drm_fourcc.h> #define MESA_EGL_NO_X11_HEADERS +#define EGL_NO_X11 #include <gbm.h> #include <glamor_egl.h> @@ -169,6 +170,8 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, xwl_screen->egl_context, EGL_NATIVE_PIXMAP_KHR, xwl_pixmap->bo, NULL); + if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) + goto error; glGenTextures(1, &xwl_pixmap->texture); glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture); @@ -176,14 +179,31 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image); - glBindTexture(GL_TEXTURE_2D, 0); + if (eglGetError() != EGL_SUCCESS) + goto error; - xwl_pixmap_set_private(pixmap, xwl_pixmap); + glBindTexture(GL_TEXTURE_2D, 0); glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture); + /* `set_pixmap_texture()` may fail silently if the FBO creation failed, + * so we check again the texture to be sure it worked. + */ + if (!glamor_get_pixmap_texture(pixmap)) + goto error; + glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); + xwl_pixmap_set_private(pixmap, xwl_pixmap); return pixmap; + +error: + if (xwl_pixmap->image != EGL_NO_IMAGE_KHR) + eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image); + if (pixmap) + glamor_destroy_pixmap(pixmap); + free(xwl_pixmap); + + return NULL; } static PixmapPtr @@ -194,6 +214,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen, struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); struct gbm_bo *bo; + PixmapPtr pixmap = NULL; if (width > 0 && height > 0 && depth >= 15 && (hint == 0 || @@ -218,11 +239,22 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); } - if (bo) - return xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); + if (bo) { + pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth); + + if (!pixmap) { + gbm_bo_destroy(bo); + } + else if (xwl_screen->rootless && hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) { + glamor_clear_pixmap(pixmap); + } + } } - return glamor_create_pixmap(screen, width, height, depth, hint); + if (!pixmap) + pixmap = glamor_create_pixmap(screen, width, height, depth, hint); + + return pixmap; } static Bool @@ -253,6 +285,9 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); unsigned short width = pixmap->drawable.width; unsigned short height = pixmap->drawable.height; + uint32_t format; + struct xwl_format *xwl_format = NULL; + Bool modifier_supported = FALSE; int prime_fd; int num_planes; uint32_t strides[4]; @@ -277,6 +312,8 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, if (!xwl_pixmap->bo) return NULL; + format = wl_drm_format_for_depth(pixmap->drawable.depth); + prime_fd = gbm_bo_get_fd(xwl_pixmap->bo); if (prime_fd == -1) return NULL; @@ -295,7 +332,23 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, offsets[0] = 0; #endif - if (xwl_gbm->dmabuf && modifier != DRM_FORMAT_MOD_INVALID) { + for (i = 0; i < xwl_screen->num_formats; i++) { + if (xwl_screen->formats[i].format == format) { + xwl_format = &xwl_screen->formats[i]; + break; + } + } + + if (xwl_format) { + for (i = 0; i < xwl_format->num_modifiers; i++) { + if (xwl_format->modifiers[i] == modifier) { + modifier_supported = TRUE; + break; + } + } + } + + if (xwl_gbm->dmabuf && modifier_supported) { struct zwp_linux_buffer_params_v1 *params; params = zwp_linux_dmabuf_v1_create_params(xwl_gbm->dmabuf); @@ -307,13 +360,12 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, xwl_pixmap->buffer = zwp_linux_buffer_params_v1_create_immed(params, width, height, - wl_drm_format_for_depth(pixmap->drawable.depth), - 0); + format, 0); zwp_linux_buffer_params_v1_destroy(params); } else if (num_planes == 1) { xwl_pixmap->buffer = wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fd, width, height, - wl_drm_format_for_depth(pixmap->drawable.depth), + format, 0, gbm_bo_get_stride(xwl_pixmap->bo), 0, 0, 0, 0); @@ -469,7 +521,8 @@ glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds, data.strides[i] = strides[i]; data.offsets[i] = offsets[i]; } - bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD_MODIFIER, &data, 0); + bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD_MODIFIER, &data, + GBM_BO_USE_RENDERING); #endif } else if (num_fds == 1) { struct gbm_import_fd_data data; @@ -480,7 +533,7 @@ glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds, data.stride = strides[0]; data.format = gbm_format_for_depth(depth); bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD, &data, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + GBM_BO_USE_RENDERING); } else { goto error; } @@ -766,6 +819,10 @@ xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, struct xwl_format *xwl_format = NULL; int i; + if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) && + modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff)) + return; + for (i = 0; i < xwl_screen->num_formats; i++) { if (xwl_screen->formats[i].format == format) { xwl_format = &xwl_screen->formats[i]; diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index 7ea6def61..48e330a0f 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -26,6 +26,7 @@ #include "xwayland.h" #define MESA_EGL_NO_X11_HEADERS +#define EGL_NO_X11 #include <glamor_egl.h> #include <glamor.h> diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index fbbcb39cc..a05d178ff 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -48,6 +48,8 @@ struct sync_pending { DeviceIntPtr pending_dev; }; +static DevPrivateKeyRec xwl_tablet_private_key; + static void xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator, double dx, @@ -831,6 +833,9 @@ remove_sync_pending(DeviceIntPtr dev) struct xwl_seat *xwl_seat = dev->public.devicePrivate; struct sync_pending *p, *npd; + if (!xwl_seat) + return; + xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) { if (p->pending_dev == dev) { xorg_list_del(&xwl_seat->sync_pending); @@ -857,11 +862,15 @@ static Bool keyboard_check_repeat (DeviceIntPtr dev, XkbSrvInfoPtr xkbi, unsigned key) { struct xwl_seat *xwl_seat = dev->public.devicePrivate; - struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; + struct xwl_screen *xwl_screen; struct wl_callback *callback; struct sync_pending *p; + if (!xwl_seat) + return FALSE; + /* Make sure we didn't miss a possible reply from the compositor */ + xwl_screen = xwl_seat->xwl_screen; xwl_sync_events (xwl_screen); xorg_list_for_each_entry(p, &xwl_seat->sync_pending, l) { @@ -1150,6 +1159,21 @@ add_device(struct xwl_seat *xwl_seat, } static void +disable_device(DeviceIntPtr dev) +{ + DisableDevice(dev, TRUE); + dev->public.devicePrivate = NULL; +} + +static void +enable_device(struct xwl_seat *xwl_seat, DeviceIntPtr dev) +{ + dev->public.devicePrivate = xwl_seat; + EnableDevice(dev, TRUE); +} + + +static void init_pointer(struct xwl_seat *xwl_seat) { xwl_seat->wl_pointer = wl_seat_get_pointer(xwl_seat->seat); @@ -1162,7 +1186,7 @@ init_pointer(struct xwl_seat *xwl_seat) add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc); ActivateDevice(xwl_seat->pointer, TRUE); } - EnableDevice(xwl_seat->pointer, TRUE); + enable_device(xwl_seat, xwl_seat->pointer); } static void @@ -1172,7 +1196,7 @@ release_pointer(struct xwl_seat *xwl_seat) xwl_seat->wl_pointer = NULL; if (xwl_seat->pointer) - DisableDevice(xwl_seat->pointer, TRUE); + disable_device(xwl_seat->pointer); } static void @@ -1196,7 +1220,7 @@ init_relative_pointer(struct xwl_seat *xwl_seat) xwl_pointer_proc_relative); ActivateDevice(xwl_seat->relative_pointer, TRUE); } - EnableDevice(xwl_seat->relative_pointer, TRUE); + enable_device(xwl_seat, xwl_seat->relative_pointer); } static void @@ -1208,7 +1232,7 @@ release_relative_pointer(struct xwl_seat *xwl_seat) } if (xwl_seat->relative_pointer) - DisableDevice(xwl_seat->relative_pointer, TRUE); + disable_device(xwl_seat->relative_pointer); } static void @@ -1225,7 +1249,7 @@ init_keyboard(struct xwl_seat *xwl_seat) add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc); ActivateDevice(xwl_seat->keyboard, TRUE); } - EnableDevice(xwl_seat->keyboard, TRUE); + enable_device(xwl_seat, xwl_seat->keyboard); xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat; if (xwl_seat->xwl_screen->wp_grab) { @@ -1245,7 +1269,7 @@ release_keyboard(struct xwl_seat *xwl_seat) if (xwl_seat->keyboard) { remove_sync_pending(xwl_seat->keyboard); - DisableDevice(xwl_seat->keyboard, TRUE); + disable_device(xwl_seat->keyboard); } } @@ -1261,8 +1285,7 @@ init_touch(struct xwl_seat *xwl_seat) add_device(xwl_seat, "xwayland-touch", xwl_touch_proc); ActivateDevice(xwl_seat->touch, TRUE); } - EnableDevice(xwl_seat->touch, TRUE); - + enable_device(xwl_seat, xwl_seat->touch); } static void @@ -1272,7 +1295,7 @@ release_touch(struct xwl_seat *xwl_seat) xwl_seat->wl_touch = NULL; if (xwl_seat->touch) - DisableDevice(xwl_seat->touch, TRUE); + disable_device(xwl_seat->touch); } static void @@ -1431,19 +1454,19 @@ tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet) xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc); ActivateDevice(xwl_seat->stylus, TRUE); } - EnableDevice(xwl_seat->stylus, TRUE); + enable_device(xwl_seat, xwl_seat->stylus); if (xwl_seat->eraser == NULL) { xwl_seat->eraser = add_device(xwl_seat, "xwayland-eraser", xwl_tablet_proc); ActivateDevice(xwl_seat->eraser, TRUE); } - EnableDevice(xwl_seat->eraser, TRUE); + enable_device(xwl_seat, xwl_seat->eraser); if (xwl_seat->puck == NULL) { xwl_seat->puck = add_device(xwl_seat, "xwayland-cursor", xwl_tablet_proc); ActivateDevice(xwl_seat->puck, TRUE); } - EnableDevice(xwl_seat->puck, TRUE); + enable_device(xwl_seat, xwl_seat->puck); } static void @@ -1458,11 +1481,11 @@ tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet) will re-use the same X devices */ if (xorg_list_is_empty(&xwl_seat->tablets)) { if (xwl_seat->stylus) - DisableDevice(xwl_seat->stylus, TRUE); + disable_device(xwl_seat->stylus); if (xwl_seat->eraser) - DisableDevice(xwl_seat->eraser, TRUE); + disable_device(xwl_seat->eraser); if (xwl_seat->puck) - DisableDevice(xwl_seat->puck, TRUE); + disable_device(xwl_seat->puck); /* pads are removed separately */ } @@ -2064,7 +2087,8 @@ static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = { static int xwl_tablet_pad_proc(DeviceIntPtr device, int what) { - struct xwl_tablet_pad *pad = device->public.devicePrivate; + struct xwl_tablet_pad *pad = dixGetPrivate(&device->devPrivates, + &xwl_tablet_private_key); /* Axis layout mirrors that of xf86-input-wacom to have better compatibility with existing clients */ #define NAXES 7 @@ -2188,7 +2212,7 @@ tablet_pad_done(void *data, pad->xdevice = add_device(pad->seat, "xwayland-pad", xwl_tablet_pad_proc); - pad->xdevice->public.devicePrivate = pad; + dixSetPrivate(&pad->xdevice->devPrivates, &xwl_tablet_private_key, pad); ActivateDevice(pad->xdevice, TRUE); EnableDevice(pad->xdevice, TRUE); } @@ -2524,6 +2548,8 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window) return FALSE; xwl_seat = device->public.devicePrivate; + if (!xwl_seat) + return FALSE; master = GetMaster(device, POINTER_OR_FLOAT); if (!master || !master->lastSlave) @@ -2667,6 +2693,7 @@ xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emul */ if (pointer_grab && !pointer_grab->ownerEvents && + sprite && XYToWindow(sprite, x, y) != xwl_seat->focus_window->window) return; @@ -2756,7 +2783,15 @@ xwl_seat_create_pointer_warp_emulator(struct xwl_seat *xwl_seat) static Bool xwl_seat_can_emulate_pointer_warp(struct xwl_seat *xwl_seat) { - struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; + struct xwl_screen *xwl_screen; + + if (!xwl_seat) + return FALSE; + + if (!xwl_seat->pointer) + return FALSE; + + xwl_screen = xwl_seat->xwl_screen; if (!xwl_screen->relative_pointer_manager) return FALSE; @@ -2850,6 +2885,9 @@ xwl_seat_confine_pointer(struct xwl_seat *xwl_seat, if (!pointer_constraints) return; + if (!xwl_seat->wl_pointer) + return; + if (xwl_seat->cursor_confinement_window == xwl_window && xwl_seat->confined_pointer) return; @@ -2894,6 +2932,11 @@ InitInput(int argc, char *argv[]) ScreenPtr pScreen = screenInfo.screens[0]; struct xwl_screen *xwl_screen = xwl_screen_get(pScreen); + if (!dixRegisterPrivateKey(&xwl_tablet_private_key, PRIVATE_DEVICE, 0)) { + ErrorF("Failed to register private key\n"); + return; + } + mieqInit(); xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display); @@ -2903,9 +2946,7 @@ InitInput(int argc, char *argv[]) xwl_screen->XYToWindow = pScreen->XYToWindow; pScreen->XYToWindow = xwl_xy_to_window; - wl_display_roundtrip(xwl_screen->display); - while (xwl_screen->expecting_event) - wl_display_roundtrip(xwl_screen->display); + xwl_screen_roundtrip(xwl_screen); } void diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index cc68f0340..ae646c663 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -30,7 +30,6 @@ #include "xwayland.h" #include <randrstr.h> -#define DEFAULT_DPI 96 #define ALL_ROTATIONS (RR_Rotate_0 | \ RR_Rotate_90 | \ RR_Rotate_180 | \ @@ -143,56 +142,57 @@ output_get_new_size(struct xwl_output *xwl_output, *height = xwl_output->y + output_height; } -/* Approximate some kind of mmpd (m.m. per dot) of the screen given the outputs - * associated with it. - * - * It either calculates the mean mmpd of all the outputs or, if no reasonable - * value could be calculated, defaults to the mmpd of a screen with a DPI value - * of DEFAULT_DPI. - */ -static double -approximate_mmpd(struct xwl_screen *xwl_screen) +static int +xwl_set_pixmap_visit_window(WindowPtr window, void *data) { - struct xwl_output *it; - int total_width_mm = 0; - int total_width = 0; + ScreenPtr screen = window->drawable.pScreen; - xorg_list_for_each_entry(it, &xwl_screen->output_list, link) { - if (it->randr_output->mmWidth == 0) - continue; + if (screen->GetWindowPixmap(window) == data) { + screen->SetWindowPixmap(window, screen->GetScreenPixmap(screen)); + return WT_WALKCHILDREN; + } + + return WT_DONTWALKCHILDREN; +} - total_width_mm += it->randr_output->mmWidth; - total_width += it->width; +static void +update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height) +{ + ScreenPtr pScreen = xwl_screen->screen; + WindowPtr pRoot = pScreen->root; + PixmapPtr old_pixmap, new_pixmap; + + old_pixmap = pScreen->GetScreenPixmap(pScreen); + new_pixmap = pScreen->CreatePixmap(pScreen, width, height, + pScreen->rootDepth, + CREATE_PIXMAP_USAGE_BACKING_PIXMAP); + pScreen->SetScreenPixmap(new_pixmap); + + if (old_pixmap) { + TraverseTree(pRoot, xwl_set_pixmap_visit_window, old_pixmap); + pScreen->DestroyPixmap(old_pixmap); } - if (total_width_mm != 0) - return (double)total_width_mm / total_width; - else - return 25.4 / DEFAULT_DPI; + pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL); } static void update_screen_size(struct xwl_output *xwl_output, int width, int height) { struct xwl_screen *xwl_screen = xwl_output->xwl_screen; - double mmpd; if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL) SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE); + if (!xwl_screen->rootless && xwl_screen->screen->root) + update_backing_pixmaps (xwl_screen, width, height); + xwl_screen->width = width; xwl_screen->height = height; xwl_screen->screen->width = width; xwl_screen->screen->height = height; - - if (xwl_output->width == width && xwl_output->height == height) { - xwl_screen->screen->mmWidth = xwl_output->randr_output->mmWidth; - xwl_screen->screen->mmHeight = xwl_output->randr_output->mmHeight; - } else { - mmpd = approximate_mmpd(xwl_screen); - xwl_screen->screen->mmWidth = width * mmpd; - xwl_screen->screen->mmHeight = height * mmpd; - } + xwl_screen->screen->mmWidth = (width * 25.4) / monitorResolution; + xwl_screen->screen->mmHeight = (height * 25.4) / monitorResolution; SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode); @@ -439,7 +439,7 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen) if (!RRScreenInit(xwl_screen->screen)) return FALSE; - RRScreenSetSizeRange(xwl_screen->screen, 320, 200, 8192, 8192); + RRScreenSetSizeRange(xwl_screen->screen, 16, 16, 32767, 32767); rp = rrGetScrPriv(xwl_screen->screen); rp->rrGetInfo = xwl_randr_get_info; diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index 2937d9c97..6076f6498 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -24,6 +24,7 @@ */ #include "xwayland.h" +#include "glamor.h" #include <present.h> @@ -59,6 +60,7 @@ xwl_present_window_get_priv(WindowPtr window) xwl_present_window->msc = 1; xwl_present_window->ust = GetTimeInMicros(); + xorg_list_init(&xwl_present_window->frame_callback_list); xorg_list_init(&xwl_present_window->event_list); xorg_list_init(&xwl_present_window->release_queue); @@ -95,7 +97,7 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window) if (xwl_present_has_events(xwl_present_window)) { CARD32 timeout; - if (xwl_present_window->frame_callback) + if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list)) timeout = TIMER_LEN_FLIP; else timeout = TIMER_LEN_COPY; @@ -109,6 +111,27 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window) } } +static void +xwl_present_free_event(struct xwl_present_event *event) +{ + if (!event) + return; + + if (event->pixmap) { + if (!event->buffer_released) { + struct wl_buffer *buffer = + xwl_glamor_pixmap_get_wl_buffer(event->pixmap, NULL); + + wl_buffer_set_user_data(buffer, NULL); + } + + dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id); + } + + xorg_list_del(&event->list); + free(event); +} + void xwl_present_cleanup(WindowPtr window) { @@ -118,10 +141,7 @@ xwl_present_cleanup(WindowPtr window) if (!xwl_present_window) return; - if (xwl_present_window->frame_callback) { - wl_callback_destroy(xwl_present_window->frame_callback); - xwl_present_window->frame_callback = NULL; - } + xorg_list_del(&xwl_present_window->frame_callback_list); if (xwl_present_window->sync_callback) { wl_callback_destroy(xwl_present_window->sync_callback); @@ -129,26 +149,13 @@ xwl_present_cleanup(WindowPtr window) } /* Clear remaining events */ - xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) { - xorg_list_del(&event->list); - free(event); - } + xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) + xwl_present_free_event(event); - /* 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; - } + xwl_present_free_event(xwl_present_window->sync_flip); + + xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) + xwl_present_free_event(event); /* Clear timer */ xwl_present_free_timer(xwl_present_window); @@ -162,13 +169,6 @@ xwl_present_cleanup(WindowPtr window) } static void -xwl_present_free_event(struct xwl_present_event *event) -{ - xorg_list_del(&event->list); - free(event); -} - -static void xwl_present_buffer_release(void *data, struct wl_buffer *buffer) { struct xwl_present_event *event = data; @@ -217,7 +217,7 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window) /* 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); + xwl_present_free_event(event); } else { xorg_list_add(&event->list, &xwl_present_window->release_queue); } @@ -243,7 +243,10 @@ xwl_present_timer_callback(OsTimerPtr timer, { struct xwl_present_window *xwl_present_window = arg; - xwl_present_window->frame_timer_firing = TRUE; + /* If we were expecting a frame callback for this window, it didn't arrive + * in a second. Stop listening to it to avoid double-bumping the MSC + */ + xorg_list_del(&xwl_present_window->frame_callback_list); xwl_present_msc_bump(xwl_present_window); xwl_present_reset_timer(xwl_present_window); @@ -251,20 +254,10 @@ xwl_present_timer_callback(OsTimerPtr timer, return 0; } -static void -xwl_present_frame_callback(void *data, - struct wl_callback *callback, - uint32_t time) +void +xwl_present_frame_callback(struct xwl_present_window *xwl_present_window) { - struct xwl_present_window *xwl_present_window = data; - - wl_callback_destroy(xwl_present_window->frame_callback); - xwl_present_window->frame_callback = NULL; - - if (xwl_present_window->frame_timer_firing) { - /* If the timer is firing, this frame callback is too late */ - return; - } + xorg_list_del(&xwl_present_window->frame_callback_list); xwl_present_msc_bump(xwl_present_window); @@ -274,10 +267,6 @@ xwl_present_frame_callback(void *data, xwl_present_reset_timer(xwl_present_window); } -static const struct wl_callback_listener xwl_present_frame_listener = { - xwl_present_frame_callback -}; - static void xwl_present_sync_callback(void *data, struct wl_callback *callback, @@ -359,6 +348,7 @@ xwl_present_queue_vblank(WindowPtr present_window, uint64_t msc) { struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window); + struct xwl_window *xwl_window = xwl_window_from_window(present_window); struct xwl_present_event *event; event = malloc(sizeof *event); @@ -366,12 +356,21 @@ xwl_present_queue_vblank(WindowPtr present_window, return BadAlloc; event->event_id = event_id; + event->pixmap = NULL; event->xwl_present_window = xwl_present_window; event->target_msc = msc; xorg_list_append(&event->list, &xwl_present_window->event_list); - if (!xwl_present_window->frame_timer) + /* If there's a pending frame callback, use that */ + if (xwl_window && xwl_window->frame_callback && + xorg_list_is_empty(&xwl_present_window->frame_callback_list)) { + xorg_list_add(&xwl_present_window->frame_callback_list, + &xwl_window->frame_callback_list); + } + + if ((xwl_window && xwl_window->frame_callback) || + !xwl_present_window->frame_timer) xwl_present_reset_timer(xwl_present_window); return Success; @@ -395,8 +394,7 @@ xwl_present_abort_vblank(WindowPtr present_window, xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) { if (event->event_id == event_id) { - xorg_list_del(&event->list); - free(event); + xwl_present_free_event(event); return; } } @@ -412,9 +410,7 @@ xwl_present_abort_vblank(WindowPtr present_window, static void xwl_present_flush(WindowPtr window) { - /* Only called when a Pixmap is copied instead of flipped, - * but in this case we wait on the next block_handler. - */ + glamor_block_handler(window->drawable.pScreen); } static Bool @@ -465,11 +461,12 @@ xwl_present_flip(WindowPtr present_window, if (!event) return FALSE; + pixmap->refcnt++; 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->pixmap = pixmap; event->target_msc = target_msc; event->pending = TRUE; event->abort = FALSE; @@ -489,18 +486,20 @@ 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_callback) { - xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface); - wl_callback_add_listener(xwl_present_window->frame_callback, - &xwl_present_frame_listener, - xwl_present_window); + if (!xwl_window->frame_callback) + xwl_window_create_frame_callback(xwl_window); + + if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) { + xorg_list_add(&xwl_present_window->frame_callback_list, + &xwl_window->frame_callback_list); } /* Realign timer */ - xwl_present_window->frame_timer_firing = FALSE; xwl_present_reset_timer(xwl_present_window); - wl_surface_damage(xwl_window->surface, 0, 0, + wl_surface_damage(xwl_window->surface, + damage_box->x1 - present_window->drawable.x, + damage_box->y1 - present_window->drawable.y, damage_box->x2 - damage_box->x1, damage_box->y2 - damage_box->y1); @@ -529,18 +528,12 @@ xwl_present_flips_stop(WindowPtr window) } void -xwl_present_unrealize_window(WindowPtr window) +xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window) { - struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); - - if (!xwl_present_window || !xwl_present_window->frame_callback) - return; - /* 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; + xorg_list_del(&xwl_present_window->frame_callback_list); xwl_present_reset_timer(xwl_present_window); } diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c index 0bcd11401..d25d1aca1 100644 --- a/hw/xwayland/xwayland-vidmode.c +++ b/hw/xwayland/xwayland-vidmode.c @@ -332,6 +332,7 @@ static Bool xwlVidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue) { /* Unsupported for now, but pretend it works */ + *red = *green = *blue = 1.0f; return TRUE; } diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 7e6e0ab25..d02934cd5 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -40,7 +40,11 @@ #ifdef XF86VIDMODE #include <X11/extensions/xf86vmproto.h> -_X_EXPORT Bool noXFree86VidModeExtension; +extern _X_EXPORT Bool noXFree86VidModeExtension; +#endif + +#ifdef XWL_HAS_GLAMOR +#include <glamor.h> #endif void @@ -74,6 +78,17 @@ ddxBeforeReset(void) } #endif +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif + +#define DEFAULT_DPI 96 + _X_NORETURN static void _X_ATTRIBUTE_PRINTF(1, 2) xwl_give_up(const char *f, ...) @@ -125,6 +140,7 @@ ddxProcessArgument(int argc, char *argv[], int i) static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_screen_private_key; static DevPrivateKeyRec xwl_pixmap_private_key; +static DevPrivateKeyRec xwl_damage_private_key; static struct xwl_window * xwl_window_get(WindowPtr window) @@ -367,8 +383,14 @@ xwl_cursor_confined_to(DeviceIntPtr device, static void damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) { - struct xwl_window *xwl_window = data; - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + WindowPtr window = data; + struct xwl_window *xwl_window = xwl_window_get(window); + struct xwl_screen *xwl_screen; + + if (!xwl_window) + return; + + xwl_screen = xwl_window->xwl_screen; #ifdef GLAMOR_HAS_GBM if (xwl_window->present_flipped) { @@ -390,6 +412,47 @@ damage_destroy(DamagePtr pDamage, void *data) { } +static Bool +register_damage(WindowPtr window) +{ + DamagePtr damage; + + damage = DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, + FALSE, window->drawable.pScreen, window); + if (damage == NULL) { + ErrorF("Failed creating damage\n"); + return FALSE; + } + + DamageRegister(&window->drawable, damage); + DamageSetReportAfterOp(damage, TRUE); + + dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, damage); + + return TRUE; +} + +static void +unregister_damage(WindowPtr window) +{ + DamagePtr damage; + + damage = dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key); + if (!damage) + return; + + DamageUnregister(damage); + DamageDestroy(damage); + + dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL); +} + +static DamagePtr +window_get_damage(WindowPtr window) +{ + return dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key); +} + static void shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) @@ -470,36 +533,25 @@ send_surface_id_event(struct xwl_window *xwl_window) } static Bool -xwl_realize_window(WindowPtr window) +ensure_surface_for_window(WindowPtr window) { ScreenPtr screen = window->drawable.pScreen; struct xwl_screen *xwl_screen; struct xwl_window *xwl_window; struct wl_region *region; - Bool ret; - xwl_screen = xwl_screen_get(screen); - - screen->RealizeWindow = xwl_screen->RealizeWindow; - ret = (*screen->RealizeWindow) (window); - xwl_screen->RealizeWindow = screen->RealizeWindow; - screen->RealizeWindow = xwl_realize_window; + if (xwl_window_get(window)) + return TRUE; - if (xwl_screen->rootless && !window->parent) { - BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height }; - - RegionReset(&window->winSize, &box); - RegionNull(&window->clipList); - RegionNull(&window->borderClip); - } + xwl_screen = xwl_screen_get(screen); if (xwl_screen->rootless) { if (window->redirectDraw != RedirectDrawManual) - return ret; + return TRUE; } else { if (window->parent) - return ret; + return TRUE; } xwl_window = calloc(1, sizeof *xwl_window); @@ -545,25 +597,18 @@ xwl_realize_window(WindowPtr window) wl_surface_set_user_data(xwl_window->surface, xwl_window); - xwl_window->damage = - DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, - FALSE, screen, xwl_window); - if (xwl_window->damage == NULL) { - ErrorF("Failed creating damage\n"); - goto err_surf; - } - compRedirectWindow(serverClient, window, CompositeRedirectManual); - DamageRegister(&window->drawable, xwl_window->damage); - DamageSetReportAfterOp(xwl_window->damage, TRUE); - dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window); xorg_list_init(&xwl_window->link_damage); +#ifdef GLAMOR_HAS_GBM + xorg_list_init(&xwl_window->frame_callback_list); +#endif + xwl_window_init_allow_commits(xwl_window); - return ret; + return TRUE; err_surf: if (xwl_window->shell_surface) @@ -575,6 +620,42 @@ err: } static Bool +xwl_realize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + screen->RealizeWindow = xwl_screen->RealizeWindow; + ret = (*screen->RealizeWindow) (window); + xwl_screen->RealizeWindow = screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + if (!ret) + return FALSE; + + if (xwl_screen->rootless && !window->parent) { + BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height }; + + RegionReset(&window->winSize, &box); + RegionNull(&window->clipList); + RegionNull(&window->borderClip); + } + + if (xwl_screen->rootless ? + (window->drawable.class == InputOutput && + window->parent == window->drawable.pScreen->root) : + !window->parent) { + if (!register_damage(window)) + return FALSE; + } + + return ensure_surface_for_window(window); +} + +static Bool xwl_unrealize_window(WindowPtr window) { ScreenPtr screen = window->drawable.pScreen; @@ -609,22 +690,29 @@ 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; wl_surface_destroy(xwl_window->surface); xorg_list_del(&xwl_window->link_damage); - DamageUnregister(xwl_window->damage); - DamageDestroy(xwl_window->damage); + unregister_damage(window); + if (xwl_window->frame_callback) wl_callback_destroy(xwl_window->frame_callback); +#ifdef GLAMOR_HAS_GBM + if (xwl_screen->present) { + struct xwl_present_window *xwl_present_window, *tmp; + + xorg_list_for_each_entry_safe(xwl_present_window, tmp, + &xwl_window->frame_callback_list, + frame_callback_list) { + xwl_present_unrealize_window(xwl_present_window); + } + } +#endif + free(xwl_window); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); @@ -638,6 +726,26 @@ xwl_save_screen(ScreenPtr pScreen, int on) } static void +xwl_set_window_pixmap(WindowPtr window, + PixmapPtr pixmap) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + + screen->SetWindowPixmap = xwl_screen->SetWindowPixmap; + (*screen->SetWindowPixmap) (window, pixmap); + xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = xwl_set_window_pixmap; + + if (!RegionNotEmpty(&window->winSize)) + return; + + ensure_surface_for_window(window); +} + +static void frame_callback(void *data, struct wl_callback *callback, uint32_t time) @@ -646,12 +754,32 @@ frame_callback(void *data, wl_callback_destroy (xwl_window->frame_callback); xwl_window->frame_callback = NULL; + +#ifdef GLAMOR_HAS_GBM + if (xwl_window->xwl_screen->present) { + struct xwl_present_window *xwl_present_window, *tmp; + + xorg_list_for_each_entry_safe(xwl_present_window, tmp, + &xwl_window->frame_callback_list, + frame_callback_list) { + xwl_present_frame_callback(xwl_present_window); + } + } +#endif } static const struct wl_callback_listener frame_listener = { frame_callback }; +void +xwl_window_create_frame_callback(struct xwl_window *xwl_window) +{ + xwl_window->frame_callback = wl_surface_frame(xwl_window->surface); + wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, + xwl_window); +} + static Bool xwl_destroy_window(WindowPtr window) { @@ -689,7 +817,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) assert(!xwl_window->frame_callback); - region = DamageRegion(xwl_window->damage); + region = DamageRegion(window_get_damage(xwl_window->window)); pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); #ifdef XWL_HAS_GLAMOR @@ -722,19 +850,17 @@ xwl_window_post_damage(struct xwl_window *xwl_window) box->x2 - box->x1, box->y2 - box->y1); } - xwl_window->frame_callback = wl_surface_frame(xwl_window->surface); - wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window); - - wl_surface_commit(xwl_window->surface); - DamageEmpty(xwl_window->damage); - - xorg_list_del(&xwl_window->link_damage); + xwl_window_create_frame_callback(xwl_window); + DamageEmpty(window_get_damage(xwl_window->window)); } static void xwl_screen_post_damage(struct xwl_screen *xwl_screen) { struct xwl_window *xwl_window, *next_xwl_window; + struct xorg_list commit_window_list; + + xorg_list_init(&commit_window_list); xorg_list_for_each_entry_safe(xwl_window, next_xwl_window, &xwl_screen->damage_window_list, link_damage) { @@ -752,6 +878,24 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) #endif xwl_window_post_damage(xwl_window); + xorg_list_del(&xwl_window->link_damage); + xorg_list_append(&xwl_window->link_damage, &commit_window_list); + } + + if (xorg_list_is_empty(&commit_window_list)) + return; + +#ifdef XWL_HAS_GLAMOR + if (xwl_screen->glamor && + xwl_screen->egl_backend == &xwl_screen->gbm_backend) { + glamor_block_handler(xwl_screen->screen); + } +#endif + + xorg_list_for_each_entry_safe(xwl_window, next_xwl_window, + &commit_window_list, link_damage) { + wl_surface_commit(xwl_window->surface); + xorg_list_del(&xwl_window->link_damage); } } @@ -901,6 +1045,19 @@ xwl_sync_events (struct xwl_screen *xwl_screen) xwl_read_events (xwl_screen); } +void +xwl_screen_roundtrip(struct xwl_screen *xwl_screen) +{ + int ret; + + ret = wl_display_roundtrip(xwl_screen->display); + while (ret >= 0 && xwl_screen->expecting_event) + ret = wl_display_roundtrip(xwl_screen->display); + + if (ret < 0) + xwl_give_up("could not connect to wayland server\n"); +} + static CARD32 add_client_fd(OsTimerPtr timer, CARD32 time, void *arg) { @@ -962,6 +1119,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) return FALSE; if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0)) return FALSE; + if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0)) + return FALSE; dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen); xwl_screen->screen = pScreen; @@ -973,6 +1132,19 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-rootless") == 0) { xwl_screen->rootless = 1; + + /* Disable the XSS extension on Xwayland rootless. + * + * Xwayland is just a Wayland client, no X11 screensaver + * should be expected to work reliably on Xwayland rootless. + */ +#ifdef SCREENSAVER + noScreenSaverExtension = TRUE; +#endif + ScreenSaverTime = 0; + ScreenSaverInterval = 0; + defaultScreenSaverTime = 0; + defaultScreenSaverInterval = 0; } else if (strcmp(argv[i], "-wm") == 0) { xwl_screen->wm_fd = atoi(argv[i + 1]); @@ -1025,6 +1197,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xorg_list_init(&xwl_screen->damage_window_list); xwl_screen->depth = 24; + if (!monitorResolution) + monitorResolution = DEFAULT_DPI; + xwl_screen->display = wl_display_connect(NULL); if (xwl_screen->display == NULL) { ErrorF("could not connect to wayland server\n"); @@ -1038,14 +1213,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xwl_screen->registry = wl_display_get_registry(xwl_screen->display); wl_registry_add_listener(xwl_screen->registry, ®istry_listener, xwl_screen); - ret = wl_display_roundtrip(xwl_screen->display); - if (ret == -1) { - ErrorF("could not connect to wayland server\n"); - return FALSE; - } - - while (xwl_screen->expecting_event > 0) - wl_display_roundtrip(xwl_screen->display); + xwl_screen_roundtrip(xwl_screen); bpc = xwl_screen->depth / 3; green_bpc = xwl_screen->depth - 2 * bpc; @@ -1062,7 +1230,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) ret = fbScreenInit(pScreen, NULL, xwl_screen->width, xwl_screen->height, - 96, 96, 0, + monitorResolution, monitorResolution, 0, BitsPerPixel(xwl_screen->depth)); if (!ret) return FALSE; @@ -1121,6 +1289,11 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xwl_screen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = xwl_close_screen; + if (xwl_screen->rootless) { + xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap; + pScreen->SetWindowPixmap = xwl_set_window_pixmap; + } + pScreen->CursorWarpedTo = xwl_cursor_warped_to; pScreen->CursorConfinedTo = xwl_cursor_confined_to; @@ -1132,9 +1305,7 @@ 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); + xwl_screen_roundtrip(xwl_screen); return ret; } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 463622669..b9495b313 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -133,6 +133,7 @@ struct xwl_screen { UnrealizeWindowProcPtr UnrealizeWindow; DestroyWindowProcPtr DestroyWindow; XYToWindowProcPtr XYToWindow; + SetWindowPixmapProcPtr SetWindowPixmap; struct xorg_list output_list; struct xorg_list seat_list; @@ -178,11 +179,11 @@ struct xwl_window { struct wl_surface *surface; struct wl_shell_surface *shell_surface; WindowPtr window; - DamagePtr damage; struct xorg_list link_damage; struct wl_callback *frame_callback; Bool allow_commits; #ifdef GLAMOR_HAS_GBM + struct xorg_list frame_callback_list; Bool present_flipped; #endif }; @@ -192,15 +193,13 @@ struct xwl_present_window { struct xwl_screen *xwl_screen; struct xwl_present_event *sync_flip; WindowPtr window; - struct xorg_list link; + struct xorg_list frame_callback_list; uint64_t msc; uint64_t ust; OsTimerPtr frame_timer; - Bool frame_timer_firing; - struct wl_callback *frame_callback; struct wl_callback *sync_callback; struct xorg_list event_list; @@ -216,7 +215,7 @@ struct xwl_present_event { Bool buffer_released; struct xwl_present_window *xwl_present_window; - struct wl_buffer *buffer; + PixmapPtr pixmap; struct xorg_list list; }; @@ -378,8 +377,12 @@ struct xwl_output { Bool xdg_output_done; }; +void xwl_window_create_frame_callback(struct xwl_window *xwl_window); + void xwl_sync_events (struct xwl_screen *xwl_screen); +void xwl_screen_roundtrip (struct xwl_screen *xwl_screen); + Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen); struct xwl_screen *xwl_screen_get(ScreenPtr screen); @@ -452,9 +455,10 @@ 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 +void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window); Bool xwl_present_init(ScreenPtr screen); void xwl_present_cleanup(WindowPtr window); -void xwl_present_unrealize_window(WindowPtr window); +void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window); #endif /* GLAMOR_HAS_GBM */ #ifdef XV diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index 47dc30cd5..3aa005041 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -153,6 +153,15 @@ ddxBeforeReset(void) } #endif +#if INPUTTHREAD +/** This function is called in Xserver/os/inputthread.c when starting + the input thread. */ +void +ddxInputThreadInit(void) +{ +} +#endif + int main(int argc, char *argv[], char *envp[]) { diff --git a/include/dix-config.h.in b/include/dix-config.h.in index c64321ef1..d02bb1b81 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -134,6 +134,9 @@ /* Define to 1 if you have the <linux/fb.h> header file. */ #undef HAVE_LINUX_FB_H +/* Define to 1 if you have the `memfd_create' function. */ +#undef HAVE_MEMFD_CREATE + /* Define to 1 if you have the `mkostemp' function. */ #undef HAVE_MKOSTEMP @@ -458,9 +461,6 @@ /* Wrap SIGBUS to catch MIT-SHM faults */ #undef BUSFAULT -/* Directory for shared memory temp files */ -#undef SHMDIR - /* Don't let Xdefs.h define 'pointer' */ #define _XTYPEDEF_POINTER 1 @@ -485,6 +485,9 @@ /* Glamor can use eglQueryDmaBuf* functions */ #undef GLAMOR_HAS_EGL_QUERY_DMABUF +/* Glamor can use EGL_MESA_query_driver functions */ +#undef GLAMOR_HAS_EGL_QUERY_DRIVER + /* byte order */ #undef X_BYTE_ORDER @@ -515,4 +518,7 @@ /* Have epoll_create1() */ #undef HAVE_EPOLL_CREATE1 +/* Have isastream */ +#undef HAVE_ISASTREAM + #endif /* _DIX_CONFIG_H_ */ diff --git a/include/glxvndabi.h b/include/glxvndabi.h index b78306d23..71f36e722 100644 --- a/include/glxvndabi.h +++ b/include/glxvndabi.h @@ -75,7 +75,7 @@ * will still work. */ #define GLXSERVER_VENDOR_ABI_MAJOR_VERSION 0 -#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 0 +#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 1 #if defined(__cplusplus) extern "C" { @@ -236,6 +236,17 @@ typedef struct GlxServerExportsRec { * \param client The client. */ int (* forwardRequest) (GlxServerVendor *vendor, ClientPtr client); + + /** + * Sets the vendor library to use for a screen for a specific client. + * + * This function changes which vendor should handle GLX requests for a + * screen. Unlike \c setScreenVendor, this function can be called at any + * time, and only applies to requests from a single client. + * + * This function is available in GLXVND version 0.1 or later. + */ + Bool (* setClientScreenVendor) (ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor); } GlxServerExports; extern _X_EXPORT const GlxServerExports glxServer; diff --git a/include/meson.build b/include/meson.build index dfca3c340..ac2415327 100644 --- a/include/meson.build +++ b/include/meson.build @@ -70,15 +70,12 @@ conf_data.set('SYSTEMD_LOGIND', build_systemd_logind) conf_data.set('NEED_DBUS', build_systemd_logind or build_hal) conf_data.set('CONFIG_WSCONS', host_machine.system() == 'openbsd') -# XXX: SHMDIR is weird in autoconf, probing the build system for -# various tmp directories. Could we replace it with C code at runtime -# that just uses whatever directory works? -conf_data.set_quoted('SHMDIR', '/tmp') - conf_data.set('HAVE_XSHMFENCE', xshmfence_dep.found()) conf_data.set('WITH_LIBDRM', libdrm_dep.found()) conf_data.set('GLAMOR_HAS_EGL_QUERY_DMABUF', epoxy_dep.found() and epoxy_dep.version().version_compare('>= 1.4.4')) +conf_data.set('GLAMOR_HAS_EGL_QUERY_DRIVER', + epoxy_dep.found() and epoxy_dep.version().version_compare('>= 1.5.4')) conf_data.set('GLXEXT', build_glx) conf_data.set('GLAMOR', build_glamor) conf_data.set('GLAMOR_HAS_GBM', gbm_dep.found()) @@ -119,12 +116,14 @@ conf_data.set('HAVE_CBRT', cc.has_function('cbrt')) conf_data.set('HAVE_EPOLL_CREATE1', cc.has_function('epoll_create1')) conf_data.set('HAVE_GETUID', cc.has_function('getuid')) conf_data.set('HAVE_GETEUID', cc.has_function('geteuid')) +conf_data.set('HAVE_ISASTREAM', cc.has_function('isastream')) conf_data.set('HAVE_ISSETUGID', cc.has_function('issetugid')) conf_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) conf_data.set('HAVE_GETPEEREID', cc.has_function('getpeereid')) conf_data.set('HAVE_GETPEERUCRED', cc.has_function('getpeerucred')) conf_data.set('HAVE_GETPROGNAME', cc.has_function('getprogname')) conf_data.set('HAVE_GETZONEID', cc.has_function('getzoneid')) +conf_data.set('HAVE_MEMFD_CREATE', cc.has_function('memfd_create')) conf_data.set('HAVE_MKOSTEMP', cc.has_function('mkostemp')) conf_data.set('HAVE_MMAP', cc.has_function('mmap')) conf_data.set('HAVE_POLL', cc.has_function('poll')) diff --git a/include/os.h b/include/os.h index 439b28661..4b5f22b6d 100644 --- a/include/os.h +++ b/include/os.h @@ -562,6 +562,8 @@ extern _X_EXPORT void AbortDDX(enum ExitCode error); extern _X_EXPORT void ddxGiveUp(enum ExitCode error); +extern _X_EXPORT void +ddxInputThreadInit(void); extern _X_EXPORT int TimeSinceLastInputEvent(void); diff --git a/meson.build b/meson.build index d99882324..e3cfe988d 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project('xserver', 'c', 'buildtype=debugoptimized', 'c_std=gnu99', ], - version: '1.20.5', + version: '1.20.9', meson_version: '>= 0.47.0', ) add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c') @@ -360,6 +360,10 @@ extern _X_EXPORT void miPushPixels(GCPtr /*pGC */ , /* miscrinit.c */ +extern _X_EXPORT void +miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int subWindowMode); + extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, diff --git a/mi/miscrinit.c b/mi/miscrinit.c index 9c6af0dc7..264622df1 100644 --- a/mi/miscrinit.c +++ b/mi/miscrinit.c @@ -124,6 +124,12 @@ miCloseScreen(ScreenPtr pScreen) return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate)); } +void +miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int subWindowMode) +{ +} + /* With the introduction of pixmap privates, the "screen pixmap" can no * longer be created in miScreenInit, since all the modules that could * possibly ask for pixmap private space have not been initialized at @@ -243,7 +249,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */ } /* else CloseScreen */ /* QueryBestSize, SaveScreen, GetImage, GetSpans */ - pScreen->SourceValidate = (SourceValidateProcPtr) 0; + pScreen->SourceValidate = miSourceValidate; /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */ /* RealizeWindow, UnrealizeWindow */ pScreen->ValidateTree = miValidateTree; diff --git a/miext/sync/misync.c b/miext/sync/misync.c index 490fa0b17..0931803f6 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -101,24 +101,29 @@ miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence, Bool initially_triggered) pFence->funcs = miSyncFenceFuncs; pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered); + + pFence->sync.initialized = TRUE; } void miSyncDestroyFence(SyncFence * pFence) { - ScreenPtr pScreen = pFence->pScreen; - SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); - SyncTriggerList *ptl, *pNext; - pFence->sync.beingDestroyed = TRUE; - /* tell all the fence's triggers that the counter has been destroyed */ - for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) { - (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); - pNext = ptl->next; - free(ptl); /* destroy the trigger list as we go */ - } - pScreenPriv->funcs.DestroyFence(pScreen, pFence); + if (pFence->sync.initialized) { + ScreenPtr pScreen = pFence->pScreen; + SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); + SyncTriggerList *ptl, *pNext; + + /* tell all the fence's triggers that the counter has been destroyed */ + for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) { + (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); + pNext = ptl->next; + free(ptl); /* destroy the trigger list as we go */ + } + + pScreenPriv->funcs.DestroyFence(pScreen, pFence); + } dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); } diff --git a/miext/sync/misync.h b/miext/sync/misync.h index dc78c5fdb..f7082d5ea 100644 --- a/miext/sync/misync.h +++ b/miext/sync/misync.h @@ -28,6 +28,7 @@ #ifndef _MISYNC_H_ #define _MISYNC_H_ +typedef struct _SyncObject SyncObject; typedef struct _SyncFence SyncFence; typedef struct _SyncTrigger SyncTrigger; diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h index 2eab2aa57..6f89714d6 100644 --- a/miext/sync/misyncstr.h +++ b/miext/sync/misyncstr.h @@ -38,13 +38,14 @@ #define SYNC_COUNTER 0 #define SYNC_FENCE 1 -typedef struct _SyncObject { +struct _SyncObject { ClientPtr client; /* Owning client. 0 for system counters */ struct _SyncTriggerList *pTriglist; /* list of triggers */ XID id; /* resource ID */ unsigned char type; /* SYNC_* */ + unsigned char initialized; /* FALSE if created but not initialized */ Bool beingDestroyed; /* in process of going away */ -} SyncObject; +}; typedef struct _SyncCounter { SyncObject sync; /* Common sync object data */ diff --git a/os/connection.c b/os/connection.c index b09595d42..60c034f2e 100644 --- a/os/connection.c +++ b/os/connection.c @@ -937,6 +937,14 @@ AttendClient(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; + if (client->clientGone) { + /* + * client is gone, so any pending requests will be dropped and its + * ignore count doesn't matter. + */ + return; + } + client->ignoreCount--; if (client->ignoreCount) return; diff --git a/os/inputthread.c b/os/inputthread.c index 97e59d21f..e6694afda 100644 --- a/os/inputthread.c +++ b/os/inputthread.c @@ -318,6 +318,8 @@ InputThreadDoWork(void *arg) sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, NULL); + ddxInputThreadInit(); + inputThreadInfo->running = TRUE; #if defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) @@ -557,6 +557,11 @@ void ResetCurrentRequest(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; + + /* ignore dying clients */ + if (!oc) + return; + register ConnectionInputPtr oci = oc->input; register xReq *request; int gotnow, needed; diff --git a/os/ospoll.c b/os/ospoll.c index db9e73811..c68aabc87 100644 --- a/os/ospoll.c +++ b/os/ospoll.c @@ -40,6 +40,7 @@ #if !HAVE_OSPOLL && defined(HAVE_PORT_CREATE) #include <port.h> +#include <poll.h> #define PORT 1 #define HAVE_OSPOLL 1 #endif @@ -78,7 +79,6 @@ struct ospoll { #endif #if EPOLL || PORT -#include <sys/epoll.h> /* epoll-based implementation */ struct ospollfd { @@ -468,10 +468,10 @@ epoll_mod(struct ospoll *ospoll, struct ospollfd *osfd) { int events = 0; if (osfd->xevents & X_NOTIFY_READ) - events |= EPOLLIN; + events |= POLLIN; if (osfd->xevents & X_NOTIFY_WRITE) - events |= EPOLLOUT; - port_associate(ospool->epoll_fd, PORT_SOURCE_FD, osfd->fd, events, osfd); + events |= POLLOUT; + port_associate(ospoll->epoll_fd, PORT_SOURCE_FD, osfd->fd, events, osfd); } #endif @@ -601,9 +601,14 @@ ospoll_wait(struct ospoll *ospoll, int timeout) #define MAX_EVENTS 256 port_event_t events[MAX_EVENTS]; uint_t nget = 1; + timespec_t port_timeout = { + .tv_sec = timeout / 1000, + .tv_nsec = (timeout % 1000) * 1000000 + }; nready = 0; - if (port_getn(ospoll->epoll_fd, events, MAX_EVENTS, &nget, &timeout) == 0) { + if (port_getn(ospoll->epoll_fd, events, MAX_EVENTS, &nget, &port_timeout) + == 0) { nready = nget; } for (int i = 0; i < nready; i++) { @@ -612,17 +617,18 @@ ospoll_wait(struct ospoll *ospoll, int timeout) uint32_t revents = ev->portev_events; int xevents = 0; - if (revents & EPOLLIN) + if (revents & POLLIN) xevents |= X_NOTIFY_READ; - if (revents & EPOLLOUT) + if (revents & POLLOUT) xevents |= X_NOTIFY_WRITE; - if (revents & (~(EPOLLIN|EPOLLOUT))) + if (revents & (~(POLLIN|POLLOUT))) xevents |= X_NOTIFY_ERROR; if (osfd->callback) osfd->callback(osfd->fd, xevents, osfd->data); - if (osfd->trigger == ospoll_trigger_level && !osfd->deleted) { + if (osfd->trigger == ospoll_trigger_level && + !xorg_list_is_empty(&osfd->deleted)) { epoll_mod(ospoll, osfd); } } diff --git a/present/present_scmd.c b/present/present_scmd.c index 3b7fbd832..6a580cb7a 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 screen_pixmap, window_pixmap; + PixmapPtr window_pixmap; WindowPtr root = screen->root; present_screen_priv_ptr screen_priv = present_screen_priv(screen); @@ -99,9 +99,8 @@ 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_pixmap && + if (window_pixmap != screen->GetScreenPixmap(screen) && window_pixmap != screen_priv->flip_pixmap && window_pixmap != present_flip_pending_pixmap(screen)) return FALSE; @@ -127,8 +126,7 @@ 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 || - pixmap->devKind != screen_pixmap->devKind) { + window->drawable.height != pixmap->drawable.height) { return FALSE; } diff --git a/present/present_screen.c b/present/present_screen.c index c7e37c5fd..bfd30b8ba 100644 --- a/present/present_screen.c +++ b/present/present_screen.c @@ -115,15 +115,13 @@ present_wnmd_clear_window_flip(WindowPtr window) present_window_priv_ptr window_priv = present_window_priv(window); present_vblank_ptr vblank, tmp; - if (window_priv->flip_pending) { - present_wnmd_set_abort_flip(window); - window_priv->flip_pending->window = NULL; + xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) { + present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); + present_vblank_destroy(vblank); } xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) { present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); - /* The pixmap will be destroyed by freeing the window resources. */ - vblank->pixmap = NULL; present_vblank_destroy(vblank); } diff --git a/present/present_wnmd.c b/present/present_wnmd.c index 9d0b147cc..32c4d55f1 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -278,7 +278,9 @@ present_wnmd_check_flip(RRCrtcPtr crtc, if (x_off || y_off) return FALSE; - // TODO: Check for valid region? + /* Valid area must contain window (for simplicity for now just never flip when one is set). */ + if (valid) + return FALSE; /* Flip pixmap must have same dimensions as window */ if (window->drawable.width != pixmap->drawable.width || @@ -325,11 +327,11 @@ present_wnmd_check_flip_window (WindowPtr window) if (flip_pending) { if (!present_wnmd_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap, - flip_pending->sync_flip, NULL, 0, 0, NULL)) + flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL)) present_wnmd_set_abort_flip(window); } else if (flip_active) { if (!present_wnmd_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap, - flip_active->sync_flip, NULL, 0, 0, NULL)) + flip_active->sync_flip, flip_active->valid, 0, 0, NULL)) present_wnmd_flips_stop(window); } @@ -337,7 +339,7 @@ present_wnmd_check_flip_window (WindowPtr window) xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) { if (vblank->queued && vblank->flip && !present_wnmd_check_flip(vblank->crtc, window, vblank->pixmap, - vblank->sync_flip, NULL, 0, 0, &reason)) { + vblank->sync_flip, vblank->valid, 0, 0, &reason)) { vblank->flip = FALSE; vblank->reason = reason; if (vblank->sync_flip) @@ -649,8 +651,6 @@ present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, ui present_window_priv_ptr window_priv = present_window_priv(window); present_vblank_ptr vblank; - assert(crtc); - (*screen_priv->wnmd_info->abort_vblank) (window, crtc, event_id, msc); xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) { diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index a851aebcc..7839a0eda 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -401,17 +401,22 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) if (crtc->scanout_pixmap_back) { pScrPriv->rrDisableSharedPixmapFlipping(crtc); - master->StopFlippingPixmapTracking(mrootdraw, - crtc->scanout_pixmap, - crtc->scanout_pixmap_back); + if (mrootdraw) { + master->StopFlippingPixmapTracking(mrootdraw, + crtc->scanout_pixmap, + crtc->scanout_pixmap_back); + } rrDestroySharedPixmap(crtc, crtc->scanout_pixmap_back); crtc->scanout_pixmap_back = NULL; } else { pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); - master->StopPixmapTracking(mrootdraw, - crtc->scanout_pixmap); + + if (mrootdraw) { + master->StopPixmapTracking(mrootdraw, + crtc->scanout_pixmap); + } } rrDestroySharedPixmap(crtc, crtc->scanout_pixmap); @@ -2007,9 +2012,15 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable) Bool RRHasScanoutPixmap(ScreenPtr pScreen) { - rrScrPriv(pScreen); + rrScrPrivPtr pScrPriv; int i; + /* Bail out if RandR wasn't initialized. */ + if (!dixPrivateKeyRegistered(rrPrivKey)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + if (!pScreen->is_output_slave) return FALSE; diff --git a/record/record.c b/record/record.c index fdcee7e00..05d751ac2 100644 --- a/record/record.c +++ b/record/record.c @@ -2362,9 +2362,9 @@ RecordDisableContext(RecordContextPtr pContext) if (!pContext->pRecordingClient->clientGone) { RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0, 0); RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0); - /* Re-enable request processing on this connection. */ - AttendClient(pContext->pRecordingClient); } + /* Re-enable request processing on this connection. */ + AttendClient(pContext->pRecordingClient); for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP) { RecordUninstallHooks(pRCAP, 0); @@ -2499,7 +2499,7 @@ SProcRecordQueryVersion(ClientPtr client) } /* SProcRecordQueryVersion */ static int _X_COLD -SwapCreateRegister(xRecordRegisterClientsReq * stuff) +SwapCreateRegister(ClientPtr client, xRecordRegisterClientsReq * stuff) { int i; XID *pClientID; @@ -2509,13 +2509,13 @@ SwapCreateRegister(xRecordRegisterClientsReq * stuff) swapl(&stuff->nRanges); pClientID = (XID *) &stuff[1]; if (stuff->nClients > - stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq)) + client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq)) return BadLength; for (i = 0; i < stuff->nClients; i++, pClientID++) { swapl(pClientID); } if (stuff->nRanges > - stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq) + client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq) - stuff->nClients) return BadLength; RecordSwapRanges((xRecordRange *) pClientID, stuff->nRanges); @@ -2530,7 +2530,7 @@ SProcRecordCreateContext(ClientPtr client) swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq); - if ((status = SwapCreateRegister((void *) stuff)) != Success) + if ((status = SwapCreateRegister(client, (void *) stuff)) != Success) return status; return ProcRecordCreateContext(client); } /* SProcRecordCreateContext */ @@ -2543,7 +2543,7 @@ SProcRecordRegisterClients(ClientPtr client) swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq); - if ((status = SwapCreateRegister((void *) stuff)) != Success) + if ((status = SwapCreateRegister(client, (void *) stuff)) != Success) return status; return ProcRecordRegisterClients(client); } /* SProcRecordRegisterClients */ diff --git a/render/render.c b/render/render.c index 7d94bd5ff..c376090ca 100644 --- a/render/render.c +++ b/render/render.c @@ -1492,6 +1492,11 @@ ProcRenderCreateCursor(ClientPtr client) return BadAlloc; } + /* what kind of maniac creates a cursor from a window picture though */ + if (pSrc->pDrawable->type == DRAWABLE_WINDOW) + pScreen->SourceValidate(pSrc->pDrawable, 0, 0, width, height, + IncludeInferiors); + if (pSrc->format == PICT_a8r8g8b8) { (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, width, height, ZPixmap, diff --git a/test/misc.c b/test/misc.c index 3c669b677..f1f76cccd 100644 --- a/test/misc.c +++ b/test/misc.c @@ -33,7 +33,7 @@ #include "tests-common.h" -ScreenInfo screenInfo; +extern ScreenInfo screenInfo; static void dix_version_compare(void) diff --git a/test/xi1/protocol-xchangedevicecontrol.c b/test/xi1/protocol-xchangedevicecontrol.c index 57a15c407..54f1f67cb 100644 --- a/test/xi1/protocol-xchangedevicecontrol.c +++ b/test/xi1/protocol-xchangedevicecontrol.c @@ -37,7 +37,7 @@ #include "protocol-common.h" -ClientRec client_window; +extern ClientRec client_window; static ClientRec client_request; static void diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c index 8cd85dd05..05dd3c4e7 100644 --- a/test/xi2/protocol-common.c +++ b/test/xi2/protocol-common.c @@ -45,6 +45,8 @@ static ClientRec server_client; void *global_userdata; +void (*reply_handler) (ClientPtr client, int len, char *data, void *userdata); + int enable_GrabButton_wrap = 1; int enable_XISetEventMask_wrap = 1; diff --git a/test/xi2/protocol-common.h b/test/xi2/protocol-common.h index 8490529ad..742ce348f 100644 --- a/test/xi2/protocol-common.h +++ b/test/xi2/protocol-common.h @@ -99,7 +99,7 @@ extern void *global_userdata; * The reply handler called from WriteToClient. Set this handler if you need * to check the reply values. */ -void (*reply_handler) (ClientPtr client, int len, char *data, void *userdata); +extern void (*reply_handler) (ClientPtr client, int len, char *data, void *userdata); /** * The default screen used for the windows. Initialized by init_simple(). diff --git a/test/xi2/protocol-xigetclientpointer.c b/test/xi2/protocol-xigetclientpointer.c index 9c38bd720..244e8438f 100644 --- a/test/xi2/protocol-xigetclientpointer.c +++ b/test/xi2/protocol-xigetclientpointer.c @@ -46,7 +46,7 @@ static struct { int win; } test_data; -ClientRec client_window; +extern ClientRec client_window; static ClientRec client_request; static void diff --git a/test/xi2/protocol-xigetselectedevents.c b/test/xi2/protocol-xigetselectedevents.c index 9a0fac5d4..b14100224 100644 --- a/test/xi2/protocol-xigetselectedevents.c +++ b/test/xi2/protocol-xigetselectedevents.c @@ -60,7 +60,7 @@ static struct { int mask_len; } test_data; -ClientRec client_window; +extern ClientRec client_window; /* AddResource is called from XISetSEventMask, we don't need this */ Bool diff --git a/test/xi2/protocol-xipassivegrabdevice.c b/test/xi2/protocol-xipassivegrabdevice.c index c703a1ee8..142bcecb7 100644 --- a/test/xi2/protocol-xipassivegrabdevice.c +++ b/test/xi2/protocol-xipassivegrabdevice.c @@ -41,7 +41,7 @@ #include "protocol-common.h" -ClientRec client_window; +extern ClientRec client_window; static ClientRec client_request; #define N_MODS 7 diff --git a/test/xi2/protocol-xiquerydevice.c b/test/xi2/protocol-xiquerydevice.c index a068038fd..6ee8a80fc 100644 --- a/test/xi2/protocol-xiquerydevice.c +++ b/test/xi2/protocol-xiquerydevice.c @@ -54,7 +54,7 @@ struct test_data { int num_devices_in_reply; }; -ClientRec client_window; +extern ClientRec client_window; static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *closure); diff --git a/test/xi2/protocol-xiquerypointer.c b/test/xi2/protocol-xiquerypointer.c index ed75d7910..0f5a2b57a 100644 --- a/test/xi2/protocol-xiquerypointer.c +++ b/test/xi2/protocol-xiquerypointer.c @@ -41,7 +41,7 @@ #include "protocol-common.h" -ClientRec client_window; +extern ClientRec client_window; static ClientRec client_request; static void reply_XIQueryPointer_data(ClientPtr client, int len, char *data, void *closure); diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c index 3ce758faa..c7ddbfc10 100644 --- a/test/xi2/protocol-xiqueryversion.c +++ b/test/xi2/protocol-xiqueryversion.c @@ -58,7 +58,7 @@ struct test_data { int minor_expected; }; -ClientRec client_window; +extern ClientRec client_window; static void reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure) diff --git a/test/xi2/protocol-xiselectevents.c b/test/xi2/protocol-xiselectevents.c index f136c23d0..06050ade7 100644 --- a/test/xi2/protocol-xiselectevents.c +++ b/test/xi2/protocol-xiselectevents.c @@ -62,7 +62,7 @@ static unsigned char *data[4096 * 20]; /* the request data buffer */ -ClientRec client_window; +extern ClientRec client_window; int __real_XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, diff --git a/test/xi2/protocol-xisetclientpointer.c b/test/xi2/protocol-xisetclientpointer.c index 6584bb9cc..ddc9f0000 100644 --- a/test/xi2/protocol-xisetclientpointer.c +++ b/test/xi2/protocol-xisetclientpointer.c @@ -48,7 +48,7 @@ #include "protocol-common.h" -ClientRec client_window; +extern ClientRec client_window; static ClientRec client_request; static void diff --git a/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c index 8484d54e5..e5c2f31ea 100644 --- a/test/xi2/protocol-xiwarppointer.c +++ b/test/xi2/protocol-xiwarppointer.c @@ -44,7 +44,7 @@ static int expected_x = SPRITE_X; static int expected_y = SPRITE_Y; -ClientRec client_window; +extern ClientRec client_window; /** * This function overrides the one in the screen rec. @@ -152,6 +152,19 @@ static RESTYPE RT_XKBCLIENT; #define CHK_REQ_KEY_RANGE(err,first,num,r) \ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) +static Bool +_XkbCheckRequestBounds(ClientPtr client, void *stuff, void *from, void *to) { + char *cstuff = (char *)stuff; + char *cfrom = (char *)from; + char *cto = (char *)to; + + return cfrom < cto && + cfrom >= cstuff && + cfrom < cstuff + ((size_t)client->req_len << 2) && + cto >= cstuff && + cto <= cstuff + ((size_t)client->req_len << 2); +} + /***====================================================================***/ int @@ -2110,6 +2123,9 @@ SetKeySyms(ClientPtr client, } } } + if (XkbKeyHasActions(xkb, i + req->firstKeySym)) + XkbResizeKeyActions(xkb, i + req->firstKeySym, + XkbNumGroups(wire->groupInfo) * wire->width); oldMap->kt_index[0] = wire->ktIndex[0]; oldMap->kt_index[1] = wire->ktIndex[1]; oldMap->kt_index[2] = wire->ktIndex[2]; @@ -2383,6 +2399,9 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, XkbSymMapPtr map; int i; + if (!dev->key) + return 0; + xkbi = dev->key->xkbInfo; xkb = xkbi->desc; @@ -2495,6 +2514,9 @@ _XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values) XkbSrvInfoPtr xkbi; XkbDescPtr xkb; + if (!dev->key) + return Success; + xkbi = dev->key->xkbInfo; xkb = xkbi->desc; @@ -4036,6 +4058,8 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, client->errorValue = _XkbErrCode2(0x04, stuff->firstType); return BadAccess; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nTypes)) + return BadLength; old = tmp; tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad); if (!tmp) { @@ -4065,6 +4089,8 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, } width = (CARD8 *) tmp; tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); + if (!_XkbCheckRequestBounds(client, stuff, width, tmp)) + return BadLength; type = &xkb->map->types[stuff->firstKTLevel]; for (i = 0; i < stuff->nKTLevels; i++, type++) { if (width[i] == 0) @@ -4074,6 +4100,8 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, type->num_levels, width[i]); return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + width[i])) + return BadLength; tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad); if (!tmp) { client->errorValue = bad; @@ -4086,6 +4114,9 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, client->errorValue = 0x08; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->indicators))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators, client->swapped, &bad); if (!tmp) { @@ -4098,6 +4129,9 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, client->errorValue = 0x09; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->virtualMods))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods, (CARD32) stuff->virtualMods, client->swapped, &bad); @@ -4111,6 +4145,9 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, client->errorValue = 0x0a; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->groupNames))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups, (CARD32) stuff->groupNames, client->swapped, &bad); @@ -4132,9 +4169,14 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, stuff->nKeys); return BadValue; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nKeys)) + return BadLength; tmp += stuff->nKeys; } if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) { + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + (stuff->nKeyAliases * 2))) + return BadLength; tmp += stuff->nKeyAliases * 2; } if (stuff->which & XkbRGNamesMask) { @@ -4142,6 +4184,9 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups); return BadValue; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + stuff->nRadioGroups)) + return BadLength; tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad); if (!tmp) { client->errorValue = bad; @@ -4335,6 +4380,8 @@ ProcXkbSetNames(ClientPtr client) /* check device-independent stuff */ tmp = (CARD32 *) &stuff[1]; + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbKeycodesNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4342,6 +4389,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbGeometryNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4349,6 +4398,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbSymbolsNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4356,6 +4407,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbPhysSymbolsNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4363,6 +4416,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbTypesNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4370,6 +4425,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbCompatNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { diff --git a/xkb/xkbSwap.c b/xkb/xkbSwap.c index 1c1ed5ff4..50cabb90e 100644 --- a/xkb/xkbSwap.c +++ b/xkb/xkbSwap.c @@ -76,7 +76,7 @@ SProcXkbSelectEvents(ClientPtr client) register unsigned bit, ndx, maskLeft, dataLeft, size; from.c8 = (CARD8 *) &stuff[1]; - dataLeft = (stuff->length * 4) - SIZEOF(xkbSelectEventsReq); + dataLeft = (client->req_len * 4) - SIZEOF(xkbSelectEventsReq); maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask)); for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) { if (((bit & maskLeft) == 0) || (ndx == XkbMapNotify)) |