From c40fb2bc5015dc03268cb888004b17ed55fc0946 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 10 2018 05:28:17 +0000 Subject: import xorg-x11-server-1.19.5-5.el7 --- diff --git a/.gitignore b/.gitignore index 8a83cf4..73879ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/xorg-server-1.19.3.tar.bz2 +SOURCES/xorg-server-1.19.5.tar.bz2 diff --git a/.xorg-x11-server.metadata b/.xorg-x11-server.metadata index 72833ff..3bee643 100644 --- a/.xorg-x11-server.metadata +++ b/.xorg-x11-server.metadata @@ -1 +1 @@ -77f580ffa22a8bbcc3536e74e19114e446417a9c SOURCES/xorg-server-1.19.3.tar.bz2 +307d3405f709f7e41966c850b37deefe7f83eb9b SOURCES/xorg-server-1.19.5.tar.bz2 diff --git a/SOURCES/0001-Always-install-vbe-and-int10-sdk-headers.patch b/SOURCES/0001-Always-install-vbe-and-int10-sdk-headers.patch index 7dd249c..fa7f836 100644 --- a/SOURCES/0001-Always-install-vbe-and-int10-sdk-headers.patch +++ b/SOURCES/0001-Always-install-vbe-and-int10-sdk-headers.patch @@ -1,4 +1,4 @@ -From fc306295751178802405e0faa3f2e4e40cd913f0 Mon Sep 17 00:00:00 2001 +From e96a83d9b1b5a52a41213c7a4840dc96b4f5b06f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 15 Aug 2012 12:35:21 -0400 Subject: [PATCH] Always install vbe and int10 sdk headers @@ -9,7 +9,7 @@ Signed-off-by: Adam Jackson 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am -index 27f2cc6..f9a078f 100644 +index b876b79..a170b58 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -26,17 +26,9 @@ if VGAHW @@ -27,11 +27,11 @@ index 27f2cc6..f9a078f 100644 -SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ +SUBDIRS = common ddc x86emu int10 os-support parser \ ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \ -- $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \ +- $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods xkb \ + $(DRI2_SUBDIR) . vbe i2c dixmods \ fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \ $(GLAMOR_EGL_SUBDIR) drivers -- -2.1.0 +2.13.6 diff --git a/SOURCES/0001-dix-Remove-clients-from-input-and-output-ready-queue.patch b/SOURCES/0001-dix-Remove-clients-from-input-and-output-ready-queue.patch deleted file mode 100644 index c4a4ef2..0000000 --- a/SOURCES/0001-dix-Remove-clients-from-input-and-output-ready-queue.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d9e23ea4228575344e3b4c0443cecc5eb75356e4 Mon Sep 17 00:00:00 2001 -From: Keith Packard -Date: Wed, 10 May 2017 21:50:45 -0700 -Subject: [PATCH xserver] dix: Remove clients from input and output ready - queues after closing -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Delay removing the client from these two queues until all potential -I/O has completed in case we mark the client as ready for reading or -with pending output during the close operation. - -Bugzilla: https://bugs.freedesktop.org/100957 -Signed-off-by: Keith Packard -Tested-by: Nick Sarnie -Reviewed-by: Michel Dänzer ---- - dix/dispatch.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dix/dispatch.c b/dix/dispatch.c -index a2df1e0e6..8b371b678 100644 ---- a/dix/dispatch.c -+++ b/dix/dispatch.c -@@ -3414,7 +3414,6 @@ CloseDownClient(ClientPtr client) - if (grabState != GrabNone && grabClient == client) { - UngrabServer(client); - } -- mark_client_not_ready(client); - BITCLEAR(grabWaiters, client->index); - DeleteClientFromAnySelections(client); - ReleaseActiveGrabs(client); -@@ -3443,8 +3442,9 @@ CloseDownClient(ClientPtr client) - if (ClientIsAsleep(client)) - ClientSignal(client); - ProcessWorkQueueZombies(); -- output_pending_clear(client); - CloseDownConnection(client); -+ output_pending_clear(client); -+ mark_client_not_ready(client); - - /* If the client made it to the Running stage, nClients has - * been incremented on its behalf, so we need to decrement it --- -2.13.0 - diff --git a/SOURCES/0001-modesetting-Validate-the-atom-for-enum-properties.patch b/SOURCES/0001-modesetting-Validate-the-atom-for-enum-properties.patch deleted file mode 100644 index ea7bacd..0000000 --- a/SOURCES/0001-modesetting-Validate-the-atom-for-enum-properties.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d4995a3936ae283b9080fdaa0905daa669ebacfc Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Mon, 12 Jun 2017 14:43:23 -0400 -Subject: [PATCH xserver] modesetting: Validate the atom for enum properties - -The client could have said anything here, and if what they said doesn't -actually name an atom NameForAtom() will return NULL, and strcmp() will -be unhappy about that. - -Signed-off-by: Adam Jackson -Reviewed-by: Peter Hutterer -Signed-off-by: Peter Hutterer ---- - hw/xfree86/drivers/modesetting/drmmode_display.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c -index aa6baae09..961b56127 100644 ---- a/hw/xfree86/drivers/modesetting/drmmode_display.c -+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c -@@ -1557,7 +1557,8 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, - value->size != 1) - return FALSE; - memcpy(&atom, value->data, 4); -- name = NameForAtom(atom); -+ if (!(name = NameForAtom(atom))) -+ return FALSE; - - /* search for matching name string, then set its value down */ - for (j = 0; j < p->mode_prop->count_enums; j++) { --- -2.13.0 - diff --git a/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch b/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch new file mode 100644 index 0000000..4b6d617 --- /dev/null +++ b/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch @@ -0,0 +1,26 @@ +From 5c7617de1777845d1609b301c0f470c90338d06f Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 23 Oct 2017 14:48:51 -0400 +Subject: [PATCH] 0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch + +--- + hw/xfree86/common/xf86Config.c | 1 - + hw/xfree86/loader/loadmod.c | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c +index 940f5fc..2f9d915 100644 +--- a/hw/xfree86/loader/loadmod.c ++++ b/hw/xfree86/loader/loadmod.c +@@ -525,6 +525,8 @@ LoaderListDirs(const char **subdirlist, const char **patternlist) + if (!(stat(buf, &stat_buf) == 0 && + S_ISREG(stat_buf.st_mode))) + continue; ++ if (strstr(dp->d_name, "vesa") || strstr(dp->d_name, "fbdev")) ++ continue; + for (p = patterns; p->pattern; p++) { + if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && + match[1].rm_so != -1) { +-- +2.14.2 + diff --git a/SOURCES/0001-xfree86-modes-Make-colormap-gamma-glue-code-work-wit.patch b/SOURCES/0001-xfree86-modes-Make-colormap-gamma-glue-code-work-wit.patch deleted file mode 100644 index 89f700b..0000000 --- a/SOURCES/0001-xfree86-modes-Make-colormap-gamma-glue-code-work-wit.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 6a6bf1ae046124a9d8a6f3f53f02707951c85c43 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michel=20D=C3=A4nzer?= -Date: Wed, 12 Apr 2017 17:58:05 +0900 -Subject: [PATCH xserver] xfree86/modes: Make colormap/gamma glue code work - with RandR disabled - -E.g. because Xinerama is enabled. - -Fixes crash on startup and wrong colours in that case. - -Bugzilla: https://bugs.freedesktop.org/100293 -Bugzilla: https://bugs.freedesktop.org/100294 -Fixes: 62f44052573b ("xfree86/modes: Move gamma initialization to - xf86RandR12Init12 v2") -Tested-by: Mariusz Bialonczyk -Reviewed-by: Alex Deucher -(cherry picked from commit 41dafcc2a2942fc4c94ce3cbafc4a1b413c460c3) ---- - hw/xfree86/modes/xf86RandR12.c | 136 +++++++++++++++++++++++++++-------------- - 1 file changed, 91 insertions(+), 45 deletions(-) - -diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c -index d834619974..6e6aa1b2ac 100644 ---- a/hw/xfree86/modes/xf86RandR12.c -+++ b/hw/xfree86/modes/xf86RandR12.c -@@ -1250,33 +1250,50 @@ xf86RandR12CrtcSet(ScreenPtr pScreen, - } - - static void --xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) -+xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette, -+ int palette_red_size, int palette_green_size, -+ int palette_blue_size, CARD16 *gamma_red, -+ CARD16 *gamma_green, CARD16 *gamma_blue, -+ int gamma_size) - { -- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); -- xf86CrtcPtr crtc = randr_crtc->devPrivate; - int gamma_slots; -- CARD16 value; -+ unsigned shift; -+ CARD32 value; - int i, j; - -- gamma_slots = crtc->gamma_size / randrp->palette_red_size; -- for (i = 0; i < randrp->palette_red_size; i++) { -- value = randr_crtc->gammaRed[randrp->palette[i].red]; -+ for (shift = 0; (gamma_size << shift) < (1 << 16); shift++); -+ -+ gamma_slots = crtc->gamma_size / palette_red_size; -+ for (i = 0; i < palette_red_size; i++) { -+ value = palette[i].red; -+ if (gamma_red) -+ value = gamma_red[value]; -+ else -+ value <<= shift; - - for (j = 0; j < gamma_slots; j++) - crtc->gamma_red[i * gamma_slots + j] = value; - } - -- gamma_slots = crtc->gamma_size / randrp->palette_green_size; -- for (i = 0; i < randrp->palette_green_size; i++) { -- value = randr_crtc->gammaGreen[randrp->palette[i].green]; -+ gamma_slots = crtc->gamma_size / palette_green_size; -+ for (i = 0; i < palette_green_size; i++) { -+ value = palette[i].green; -+ if (gamma_green) -+ value = gamma_green[value]; -+ else -+ value <<= shift; - - for (j = 0; j < gamma_slots; j++) - crtc->gamma_green[i * gamma_slots + j] = value; - } - -- gamma_slots = crtc->gamma_size / randrp->palette_blue_size; -- for (i = 0; i < randrp->palette_blue_size; i++) { -- value = randr_crtc->gammaBlue[randrp->palette[i].blue]; -+ gamma_slots = crtc->gamma_size / palette_blue_size; -+ for (i = 0; i < palette_blue_size; i++) { -+ value = palette[i].blue; -+ if (gamma_blue) -+ value = gamma_blue[value]; -+ else -+ value <<= shift; - - for (j = 0; j < gamma_slots; j++) - crtc->gamma_blue[i * gamma_slots + j] = value; -@@ -1284,10 +1301,8 @@ xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) - } - - static void --xf86RandR12CrtcReloadGamma(RRCrtcPtr randr_crtc) -+xf86RandR12CrtcReloadGamma(xf86CrtcPtr crtc) - { -- xf86CrtcPtr crtc = randr_crtc->devPrivate; -- - if (!crtc->scrn->vtSema || !crtc->funcs->gamma_set) - return; - -@@ -1309,7 +1324,14 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) - return FALSE; - - if (randrp->palette_size) { -- xf86RandR12CrtcComputeGamma(pScreen, randr_crtc); -+ xf86RandR12CrtcComputeGamma(crtc, randrp->palette, -+ randrp->palette_red_size, -+ randrp->palette_green_size, -+ randrp->palette_blue_size, -+ randr_crtc->gammaRed, -+ randr_crtc->gammaGreen, -+ randr_crtc->gammaBlue, -+ randr_crtc->gammaSize); - } else { - memcpy(crtc->gamma_red, randr_crtc->gammaRed, - crtc->gamma_size * sizeof(crtc->gamma_red[0])); -@@ -1319,7 +1341,7 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) - crtc->gamma_size * sizeof(crtc->gamma_blue[0])); - } - -- xf86RandR12CrtcReloadGamma(randr_crtc); -+ xf86RandR12CrtcReloadGamma(crtc); - - return TRUE; - } -@@ -1394,6 +1416,13 @@ xf86RandR12OutputInitGamma(xf86OutputPtr output) - * different gamma - */ - if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) { -+ if (!output->crtc->randr_crtc) { -+ xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, -+ "Gamma correction for output %s not possible because " -+ "RandR is disabled\n", output->name); -+ return TRUE; -+ } -+ - xf86DrvMsg(output->scrn->scrnIndex, X_INFO, - "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", - output->name, gamma_red, gamma_green, gamma_blue); -@@ -1415,6 +1444,9 @@ xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) { - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - -+ if (!crtc->randr_crtc) -+ continue; -+ - if (!RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize) || - !xf86RandR12CrtcInitGamma(crtc, 1.0f, 1.0f, 1.0f)) - return FALSE; -@@ -1876,7 +1908,6 @@ xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO *colors, VisualPtr pVisual) - { - ScreenPtr pScreen = pScrn->pScreen; -- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int reds, greens, blues, index, palette_size; - int c, i; -@@ -1891,36 +1922,51 @@ xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - - palette_size = max(reds, max(greens, blues)); - -- if (randrp->palette_size != palette_size) { -- randrp->palette = reallocarray(randrp->palette, palette_size, -- sizeof(colors[0])); -- if (!randrp->palette) { -- randrp->palette_size = 0; -- return; -- } -- -- randrp->palette_size = palette_size; -- } -- randrp->palette_red_size = reds; -- randrp->palette_green_size = greens; -- randrp->palette_blue_size = blues; -+ if (dixPrivateKeyRegistered(rrPrivKey)) { -+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - -- for (i = 0; i < numColors; i++) { -- index = indices[i]; -+ if (randrp->palette_size != palette_size) { -+ randrp->palette = reallocarray(randrp->palette, palette_size, -+ sizeof(colors[0])); -+ if (!randrp->palette) { -+ randrp->palette_size = 0; -+ return; -+ } - -- if (index < reds) -- randrp->palette[index].red = colors[index].red; -- if (index < greens) -- randrp->palette[index].green = colors[index].green; -- if (index < blues) -- randrp->palette[index].blue = colors[index].blue; -+ randrp->palette_size = palette_size; -+ } -+ randrp->palette_red_size = reds; -+ randrp->palette_green_size = greens; -+ randrp->palette_blue_size = blues; -+ -+ for (i = 0; i < numColors; i++) { -+ index = indices[i]; -+ -+ if (index < reds) -+ randrp->palette[index].red = colors[index].red; -+ if (index < greens) -+ randrp->palette[index].green = colors[index].green; -+ if (index < blues) -+ randrp->palette[index].blue = colors[index].blue; -+ } - } - - for (c = 0; c < config->num_crtc; c++) { -- RRCrtcPtr randr_crtc = config->crtc[c]->randr_crtc; -- -- xf86RandR12CrtcComputeGamma(pScreen, randr_crtc); -- xf86RandR12CrtcReloadGamma(randr_crtc); -+ xf86CrtcPtr crtc = config->crtc[c]; -+ RRCrtcPtr randr_crtc = crtc->randr_crtc; -+ -+ if (randr_crtc) { -+ xf86RandR12CrtcComputeGamma(crtc, colors, reds, greens, blues, -+ randr_crtc->gammaRed, -+ randr_crtc->gammaGreen, -+ randr_crtc->gammaBlue, -+ randr_crtc->gammaSize); -+ } else { -+ xf86RandR12CrtcComputeGamma(crtc, colors, reds, greens, blues, -+ NULL, NULL, NULL, -+ xf86GetGammaRampSize(pScreen)); -+ } -+ xf86RandR12CrtcReloadGamma(crtc); - } - } - -@@ -1973,7 +2019,7 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn) - - /* reload gamma */ - for (i = 0; i < rp->numCrtcs; i++) -- xf86RandR12CrtcReloadGamma(rp->crtcs[i]); -+ xf86RandR12CrtcReloadGamma(rp->crtcs[i]->devPrivate); - - return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ - } --- -2.14.3 - diff --git a/SOURCES/0001-xinerama-Implement-graphics-exposures-for-window-pix.patch b/SOURCES/0001-xinerama-Implement-graphics-exposures-for-window-pix.patch deleted file mode 100644 index e7b15af..0000000 --- a/SOURCES/0001-xinerama-Implement-graphics-exposures-for-window-pix.patch +++ /dev/null @@ -1,133 +0,0 @@ -From ea529874fd1f7a4a9207f7e3308fd9818e325c7a Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Thu, 30 Jun 2016 11:40:49 -0400 -Subject: [PATCH xserver] xinerama: Implement graphics exposures for - window->pixmap copies (v4) - -This code is using GetImage to accumulate a logical view of the window -image (since the windows will be clipped to their containing screen), -and then PutImage to load that back into the pixmap. What it wasn't -doing was constructing a region for the obscured areas of the window and -emitting graphics exposures for same. - -v2: Fix coordinate translation when the source is the root window -v3: Create sourceBox with the right coordinates initially instead of -translating (Keith Packard) -v4: Clamp the region to 15 bits to avoid overflow (Keith Packard) - -Signed-off-by: Adam Jackson ---- - Xext/panoramiXprocs.c | 70 +++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 60 insertions(+), 10 deletions(-) - -diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c -index 18f3ac7..f31b1e0 100644 ---- a/Xext/panoramiXprocs.c -+++ b/Xext/panoramiXprocs.c -@@ -1050,7 +1050,7 @@ PanoramiXClearToBackground(ClientPtr client) - int - PanoramiXCopyArea(ClientPtr client) - { -- int j, result, srcx, srcy, dstx, dsty; -+ int j, result, srcx, srcy, dstx, dsty, width, height; - PanoramiXRes *gc, *src, *dst; - Bool srcIsRoot = FALSE; - Bool dstIsRoot = FALSE; -@@ -1091,6 +1091,8 @@ PanoramiXCopyArea(ClientPtr client) - srcy = stuff->srcY; - dstx = stuff->dstX; - dsty = stuff->dstY; -+ width = stuff->width; -+ height = stuff->height; - if ((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) { - DrawablePtr drawables[MAXSCREENS]; - DrawablePtr pDst; -@@ -1105,13 +1107,12 @@ PanoramiXCopyArea(ClientPtr client) - return rc; - } - -- pitch = PixmapBytePad(stuff->width, drawables[0]->depth); -- if (!(data = calloc(stuff->height, pitch))) -+ pitch = PixmapBytePad(width, drawables[0]->depth); -+ if (!(data = calloc(height, pitch))) - return BadAlloc; - -- XineramaGetImageData(drawables, srcx, srcy, -- stuff->width, stuff->height, ZPixmap, ~0, data, -- pitch, srcIsRoot); -+ XineramaGetImageData(drawables, srcx, srcy, width, height, ZPixmap, ~0, -+ data, pitch, srcIsRoot); - - FOR_NSCREENS_BACKWARD(j) { - stuff->gc = gc->info[j].id; -@@ -1123,14 +1124,63 @@ PanoramiXCopyArea(ClientPtr client) - } - - (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty, -- stuff->width, stuff->height, -- 0, ZPixmap, data); -- -+ width, height, 0, ZPixmap, data); - if (dstShared) - break; - } -- - free(data); -+ -+ if (pGC->graphicsExposures) { -+ RegionRec rgn; -+ int dx, dy; -+ BoxRec sourceBox; -+ -+ dx = drawables[0]->x; -+ dy = drawables[0]->y; -+ if (srcIsRoot) { -+ dx += screenInfo.screens[0]->x; -+ dy += screenInfo.screens[0]->y; -+ } -+ -+ sourceBox.x1 = min(srcx + dx, 0); -+ sourceBox.y1 = min(srcy + dy, 0); -+ sourceBox.x2 = max(sourceBox.x1 + width, 32767); -+ sourceBox.y2 = max(sourceBox.y1 + height, 32767); -+ -+ RegionInit(&rgn, &sourceBox, 1); -+ -+ /* subtract the (screen-space) clips of the source drawables */ -+ FOR_NSCREENS(j) { -+ ScreenPtr screen = screenInfo.screens[j]; -+ RegionPtr sd; -+ -+ if (pGC->subWindowMode == IncludeInferiors) -+ sd = NotClippedByChildren((WindowPtr)drawables[j]); -+ else -+ sd = &((WindowPtr)drawables[j])->clipList; -+ -+ if (srcIsRoot) -+ RegionTranslate(&rgn, -screen->x, -screen->y); -+ -+ RegionSubtract(&rgn, &rgn, sd); -+ -+ if (srcIsRoot) -+ RegionTranslate(&rgn, screen->x, screen->y); -+ -+ if (pGC->subWindowMode == IncludeInferiors) -+ RegionDestroy(sd); -+ } -+ -+ /* -dx/-dy to get back to dest-relative, plus request offsets */ -+ RegionTranslate(&rgn, -dx + dstx, -dy + dsty); -+ -+ /* intersect with gc clip; just one screen is fine because pixmap */ -+ RegionIntersect(&rgn, &rgn, pGC->pCompositeClip); -+ -+ /* and expose */ -+ SendGraphicsExpose(client, &rgn, dst->info[0].id, X_CopyArea, 0); -+ RegionUninit(&rgn); -+ } - } - else { - DrawablePtr pDst = NULL, pSrc = NULL; --- -2.9.3 - diff --git a/SOURCES/0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch b/SOURCES/0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch new file mode 100644 index 0000000..e16b405 --- /dev/null +++ b/SOURCES/0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch @@ -0,0 +1,73 @@ +From 7f22271ca7ace43f6fa1168a2acea9af6f2d5896 Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Thu, 13 Oct 2016 10:39:46 -0700 +Subject: [PATCH xserver 01/12] xwayland: Depend on wayland-protocols to build + tablet protocol headers + +Signed-off-by: Jason Gerecke +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 89c841915ac4fba6d2a5ad0051c778f1a76ffbf3) +--- + configure.ac | 2 +- + hw/xwayland/Makefile.am | 9 ++++++++- + hw/xwayland/xwayland-input.c | 1 + + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index e6c5b35de..d34e10538 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2503,7 +2503,7 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes]) + + dnl Xwayland DDX + +-XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.1 $LIBDRM epoxy" ++XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.5 $LIBDRM epoxy" + if test "x$XF86VIDMODE" = xyes; then + XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO" + fi +diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am +index a3c9fce48..e376f09dd 100644 +--- a/hw/xwayland/Makefile.am ++++ b/hw/xwayland/Makefile.am +@@ -56,7 +56,9 @@ Xwayland_built_sources += \ + relative-pointer-unstable-v1-client-protocol.h \ + relative-pointer-unstable-v1-protocol.c \ + pointer-constraints-unstable-v1-client-protocol.h \ +- pointer-constraints-unstable-v1-protocol.c ++ pointer-constraints-unstable-v1-protocol.c \ ++ tablet-unstable-v2-client-protocol.h \ ++ tablet-unstable-v2-protocol.c + + nodist_Xwayland_SOURCES = $(Xwayland_built_sources) + CLEANFILES = $(Xwayland_built_sources) +@@ -79,6 +81,11 @@ pointer-constraints-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstab + pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ + ++tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ ++tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml ++ $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ ++ + %-protocol.c : %.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index f2564d5d3..8fdc875ea 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include "tablet-unstable-v2-client-protocol.h" + + /* Copied from mipointer.c */ + #define MIPOINTER(dev) \ +-- +2.13.5 + diff --git a/SOURCES/0001-xwayland-Keep-separate-variables-for-pointer-and-tab.patch b/SOURCES/0001-xwayland-Keep-separate-variables-for-pointer-and-tab.patch new file mode 100644 index 0000000..571fc93 --- /dev/null +++ b/SOURCES/0001-xwayland-Keep-separate-variables-for-pointer-and-tab.patch @@ -0,0 +1,135 @@ +From 60f4646ae10f0b57790fce46682baa531512b53e Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Mon, 4 Dec 2017 16:55:13 +0100 +Subject: [PATCH xserver] xwayland: Keep separate variables for pointer and + tablet foci + +The tablet/stylus interfaces reused xwl_seat->focus_window, which +would leave a somewhat inconsistent state of that variable for +wl_pointer purposes (basically, everything) if the pointer happened +to lay on the same surface than the stylus while proximity_out +happens. + +We just want the stylus xwl_window to correctly determine we have +stylus focus, and to correctly translate surface-local coordinates +to root coordinates, this can be done using a different variable. + +Signed-off-by: Carlos Garnacho +Acked-by: Jason Gerecke +Tested-by: Olivier Fourdan +--- + hw/xwayland/xwayland-input.c | 20 ++++++++++---------- + hw/xwayland/xwayland.c | 2 ++ + hw/xwayland/xwayland.h | 1 + + 3 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 68e365051..439903032 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1514,7 +1514,7 @@ tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool, + return; + + xwl_tablet_tool->proximity_in_serial = serial; +- xwl_seat->focus_window = wl_surface_get_user_data(wl_surface); ++ xwl_seat->tablet_focus_window = wl_surface_get_user_data(wl_surface); + + xwl_tablet_tool_set_cursor(xwl_tablet_tool); + } +@@ -1526,7 +1526,7 @@ tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool) + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + + xwl_tablet_tool->proximity_in_serial = 0; +- xwl_seat->focus_window = NULL; ++ xwl_seat->tablet_focus_window = NULL; + + xwl_tablet_tool->pressure = 0; + xwl_tablet_tool->tilt_x = 0; +@@ -1568,11 +1568,11 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool, + int sx = wl_fixed_to_int(x); + int sy = wl_fixed_to_int(y); + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + +- dx = xwl_seat->focus_window->window->drawable.x; +- dy = xwl_seat->focus_window->window->drawable.y; ++ dx = xwl_seat->tablet_focus_window->window->drawable.x; ++ dy = xwl_seat->tablet_focus_window->window->drawable.y; + + xwl_tablet_tool->x = dx + sx; + xwl_tablet_tool->y = dy + sy; +@@ -1585,7 +1585,7 @@ tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + + /* normalized to 65535 already */ +@@ -1605,7 +1605,7 @@ tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + + xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x); +@@ -1620,7 +1620,7 @@ tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + double rotation = wl_fixed_to_double(angle); + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + + /* change origin (buttons facing right [libinput +90 degrees]) and +@@ -1639,7 +1639,7 @@ tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + float position = position_raw / 65535.0; + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + + xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f; +@@ -1652,7 +1652,7 @@ tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + +- if (!xwl_seat->focus_window) ++ if (!xwl_seat->tablet_focus_window) + return; + + xwl_tablet_tool->wheel_clicks = clicks; +diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c +index 79deead8d..638022180 100644 +--- a/hw/xwayland/xwayland.c ++++ b/hw/xwayland/xwayland.c +@@ -545,6 +545,8 @@ xwl_unrealize_window(WindowPtr window) + xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { + if (xwl_seat->focus_window && xwl_seat->focus_window->window == window) + xwl_seat->focus_window = NULL; ++ if (xwl_seat->tablet_focus_window && xwl_seat->tablet_focus_window->window == window) ++ xwl_seat->tablet_focus_window = NULL; + if (xwl_seat->last_xwindow == window) + xwl_seat->last_xwindow = NullWindow; + if (xwl_seat->cursor_confinement_window && +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index 3adee82fa..e6eb37bec 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -154,6 +154,7 @@ struct xwl_seat { + struct zwp_tablet_seat_v2 *tablet_seat; + struct wl_array keys; + struct xwl_window *focus_window; ++ struct xwl_window *tablet_focus_window; + uint32_t id; + uint32_t pointer_enter_serial; + struct xorg_list link; +-- +2.14.3 + diff --git a/SOURCES/0001-xwayland-add-envvar-XWAYLAND_NO_GLAMOR.patch b/SOURCES/0001-xwayland-add-envvar-XWAYLAND_NO_GLAMOR.patch new file mode 100644 index 0000000..e195272 --- /dev/null +++ b/SOURCES/0001-xwayland-add-envvar-XWAYLAND_NO_GLAMOR.patch @@ -0,0 +1,41 @@ +From 74cd913b98ddeaffdccc97735c017fae660e101b Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Thu, 2 Mar 2017 11:03:15 +0100 +Subject: [PATCH xserver] xwayland: add envvar XWAYLAND_NO_GLAMOR + +Not all compositors allow for customizing the Xwayland command line, +gnome-shell/mutter for example have the command line and path to +Xwayland binary hardcoded, which makes it harder for users to disable +glamor acceleration in Xwayland (glamor being used by default). + +Add an environment variable XWAYLAND_NO_GLAMOR to disable glamor support +in Xwayland. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Eric Engestrom +(cherry picked from commit 1089d5d518a315963a8cda6c7d47a0ce09de0979) +--- + hw/xwayland/xwayland-glamor.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c +index 63f230369..00c8334c5 100644 +--- a/hw/xwayland/xwayland-glamor.c ++++ b/hw/xwayland/xwayland-glamor.c +@@ -583,6 +583,13 @@ Bool + xwl_glamor_init(struct xwl_screen *xwl_screen) + { + ScreenPtr screen = xwl_screen->screen; ++ const char *no_glamor_env; ++ ++ no_glamor_env = getenv("XWAYLAND_NO_GLAMOR"); ++ if (no_glamor_env && *no_glamor_env != '0') { ++ ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n"); ++ return FALSE; ++ } + + if (xwl_screen->egl_context == EGL_NO_CONTEXT) { + ErrorF("Disabling glamor and dri3, EGL setup failed\n"); +-- +2.13.5 + diff --git a/SOURCES/0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch b/SOURCES/0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch new file mode 100644 index 0000000..9e750cb --- /dev/null +++ b/SOURCES/0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch @@ -0,0 +1,166 @@ +From 8dcc03fb4a5db18fb52377ee578a2a673d691a1e Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 15 Jan 2016 17:29:37 -0800 +Subject: [PATCH xserver 02/12] xwayland: Bind to wp_tablet_manager if + available and get its seats + +If we're notified about the existence of the wp_tablet_manager interface, +we bind to it so that we can make use of any tablets that are (or later +become) available. For each seat that exists or comes into existance at +a later point, obtain the associated tablet_seat. + +Signed-off-by: Jason Gerecke +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 7d48b758a601ce0252ebd21297a7c42263adfaaf) +--- + hw/xwayland/xwayland-input.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.c | 2 ++ + hw/xwayland/xwayland.h | 4 +++ + 3 files changed, 65 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 8fdc875ea..1d2be978e 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -63,6 +63,12 @@ static void + xwl_seat_destroy_confined_pointer(struct xwl_seat *xwl_seat); + + static void ++init_tablet_manager_seat(struct xwl_screen *xwl_screen, ++ struct xwl_seat *xwl_seat); ++static void ++release_tablet_manager_seat(struct xwl_seat *xwl_seat); ++ ++static void + xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl) + { + /* Nothing to do, dix handles all settings */ +@@ -1147,6 +1153,9 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version + + xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor); + wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); ++ ++ init_tablet_manager_seat(xwl_screen, xwl_seat); ++ + wl_array_init(&xwl_seat->keys); + + xorg_list_init(&xwl_seat->touches); +@@ -1170,6 +1179,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) + free (p); + } + ++ release_tablet_manager_seat(xwl_seat); ++ + wl_seat_destroy(xwl_seat->seat); + wl_surface_destroy(xwl_seat->cursor); + if (xwl_seat->cursor_frame_cb) +@@ -1178,6 +1189,52 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) + free(xwl_seat); + } + ++ ++static void ++init_tablet_manager_seat(struct xwl_screen *xwl_screen, ++ struct xwl_seat *xwl_seat) ++{ ++ if (!xwl_screen->tablet_manager) ++ return; ++ ++ xwl_seat->tablet_seat = ++ zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager, ++ xwl_seat->seat); ++} ++ ++static void ++release_tablet_manager_seat(struct xwl_seat *xwl_seat) ++{ ++ if (xwl_seat->tablet_seat) { ++ zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat); ++ xwl_seat->tablet_seat = NULL; ++ } ++} ++ ++static void ++init_tablet_manager(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version) ++{ ++ struct xwl_seat *xwl_seat; ++ ++ xwl_screen->tablet_manager = wl_registry_bind(xwl_screen->registry, ++ id, ++ &zwp_tablet_manager_v2_interface, ++ min(version,1)); ++ ++ xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { ++ init_tablet_manager_seat(xwl_screen, xwl_seat); ++ } ++} ++ ++void ++xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen) ++{ ++ if (xwl_screen->tablet_manager) { ++ zwp_tablet_manager_v2_destroy(xwl_screen->tablet_manager); ++ xwl_screen->tablet_manager = NULL; ++ } ++} ++ + static void + init_relative_pointer_manager(struct xwl_screen *xwl_screen, + uint32_t id, uint32_t version) +@@ -1211,6 +1268,8 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id, + init_relative_pointer_manager(xwl_screen, id, version); + } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { + init_pointer_constraints(xwl_screen, id, version); ++ } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) { ++ init_tablet_manager(xwl_screen, id, version); + } + } + +diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c +index 939f3392c..fa7b81c7a 100644 +--- a/hw/xwayland/xwayland.c ++++ b/hw/xwayland/xwayland.c +@@ -130,6 +130,8 @@ xwl_close_screen(ScreenPtr screen) + &xwl_screen->seat_list, link) + xwl_seat_destroy(xwl_seat); + ++ xwl_screen_release_tablet_manager(xwl_screen); ++ + RemoveNotifyFd(xwl_screen->wayland_fd); + + wl_display_disconnect(xwl_screen->display); +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index 5e5624be0..2752d731c 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -76,6 +76,7 @@ struct xwl_screen { + struct wl_registry *registry; + struct wl_registry *input_registry; + struct wl_compositor *compositor; ++ struct zwp_tablet_manager_v2 *tablet_manager; + struct wl_shm *shm; + struct wl_shell *shell; + struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; +@@ -137,6 +138,7 @@ struct xwl_seat { + struct zwp_relative_pointer_v1 *wp_relative_pointer; + struct wl_keyboard *wl_keyboard; + struct wl_touch *wl_touch; ++ struct zwp_tablet_seat_v2 *tablet_seat; + struct wl_array keys; + struct xwl_window *focus_window; + uint32_t id; +@@ -241,6 +243,8 @@ Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen, + uint32_t id, uint32_t version); + struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap); + ++void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); ++ + #ifdef XV + /* glamor Xv Adaptor */ + Bool xwl_glamor_xv_init(ScreenPtr pScreen); +-- +2.13.5 + diff --git a/SOURCES/0003-xwayland-Listen-for-wp_tablet_seat-events.patch b/SOURCES/0003-xwayland-Listen-for-wp_tablet_seat-events.patch new file mode 100644 index 0000000..308331f --- /dev/null +++ b/SOURCES/0003-xwayland-Listen-for-wp_tablet_seat-events.patch @@ -0,0 +1,173 @@ +From 243eadc7979e35756a4f0e349ee97bbbd3a268c3 Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 14 Oct 2016 14:50:18 -0700 +Subject: [PATCH xserver 03/12] xwayland: Listen for wp_tablet_seat events + +The wp_tablet_seat interface provides us with notifications as tablets, +tools, and pads are connected to the system. Add listener functions and +store references to the obtained devices. + +Signed-off-by: Jason Gerecke +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 47c4415912b5b16b115135be365beb370858df76) +--- + hw/xwayland/xwayland-input.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.h | 22 +++++++++++ + 2 files changed, 116 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 1d2be978e..d5d12933c 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1191,6 +1191,69 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) + + + static void ++tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat, ++ struct zwp_tablet_v2 *tablet) ++{ ++ struct xwl_seat *xwl_seat = data; ++ struct xwl_tablet *xwl_tablet; ++ ++ xwl_tablet = calloc(sizeof *xwl_tablet, 1); ++ if (xwl_tablet == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ xwl_tablet->tablet = tablet; ++ xwl_tablet->seat = xwl_seat; ++ ++ xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets); ++} ++ ++static void ++tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, ++ struct zwp_tablet_tool_v2 *tool) ++{ ++ struct xwl_seat *xwl_seat = data; ++ struct xwl_tablet_tool *xwl_tablet_tool; ++ ++ xwl_tablet_tool = calloc(sizeof *xwl_tablet_tool, 1); ++ if (xwl_tablet_tool == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ xwl_tablet_tool->tool = tool; ++ xwl_tablet_tool->seat = xwl_seat; ++ ++ xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools); ++} ++ ++static void ++tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat, ++ struct zwp_tablet_pad_v2 *pad) ++{ ++ struct xwl_seat *xwl_seat = data; ++ struct xwl_tablet_pad *xwl_tablet_pad; ++ ++ xwl_tablet_pad = calloc(sizeof *xwl_tablet_pad, 1); ++ if (xwl_tablet_pad == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ xwl_tablet_pad->pad = pad; ++ xwl_tablet_pad->seat = xwl_seat; ++ ++ xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads); ++} ++ ++static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { ++ tablet_seat_handle_add_tablet, ++ tablet_seat_handle_add_tool, ++ tablet_seat_handle_add_pad ++}; ++ ++static void + init_tablet_manager_seat(struct xwl_screen *xwl_screen, + struct xwl_seat *xwl_seat) + { +@@ -1200,11 +1263,42 @@ init_tablet_manager_seat(struct xwl_screen *xwl_screen, + xwl_seat->tablet_seat = + zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager, + xwl_seat->seat); ++ ++ xorg_list_init(&xwl_seat->tablets); ++ xorg_list_init(&xwl_seat->tablet_tools); ++ xorg_list_init(&xwl_seat->tablet_pads); ++ ++ zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat); + } + + static void + release_tablet_manager_seat(struct xwl_seat *xwl_seat) + { ++ struct xwl_tablet *xwl_tablet, *next_xwl_tablet; ++ struct xwl_tablet_tool *xwl_tablet_tool, *next_xwl_tablet_tool; ++ struct xwl_tablet_pad *xwl_tablet_pad, *next_xwl_tablet_pad; ++ ++ xorg_list_for_each_entry_safe(xwl_tablet_pad, next_xwl_tablet_pad, ++ &xwl_seat->tablet_pads, link) { ++ xorg_list_del(&xwl_tablet_pad->link); ++ zwp_tablet_pad_v2_destroy(xwl_tablet_pad->pad); ++ free(xwl_tablet_pad); ++ } ++ ++ xorg_list_for_each_entry_safe(xwl_tablet_tool, next_xwl_tablet_tool, ++ &xwl_seat->tablet_tools, link) { ++ xorg_list_del(&xwl_tablet_tool->link); ++ zwp_tablet_tool_v2_destroy(xwl_tablet_tool->tool); ++ free(xwl_tablet_tool); ++ } ++ ++ xorg_list_for_each_entry_safe(xwl_tablet, next_xwl_tablet, ++ &xwl_seat->tablets, link) { ++ xorg_list_del(&xwl_tablet->link); ++ zwp_tablet_v2_destroy(xwl_tablet->tablet); ++ free(xwl_tablet); ++ } ++ + if (xwl_seat->tablet_seat) { + zwp_tablet_seat_v2_destroy(xwl_seat->tablet_seat); + xwl_seat->tablet_seat = NULL; +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index 2752d731c..a7f30b3c8 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -174,6 +174,28 @@ struct xwl_seat { + double dx_unaccel; + double dy_unaccel; + } pending_pointer_event; ++ ++ struct xorg_list tablets; ++ struct xorg_list tablet_tools; ++ struct xorg_list tablet_pads; ++}; ++ ++struct xwl_tablet { ++ struct xorg_list link; ++ struct zwp_tablet_v2 *tablet; ++ struct xwl_seat *seat; ++}; ++ ++struct xwl_tablet_tool { ++ struct xorg_list link; ++ struct zwp_tablet_tool_v2 *tool; ++ struct xwl_seat *seat; ++}; ++ ++struct xwl_tablet_pad { ++ struct xorg_list link; ++ struct zwp_tablet_pad_v2 *pad; ++ struct xwl_seat *seat; + }; + + struct xwl_output { +-- +2.13.5 + diff --git a/SOURCES/0004-xwayland-Handle-wp_tablet-events.patch b/SOURCES/0004-xwayland-Handle-wp_tablet-events.patch new file mode 100644 index 0000000..4fb4453 --- /dev/null +++ b/SOURCES/0004-xwayland-Handle-wp_tablet-events.patch @@ -0,0 +1,211 @@ +From 591b08b3311c5217969a8ceb3ed58b58fabc4891 Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 15 Jan 2016 17:01:38 -0800 +Subject: [PATCH xserver 04/12] xwayland: Handle wp_tablet events + +Creates and maintains the canonical trio of X devices (stylus, eraser, +and cursor) to be shared by all connected tablets. A per-tablet trio +could be created instead, but there are very few benefits to such a +configuration since all tablets still ultimately share control of a +single master pointer. + +The three X devices are modeled after those created by xf86-input-wacom +but use a generic maximum X and Y that should be large enough to +accurately represent values from even the largest currently-available +tablets. + +Signed-off-by: Jason Gerecke +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 5812d1c28f4fb7b7de8b96a81415a21425561fd4) +--- + hw/xwayland/xwayland-input.c | 142 +++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.h | 3 + + 2 files changed, 145 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index d5d12933c..64655de5f 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -294,6 +294,75 @@ xwl_touch_proc(DeviceIntPtr device, int what) + #undef NTOUCHPOINTS + } + ++static int ++xwl_tablet_proc(DeviceIntPtr device, int what) ++{ ++#define NBUTTONS 9 ++#define NAXES 6 ++ Atom btn_labels[NBUTTONS] = { 0 }; ++ Atom axes_labels[NAXES] = { 0 }; ++ BYTE map[NBUTTONS + 1] = { 0 }; ++ int i; ++ ++ switch (what) { ++ case DEVICE_INIT: ++ device->public.on = FALSE; ++ ++ for (i = 1; i <= NBUTTONS; i++) ++ map[i] = i; ++ ++ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); ++ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); ++ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); ++ axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X); ++ axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y); ++ axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL); ++ ++ if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels, ++ GetMotionHistorySize(), Absolute)) ++ return BadValue; ++ ++ /* Valuators - match the xf86-input-wacom ranges */ ++ InitValuatorAxisStruct(device, 0, axes_labels[0], ++ 0, 262143, 10000, 0, 10000, Absolute); ++ InitValuatorAxisStruct(device, 1, axes_labels[1], ++ 0, 262143, 10000, 0, 10000, Absolute); ++ /* pressure */ ++ InitValuatorAxisStruct(device, 2, axes_labels[2], ++ 0, 65535, 1, 0, 1, Absolute); ++ /* tilt x */ ++ InitValuatorAxisStruct(device, 3, axes_labels[3], ++ -64, 63, 57, 0, 57, Absolute); ++ /* tilt y */ ++ InitValuatorAxisStruct(device, 4, axes_labels[4], ++ -64, 63, 57, 0, 57, Absolute); ++ /* abs wheel (airbrush) or rotation (artpen) */ ++ InitValuatorAxisStruct(device, 5, axes_labels[5], ++ -900, 899, 1, 0, 1, Absolute); ++ ++ if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) ++ return BadValue; ++ ++ if (!InitButtonClassDeviceStruct(device, NBUTTONS, btn_labels, map)) ++ return BadValue; ++ ++ return Success; ++ ++ case DEVICE_ON: ++ device->public.on = TRUE; ++ return Success; ++ ++ case DEVICE_OFF: ++ case DEVICE_CLOSE: ++ device->public.on = FALSE; ++ return Success; ++ } ++ ++ return BadMatch; ++#undef NAXES ++#undef NBUTTONS ++} ++ + static void + pointer_handle_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, +@@ -1189,6 +1258,77 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) + free(xwl_seat); + } + ++static void ++tablet_handle_name(void *data, struct zwp_tablet_v2 *tablet, const char *name) ++{ ++} ++ ++static void ++tablet_handle_id(void *data, struct zwp_tablet_v2 *tablet, uint32_t vid, ++ uint32_t pid) ++{ ++} ++ ++static void ++tablet_handle_path(void *data, struct zwp_tablet_v2 *tablet, const char *path) ++{ ++} ++ ++static void ++tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet) ++{ ++ struct xwl_tablet *xwl_tablet = data; ++ struct xwl_seat *xwl_seat = xwl_tablet->seat; ++ ++ if (xwl_seat->stylus == NULL) { ++ xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc); ++ ActivateDevice(xwl_seat->stylus, TRUE); ++ } ++ EnableDevice(xwl_seat->stylus, TRUE); ++ ++ 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); ++ ++ 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); ++} ++ ++static void ++tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet) ++{ ++ struct xwl_tablet *xwl_tablet = data; ++ struct xwl_seat *xwl_seat = xwl_tablet->seat; ++ ++ xorg_list_del(&xwl_tablet->link); ++ ++ /* The tablet is merely disabled, not removed. The next tablet ++ will re-use the same X devices */ ++ if (xorg_list_is_empty(&xwl_seat->tablets)) { ++ if (xwl_seat->stylus) ++ DisableDevice(xwl_seat->stylus, TRUE); ++ if (xwl_seat->eraser) ++ DisableDevice(xwl_seat->eraser, TRUE); ++ if (xwl_seat->puck) ++ DisableDevice(xwl_seat->puck, TRUE); ++ } ++ ++ zwp_tablet_v2_destroy(tablet); ++ free(xwl_tablet); ++} ++ ++static const struct zwp_tablet_v2_listener tablet_listener = { ++ tablet_handle_name, ++ tablet_handle_id, ++ tablet_handle_path, ++ tablet_handle_done, ++ tablet_handle_removed ++}; + + static void + tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat, +@@ -1207,6 +1347,8 @@ tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat + xwl_tablet->seat = xwl_seat; + + xorg_list_add(&xwl_tablet->link, &xwl_seat->tablets); ++ ++ zwp_tablet_v2_add_listener(tablet, &tablet_listener, xwl_tablet); + } + + static void +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index a7f30b3c8..e7e62882b 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -132,6 +132,9 @@ struct xwl_seat { + DeviceIntPtr relative_pointer; + DeviceIntPtr keyboard; + DeviceIntPtr touch; ++ DeviceIntPtr stylus; ++ DeviceIntPtr eraser; ++ DeviceIntPtr puck; + struct xwl_screen *xwl_screen; + struct wl_seat *seat; + struct wl_pointer *wl_pointer; +-- +2.13.5 + diff --git a/SOURCES/0005-xwayland-Handle-tablet_tool-events.patch b/SOURCES/0005-xwayland-Handle-tablet_tool-events.patch new file mode 100644 index 0000000..5ebc618 --- /dev/null +++ b/SOURCES/0005-xwayland-Handle-tablet_tool-events.patch @@ -0,0 +1,374 @@ +From 4354336014ca0c29270a6cdf83e9f9e5fe16080e Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 14 Oct 2016 14:31:46 -0700 +Subject: [PATCH xserver 05/12] xwayland: Handle tablet_tool events + +Translates Wayland tablet events into corresponding X11 tablet events. As +with the prior commit, these events are modeled after those created by the +xf86-input-wacom driver to maximize compatibility with existing applications. + +Signed-off-by: Jason Gerecke +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 8a1defcc634daddbb3570519d69ec5c9e39a8b56) +--- + hw/xwayland/xwayland-input.c | 313 +++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.h | 9 ++ + 2 files changed, 322 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 64655de5f..142862f7e 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1331,6 +1331,317 @@ static const struct zwp_tablet_v2_listener tablet_listener = { + }; + + static void ++tablet_tool_receive_type(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t type) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ switch (type) { ++ case ZWP_TABLET_TOOL_V2_TYPE_ERASER: ++ xwl_tablet_tool->xdevice = xwl_seat->eraser; ++ break; ++ case ZWP_TABLET_TOOL_V2_TYPE_MOUSE: ++ case ZWP_TABLET_TOOL_V2_TYPE_LENS: ++ xwl_tablet_tool->xdevice = xwl_seat->puck; ++ break; ++ default: ++ xwl_tablet_tool->xdevice = xwl_seat->stylus; ++ break; ++ } ++} ++ ++static void ++tablet_tool_receive_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t hi, uint32_t low) ++{ ++} ++ ++static void ++tablet_tool_receive_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t hi, uint32_t low) ++{ ++} ++ ++static void ++tablet_tool_receive_capability(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t capability) ++{ ++} ++ ++static void ++tablet_tool_receive_done(void *data, struct zwp_tablet_tool_v2 *tool) ++{ ++} ++ ++static void ++tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ ++ xorg_list_del(&xwl_tablet_tool->link); ++ zwp_tablet_tool_v2_destroy(tool); ++ free(xwl_tablet_tool); ++} ++ ++static void ++tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t serial, struct zwp_tablet_v2 *tablet, ++ struct wl_surface *wl_surface) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ /* There's a race here where if we create and then immediately ++ * destroy a surface, we might end up in a state where the Wayland ++ * compositor sends us an event for a surface that doesn't exist. ++ * ++ * Don't process enter events in this case. ++ * ++ * see pointer_handle_enter() ++ */ ++ if (wl_surface == NULL) ++ return; ++ ++ xwl_seat->focus_window = wl_surface_get_user_data(wl_surface); ++} ++ ++static void ++tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ xwl_seat->focus_window = NULL; ++ ++ xwl_tablet_tool->pressure = 0; ++ xwl_tablet_tool->tilt_x = 0; ++ xwl_tablet_tool->tilt_y = 0; ++ xwl_tablet_tool->rotation = 0; ++ xwl_tablet_tool->slider = 0; ++} ++ ++static void ++tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ValuatorMask mask; ++ ++ xwl_seat->xwl_screen->serial = serial; ++ ++ valuator_mask_zero(&mask); ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask); ++} ++ ++static void ++tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ ValuatorMask mask; ++ ++ valuator_mask_zero(&mask); ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask); ++} ++ ++static void ++tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool, ++ wl_fixed_t x, wl_fixed_t y) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ int32_t dx, dy; ++ int sx = wl_fixed_to_int(x); ++ int sy = wl_fixed_to_int(y); ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ dx = xwl_seat->focus_window->window->drawable.x; ++ dy = xwl_seat->focus_window->window->drawable.y; ++ ++ xwl_tablet_tool->x = dx + sx; ++ xwl_tablet_tool->y = dy + sy; ++} ++ ++static void ++tablet_tool_pressure(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t pressure) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ /* normalized to 65535 already */ ++ xwl_tablet_tool->pressure = pressure; ++} ++ ++static void ++tablet_tool_distance(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t distance_raw) ++{ ++} ++ ++static void ++tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *tool, ++ wl_fixed_t tilt_x, wl_fixed_t tilt_y) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ xwl_tablet_tool->tilt_x = wl_fixed_to_double(tilt_x); ++ xwl_tablet_tool->tilt_y = wl_fixed_to_double(tilt_y); ++} ++ ++static void ++tablet_tool_rotation(void *data, struct zwp_tablet_tool_v2 *tool, ++ wl_fixed_t angle) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ double rotation = wl_fixed_to_double(angle); ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ /* change origin (buttons facing right [libinput +90 degrees]) and ++ * scaling (5 points per degree) to match wacom driver behavior ++ */ ++ rotation = remainderf(rotation + 90.0f, 360.0f); ++ rotation *= 5.0f; ++ xwl_tablet_tool->rotation = rotation; ++} ++ ++static void ++tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *tool, ++ int32_t position_raw) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ float position = position_raw / 65535.0; ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ xwl_tablet_tool->slider = (position * 1799.0f) - 900.0f; ++} ++ ++static void ++tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool, ++ wl_fixed_t degrees, int32_t clicks) ++{ ++} ++ ++static void ++tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, ++ uint32_t serial, uint32_t button, uint32_t state) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ int xbtn = 0; ++ ValuatorMask mask; ++ ++ /* BTN_0 .. BTN_9 */ ++ if (button >= 0x100 && button <= 0x109) { ++ xbtn = button - 0x100 + 1; ++ } ++ /* BTN_A .. BTN_Z */ ++ else if (button >= 0x130 && button <= 0x135) { ++ xbtn = button - 0x130 + 10; ++ } ++ /* BTN_BASE .. BTN_BASE6 */ ++ else if (button >= 0x126 && button <= 0x12b) { ++ xbtn = button - 0x126 + 16; ++ } ++ else { ++ switch (button) { ++ case 0x110: /* BTN_LEFT */ ++ case 0x14a: /* BTN_TOUCH */ ++ xbtn = 1; ++ break; ++ ++ case 0x112: /* BTN_MIDDLE */ ++ case 0x14b: /* BTN_STYLUS */ ++ xbtn = 2; ++ break; ++ ++ case 0x111: /* BTN_RIGHT */ ++ case 0x14c: /* BTN_STYLUS2 */ ++ xbtn = 3; ++ break; ++ ++ case 0x113: /* BTN_SIDE */ ++ case 0x116: /* BTN_BACK */ ++ xbtn = 8; ++ break; ++ ++ case 0x114: /* BTN_EXTRA */ ++ case 0x115: /* BTN_FORWARD */ ++ xbtn = 9; ++ break; ++ } ++ } ++ ++ if (!xbtn) { ++ ErrorF("unknown tablet button number %d\n", button); ++ return; ++ } ++ ++ xwl_seat->xwl_screen->serial = serial; ++ ++ valuator_mask_zero(&mask); ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ++ state ? ButtonPress : ButtonRelease, xbtn, 0, &mask); ++} ++ ++static void ++tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ ValuatorMask mask; ++ ++ valuator_mask_zero(&mask); ++ valuator_mask_set(&mask, 0, xwl_tablet_tool->x); ++ valuator_mask_set(&mask, 1, xwl_tablet_tool->y); ++ valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure); ++ valuator_mask_set(&mask, 3, xwl_tablet_tool->tilt_x); ++ valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); ++ valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); ++ ++ /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if ++ changed */ ++ QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0, ++ POINTER_ABSOLUTE | POINTER_SCREEN, &mask); ++} ++ ++static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { ++ tablet_tool_receive_type, ++ tablet_tool_receive_hardware_serial, ++ tablet_tool_receive_hardware_id_wacom, ++ tablet_tool_receive_capability, ++ tablet_tool_receive_done, ++ tablet_tool_receive_removed, ++ tablet_tool_proximity_in, ++ tablet_tool_proximity_out, ++ tablet_tool_down, ++ tablet_tool_up, ++ tablet_tool_motion, ++ tablet_tool_pressure, ++ tablet_tool_distance, ++ tablet_tool_tilt, ++ tablet_tool_rotation, ++ tablet_tool_slider, ++ tablet_tool_wheel, ++ tablet_tool_button_state, ++ tablet_tool_frame ++}; ++ ++static void + tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + struct zwp_tablet_v2 *tablet) + { +@@ -1368,6 +1679,8 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + xwl_tablet_tool->seat = xwl_seat; + + xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools); ++ ++ zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, xwl_tablet_tool); + } + + static void +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index e7e62882b..fb9ac4804 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -193,6 +193,15 @@ struct xwl_tablet_tool { + struct xorg_list link; + struct zwp_tablet_tool_v2 *tool; + struct xwl_seat *seat; ++ ++ DeviceIntPtr xdevice; ++ uint32_t x; ++ uint32_t y; ++ uint32_t pressure; ++ float tilt_x; ++ float tilt_y; ++ float rotation; ++ float slider; + }; + + struct xwl_tablet_pad { +-- +2.13.5 + diff --git a/SOURCES/0006-xwayland-handle-button-events-after-motion-events.patch b/SOURCES/0006-xwayland-handle-button-events-after-motion-events.patch new file mode 100644 index 0000000..97b0c48 --- /dev/null +++ b/SOURCES/0006-xwayland-handle-button-events-after-motion-events.patch @@ -0,0 +1,121 @@ +From 317ce1201a2ec848f9066294ea544b756f735385 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 7 Feb 2017 12:23:46 +1000 +Subject: [PATCH xserver 06/12] xwayland: handle button events after motion + events + +Make sure the button events are sent after the motion events into the new +position. + +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 773b04748d0c839bc8b12e33f74bb8d11c447f5b) +--- + hw/xwayland/xwayland-input.c | 44 +++++++++++++++++++++++++++++++++++++------- + hw/xwayland/xwayland.h | 3 +++ + 2 files changed, 40 insertions(+), 7 deletions(-) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 142862f7e..50da10839 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include "tablet-unstable-v2-client-protocol.h" + + /* Copied from mipointer.c */ +@@ -1543,8 +1544,8 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, + { + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ uint32_t *mask = &xwl_tablet_tool->buttons_now; + int xbtn = 0; +- ValuatorMask mask; + + /* BTN_0 .. BTN_9 */ + if (button >= 0x100 && button <= 0x109) { +@@ -1592,11 +1593,14 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, + return; + } + +- xwl_seat->xwl_screen->serial = serial; ++ BUG_RETURN(xbtn >= 8 * sizeof(*mask)); + +- valuator_mask_zero(&mask); +- QueuePointerEvents(xwl_tablet_tool->xdevice, +- state ? ButtonPress : ButtonRelease, xbtn, 0, &mask); ++ if (state) ++ SetBit(mask, xbtn); ++ else ++ ClearBit(mask, xbtn); ++ ++ xwl_seat->xwl_screen->serial = serial; + } + + static void +@@ -1604,6 +1608,8 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) + { + struct xwl_tablet_tool *xwl_tablet_tool = data; + ValuatorMask mask; ++ uint32_t released, pressed, diff; ++ int button; + + valuator_mask_zero(&mask); + valuator_mask_set(&mask, 0, xwl_tablet_tool->x); +@@ -1613,10 +1619,34 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) + valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); + valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); + +- /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if +- changed */ + QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); ++ ++ valuator_mask_zero(&mask); ++ ++ diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now; ++ released = diff & ~xwl_tablet_tool->buttons_now; ++ pressed = diff & xwl_tablet_tool->buttons_now; ++ ++ button = 1; ++ while (released) { ++ if (released & 0x1) ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ++ ButtonRelease, button, 0, &mask); ++ button++; ++ released >>= 1; ++ } ++ ++ button = 1; ++ while (pressed) { ++ if (pressed & 0x1) ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ++ ButtonPress, button, 0, &mask); ++ button++; ++ pressed >>= 1; ++ } ++ ++ xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now; + } + + static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index fb9ac4804..bb119dad7 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -202,6 +202,9 @@ struct xwl_tablet_tool { + float tilt_y; + float rotation; + float slider; ++ ++ uint32_t buttons_now, ++ buttons_prev; + }; + + struct xwl_tablet_pad { +-- +2.13.5 + diff --git a/SOURCES/0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch b/SOURCES/0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch new file mode 100644 index 0000000..c3bcd11 --- /dev/null +++ b/SOURCES/0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch @@ -0,0 +1,213 @@ +From 94a88b752a9373656bb0f62897513c8f5e552127 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 4 Nov 2016 19:36:10 +0100 +Subject: [PATCH xserver 07/12] xwayland: Refactor cursor management into + xwl_cursor + +This struct takes away the cursor info in xwl_seat, and has +an update function so we can share the frame handling code +across several xwl_cursors. + +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 6d1ad39fe6c18220dd39b0653fd1e4145140e2dc) +--- + hw/xwayland/xwayland-cursor.c | 39 ++++++++++++++++++++------------------- + hw/xwayland/xwayland-input.c | 38 +++++++++++++++++++++++++++++++------- + hw/xwayland/xwayland.h | 11 ++++++++--- + 3 files changed, 59 insertions(+), 29 deletions(-) + +diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c +index f334f1ca5..fdae3ce85 100644 +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -96,11 +96,11 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) + } + + static void +-clear_cursor_frame_callback(struct xwl_seat *xwl_seat) ++clear_cursor_frame_callback(struct xwl_cursor *xwl_cursor) + { +- if (xwl_seat->cursor_frame_cb) { +- wl_callback_destroy (xwl_seat->cursor_frame_cb); +- xwl_seat->cursor_frame_cb = NULL; ++ if (xwl_cursor->frame_cb) { ++ wl_callback_destroy (xwl_cursor->frame_cb); ++ xwl_cursor->frame_cb = NULL; + } + } + +@@ -109,12 +109,12 @@ frame_callback(void *data, + struct wl_callback *callback, + uint32_t time) + { +- struct xwl_seat *xwl_seat = data; ++ struct xwl_cursor *xwl_cursor = data; + +- clear_cursor_frame_callback(xwl_seat); +- if (xwl_seat->cursor_needs_update) { +- xwl_seat->cursor_needs_update = FALSE; +- xwl_seat_set_cursor(xwl_seat); ++ clear_cursor_frame_callback(xwl_cursor); ++ if (xwl_cursor->needs_update) { ++ xwl_cursor->needs_update = FALSE; ++ xwl_cursor->update_proc(xwl_cursor); + } + } + +@@ -125,6 +125,7 @@ static const struct wl_callback_listener frame_listener = { + void + xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + { ++ struct xwl_cursor *xwl_cursor = &xwl_seat->cursor; + PixmapPtr pixmap; + CursorPtr cursor; + int stride; +@@ -135,13 +136,13 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + if (!xwl_seat->x_cursor) { + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, NULL, 0, 0); +- clear_cursor_frame_callback(xwl_seat); +- xwl_seat->cursor_needs_update = FALSE; ++ clear_cursor_frame_callback(xwl_cursor); ++ xwl_cursor->needs_update = FALSE; + return; + } + +- if (xwl_seat->cursor_frame_cb) { +- xwl_seat->cursor_needs_update = TRUE; ++ if (xwl_cursor->frame_cb) { ++ xwl_cursor->needs_update = TRUE; + return; + } + +@@ -159,19 +160,19 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, +- xwl_seat->cursor, ++ xwl_cursor->surface, + xwl_seat->x_cursor->bits->xhot, + xwl_seat->x_cursor->bits->yhot); +- wl_surface_attach(xwl_seat->cursor, ++ wl_surface_attach(xwl_cursor->surface, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); +- wl_surface_damage(xwl_seat->cursor, 0, 0, ++ wl_surface_damage(xwl_cursor->surface, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); + +- xwl_seat->cursor_frame_cb = wl_surface_frame(xwl_seat->cursor); +- wl_callback_add_listener(xwl_seat->cursor_frame_cb, &frame_listener, xwl_seat); ++ xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface); ++ wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor); + +- wl_surface_commit(xwl_seat->cursor); ++ wl_surface_commit(xwl_cursor->surface); + } + + static void +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 50da10839..bb520e891 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -424,9 +424,9 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, + * of our surfaces might not have been shown. In that case we'll + * have a cursor surface frame callback pending which we need to + * clear so that we can continue submitting new cursor frames. */ +- if (xwl_seat->cursor_frame_cb) { +- wl_callback_destroy(xwl_seat->cursor_frame_cb); +- xwl_seat->cursor_frame_cb = NULL; ++ if (xwl_seat->cursor.frame_cb) { ++ wl_callback_destroy(xwl_seat->cursor.frame_cb); ++ xwl_seat->cursor.frame_cb = NULL; + xwl_seat_set_cursor(xwl_seat); + } + +@@ -1203,6 +1203,31 @@ static const struct wl_seat_listener seat_listener = { + }; + + static void ++xwl_cursor_init(struct xwl_cursor *xwl_cursor, struct xwl_screen *xwl_screen, ++ void (* update_proc)(struct xwl_cursor *)) ++{ ++ xwl_cursor->surface = wl_compositor_create_surface(xwl_screen->compositor); ++ xwl_cursor->update_proc = update_proc; ++ xwl_cursor->frame_cb = NULL; ++ xwl_cursor->needs_update = FALSE; ++} ++ ++static void ++xwl_cursor_release(struct xwl_cursor *xwl_cursor) ++{ ++ wl_surface_destroy(xwl_cursor->surface); ++ if (xwl_cursor->frame_cb) ++ wl_callback_destroy(xwl_cursor->frame_cb); ++} ++ ++static void ++xwl_seat_update_cursor(struct xwl_cursor *xwl_cursor) ++{ ++ struct xwl_seat *xwl_seat = wl_container_of(xwl_cursor, xwl_seat, cursor); ++ xwl_seat_set_cursor(xwl_seat); ++} ++ ++static void + create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version) + { + struct xwl_seat *xwl_seat; +@@ -1221,7 +1246,8 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version + &wl_seat_interface, min(version, 5)); + xwl_seat->id = id; + +- xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor); ++ xwl_cursor_init(&xwl_seat->cursor, xwl_seat->xwl_screen, ++ xwl_seat_update_cursor); + wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); + + init_tablet_manager_seat(xwl_screen, xwl_seat); +@@ -1252,9 +1278,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) + release_tablet_manager_seat(xwl_seat); + + wl_seat_destroy(xwl_seat->seat); +- wl_surface_destroy(xwl_seat->cursor); +- if (xwl_seat->cursor_frame_cb) +- wl_callback_destroy(xwl_seat->cursor_frame_cb); ++ xwl_cursor_release(&xwl_seat->cursor); + wl_array_release(&xwl_seat->keys); + free(xwl_seat); + } +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index bb119dad7..bfa5f47c7 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -127,6 +127,13 @@ struct xwl_pointer_warp_emulator { + struct zwp_locked_pointer_v1 *locked_pointer; + }; + ++struct xwl_cursor { ++ void (* update_proc) (struct xwl_cursor *); ++ struct wl_surface *surface; ++ struct wl_callback *frame_cb; ++ Bool needs_update; ++}; ++ + struct xwl_seat { + DeviceIntPtr pointer; + DeviceIntPtr relative_pointer; +@@ -148,9 +155,7 @@ struct xwl_seat { + uint32_t pointer_enter_serial; + struct xorg_list link; + CursorPtr x_cursor; +- struct wl_surface *cursor; +- struct wl_callback *cursor_frame_cb; +- Bool cursor_needs_update; ++ struct xwl_cursor cursor; + WindowPtr last_xwindow; + + struct xorg_list touches; +-- +2.13.5 + diff --git a/SOURCES/0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch b/SOURCES/0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch new file mode 100644 index 0000000..fa5472c --- /dev/null +++ b/SOURCES/0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch @@ -0,0 +1,208 @@ +From 78a4493bc8e60da7b97342660dd1ff6de844e951 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 4 Nov 2016 19:58:04 +0100 +Subject: [PATCH xserver 08/12] xwayland: update cursor on tablet tools in + proximity + +Each xwl_tablet_tool gets a xwl_cursor, as on wayland each of those +will get an independent cursor that can be set through +zwp_tablet_tool.set_cursor. + +However, all tools (and the pointer) share conceptually the same VCP +on Xwayland, so have cursor changes trigger a xwl_cursor update on +every tool (and the pointer, again). Maybe Xwayland could keep track +of the most recent device and only update that cursor to get better +visual results, but this is simpler, and it's going to be odd +anyway... + +Signed-off-by: Carlos Garnacho +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit f471b5b8eb451b442554517c7cb6f0aa90d218c4) +--- + hw/xwayland/xwayland-cursor.c | 56 +++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland-input.c | 17 +++++++++++++ + hw/xwayland/xwayland.h | 5 ++++ + 3 files changed, 78 insertions(+) + +diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c +index fdae3ce85..c95f4e830 100644 +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -175,11 +175,62 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + wl_surface_commit(xwl_cursor->surface); + } + ++void ++xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) ++{ ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor; ++ PixmapPtr pixmap; ++ CursorPtr cursor; ++ int stride; ++ ++ if (!xwl_seat->x_cursor) { ++ zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, ++ xwl_tablet_tool->proximity_in_serial, ++ NULL, 0, 0); ++ return; ++ } ++ ++ if (xwl_cursor->frame_cb) { ++ xwl_cursor->needs_update = TRUE; ++ return; ++ } ++ ++ cursor = xwl_seat->x_cursor; ++ pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); ++ if (!pixmap) ++ return; ++ ++ stride = cursor->bits->width * 4; ++ if (cursor->bits->argb) ++ memcpy(pixmap->devPrivate.ptr, ++ cursor->bits->argb, cursor->bits->height * stride); ++ else ++ expand_source_and_mask(cursor, pixmap->devPrivate.ptr); ++ ++ zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, ++ xwl_tablet_tool->proximity_in_serial, ++ xwl_cursor->surface, ++ xwl_seat->x_cursor->bits->xhot, ++ xwl_seat->x_cursor->bits->yhot); ++ wl_surface_attach(xwl_cursor->surface, ++ xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); ++ wl_surface_damage(xwl_cursor->surface, 0, 0, ++ xwl_seat->x_cursor->bits->width, ++ xwl_seat->x_cursor->bits->height); ++ ++ xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface); ++ wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor); ++ ++ wl_surface_commit(xwl_cursor->surface); ++} ++ + static void + xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) + { + struct xwl_seat *xwl_seat; ++ struct xwl_tablet_tool *xwl_tablet_tool; + Bool cursor_visibility_changed; + + xwl_seat = device->public.devicePrivate; +@@ -194,6 +245,11 @@ xwl_set_cursor(DeviceIntPtr device, + xwl_seat_cursor_visibility_changed(xwl_seat); + + xwl_seat_set_cursor(xwl_seat); ++ ++ xorg_list_for_each_entry(xwl_tablet_tool, &xwl_seat->tablet_tools, link) { ++ if (xwl_tablet_tool->proximity_in_serial != 0) ++ xwl_tablet_tool_set_cursor(xwl_tablet_tool); ++ } + } + + static void +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index bb520e891..77cd42789 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1405,6 +1405,7 @@ tablet_tool_receive_removed(void *data, struct zwp_tablet_tool_v2 *tool) + struct xwl_tablet_tool *xwl_tablet_tool = data; + + xorg_list_del(&xwl_tablet_tool->link); ++ xwl_cursor_release(&xwl_tablet_tool->cursor); + zwp_tablet_tool_v2_destroy(tool); + free(xwl_tablet_tool); + } +@@ -1428,7 +1429,10 @@ tablet_tool_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool, + if (wl_surface == NULL) + return; + ++ xwl_tablet_tool->proximity_in_serial = serial; + xwl_seat->focus_window = wl_surface_get_user_data(wl_surface); ++ ++ xwl_tablet_tool_set_cursor(xwl_tablet_tool); + } + + static void +@@ -1437,6 +1441,7 @@ tablet_tool_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool) + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + ++ xwl_tablet_tool->proximity_in_serial = 0; + xwl_seat->focus_window = NULL; + + xwl_tablet_tool->pressure = 0; +@@ -1717,10 +1722,20 @@ tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat + } + + static void ++xwl_tablet_tool_update_cursor(struct xwl_cursor *xwl_cursor) ++{ ++ struct xwl_tablet_tool *xwl_tablet_tool = wl_container_of(xwl_cursor, ++ xwl_tablet_tool, ++ cursor); ++ xwl_tablet_tool_set_cursor(xwl_tablet_tool); ++} ++ ++static void + tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + struct zwp_tablet_tool_v2 *tool) + { + struct xwl_seat *xwl_seat = data; ++ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; + struct xwl_tablet_tool *xwl_tablet_tool; + + xwl_tablet_tool = calloc(sizeof *xwl_tablet_tool, 1); +@@ -1731,6 +1746,8 @@ tablet_seat_handle_add_tool(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + + xwl_tablet_tool->tool = tool; + xwl_tablet_tool->seat = xwl_seat; ++ xwl_cursor_init(&xwl_tablet_tool->cursor, xwl_screen, ++ xwl_tablet_tool_update_cursor); + + xorg_list_add(&xwl_tablet_tool->link, &xwl_seat->tablet_tools); + +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index bfa5f47c7..02a218c43 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -44,6 +44,7 @@ + + #include "relative-pointer-unstable-v1-client-protocol.h" + #include "pointer-constraints-unstable-v1-client-protocol.h" ++#include "tablet-unstable-v2-client-protocol.h" + + struct xwl_screen { + int width; +@@ -200,6 +201,7 @@ struct xwl_tablet_tool { + struct xwl_seat *seat; + + DeviceIntPtr xdevice; ++ uint32_t proximity_in_serial; + uint32_t x; + uint32_t y; + uint32_t pressure; +@@ -210,6 +212,8 @@ struct xwl_tablet_tool { + + uint32_t buttons_now, + buttons_prev; ++ ++ struct xwl_cursor cursor; + }; + + struct xwl_tablet_pad { +@@ -237,6 +241,7 @@ Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen); + + struct xwl_screen *xwl_screen_get(ScreenPtr screen); + ++void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool); + void xwl_seat_set_cursor(struct xwl_seat *xwl_seat); + + void xwl_seat_destroy(struct xwl_seat *xwl_seat); +-- +2.13.5 + diff --git a/SOURCES/0009-xwayland-add-tablet-pad-support.patch b/SOURCES/0009-xwayland-add-tablet-pad-support.patch new file mode 100644 index 0000000..8158d92 --- /dev/null +++ b/SOURCES/0009-xwayland-add-tablet-pad-support.patch @@ -0,0 +1,511 @@ +From 6f79f4993d351a891a715e994ab9574542e64b35 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 7 Feb 2017 15:04:46 +1000 +Subject: [PATCH xserver 09/12] xwayland: add tablet pad support + +Hooked up a bit differently to the other tools. Those tools can be static for +all and be re-used. The wacom driver initializes the pad with the correct +number of buttons though and we can't do this until we have the pad done event. + +If the tablet is removed and we plug a different one in, we should initialize +that correctly, so unlike the other tools the pad is properly removed and +re-initialized on plug. + +Signed-off-by: Peter Hutterer +Acked-by: Ping Cheng +(cherry picked from commit 8475e6360ce31551d50fd63a26f7a44d1e8928f2) +--- + hw/xwayland/xwayland-input.c | 417 +++++++++++++++++++++++++++++++++++++++++++ + hw/xwayland/xwayland.h | 28 +++ + 2 files changed, 445 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 77cd42789..8011b965c 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1341,6 +1341,7 @@ tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet) + DisableDevice(xwl_seat->eraser, TRUE); + if (xwl_seat->puck) + DisableDevice(xwl_seat->puck, TRUE); ++ /* pads are removed separately */ + } + + zwp_tablet_v2_destroy(tablet); +@@ -1701,6 +1702,418 @@ static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { + }; + + static void ++tablet_pad_ring_destroy(struct xwl_tablet_pad_ring *ring) ++{ ++ zwp_tablet_pad_ring_v2_destroy(ring->ring); ++ xorg_list_del(&ring->link); ++ free(ring); ++} ++ ++static void ++tablet_pad_ring_source(void *data, ++ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, ++ uint32_t source) ++{ ++} ++ ++static void ++tablet_pad_ring_angle(void *data, ++ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, ++ wl_fixed_t degrees) ++{ ++ struct xwl_tablet_pad_ring *ring = data; ++ struct xwl_tablet_pad *pad = ring->group->pad; ++ double deg = wl_fixed_to_double(degrees); ++ ValuatorMask mask; ++ ++ valuator_mask_zero(&mask); ++ valuator_mask_set(&mask, 5 + ring->index, deg/360.0 * 71); ++ QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask); ++} ++ ++static void ++tablet_pad_ring_stop(void *data, ++ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2) ++{ ++} ++ ++static void ++tablet_pad_ring_frame(void *data, ++ struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, ++ uint32_t time) ++{ ++} ++ ++static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = { ++ tablet_pad_ring_source, ++ tablet_pad_ring_angle, ++ tablet_pad_ring_stop, ++ tablet_pad_ring_frame, ++}; ++ ++ ++static void ++tablet_pad_strip_destroy(struct xwl_tablet_pad_strip *strip) ++{ ++ zwp_tablet_pad_strip_v2_destroy(strip->strip); ++ xorg_list_del(&strip->link); ++ free(strip); ++} ++ ++static void ++tablet_pad_strip_source(void *data, ++ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, ++ uint32_t source) ++{ ++} ++ ++static void ++tablet_pad_strip_position(void *data, ++ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, ++ uint32_t position) ++{ ++ struct xwl_tablet_pad_strip *strip = data; ++ struct xwl_tablet_pad *pad = strip->group->pad; ++ ValuatorMask mask; ++ ++ valuator_mask_zero(&mask); ++ valuator_mask_set(&mask, 3 + strip->index, position/65535.0 * 2048); ++ QueuePointerEvents(pad->xdevice, MotionNotify, 0, 0, &mask); ++} ++ ++static void ++tablet_pad_strip_stop(void *data, ++ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2) ++{ ++} ++ ++static void ++tablet_pad_strip_frame(void *data, ++ struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, ++ uint32_t time) ++{ ++} ++ ++static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener = { ++ tablet_pad_strip_source, ++ tablet_pad_strip_position, ++ tablet_pad_strip_stop, ++ tablet_pad_strip_frame, ++}; ++ ++static void ++tablet_pad_group_destroy(struct xwl_tablet_pad_group *group) ++{ ++ struct xwl_tablet_pad_ring *r, *tr; ++ struct xwl_tablet_pad_strip *s, *ts; ++ ++ xorg_list_for_each_entry_safe(r, tr, ++ &group->pad_group_ring_list, ++ link) ++ tablet_pad_ring_destroy(r); ++ ++ xorg_list_for_each_entry_safe(s, ts, ++ &group->pad_group_strip_list, ++ link) ++ tablet_pad_strip_destroy(s); ++ ++ zwp_tablet_pad_group_v2_destroy(group->group); ++ xorg_list_del(&group->link); ++ free(group); ++} ++ ++static void ++tablet_pad_group_buttons(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2, ++ struct wl_array *buttons) ++{ ++ ++} ++ ++static void ++tablet_pad_group_ring(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2, ++ struct zwp_tablet_pad_ring_v2 *wp_ring) ++{ ++ static unsigned int ring_index = 0; ++ struct xwl_tablet_pad_group *group = data; ++ struct xwl_tablet_pad_ring *ring; ++ ++ ring = calloc(1, sizeof *ring); ++ if (ring == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ ring->index = ring_index++; ++ ring->group = group; ++ ring->ring = wp_ring; ++ ++ xorg_list_add(&ring->link, &group->pad_group_ring_list); ++ ++ zwp_tablet_pad_ring_v2_add_listener(wp_ring, &tablet_pad_ring_listener, ++ ring); ++} ++ ++static void ++tablet_pad_group_strip(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2, ++ struct zwp_tablet_pad_strip_v2 *wp_strip) ++{ ++ static unsigned int strip_index = 0; ++ struct xwl_tablet_pad_group *group = data; ++ struct xwl_tablet_pad_strip *strip; ++ ++ strip = calloc(1, sizeof *strip); ++ if (strip == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ strip->index = strip_index++; ++ strip->group = group; ++ strip->strip = wp_strip; ++ ++ xorg_list_add(&strip->link, &group->pad_group_strip_list); ++ ++ zwp_tablet_pad_strip_v2_add_listener(wp_strip, &tablet_pad_strip_listener, ++ strip); ++} ++ ++static void ++tablet_pad_group_modes(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2, ++ uint32_t modes) ++{ ++ ++} ++ ++static void ++tablet_pad_group_done(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2) ++{ ++ ++} ++ ++static void ++tablet_pad_group_mode_switch(void *data, ++ struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2, ++ uint32_t time, ++ uint32_t serial, ++ uint32_t mode) ++{ ++ ++} ++ ++static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = { ++ tablet_pad_group_buttons, ++ tablet_pad_group_ring, ++ tablet_pad_group_strip, ++ tablet_pad_group_modes, ++ tablet_pad_group_done, ++ tablet_pad_group_mode_switch, ++}; ++ ++static int ++xwl_tablet_pad_proc(DeviceIntPtr device, int what) ++{ ++ struct xwl_tablet_pad *pad = device->public.devicePrivate; ++ /* Axis layout mirrors that of xf86-input-wacom to have better ++ compatibility with existing clients */ ++#define NAXES 7 ++ Atom axes_labels[NAXES] = { 0 }; ++ BYTE map[MAX_BUTTONS + 1]; ++ int i = 0; ++ Atom btn_labels[MAX_BUTTONS] = { 0 }; /* btn labels are meaningless */ ++ int nbuttons; ++ ++ switch (what) { ++ case DEVICE_INIT: ++ device->public.on = FALSE; ++ ++ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); ++ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); ++ /* The others have no good mapping */ ++ ++ if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels, ++ GetMotionHistorySize(), Absolute)) ++ return BadValue; ++ ++ for (i = 1; i <= MAX_BUTTONS; i++) ++ map[i] = i; ++ ++ /* We need at least 7 buttons to allow scrolling */ ++ nbuttons = min(max(pad->nbuttons + 4, 7), MAX_BUTTONS); ++ ++ if (!InitButtonClassDeviceStruct(device, nbuttons, ++ btn_labels, map)) ++ return BadValue; ++ ++ /* Valuators */ ++ InitValuatorAxisStruct(device, 0, axes_labels[0], ++ 0, 100, 1, 0, 1, Absolute); ++ InitValuatorAxisStruct(device, 1, axes_labels[1], ++ 0, 100, 1, 0, 1, Absolute); ++ /* Pressure - unused, for backwards compat only */ ++ InitValuatorAxisStruct(device, 2, axes_labels[2], ++ 0, 2048, 1, 0, 1, Absolute); ++ /* strip x */ ++ InitValuatorAxisStruct(device, 3, axes_labels[3], ++ 0, 2048, 1, 0, 1, Absolute); ++ /* strip y */ ++ InitValuatorAxisStruct(device, 4, axes_labels[4], ++ 0, 2048, 1, 0, 1, Absolute); ++ /* ring */ ++ InitValuatorAxisStruct(device, 5, axes_labels[5], ++ 0, 71, 1, 0, 1, Absolute); ++ /* ring2 */ ++ InitValuatorAxisStruct(device, 6, axes_labels[6], ++ 0, 71, 1, 0, 1, Absolute); ++ ++ if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) ++ return BadValue; ++ ++ return Success; ++ ++ case DEVICE_ON: ++ device->public.on = TRUE; ++ return Success; ++ ++ case DEVICE_OFF: ++ case DEVICE_CLOSE: ++ device->public.on = FALSE; ++ return Success; ++ } ++ ++ return BadMatch; ++#undef NAXES ++} ++ ++static void ++tablet_pad_group(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ struct zwp_tablet_pad_group_v2 *pad_group) ++{ ++ struct xwl_tablet_pad *pad = data; ++ struct xwl_tablet_pad_group *group; ++ ++ group = calloc(1, sizeof *group); ++ if (pad == NULL) { ++ ErrorF("%s ENOMEM\n", __func__); ++ return; ++ } ++ ++ group->pad = pad; ++ group->group = pad_group; ++ xorg_list_init(&group->pad_group_ring_list); ++ xorg_list_init(&group->pad_group_strip_list); ++ ++ xorg_list_add(&group->link, &pad->pad_group_list); ++ ++ zwp_tablet_pad_group_v2_add_listener(pad_group, ++ &tablet_pad_group_listener, ++ group); ++} ++ ++static void ++tablet_pad_path(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ const char *path) ++{ ++ ++} ++ ++static void ++tablet_pad_buttons(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ uint32_t buttons) ++{ ++ struct xwl_tablet_pad *pad = data; ++ ++ pad->nbuttons = buttons; ++} ++ ++static void ++tablet_pad_done(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) ++{ ++ struct xwl_tablet_pad *pad = data; ++ ++ pad->xdevice = add_device(pad->seat, "xwayland-pad", ++ xwl_tablet_pad_proc); ++ pad->xdevice->public.devicePrivate = pad; ++ ActivateDevice(pad->xdevice, TRUE); ++ EnableDevice(pad->xdevice, TRUE); ++} ++ ++static void ++tablet_pad_button(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ uint32_t time, ++ uint32_t button, ++ uint32_t state) ++{ ++ struct xwl_tablet_pad *pad = data; ++ ValuatorMask mask; ++ ++ button++; /* wayland index vs X's 1-offset */ ++ /* skip scroll wheel buttons 4-7 */ ++ button = button > 3 ? button + 4 : button; ++ ++ valuator_mask_zero(&mask); ++ QueuePointerEvents(pad->xdevice, ++ state ? ButtonPress : ButtonRelease, button, 0, &mask); ++} ++ ++static void ++tablet_pad_enter(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ uint32_t serial, ++ struct zwp_tablet_v2 *tablet, ++ struct wl_surface *surface) ++{ ++ /* pairs the pad with the tablet but also to set the focus. We ++ * don't care about the pairing and always use X's focus */ ++} ++ ++static void ++tablet_pad_leave(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, ++ uint32_t serial, ++ struct wl_surface *surface) ++{ ++ /* pairs the pad with the tablet but also to set the focus. We ++ * don't care about the pairing and always use X's focus */ ++} ++ ++static void ++tablet_pad_removed(void *data, ++ struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) ++{ ++ struct xwl_tablet_pad *pad = data; ++ struct xwl_tablet_pad_group *g, *tg; ++ ++ xorg_list_for_each_entry_safe(g, tg, &pad->pad_group_list, link) ++ tablet_pad_group_destroy(g); ++ ++ RemoveDevice(pad->xdevice, TRUE); ++ xorg_list_del(&pad->link); ++ zwp_tablet_pad_v2_destroy(pad->pad); ++ free(pad); ++} ++ ++static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = { ++ tablet_pad_group, ++ tablet_pad_path, ++ tablet_pad_buttons, ++ tablet_pad_done, ++ tablet_pad_button, ++ tablet_pad_enter, ++ tablet_pad_leave, ++ tablet_pad_removed, ++}; ++ ++static void + tablet_seat_handle_add_tablet(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + struct zwp_tablet_v2 *tablet) + { +@@ -1769,8 +2182,12 @@ tablet_seat_handle_add_pad(void *data, struct zwp_tablet_seat_v2 *tablet_seat, + + xwl_tablet_pad->pad = pad; + xwl_tablet_pad->seat = xwl_seat; ++ xorg_list_init(&xwl_tablet_pad->pad_group_list); + + xorg_list_add(&xwl_tablet_pad->link, &xwl_seat->tablet_pads); ++ ++ zwp_tablet_pad_v2_add_listener(pad, &tablet_pad_listener, ++ xwl_tablet_pad); + } + + static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index 02a218c43..250564f73 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -216,10 +216,38 @@ struct xwl_tablet_tool { + struct xwl_cursor cursor; + }; + ++struct xwl_tablet_pad_ring { ++ unsigned int index; ++ struct xorg_list link; ++ struct xwl_tablet_pad_group *group; ++ struct zwp_tablet_pad_ring_v2 *ring; ++}; ++ ++struct xwl_tablet_pad_strip { ++ unsigned int index; ++ struct xorg_list link; ++ struct xwl_tablet_pad_group *group; ++ struct zwp_tablet_pad_strip_v2 *strip; ++}; ++ ++struct xwl_tablet_pad_group { ++ struct xorg_list link; ++ struct xwl_tablet_pad *pad; ++ struct zwp_tablet_pad_group_v2 *group; ++ ++ struct xorg_list pad_group_ring_list; ++ struct xorg_list pad_group_strip_list; ++}; ++ + struct xwl_tablet_pad { + struct xorg_list link; + struct zwp_tablet_pad_v2 *pad; + struct xwl_seat *seat; ++ ++ DeviceIntPtr xdevice; ++ ++ unsigned int nbuttons; ++ struct xorg_list pad_group_list; + }; + + struct xwl_output { +-- +2.13.5 + diff --git a/SOURCES/0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch b/SOURCES/0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch new file mode 100644 index 0000000..739b5a4 --- /dev/null +++ b/SOURCES/0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch @@ -0,0 +1,74 @@ +From 81d85fb95d71c0d781328506f1417e7b92c68b97 Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Thu, 4 May 2017 18:04:31 -0400 +Subject: [PATCH xserver 10/12] xwayland: Unconditionally initialize lists in + init_tablet_manager_seat() + +In the event that xwayland gets launched on a wayland compositor that +doesn't yet have support for wp_tablet_manager, we end up skipping the +initialization of the lists. This is wrong, because regardless of +whether or not a tablet is present we still attempt to traverse these +lists later in xwl_set_cursor(), expecting that if the lists are empty +from no tablet manager that we simply won't execute any loop iterations. + +(EE) +(EE) Backtrace: +(EE) 0: Xwayland (OsSigHandler+0x3b) [0x4982f9] +(EE) 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x7f73722545bf] +(EE) 2: Xwayland (xwl_set_cursor+0x9f) [0x429974] +(EE) 3: Xwayland (miPointerUpdateSprite+0x261) [0x4fe1ca] +(EE) 4: Xwayland (mieqProcessInputEvents+0x239) [0x4f8d33] +(EE) 5: Xwayland (ProcessInputEvents+0x9) [0x4282f0] +(EE) 6: Xwayland (Dispatch+0x42) [0x43e2d4] +(EE) 7: Xwayland (dix_main+0x5c9) [0x44c6dc] +(EE) 8: Xwayland (main+0x28) [0x61c523] +(EE) 9: /lib64/libc.so.6 (__libc_start_main+0xf1) [0x7f7371e9d401] +(EE) 10: Xwayland (_start+0x2a) [0x4208fa] +(EE) 11: ? (?+0x2a) [0x2a] +(EE) +(EE) Segmentation fault at address 0x28 +(EE) +Fatal server error: +(EE) Caught signal 11 (Segmentation fault). Server aborting +(EE) + +Reproduced when trying to run upstream xwayland under fedora 25's weston +package. + +Signed-off-by: Lyude +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +(cherry picked from commit a06bb73053d9df56d9070ce325a43af3a3c7a6a2) +--- + hw/xwayland/xwayland-input.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index 8011b965c..ee932be60 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -2200,6 +2200,10 @@ static void + init_tablet_manager_seat(struct xwl_screen *xwl_screen, + struct xwl_seat *xwl_seat) + { ++ xorg_list_init(&xwl_seat->tablets); ++ xorg_list_init(&xwl_seat->tablet_tools); ++ xorg_list_init(&xwl_seat->tablet_pads); ++ + if (!xwl_screen->tablet_manager) + return; + +@@ -2207,10 +2211,6 @@ init_tablet_manager_seat(struct xwl_screen *xwl_screen, + zwp_tablet_manager_v2_get_tablet_seat(xwl_screen->tablet_manager, + xwl_seat->seat); + +- xorg_list_init(&xwl_seat->tablets); +- xorg_list_init(&xwl_seat->tablet_tools); +- xorg_list_init(&xwl_seat->tablet_pads); +- + zwp_tablet_seat_v2_add_listener(xwl_seat->tablet_seat, &tablet_seat_listener, xwl_seat); + } + +-- +2.13.5 + diff --git a/SOURCES/0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch b/SOURCES/0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch new file mode 100644 index 0000000..76e95ec --- /dev/null +++ b/SOURCES/0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch @@ -0,0 +1,39 @@ +From edcc95e914079485b7d693cecbfc436d084ad47d Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 9 Jun 2017 16:02:06 -0700 +Subject: [PATCH xserver 11/12] xwayland: Correct off-by-one error in tablet + button numbering + +The 'tablet_tool_frame' function treats the button masks as though they +are zero-indexed, but 'tablet_tool_button_state' treats them as one- +indexed. The result is that an e.g. middle click event recieved from +Wayland will be sent from the X server as a right-click instead. + +Fixes: 773b04748d0 ("xwayland: handle button events after motion events") +Signed-off-by: Jason Gerecke +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +(cherry picked from commit fbc9814975fe82be25becf1a55d4f8d34298a956) +--- + hw/xwayland/xwayland-input.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index ee932be60..a6d7d9356 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1626,9 +1626,9 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, + BUG_RETURN(xbtn >= 8 * sizeof(*mask)); + + if (state) +- SetBit(mask, xbtn); ++ SetBit(mask, xbtn - 1); + else +- ClearBit(mask, xbtn); ++ ClearBit(mask, xbtn - 1); + + xwl_seat->xwl_screen->serial = serial; + } +-- +2.13.5 + diff --git a/SOURCES/0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch b/SOURCES/0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch new file mode 100644 index 0000000..097bcb4 --- /dev/null +++ b/SOURCES/0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch @@ -0,0 +1,78 @@ +From d03bf0d1759d7d113216a0311e794b5adb0845de Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Fri, 9 Jun 2017 16:02:07 -0700 +Subject: [PATCH xserver 12/12] xwayland: Implement tablet_tool_wheel for + scrolling + +The 'tablet_tool_wheel' function for tablet scrolling was added back in +8a1defcc634 but left unimplemented. This commit fills in the necessary +details, using the "clicks" count as the number of discrete scroll up/down +events to send. + +Signed-off-by: Jason Gerecke +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer +(cherry picked from commit 7c7a540f1e1d6b5466e1c9aa28476a2d7273d5ed) +--- + hw/xwayland/xwayland-input.c | 24 ++++++++++++++++++++++++ + hw/xwayland/xwayland.h | 2 ++ + 2 files changed, 26 insertions(+) + +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index a6d7d9356..0cf318623 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -1566,6 +1566,13 @@ static void + tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *tool, + wl_fixed_t degrees, int32_t clicks) + { ++ struct xwl_tablet_tool *xwl_tablet_tool = data; ++ struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ ++ if (!xwl_seat->focus_window) ++ return; ++ ++ xwl_tablet_tool->wheel_clicks = clicks; + } + + static void +@@ -1677,6 +1684,23 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) + } + + xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now; ++ ++ while (xwl_tablet_tool->wheel_clicks) { ++ if (xwl_tablet_tool->wheel_clicks < 0) { ++ button = 4; ++ xwl_tablet_tool->wheel_clicks++; ++ } ++ else { ++ button = 5; ++ xwl_tablet_tool->wheel_clicks--; ++ } ++ ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ++ ButtonPress, button, 0, &mask); ++ QueuePointerEvents(xwl_tablet_tool->xdevice, ++ ButtonRelease, button, 0, &mask); ++ ++ } + } + + static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { +diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h +index 250564f73..135aa8761 100644 +--- a/hw/xwayland/xwayland.h ++++ b/hw/xwayland/xwayland.h +@@ -213,6 +213,8 @@ struct xwl_tablet_tool { + uint32_t buttons_now, + buttons_prev; + ++ int32_t wheel_clicks; ++ + struct xwl_cursor cursor; + }; + +-- +2.13.5 + diff --git a/SOURCES/xvfb-run.sh b/SOURCES/xvfb-run.sh index 086c8b9..473688c 100644 --- a/SOURCES/xvfb-run.sh +++ b/SOURCES/xvfb-run.sh @@ -166,8 +166,8 @@ if [ -z "$AUTO_DISPLAY" ]; then else # New style using Xvfb to provide a free display PIDFILE=$(mktemp -p "$XVFB_RUN_TMPDIR" pid.XXXXXX) - SERVERNUM=$(XAUTHORITY=$AUTHFILE Xvfb -displayfd 9 $XVFBARGS $LISTENTCP \ - 9>&1 2>"$ERRORFILE" & echo $! > $PIDFILE) + SERVERNUM=$(XAUTHORITY=$AUTHFILE Xvfb -displayfd 1 $XVFBARGS $LISTENTCP \ + 2>"$ERRORFILE" & echo $! > $PIDFILE) XVFBPID=$(cat $PIDFILE) fi sleep "$STARTWAIT" diff --git a/SPECS/xorg-x11-server.spec b/SPECS/xorg-x11-server.spec index 247cb03..dbe33f5 100644 --- a/SPECS/xorg-x11-server.spec +++ b/SPECS/xorg-x11-server.spec @@ -41,8 +41,8 @@ Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.19.3 -Release: 11%{?gitdate:.%{gitdate}}%{?dist}.2 +Version: 1.19.5 +Release: 5%{?gitdate:.%{gitdate}}%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -52,11 +52,11 @@ Group: User Interface/X # git snapshot. to recreate, run: # ./make-git-snapshot.sh `cat commitid` #Source0: xorg-server-%{gitdate}.tar.xz -Source0: http://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 +Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 Source1: make-git-snapshot.sh Source2: commitid %else -Source0: http://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 +Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 Source1: gitignore %endif @@ -86,6 +86,7 @@ Patch101: 0001-Always-install-vbe-and-int10-sdk-headers.patch Patch102: 0001-mustard-Enable-indirect-GLX-by-default.patch Patch103: 06_use-intel-only-on-pre-gen4.diff Patch104: 0001-xfree86-use-modesetting-driver-by-default-on-GeForce.patch +Patch105: 0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch # Trivial things to never merge upstream ever: # This really could be done prettier. @@ -93,9 +94,6 @@ Patch5002: xserver-1.4.99-ssh-isnt-local.patch Patch5004: xserver-autobind-hotplug.patch Patch5005: 0001-link-with-z-now.patch -# Bug 798994 - Exposure event not generated in Xinerama mode -Patch9231: 0001-xinerama-Implement-graphics-exposures-for-window-pix.patch - # Bug 1166989 - Tcl/tk Canvas draw error Patch9423: RFC-mi-reduce-missing-segments-on-large-ellipse.patch @@ -111,11 +109,24 @@ Patch9703: 0003-miarc-Cache-arc-span-data-for-dashed-arcs.patch Patch9710: 0001-modesetting-software-cursor-hack.patch Patch9711: 0001-handle-NullCursor-to-avoid-crash.patch Patch9712: 0001-xfixes-Remove-the-CursorCurrent-array.patch -Patch9713: 0001-modesetting-Validate-the-atom-for-enum-properties.patch -Patch9714: 0001-dix-Remove-clients-from-input-and-output-ready-queue.patch Patch9715: 0001-modesetting-Fix-PCI-initialization-on-non-zero-domai.patch Patch9716: 0001-xfree86-Fix-off-by-one-in-X-configure.patch -Patch9717: 0001-xfree86-modes-Make-colormap-gamma-glue-code-work-wit.patch + +# Backport tablet support for Xwayland - *NOT* in server-1.19-branch +Patch9901: 0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch +Patch9902: 0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch +Patch9903: 0003-xwayland-Listen-for-wp_tablet_seat-events.patch +Patch9904: 0004-xwayland-Handle-wp_tablet-events.patch +Patch9905: 0005-xwayland-Handle-tablet_tool-events.patch +Patch9906: 0006-xwayland-handle-button-events-after-motion-events.patch +Patch9907: 0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch +Patch9908: 0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch +Patch9909: 0009-xwayland-add-tablet-pad-support.patch +Patch9910: 0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch +Patch9911: 0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch +Patch9912: 0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch +# Bug 1544442 +Patch9913: 0001-xwayland-Keep-separate-variables-for-pointer-and-tab.patch Patch9922: 0002-animcur-Use-fixed-size-screen-private.patch Patch9923: 0003-animcur-Return-the-next-interval-directly-from-the-t.patch @@ -123,6 +134,10 @@ Patch9924: 0004-animcur-Run-the-timer-from-the-device-not-the-screen.patch Patch9925: 0005-animcur-Fix-transitions-between-animated-cursors.patch Patch9926: 0006-animcur-Change-which-CursorPtr-we-save-in-external-s.patch +# Additional debug feature, allow to disable glamor in Xwayland using +# an envvar, could be useful in el7 - *NOT* in server-1.19-branch +Patch9951: 0001-xwayland-add-envvar-XWAYLAND_NO_GLAMOR.patch + %global moduledir %{_libdir}/xorg/modules %global drimoduledir %{_libdir}/dri %global sdkdir %{_includedir}/xorg @@ -145,6 +160,7 @@ Patch9926: 0006-animcur-Change-which-CursorPtr-we-save-in-external-s.patch %global kdrive --enable-kdrive --enable-xephyr --disable-xfake --disable-xfbdev %global xservers --enable-xvfb --enable-xnest --enable-dmx %{kdrive} %{enable_xorg} +%global wayland --enable-xwayland BuildRequires: pam-devel BuildRequires: systemtap-sdt-devel @@ -165,6 +181,10 @@ BuildRequires: libXinerama-devel libXi-devel BuildRequires: libXt-devel libdmx-devel libXmu-devel libXrender-devel BuildRequires: libXi-devel libXpm-devel libXaw-devel libXfixes-devel +BuildRequires: wayland-devel +BuildRequires: wayland-protocols-devel >= 1.5 +BuildRequires: pkgconfig(wayland-client) >= 1.3.0 +BuildRequires: pkgconfig(epoxy) BuildRequires: libXv-devel BuildRequires: pixman-devel >= 0.30.0 BuildRequires: libpciaccess-devel >= 0.13.1 openssl-devel byacc flex @@ -303,6 +323,15 @@ X protocol, and therefore supports the newer X extensions like Render and Composite. +%package Xwayland +Summary: Wayland X Server +Group: User Interface/X +Requires: xorg-x11-server-common >= %{version}-%{release} + +%description Xwayland +Xwayland is an X server for running X clients under Wayland. + + %if %{with_hw_servers} %package devel Summary: SDK for X server driver module development @@ -367,15 +396,13 @@ test `getminor extension` == %{extension_minor} %global default_font_path "catalogue:/etc/X11/fontpath.d,built-ins" %if %{with_hw_servers} -%global dri_flags --with-dri-driver-path=%{drimoduledir} --enable-dri2 --enable-dri3 --enable-glamor --enable-xshmfence +%global dri_flags --with-dri-driver-path=%{drimoduledir} --enable-dri --enable-dri2 --enable-dri3 --enable-glamor --enable-xshmfence %else %global dri_flags --disable-dri %endif # ick -%if 0%{?rhel} sed -i 's/WAYLAND_SCANNER_RULES.*//g' configure.ac -%endif # --with-pie ? autoreconf -f -v --install || exit 1 @@ -396,8 +423,10 @@ autoreconf -f -v --install || exit 1 --without-dtrace \ --disable-linux-acpi --disable-linux-apm \ --enable-xselinux --enable-record --enable-present \ + --enable-xcsecurity \ --enable-config-udev \ --disable-unit-tests \ + %{?wayland} \ %{dri_flags} %{?bodhi_flags} \ ${CONFIGURE} @@ -505,9 +534,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/xorg/modules/drivers/modesetting_drv.so %dir %{_libdir}/xorg/modules/extensions %{_libdir}/xorg/modules/extensions/libglx.so -%if !0%{?rhel} -%{_libdir}/xorg/modules/extensions/libxwayland.so -%endif %dir %{_libdir}/xorg/modules/input %{_libdir}/xorg/modules/libfbdevhw.so %{_libdir}/xorg/modules/libexa.so @@ -569,6 +595,10 @@ rm -rf $RPM_BUILD_ROOT %{_bindir}/Xephyr %{_mandir}/man1/Xephyr.1* +%files Xwayland +%defattr(-,root,root,-) +%{_bindir}/Xwayland + %if %{with_hw_servers} %files devel %doc COPYING @@ -586,11 +616,29 @@ rm -rf $RPM_BUILD_ROOT %{xserver_source_dir} %changelog -* Wed Feb 21 2018 Adam Jackson - 1.19.3-11.2 +* Tue Feb 13 2018 Adam Jackson - 1.19.5-5 - Fix fetching animated cursor images with the XFIXES extension -* Mon Dec 11 2017 Adam Jackson - 1.19.3-11.1 -- Fix a crash in RANDR gamma/colormap setup +* Mon Feb 12 2018 Olivier Fourdan - 1.19.5-4 +- Fix cursor issue with Xwayland and tablet. + +* Wed Feb 7 2018 Olivier Fourdan - 1.19.5-3 +- Fix "xvfb-run --auto-display" not working with xserver-1.19 + +* Mon Oct 23 2017 Adam Jackson - 1.19.5-2 +- Don't attempt to probe vesa or fbdev in X -configure + +* Thu Oct 12 2017 Adam Jackson - 1.19.5-1 +- xserver 1.19.5 + +* Thu Oct 05 2017 Adam Jackson - 1.19.4-1 +- xserver 1.19.4 + +* Thu Sep 28 2017 Olivier Fourdan - 1.19.3-13 +- Enable dri3 and Xwayland, backport Xwayland and glamor fixes + +* Fri Aug 25 2017 Adam Jackson - 1.19.3-12 +- Enable XC-SECURITY * Mon Jun 26 2017 Adam Jackson - 1.19.3-11 - Fix off-by-one in X -configure