From 71dce0ed65d65323cdbd8529c05ff95625970c58 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Apr 2017 15:35:40 +0200 Subject: [PATCH 1/5] Xserver/mi/miexpose.c: Rewrite miPaintWindow to draw to window pixmap. And... Remove override for miPaintWindow from hw/nxagent/NXmiexpose.c, use the version that we ship in Xserver/mi/miexpose.c. commit 06d27f8045966c1fb154eafaff308a01b93f265b Author: Keith Packard Date: Wed Sep 12 23:57:30 2007 +0100 Try again to fix drawable and tile offsets in miPaintWindow Many coordinate spaces are hard. Let's go drinking. commit dd3992eb86377684a5dbe86fa19c756a9e53cda2 Author: Keith Packard Date: Wed Sep 12 22:39:31 2007 +0100 miPaintWindow draw to window for background. Instead of drawing to window pixmap for everything, draw to window for background as that works for Xnest and Xdmx; draw to pixmap for borders which neither of those X servers use. commit 257c8ed17f4f908e0d0d5e53aaf13aa3b1313f50 Author: Keith Packard Date: Wed Sep 12 12:11:49 2007 +0100 Rewrite miPaintWindow to draw to window pixmap. miPaintWindow was drawing to the root window, or (sometimes) drawing to the window after smashing the window clip list. This is losing, and easily fixed by just drawing to the window pixmap. Backported-to-NX-by: Mike Gabriel --- .../programs/Xserver/hw/nxagent/NXmiexpose.c | 265 --------------- nx-X11/programs/Xserver/mi/miexpose.c | 301 +++++------------- 2 files changed, 84 insertions(+), 482 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c index bcb88d42da..c90a1f644a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c @@ -476,268 +476,3 @@ miWindowExposures(pWin, prgn, other_exposed) else if (exposures && exposures != prgn) RegionDestroy(exposures); } - -void -miPaintWindow(pWin, prgn, what) -register WindowPtr pWin; -RegionPtr prgn; -int what; -{ - int status; - - Bool usingScratchGC = FALSE; - WindowPtr pRoot; - -#define FUNCTION 0 -#define FOREGROUND 1 -#define TILE 2 -#define FILLSTYLE 3 -#define ABSX 4 -#define ABSY 5 -#define CLIPMASK 6 -#define SUBWINDOW 7 -#define COUNT_BITS 8 - - ChangeGCVal gcval[7]; - ChangeGCVal newValues [COUNT_BITS] = {{ 0 }}; - - BITS32 gcmask, index, mask; - RegionRec prgnWin; - DDXPointRec oldCorner; - BoxRec box; - WindowPtr pBgWin; - GCPtr pGC; - register int i; - register BoxPtr pbox; - register ScreenPtr pScreen = pWin->drawable.pScreen; - register xRectangle *prect; - int numRects; - - /* - * Set the elements reported by the compiler - * as uninitialized. - */ - - prgnWin.extents.x1 = 0; - prgnWin.extents.y1 = 0; - prgnWin.extents.x2 = 0; - prgnWin.extents.y2 = 0; - - prgnWin.data = NULL; - - oldCorner.x = 0; - oldCorner.y = 0; - - gcmask = 0; - - if (what == PW_BACKGROUND) - { - switch (pWin->backgroundState) { - case None: - return; - case ParentRelative: - (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what); - return; - case BackgroundPixel: - newValues[FOREGROUND].val = pWin->background.pixel; - newValues[FILLSTYLE].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; - break; - case BackgroundPixmap: - newValues[TILE].ptr = (void *)pWin->background.pixmap; - newValues[FILLSTYLE].val = FillTiled; - gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; - break; - } - } - else - { - if (pWin->borderIsPixel) - { - newValues[FOREGROUND].val = pWin->border.pixel; - newValues[FILLSTYLE].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; - } - else - { - newValues[TILE].ptr = (void *)pWin->border.pixmap; - newValues[FILLSTYLE].val = FillTiled; - gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; - } - } - - prect = (xRectangle *)malloc(RegionNumRects(prgn) * - sizeof(xRectangle)); - if (!prect) - return; - - newValues[FUNCTION].val = GXcopy; - gcmask |= GCFunction | GCClipMask; - - i = pScreen->myNum; - pRoot = screenInfo.screens[i]->root; - - pBgWin = pWin; - if (what == PW_BORDER) - { - while (pBgWin->backgroundState == ParentRelative) - pBgWin = pBgWin->parent; - } - - if ((pWin->drawable.depth != pRoot->drawable.depth) || - (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel)) - { - usingScratchGC = TRUE; - pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); - if (!pGC) - { - free(prect); - return; - } - /* - * mash the clip list so we can paint the border by - * mangling the window in place, pretending it - * spans the entire screen - */ - if (what == PW_BORDER) - { - prgnWin = pWin->clipList; - oldCorner.x = pWin->drawable.x; - oldCorner.y = pWin->drawable.y; - pWin->drawable.x = pWin->drawable.y = 0; - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - RegionInit(&pWin->clipList, &box, 1); - pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; - newValues[ABSX].val = pBgWin->drawable.x; - newValues[ABSY].val = pBgWin->drawable.y; - } - else - { - newValues[ABSX].val = 0; - newValues[ABSY].val = 0; - } - } else { - /* - * draw the background to the root window - */ - if (screenContext[i] == (GCPtr)NULL) - { - if (!ResType && !(ResType = CreateNewResourceType(tossGC))) - return; - screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0, - (XID *)NULL, &status); - if (!screenContext[i]) - return; - numGCs++; - if (!AddResource(FakeClientID(0), ResType, - (void *)screenContext[i])) - return; - } - pGC = screenContext[i]; - newValues[SUBWINDOW].val = IncludeInferiors; - newValues[ABSX].val = pBgWin->drawable.x; - newValues[ABSY].val = pBgWin->drawable.y; - gcmask |= GCSubwindowMode; - pWin = pRoot; - } - - if (pWin->backStorage) - (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack); - - mask = gcmask; - gcmask = 0; - i = 0; - while (mask) { - index = lowbit (mask); - mask &= ~index; - switch (index) { - case GCFunction: - if (pGC->alu != newValues[FUNCTION].val) { - gcmask |= index; - gcval[i++].val = newValues[FUNCTION].val; - } - break; - case GCTileStipXOrigin: - if ( pGC->patOrg.x != newValues[ABSX].val) { - gcmask |= index; - gcval[i++].val = newValues[ABSX].val; - } - break; - case GCTileStipYOrigin: - if ( pGC->patOrg.y != newValues[ABSY].val) { - gcmask |= index; - gcval[i++].val = newValues[ABSY].val; - } - break; - case GCClipMask: - if ( pGC->clientClipType != CT_NONE) { - gcmask |= index; - gcval[i++].val = CT_NONE; - } - break; - case GCSubwindowMode: - if ( pGC->subWindowMode != newValues[SUBWINDOW].val) { - gcmask |= index; - gcval[i++].val = newValues[SUBWINDOW].val; - } - break; - case GCTile: - if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr) - { - gcmask |= index; - gcval[i++].ptr = newValues[TILE].ptr; - } - break; - case GCFillStyle: - if ( pGC->fillStyle != newValues[FILLSTYLE].val) { - gcmask |= index; - gcval[i++].val = newValues[FILLSTYLE].val; - } - break; - case GCForeground: - if ( pGC->fgPixel != newValues[FOREGROUND].val) { - gcmask |= index; - gcval[i++].val = newValues[FOREGROUND].val; - } - break; - } - } - - if (gcmask) - dixChangeGC(NullClient, pGC, gcmask, NULL, gcval); - - if (pWin->drawable.serialNumber != pGC->serialNumber) - ValidateGC((DrawablePtr)pWin, pGC); - - numRects = RegionNumRects(prgn); - pbox = RegionRects(prgn); - for (i= numRects; --i >= 0; pbox++, prect++) - { - prect->x = pbox->x1 - pWin->drawable.x; - prect->y = pbox->y1 - pWin->drawable.y; - prect->width = pbox->x2 - pbox->x1; - prect->height = pbox->y2 - pbox->y1; - } - prect -= numRects; - (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect); - free(prect); - - if (pWin->backStorage) - (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing); - - if (usingScratchGC) - { - if (what == PW_BORDER) - { - RegionUninit(&pWin->clipList); - pWin->clipList = prgnWin; - pWin->drawable.x = oldCorner.x; - pWin->drawable.y = oldCorner.y; - pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } - FreeScratchGC(pGC); - } -} diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c index c392210000..590a7eacc8 100644 --- a/nx-X11/programs/Xserver/mi/miexpose.c +++ b/nx-X11/programs/Xserver/mi/miexpose.c @@ -630,257 +630,124 @@ tossGC ( return 0; } -#ifndef NXAGENT_SERVER void -miPaintWindow(pWin, prgn, what) -register WindowPtr pWin; -RegionPtr prgn; -int what; +miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) { - int status; + ScreenPtr pScreen = pWin->drawable.pScreen; + ChangeGCVal gcval[5]; + BITS32 gcmask; + GCPtr pGC; + int i; + BoxPtr pbox; + xRectangle *prect; + int numRects; + /* + * Distance from screen to destination drawable, use this + * to adjust rendering coordinates which come in in screen space + */ + int draw_x_off, draw_y_off; + /* + * Tile offset for drawing; these need to align the tile + * to the appropriate window origin + */ + int tile_x_off, tile_y_off; - Bool usingScratchGC = FALSE; - WindowPtr pRoot; - -#define FUNCTION 0 -#define FOREGROUND 1 -#define TILE 2 -#define FILLSTYLE 3 -#define ABSX 4 -#define ABSY 5 -#define CLIPMASK 6 -#define SUBWINDOW 7 -#define COUNT_BITS 8 - - ChangeGCVal gcval[7]; - ChangeGCVal newValues [COUNT_BITS] = {{ 0 }}; - - BITS32 gcmask, index, mask; - RegionRec prgnWin; - DDXPointRec oldCorner; - BoxRec box; - WindowPtr pBgWin; - GCPtr pGC; - register int i; - register BoxPtr pbox; - register ScreenPtr pScreen = pWin->drawable.pScreen; - register xRectangle *prect; - int numRects; + PixUnion fill; + Bool solid = TRUE; + DrawablePtr drawable = &pWin->drawable; - gcmask = 0; + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; if (what == PW_BACKGROUND) { + draw_x_off = drawable->x; + draw_y_off = drawable->y; + + tile_x_off = 0; + tile_y_off = 0; + fill = pWin->background; switch (pWin->backgroundState) { - case None: - return; - case ParentRelative: - (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what); - return; - case BackgroundPixel: - newValues[FOREGROUND].val = pWin->background.pixel; - newValues[FILLSTYLE].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; - break; - case BackgroundPixmap: - newValues[TILE].ptr = (void *)pWin->background.pixmap; - newValues[FILLSTYLE].val = FillTiled; - gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; - break; + case None: + return; + case BackgroundPixmap: + solid = FALSE; + break; } } else { - if (pWin->borderIsPixel) - { - newValues[FOREGROUND].val = pWin->border.pixel; - newValues[FILLSTYLE].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; - } - else - { - newValues[TILE].ptr = (void *)pWin->border.pixmap; - newValues[FILLSTYLE].val = FillTiled; - gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; - } - } + PixmapPtr pixmap; - prect = (xRectangle *)malloc(RegionNumRects(prgn) * - sizeof(xRectangle)); - if (!prect) - return; + tile_x_off = drawable->x; + tile_y_off = drawable->y; - newValues[FUNCTION].val = GXcopy; - gcmask |= GCFunction | GCClipMask; + /* servers without pixmaps draw their own borders */ + if (!pScreen->GetWindowPixmap) + return; + pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); + drawable = &pixmap->drawable; + +#ifdef COMPOSITE + draw_x_off = pixmap->screen_x; + draw_y_off = pixmap->screen_y; + tile_x_off -= draw_x_off; + tile_y_off -= draw_y_off; +#else + draw_x_off = 0; + draw_y_off = 0; +#endif + fill = pWin->border; + solid = pWin->borderIsPixel; + } - i = pScreen->myNum; - pRoot = screenInfo.screens[i]->root; + gcval[0].val = GXcopy; + gcmask = GCFunction; - pBgWin = pWin; - if (what == PW_BORDER) + if (solid) { - while (pBgWin->backgroundState == ParentRelative) - pBgWin = pBgWin->parent; + gcval[1].val = fill.pixel; + gcval[2].val = FillSolid; + gcmask |= GCForeground | GCFillStyle; } - - if ((pWin->drawable.depth != pRoot->drawable.depth) || - (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel)) + else { - usingScratchGC = TRUE; - pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); - if (!pGC) - { - free(prect); - return; - } - /* - * mash the clip list so we can paint the border by - * mangling the window in place, pretending it - * spans the entire screen - */ - if (what == PW_BORDER) - { - prgnWin = pWin->clipList; - oldCorner.x = pWin->drawable.x; - oldCorner.y = pWin->drawable.y; - pWin->drawable.x = pWin->drawable.y = 0; - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - RegionInit(&pWin->clipList, &box, 1); - pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; - newValues[ABSX].val = pBgWin->drawable.x; - newValues[ABSY].val = pBgWin->drawable.y; - } - else - { - newValues[ABSX].val = 0; - newValues[ABSY].val = 0; - } - } else { - /* - * draw the background to the root window - */ - if (screenContext[i] == (GCPtr)NULL) - { - if (!ResType && !(ResType = CreateNewResourceType(tossGC))) - return; - screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0, - (XID *)NULL, &status); - if (!screenContext[i]) - return; - numGCs++; - if (!AddResource(FakeClientID(0), ResType, - (void *)screenContext[i])) - return; - } - pGC = screenContext[i]; - newValues[SUBWINDOW].val = IncludeInferiors; - newValues[ABSX].val = pBgWin->drawable.x; - newValues[ABSY].val = pBgWin->drawable.y; - gcmask |= GCSubwindowMode; - pWin = pRoot; - } - - if (pWin->backStorage) - (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack); - - mask = gcmask; - gcmask = 0; - i = 0; - while (mask) { - index = lowbit (mask); - mask &= ~index; - switch (index) { - case GCFunction: - if (pGC->alu != newValues[FUNCTION].val) { - gcmask |= index; - gcval[i++].val = newValues[FUNCTION].val; - } - break; - case GCTileStipXOrigin: - if ( pGC->patOrg.x != newValues[ABSX].val) { - gcmask |= index; - gcval[i++].val = newValues[ABSX].val; - } - break; - case GCTileStipYOrigin: - if ( pGC->patOrg.y != newValues[ABSY].val) { - gcmask |= index; - gcval[i++].val = newValues[ABSY].val; - } - break; - case GCClipMask: - if ( pGC->clientClipType != CT_NONE) { - gcmask |= index; - gcval[i++].val = CT_NONE; - } - break; - case GCSubwindowMode: - if ( pGC->subWindowMode != newValues[SUBWINDOW].val) { - gcmask |= index; - gcval[i++].val = newValues[SUBWINDOW].val; - } - break; - case GCTile: - if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr) - { - gcmask |= index; - gcval[i++].ptr = newValues[TILE].ptr; - } - break; - case GCFillStyle: - if ( pGC->fillStyle != newValues[FILLSTYLE].val) { - gcmask |= index; - gcval[i++].val = newValues[FILLSTYLE].val; - } - break; - case GCForeground: - if ( pGC->fgPixel != newValues[FOREGROUND].val) { - gcmask |= index; - gcval[i++].val = newValues[FOREGROUND].val; - } - break; - } + gcval[1].val = FillTiled; + gcval[2].ptr = (pointer)fill.pixmap; + gcval[3].val = tile_x_off; + gcval[4].val = tile_y_off; + gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } - if (gcmask) - dixChangeGC(NullClient, pGC, gcmask, NULL, gcval); + prect = (xRectangle *)xallocarray(RegionNumRects(prgn), sizeof(xRectangle)); + if (!prect) + return; + + pGC = GetScratchGC(drawable->depth, drawable->pScreen); + if (!pGC) + { + free(prect); + return; + } - if (pWin->drawable.serialNumber != pGC->serialNumber) - ValidateGC((DrawablePtr)pWin, pGC); + dixChangeGC(NullClient, pGC, gcmask, NULL, gcval); + ValidateGC(drawable, pGC); numRects = RegionNumRects(prgn); pbox = RegionRects(prgn); for (i= numRects; --i >= 0; pbox++, prect++) { - prect->x = pbox->x1 - pWin->drawable.x; - prect->y = pbox->y1 - pWin->drawable.y; + prect->x = pbox->x1 - draw_x_off; + prect->y = pbox->y1 - draw_y_off; prect->width = pbox->x2 - pbox->x1; prect->height = pbox->y2 - pbox->y1; } prect -= numRects; - (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect); + (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); free(prect); - if (pWin->backStorage) - (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing); - - if (usingScratchGC) - { - if (what == PW_BORDER) - { - RegionUninit(&pWin->clipList); - pWin->clipList = prgnWin; - pWin->drawable.x = oldCorner.x; - pWin->drawable.y = oldCorner.y; - pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } - FreeScratchGC(pGC); - } + FreeScratchGC(pGC); } -#endif /* MICLEARDRAWABLE -- sets the entire drawable to the background color of * the GC. Useful when we have a scratch drawable and need to initialize From 2e54c23e62caba78df052c8fd17f8bbb7c0567eb Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 11 Apr 2017 16:29:48 +0200 Subject: [PATCH 2/5] mi: Move pScreen->SendGraphicsExpose up to dix commit 1e56b2dfc6377234ffdcdf206528d476b04d13af Author: Adam Jackson Date: Fri Sep 12 12:51:13 2014 -0400 mi: Move pScreen->SendGraphicsExpose up to dix No DDX is overriding this and it's fairly absurd to expose it as a screen operation anyway. Reviewed-by: Julien Cristau Signed-off-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/Xext/panoramiXprocs.c | 6 +- nx-X11/programs/Xserver/dix/Imakefile | 3 + nx-X11/programs/Xserver/dix/dispatch.c | 57 +++++++++++++++++-- nx-X11/programs/Xserver/hw/nxagent/Imakefile | 1 + nx-X11/programs/Xserver/include/dix.h | 6 ++ nx-X11/programs/Xserver/include/scrnintstr.h | 8 --- nx-X11/programs/Xserver/mi/mi.h | 8 --- nx-X11/programs/Xserver/mi/miexpose.c | 54 ------------------ nx-X11/programs/Xserver/mi/miscrinit.c | 1 - 9 files changed, 65 insertions(+), 79 deletions(-) diff --git a/nx-X11/programs/Xserver/Xext/panoramiXprocs.c b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c index 93626bbebe..f0e45f6fdd 100644 --- a/nx-X11/programs/Xserver/Xext/panoramiXprocs.c +++ b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c @@ -1117,8 +1117,7 @@ int PanoramiXCopyArea(ClientPtr client) } } RegionValidate(&totalReg, &overlap); - (*pScreen->SendGraphicsExpose)( - client, &totalReg, stuff->dstDrawable, X_CopyArea, 0); + SendGraphicsExpose(client, &totalReg, stuff->dstDrawable, X_CopyArea, 0); RegionUninit(&totalReg); } @@ -1224,8 +1223,7 @@ int PanoramiXCopyPlane(ClientPtr client) } } RegionValidate(&totalReg, &overlap); - (*pScreen->SendGraphicsExpose)( - client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0); + SendGraphicsExpose(client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0); RegionUninit(&totalReg); } diff --git a/nx-X11/programs/Xserver/dix/Imakefile b/nx-X11/programs/Xserver/dix/Imakefile index 1024de965a..82294b4e6d 100644 --- a/nx-X11/programs/Xserver/dix/Imakefile +++ b/nx-X11/programs/Xserver/dix/Imakefile @@ -125,6 +125,8 @@ VENDORRELEASE = XVendorRelease SITE_DEFINES = $(SITE_FONT_PATH) $(SITE_DISPLAY_CLASS) +XSERVER_ABI_DEFINES = -DXSERVER_OLD_TRYCLIENTEVENTS_ABI + VENDOR_DEFINES = $(VENDOR_STRING) $(VENDOR_RELEASE) $(QUARTZ_DEFINES) NormalLibraryObjectRule() @@ -137,6 +139,7 @@ SpecialCObjectRule(main,$(ICONFIGFILES),$(VENDOR_DEFINES)) SpecialCObjectRule(pixmap,$(ICONFIGFILES),$(_NOOP_)) SpecialCObjectRule(privates,$(ICONFIGFILES),$(_NOOP_)) SpecialCObjectRule(window,$(ICONFIGFILES),$(QUARTZ_DEFINES)) +SpecialCObjectRule(dispatch,$(ICONFIGFILES),$(XSERVER_ABI_DEFINES)) NormalLibraryTarget(xpstubs,$(XPOBJ)) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index c9ce8981c7..b15a8ac578 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -1711,6 +1711,57 @@ ProcClearToBackground(register ClientPtr client) return(client->noClientException); } +/* send GraphicsExpose events, or a NoExpose event, based on the region */ +void +SendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, + int major, int minor) +{ + if (pRgn && !RegionNil(pRgn)) { + xEvent *pEvent; + xEvent *pe; + BoxPtr pBox; + int i; + int numRects; + + numRects = RegionNumRects(pRgn); + pBox = RegionRects(pRgn); + if (!(pEvent = calloc(numRects, sizeof(xEvent)))) + return; + pe = pEvent; + + for (i = 1; i <= numRects; i++, pe++, pBox++) { + pe->u.u.type = GraphicsExpose; + pe->u.graphicsExposure.drawable = drawable; + pe->u.graphicsExposure.x = pBox->x1; + pe->u.graphicsExposure.y = pBox->y1; + pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; + pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; + pe->u.graphicsExposure.count = numRects - i; + pe->u.graphicsExposure.majorEvent = major; + pe->u.graphicsExposure.minorEvent = minor; + } + /* GraphicsExpose is a "critical event", which TryClientEvents + * handles specially. */ +#ifndef XSERVER_OLD_TRYCLIENTEVENTS_ABI + TryClientEvents(client, NULL, pEvent, numRects, + (Mask) 0, NoEventMask, NullGrab); +#else + TryClientEvents(client, pEvent, numRects, + (Mask) 0, NoEventMask, NullGrab); +#endif /* XSERVER_OLD_TRYCLIENTEVENTS_ABI */ + free(pEvent); + } + else { + xEvent event = { + .u.noExposure.drawable = drawable, + .u.noExposure.majorEvent = major, + .u.noExposure.minorEvent = minor + }; + event.u.u.type = NoExpose; + WriteEventsToClient(client, 1, &event); + } +} + int ProcCopyArea(register ClientPtr client) { @@ -1743,8 +1794,7 @@ ProcCopyArea(register ClientPtr client) stuff->dstX, stuff->dstY); if (pGC->graphicsExposures) { - (*pDst->pScreen->SendGraphicsExpose) - (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); + SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0); if (pRgn) RegionDestroy(pRgn); } @@ -1791,8 +1841,7 @@ ProcCopyPlane(register ClientPtr client) stuff->dstX, stuff->dstY, stuff->bitPlane); if (pGC->graphicsExposures) { - (*pdstDraw->pScreen->SendGraphicsExpose) - (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); + SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); if (pRgn) RegionDestroy(pRgn); } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile index a1b059caef..4c1196e81c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile +++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile @@ -251,6 +251,7 @@ DEFINES = \ -DRANDR_15_INTERFACE=1 \ -DPANORAMIX \ -UDEBUG_TREE \ + -DXSERVER_OLD_TRYCLIENTEVENTS_ABI \ $(NULL) all:: $(OBJS) diff --git a/nx-X11/programs/Xserver/include/dix.h b/nx-X11/programs/Xserver/include/dix.h index 4a57f724d1..96b1af5b0f 100644 --- a/nx-X11/programs/Xserver/include/dix.h +++ b/nx-X11/programs/Xserver/include/dix.h @@ -470,6 +470,12 @@ extern void ClientWakeup( extern Bool ClientIsAsleep( ClientPtr /*client*/); +extern void SendGraphicsExpose(ClientPtr /*client */ , + RegionPtr /*pRgn */ , + XID /*drawable */ , + int /*major */ , + int /*minor */); + /* atom.c */ extern Atom MakeAtom( diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index 5a3f32309e..bc3a8c04a1 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -427,13 +427,6 @@ typedef RegionPtr (* RectsToRegionProcPtr)( #endif /* NEED_SCREEN_REGIONS */ -typedef void (* SendGraphicsExposeProcPtr)( - ClientPtr /*client*/, - RegionPtr /*pRgn*/, - XID /*drawable*/, - int /*major*/, - int /*minor*/); - typedef void (* ScreenBlockHandlerProcPtr)( int /*screenNum*/, void * /*blockData*/, @@ -679,7 +672,6 @@ typedef struct _Screen { #ifdef NEED_SCREEN_REGIONS RectsToRegionProcPtr RectsToRegion; #endif /* NEED_SCREEN_REGIONS */ - SendGraphicsExposeProcPtr SendGraphicsExpose; /* os layer procedures */ diff --git a/nx-X11/programs/Xserver/mi/mi.h b/nx-X11/programs/Xserver/mi/mi.h index 409e21e343..bc960721b0 100644 --- a/nx-X11/programs/Xserver/mi/mi.h +++ b/nx-X11/programs/Xserver/mi/mi.h @@ -211,14 +211,6 @@ extern RegionPtr miHandleExposures( unsigned long /*plane*/ ); -extern void miSendGraphicsExpose( - ClientPtr /*client*/, - RegionPtr /*pRgn*/, - XID /*drawable*/, - int /*major*/, - int /*minor*/ -); - extern void miSendExposures( WindowPtr /*pWin*/, RegionPtr /*pRgn*/, diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c index 590a7eacc8..2774c70c03 100644 --- a/nx-X11/programs/Xserver/mi/miexpose.c +++ b/nx-X11/programs/Xserver/mi/miexpose.c @@ -375,60 +375,6 @@ miHandleExposures(pSrcDrawable, pDstDrawable, } #endif -/* send GraphicsExpose events, or a NoExpose event, based on the region */ - -void -miSendGraphicsExpose (client, pRgn, drawable, major, minor) - ClientPtr client; - RegionPtr pRgn; - XID drawable; - int major; - int minor; -{ - if (pRgn && !RegionNil(pRgn)) - { - xEvent *pEvent; - register xEvent *pe; - register BoxPtr pBox; - register int i; - int numRects; - - numRects = RegionNumRects(pRgn); - pBox = RegionRects(pRgn); - if(!(pEvent = (xEvent *)malloc(numRects * sizeof(xEvent)))) - return; - pe = pEvent; - - for (i=1; i<=numRects; i++, pe++, pBox++) - { - pe->u.u.type = GraphicsExpose; - pe->u.graphicsExposure.drawable = drawable; - pe->u.graphicsExposure.x = pBox->x1; - pe->u.graphicsExposure.y = pBox->y1; - pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; - pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; - pe->u.graphicsExposure.count = numRects - i; - pe->u.graphicsExposure.majorEvent = major; - pe->u.graphicsExposure.minorEvent = minor; - } - TryClientEvents(client, pEvent, numRects, - (Mask)0, NoEventMask, NullGrab); - free(pEvent); - } - else - { - xEvent event; - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = NoExpose; - event.u.noExposure.drawable = drawable; - event.u.noExposure.majorEvent = major; - event.u.noExposure.minorEvent = minor; - TryClientEvents(client, &event, 1, - (Mask)0, NoEventMask, NullGrab); - } -} - - void miSendExposures(pWin, pRgn, dx, dy) WindowPtr pWin; diff --git a/nx-X11/programs/Xserver/mi/miscrinit.c b/nx-X11/programs/Xserver/mi/miscrinit.c index e38284c501..7f7a5510e0 100644 --- a/nx-X11/programs/Xserver/mi/miscrinit.c +++ b/nx-X11/programs/Xserver/mi/miscrinit.c @@ -289,7 +289,6 @@ miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, #ifdef NEED_SCREEN_REGIONS pScreen->RectsToRegion = RegionFromRects; #endif /* NEED_SCREEN_REGIONS */ - pScreen->SendGraphicsExpose = miSendGraphicsExpose; pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA; pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA; pScreen->blockData = (void *)0; From 0090b313a673e40527d2159b7a3529cd6bfba623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Tue, 11 Apr 2017 16:35:49 +0200 Subject: [PATCH 3/5] Xserver/mi/miexpose.c: Fix the tile offset in miPaintWindow for ParentRelative windows. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 244a635fcdc9e0a7212d51b26d74f49d8e1b071f Author: Fredrik Höglund Date: Mon Aug 18 19:27:34 2008 +0200 Fix the tile offset in miPaintWindow for ParentRelative windows. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/mi/miexpose.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c index 2774c70c03..0a94dc1ba8 100644 --- a/nx-X11/programs/Xserver/mi/miexpose.c +++ b/nx-X11/programs/Xserver/mi/miexpose.c @@ -610,8 +610,8 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) draw_x_off = drawable->x; draw_y_off = drawable->y; - tile_x_off = 0; - tile_y_off = 0; + tile_x_off = pWin->drawable.x - draw_x_off; + tile_y_off = pWin->drawable.y - draw_y_off; fill = pWin->background; switch (pWin->backgroundState) { case None: From fca6b5ba842c2b1bb3baf182b5db7b4bce6ad953 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Tue, 11 Apr 2017 16:39:51 +0200 Subject: [PATCH 4/5] Xserver/mi/miexpose.c: Fix border tile origin when background is ParentRelative commit b4061cf5f76241157b2dc81dec053012075311c0 Author: Peter Harris Date: Tue May 12 14:19:15 2015 -0400 Fix border tile origin when background is ParentRelative According to http://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#requests:CreateWindow "The border tile origin is always the same as the background tile origin." ChangeWindowAttributes goes to some effort to make sure it repaints the border tile whenever the background origin may have changed, but ChangeWindowAttributes goes to some effort to make sure it repaints the border tile whenever the background origin may have changed, but miPaintWindow was ignoring the background origin. Found by xts XChangeWindowAttributes-3 Signed-off-by: Peter Harris Reviewed-by: Keith Packard Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/mi/miexpose.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c index 0a94dc1ba8..d029a54862 100644 --- a/nx-X11/programs/Xserver/mi/miexpose.c +++ b/nx-X11/programs/Xserver/mi/miexpose.c @@ -625,8 +625,8 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) { PixmapPtr pixmap; - tile_x_off = drawable->x; - tile_y_off = drawable->y; + fill = pWin->border; + solid = pWin->borderIsPixel; /* servers without pixmaps draw their own borders */ if (!pScreen->GetWindowPixmap) @@ -634,6 +634,12 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); drawable = &pixmap->drawable; + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + + tile_x_off = pWin->drawable.x; + tile_y_off = pWin->drawable.y; + #ifdef COMPOSITE draw_x_off = pixmap->screen_x; draw_y_off = pixmap->screen_y; @@ -643,8 +649,6 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) draw_x_off = 0; draw_y_off = 0; #endif - fill = pWin->border; - solid = pWin->borderIsPixel; } gcval[0].val = GXcopy; From 2d23e8a6c29b15068835bc07c26c82a1cff83117 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan <ïonic@ionic.de> Date: Sun, 11 Sep 2016 23:29:19 +0000 Subject: [PATCH 5/5] misc nx-X11/programs/Xserver/{fb,mi}/: backport 2e76958d304a3c4080d62f32449724eeb9b95d93. Move some fb code to mi code. Allows for easier changes afterwards, because the diffs reference the new actual files. --- nx-X11/programs/Xserver/fb/fb.h | 37 --- nx-X11/programs/Xserver/fb/fbcopy.c | 331 +------------------ nx-X11/programs/Xserver/fb/fboverlay.c | 2 +- nx-X11/programs/Xserver/fb/fboverlay.h | 2 +- nx-X11/programs/Xserver/fb/fbwindow.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/GCOps.c | 4 +- nx-X11/programs/Xserver/mi/Imakefile | 2 + nx-X11/programs/Xserver/mi/mi.h | 42 +++ nx-X11/programs/Xserver/mi/micopy.c | 354 +++++++++++++++++++++ 9 files changed, 407 insertions(+), 369 deletions(-) create mode 100644 nx-X11/programs/Xserver/mi/micopy.c diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h index 61bf18caf4..1628edbeb5 100644 --- a/nx-X11/programs/Xserver/fb/fb.h +++ b/nx-X11/programs/Xserver/fb/fb.h @@ -1291,18 +1291,6 @@ fbInitVisuals (VisualPtr *visualp, * fbcopy.c */ -typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pDstBox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - void fbCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, @@ -1342,31 +1330,6 @@ fbCopyNto1 (DrawablePtr pSrcDrawable, Pixel bitplane, void *closure); -void -fbCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure); - -RegionPtr -fbDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - fbCopyProc copyProc, - Pixel bitplane, - void *closure); - RegionPtr fbCopyArea (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, diff --git a/nx-X11/programs/Xserver/fb/fbcopy.c b/nx-X11/programs/Xserver/fb/fbcopy.c index 7a1dbb5aaa..9de5b0a28f 100644 --- a/nx-X11/programs/Xserver/fb/fbcopy.c +++ b/nx-X11/programs/Xserver/fb/fbcopy.c @@ -261,329 +261,6 @@ fbCopyNto1 (DrawablePtr pSrcDrawable, } } -void -fbCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure) -{ - int careful; - Bool reverse; - Bool upsidedown; - BoxPtr pbox; - int nbox; - BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; - - pbox = RegionRects(pDstRegion); - nbox = RegionNumRects(pDstRegion); - - /* XXX we have to err on the side of safety when both are windows, - * because we don't know if IncludeInferiors is being used. - */ - careful = ((pSrcDrawable == pDstDrawable) || - ((pSrcDrawable->type == DRAWABLE_WINDOW) && - (pDstDrawable->type == DRAWABLE_WINDOW))); - - pboxNew1 = NULL; - pboxNew2 = NULL; - if (careful && dy < 0) - { - upsidedown = TRUE; - - if (nbox > 1) - { - /* keep ordering in each band, reverse order of bands */ - pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox); - if(!pboxNew1) - return; - pboxBase = pboxNext = pbox+nbox-1; - while (pboxBase >= pbox) - { - while ((pboxNext >= pbox) && - (pboxBase->y1 == pboxNext->y1)) - pboxNext--; - pboxTmp = pboxNext+1; - while (pboxTmp <= pboxBase) - { - *pboxNew1++ = *pboxTmp++; - } - pboxBase = pboxNext; - } - pboxNew1 -= nbox; - pbox = pboxNew1; - } - } - else - { - /* walk source top to bottom */ - upsidedown = FALSE; - } - - if (careful && dx < 0) - { - /* walk source right to left */ - if (dy <= 0) - reverse = TRUE; - else - reverse = FALSE; - - if (nbox > 1) - { - /* reverse order of rects in each band */ - pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox); - if(!pboxNew2) - { - if (pboxNew1) - free(pboxNew1); - return; - } - pboxBase = pboxNext = pbox; - while (pboxBase < pbox+nbox) - { - while ((pboxNext < pbox+nbox) && - (pboxNext->y1 == pboxBase->y1)) - pboxNext++; - pboxTmp = pboxNext; - while (pboxTmp != pboxBase) - { - *pboxNew2++ = *--pboxTmp; - } - pboxBase = pboxNext; - } - pboxNew2 -= nbox; - pbox = pboxNew2; - } - } - else - { - /* walk source left to right */ - reverse = FALSE; - } - - (*copyProc) (pSrcDrawable, - pDstDrawable, - pGC, - pbox, - nbox, - dx, dy, - reverse, upsidedown, bitPlane, closure); - - if (pboxNew1) - free (pboxNew1); - if (pboxNew2) - free (pboxNew2); -} - -RegionPtr -fbDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure) -{ - RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ - Bool freeSrcClip = FALSE; - RegionPtr prgnExposed = NULL; - RegionRec rgnDst; - int dx; - int dy; - int numRects; - int box_x1; - int box_y1; - int box_x2; - int box_y2; - Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ - Bool fastDst = FALSE; /* for fast clipping with one rect dest */ - Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ - - /* Short cut for unmapped windows */ - - if (pDstDrawable->type == DRAWABLE_WINDOW && - !((WindowPtr)pDstDrawable)->realized) - { - return NULL; - } - - if ((pSrcDrawable != pDstDrawable) && - pSrcDrawable->pScreen->SourceValidate) - { - (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc); - } - - /* Compute source clip region */ - if (pSrcDrawable->type == DRAWABLE_PIXMAP) - { - if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) - prgnSrcClip = fbGetCompositeClip(pGC); - else - fastSrc = TRUE; - } - else - { - if (pGC->subWindowMode == IncludeInferiors) - { - /* - * XFree86 DDX empties the border clip when the - * VT is inactive, make sure the region isn't empty - */ - if (!((WindowPtr) pSrcDrawable)->parent && - RegionNotEmpty( - &((WindowPtr) pSrcDrawable)->borderClip)) - { - /* - * special case bitblt from root window in - * IncludeInferiors mode; just like from a pixmap - */ - fastSrc = TRUE; - } - else if ((pSrcDrawable == pDstDrawable) && - (pGC->clientClipType == CT_NONE)) - { - prgnSrcClip = fbGetCompositeClip(pGC); - } - else - { - prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); - freeSrcClip = TRUE; - } - } - else - { - prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; - } - } - - xIn += pSrcDrawable->x; - yIn += pSrcDrawable->y; - - xOut += pDstDrawable->x; - yOut += pDstDrawable->y; - - box_x1 = xIn; - box_y1 = yIn; - box_x2 = xIn + widthSrc; - box_y2 = yIn + heightSrc; - - dx = xIn - xOut; - dy = yIn - yOut; - - /* Don't create a source region if we are doing a fast clip */ - if (fastSrc) - { - RegionPtr cclip; - - fastExpose = TRUE; - /* - * clip the source; if regions extend beyond the source size, - * make sure exposure events get sent - */ - if (box_x1 < pSrcDrawable->x) - { - box_x1 = pSrcDrawable->x; - fastExpose = FALSE; - } - if (box_y1 < pSrcDrawable->y) - { - box_y1 = pSrcDrawable->y; - fastExpose = FALSE; - } - if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) - { - box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; - fastExpose = FALSE; - } - if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) - { - box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; - fastExpose = FALSE; - } - - /* Translate and clip the dst to the destination composite clip */ - box_x1 -= dx; - box_x2 -= dx; - box_y1 -= dy; - box_y2 -= dy; - - /* If the destination composite clip is one rectangle we can - do the clip directly. Otherwise we have to create a full - blown region and call intersect */ - - cclip = fbGetCompositeClip(pGC); - if (RegionNumRects(cclip) == 1) - { - BoxPtr pBox = RegionRects(cclip); - - if (box_x1 < pBox->x1) box_x1 = pBox->x1; - if (box_x2 > pBox->x2) box_x2 = pBox->x2; - if (box_y1 < pBox->y1) box_y1 = pBox->y1; - if (box_y2 > pBox->y2) box_y2 = pBox->y2; - fastDst = TRUE; - } - } - - /* Check to see if the region is empty */ - if (box_x1 >= box_x2 || box_y1 >= box_y2) - { - RegionNull(&rgnDst); - } - else - { - BoxRec box; - box.x1 = box_x1; - box.y1 = box_y1; - box.x2 = box_x2; - box.y2 = box_y2; - RegionInit(&rgnDst, &box, 1); - } - - /* Clip against complex source if needed */ - if (!fastSrc) - { - RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); - RegionTranslate(&rgnDst, -dx, -dy); - } - - /* Clip against complex dest if needed */ - if (!fastDst) - { - RegionIntersect(&rgnDst, &rgnDst, - fbGetCompositeClip(pGC)); - } - - /* Do bit blitting */ - numRects = RegionNumRects(&rgnDst); - if (numRects && widthSrc && heightSrc) - fbCopyRegion (pSrcDrawable, pDstDrawable, pGC, - &rgnDst, dx, dy, copyProc, bitPlane, closure); - - /* Pixmap sources generate a NoExposed (we return NULL to do this) */ - if (!fastExpose && pGC->fExpose) - prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, - xIn - pSrcDrawable->x, - yIn - pSrcDrawable->y, - widthSrc, heightSrc, - xOut - pDstDrawable->x, - yOut - pDstDrawable->y, - (unsigned long) bitPlane); - RegionUninit(&rgnDst); - if (freeSrcClip) - RegionDestroy(prgnSrcClip); - fbValidateDrawable (pDstDrawable); - return prgnExposed; -} - RegionPtr fbCopyArea (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, @@ -595,7 +272,7 @@ fbCopyArea (DrawablePtr pSrcDrawable, int xOut, int yOut) { - fbCopyProc copy; + miCopyProc copy; #ifdef FB_24_32BIT if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) @@ -603,7 +280,7 @@ fbCopyArea (DrawablePtr pSrcDrawable, else #endif copy = fbCopyNtoN; - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, copy, 0, 0); } @@ -620,11 +297,11 @@ fbCopyPlane (DrawablePtr pSrcDrawable, unsigned long bitplane) { if (pSrcDrawable->bitsPerPixel > 1) - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); else if (bitplane & 1) - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopy1toN, (Pixel) bitplane, 0); else diff --git a/nx-X11/programs/Xserver/fb/fboverlay.c b/nx-X11/programs/Xserver/fb/fboverlay.c index 6e0bbf2522..b8d8fe6a13 100644 --- a/nx-X11/programs/Xserver/fb/fboverlay.c +++ b/nx-X11/programs/Xserver/fb/fboverlay.c @@ -249,7 +249,7 @@ fbOverlayCopyWindow(WindowPtr pWin, { RegionTranslate(&layerRgn[i], -dx, -dy); pPixmap = pScrPriv->layer[i].u.run.pixmap; - fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, 0, &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0, (void *)(long) i); diff --git a/nx-X11/programs/Xserver/fb/fboverlay.h b/nx-X11/programs/Xserver/fb/fboverlay.h index 2bb8b176a0..65b057f751 100644 --- a/nx-X11/programs/Xserver/fb/fboverlay.h +++ b/nx-X11/programs/Xserver/fb/fboverlay.h @@ -52,7 +52,7 @@ typedef struct _fbOverlayLayer { typedef struct _fbOverlayScrPriv { int nlayers; fbOverlayPaintKeyProc PaintKey; - fbCopyProc CopyWindow; + miCopyProc CopyWindow; FbOverlayLayer layer[FB_OVERLAY_MAX]; } FbOverlayScrPrivRec, *FbOverlayScrPrivPtr; diff --git a/nx-X11/programs/Xserver/fb/fbwindow.c b/nx-X11/programs/Xserver/fb/fbwindow.c index c4e28de5ba..5a94cd5c08 100644 --- a/nx-X11/programs/Xserver/fb/fbwindow.c +++ b/nx-X11/programs/Xserver/fb/fbwindow.c @@ -141,7 +141,7 @@ fbCopyWindow(WindowPtr pWin, -pPixmap->screen_x, -pPixmap->screen_y); #endif - fbCopyRegion (pDrawable, pDrawable, + miCopyRegion (pDrawable, pDrawable, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c index 1bca067fcf..98f7f58ba6 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c +++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c @@ -614,8 +614,8 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, #endif /* - * Here, before using fbDoCopy() called by fbCopyArea(), - * it should be provided that the cast in fbDoCopy() from + * Here, before using miDoCopy() called by fbCopyArea(), + * it should be provided that the cast in miDoCopy() from * int to short int would not cut off significative bits. */ diff --git a/nx-X11/programs/Xserver/mi/Imakefile b/nx-X11/programs/Xserver/mi/Imakefile index 15e897e8bd..3371fd2bac 100644 --- a/nx-X11/programs/Xserver/mi/Imakefile +++ b/nx-X11/programs/Xserver/mi/Imakefile @@ -84,6 +84,7 @@ SRCS = $(CBRT_SRC) \ migc.c \ micmap.c \ mioverlay.c \ + micopy.c \ $(NXAGENT_SKIP_SRCS) \ $(NULL) @@ -123,6 +124,7 @@ OBJS = $(CBRT_OBJ) \ migc.o \ micmap.o \ mioverlay.o \ + micopy.o \ $(NXAGENT_SKIP_OBJS) \ $(NULL) diff --git a/nx-X11/programs/Xserver/mi/mi.h b/nx-X11/programs/Xserver/mi/mi.h index bc960721b0..18add35562 100644 --- a/nx-X11/programs/Xserver/mi/mi.h +++ b/nx-X11/programs/Xserver/mi/mi.h @@ -55,6 +55,7 @@ SOFTWARE. #include #include "input.h" #include "cursor.h" +#include "colormap.h" #define MiBits CARD32 @@ -134,6 +135,47 @@ extern void miPutImage( char * /*pImage*/ ); +/* micopy.c */ + +#define miGetCompositeClip(pGC) ((pGC)->pCompositeClip) + +typedef void (*miCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +miCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + miCopyProc copyProc, + Pixel bitPlane, + void *closure); + +extern _X_EXPORT RegionPtr +miDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + miCopyProc copyProc, + Pixel bitplane, + void *closure); + /* miclipn.c */ extern void miClipNotify( diff --git a/nx-X11/programs/Xserver/mi/micopy.c b/nx-X11/programs/Xserver/mi/micopy.c new file mode 100644 index 0000000000..d892b516a6 --- /dev/null +++ b/nx-X11/programs/Xserver/mi/micopy.c @@ -0,0 +1,354 @@ +/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmap.h" +#include "pixmapstr.h" +#include "windowstr.h" + +void +miCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + miCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + int careful; + Bool reverse; + Bool upsidedown; + BoxPtr pbox; + int nbox; + BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; + + pbox = RegionRects(pDstRegion); + nbox = RegionNumRects(pDstRegion); + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrcDrawable == pDstDrawable) || + ((pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW))); + + pboxNew1 = NULL; + pboxNew2 = NULL; + if (careful && dy < 0) + { + upsidedown = TRUE; + + if (nbox > 1) + { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); + if(!pboxNew1) + return; + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) + { + while ((pboxNext >= pbox) && + (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + while (pboxTmp <= pboxBase) + { + *pboxNew1++ = *pboxTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + } + } + else + { + /* walk source top to bottom */ + upsidedown = FALSE; + } + + if (careful && dx < 0) + { + /* walk source right to left */ + if (dy <= 0) + reverse = TRUE; + else + reverse = FALSE; + + if (nbox > 1) + { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); + if(!pboxNew2) + { + if (pboxNew1) + DEALLOCATE_LOCAL(pboxNew1); + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) + { + while ((pboxNext < pbox+nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + while (pboxTmp != pboxBase) + { + *pboxNew2++ = *--pboxTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + } + } + else + { + /* walk source left to right */ + reverse = FALSE; + } + + (*copyProc) (pSrcDrawable, + pDstDrawable, + pGC, + pbox, + nbox, + dx, dy, + reverse, upsidedown, bitPlane, closure); + + if (pboxNew1) + DEALLOCATE_LOCAL (pboxNew1); + if (pboxNew2) + DEALLOCATE_LOCAL (pboxNew2); +} + +RegionPtr +miDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + miCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + RegionPtr prgnExposed = NULL; + RegionRec rgnDst; + int dx; + int dy; + int numRects; + int box_x1; + int box_y1; + int box_x2; + int box_y2; + Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ + Bool fastDst = FALSE; /* for fast clipping with one rect dest */ + Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ + + /* Short cut for unmapped windows */ + + if (pDstDrawable->type == DRAWABLE_WINDOW && + !((WindowPtr)pDstDrawable)->realized) + { + return NULL; + } + + if ((pSrcDrawable != pDstDrawable) && + pSrcDrawable->pScreen->SourceValidate) + { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc); + } + + /* Compute source clip region */ + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = miGetCompositeClip(pGC); + else + fastSrc = TRUE; + } + else + { + if (pGC->subWindowMode == IncludeInferiors) + { + /* + * XFree86 DDX empties the border clip when the + * VT is inactive, make sure the region isn't empty + */ + if (!((WindowPtr) pSrcDrawable)->parent && + RegionNotEmpty( + &((WindowPtr) pSrcDrawable)->borderClip)) + { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastSrc = TRUE; + } + else if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) + { + prgnSrcClip = miGetCompositeClip(pGC); + } + else + { + prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); + freeSrcClip = TRUE; + } + } + else + { + prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + } + } + + xIn += pSrcDrawable->x; + yIn += pSrcDrawable->y; + + xOut += pDstDrawable->x; + yOut += pDstDrawable->y; + + box_x1 = xIn; + box_y1 = yIn; + box_x2 = xIn + widthSrc; + box_y2 = yIn + heightSrc; + + dx = xIn - xOut; + dy = yIn - yOut; + + /* Don't create a source region if we are doing a fast clip */ + if (fastSrc) + { + RegionPtr cclip; + + fastExpose = TRUE; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (box_x1 < pSrcDrawable->x) + { + box_x1 = pSrcDrawable->x; + fastExpose = FALSE; + } + if (box_y1 < pSrcDrawable->y) + { + box_y1 = pSrcDrawable->y; + fastExpose = FALSE; + } + if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) + { + box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + fastExpose = FALSE; + } + if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) + { + box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + fastExpose = FALSE; + } + + /* Translate and clip the dst to the destination composite clip */ + box_x1 -= dx; + box_x2 -= dx; + box_y1 -= dy; + box_y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + + cclip = miGetCompositeClip(pGC); + if (RegionNumRects(cclip) == 1) + { + BoxPtr pBox = RegionRects(cclip); + + if (box_x1 < pBox->x1) box_x1 = pBox->x1; + if (box_x2 > pBox->x2) box_x2 = pBox->x2; + if (box_y1 < pBox->y1) box_y1 = pBox->y1; + if (box_y2 > pBox->y2) box_y2 = pBox->y2; + fastDst = TRUE; + } + } + + /* Check to see if the region is empty */ + if (box_x1 >= box_x2 || box_y1 >= box_y2) + { + RegionNull(&rgnDst); + } + else + { + BoxRec box; + box.x1 = box_x1; + box.y1 = box_y1; + box.x2 = box_x2; + box.y2 = box_y2; + RegionInit(&rgnDst, &box, 1); + } + + /* Clip against complex source if needed */ + if (!fastSrc) + { + RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); + RegionTranslate(&rgnDst, -dx, -dy); + } + + /* Clip against complex dest if needed */ + if (!fastDst) + { + RegionIntersect(&rgnDst, &rgnDst, + miGetCompositeClip(pGC)); + } + + /* Do bit blitting */ + numRects = RegionNumRects(&rgnDst); + if (numRects && widthSrc && heightSrc) + miCopyRegion (pSrcDrawable, pDstDrawable, pGC, + &rgnDst, dx, dy, copyProc, bitPlane, closure); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose && pGC->fExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + xIn - pSrcDrawable->x, + yIn - pSrcDrawable->y, + widthSrc, heightSrc, + xOut - pDstDrawable->x, + yOut - pDstDrawable->y, + (unsigned long) bitPlane); + RegionUninit(&rgnDst); + if (freeSrcClip) + RegionDestroy(prgnSrcClip); + return prgnExposed; +}