diff options
Diffstat (limited to 'xorg-server/hw/xfree86')
-rw-r--r-- | xorg-server/hw/xfree86/.gitignore | 1 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/compiler.h | 3 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/dri/dri.c | 14 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/dri2/dri2.c | 23 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/man/Makefile.am | 2 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/man/Xorg.wrap.man | 4 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/man/Xwrapper.config.man | 2 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/modes/xf86RandR12.c | 7 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/shadowfb/shadow.c | 1590 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/xorg-wrapper.c | 75 |
10 files changed, 145 insertions, 1576 deletions
diff --git a/xorg-server/hw/xfree86/.gitignore b/xorg-server/hw/xfree86/.gitignore index fb6830b2c..c84c37ffb 100644 --- a/xorg-server/hw/xfree86/.gitignore +++ b/xorg-server/hw/xfree86/.gitignore @@ -1,4 +1,5 @@ Xorg +Xorg.wrap Xorg.sh xorg.conf.example sdksyms.c diff --git a/xorg-server/hw/xfree86/common/compiler.h b/xorg-server/hw/xfree86/common/compiler.h index afde9f9d3..d6a0d24fc 100644 --- a/xorg-server/hw/xfree86/common/compiler.h +++ b/xorg-server/hw/xfree86/common/compiler.h @@ -103,6 +103,7 @@ #if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) && !defined(__nds32__) \ && !(defined(__alpha__) && defined(linux)) \ && !(defined(__ia64__) && defined(linux)) \ + && !(defined(__mips64) && defined(linux)) \ extern _X_EXPORT void outb(unsigned short, unsigned char); extern _X_EXPORT void outw(unsigned short, unsigned short); @@ -721,7 +722,7 @@ xf86WriteMmio32LeNB(__volatile__ void *base, const unsigned long offset, } #elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__)) -#ifdef __arm32__ +#if defined(__arm32__) || defined(__mips64) #define PORT_SIZE long #else #define PORT_SIZE short diff --git a/xorg-server/hw/xfree86/dri/dri.c b/xorg-server/hw/xfree86/dri/dri.c index 60339995d..95828bbac 100644 --- a/xorg-server/hw/xfree86/dri/dri.c +++ b/xorg-server/hw/xfree86/dri/dri.c @@ -177,19 +177,15 @@ DRIOpenDRMMaster(ScrnInfoPtr pScrn, memset(&tmp, 0, sizeof(tmp)); /* Check the DRM lib version. - * drmGetLibVersion was not supported in version 1.0, so check for - * symbol first to avoid possible crash or hang. */ drmlibmajor = 1; drmlibminor = 0; - if (xf86LoaderCheckSymbol("drmGetLibVersion")) { - drmlibv = drmGetLibVersion(-1); - if (drmlibv != NULL) { - drmlibmajor = drmlibv->version_major; - drmlibminor = drmlibv->version_minor; - drmFreeVersion(drmlibv); - } + drmlibv = drmGetLibVersion(-1); + if (drmlibv != NULL) { + drmlibmajor = drmlibv->version_major; + drmlibminor = drmlibv->version_minor; + drmFreeVersion(drmlibv); } /* Check if the libdrm can handle falling back to loading based on name diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c index 729a323da..76708cabc 100644 --- a/xorg-server/hw/xfree86/dri2/dri2.c +++ b/xorg-server/hw/xfree86/dri2/dri2.c @@ -1092,6 +1092,14 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, return BadDrawable; } + /* According to spec, return expected swapbuffers count SBC after this swap + * will complete. This is ignored unless we return Success, but it must be + * initialized on every path where we return Success or the caller will send + * an uninitialized value off the stack to the client. So let's initialize + * it as early as possible, just to be sure. + */ + *swap_target = pPriv->swap_count + pPriv->swapsPending + 1; + for (i = 0; i < pPriv->bufferCount; i++) { if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft) pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i]; @@ -1149,17 +1157,13 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, * we have to account for the current swap count, interval, and the * number of pending swaps. */ - *swap_target = pPriv->last_swap_target + pPriv->swap_interval; + target_msc = pPriv->last_swap_target + pPriv->swap_interval; } - else { - /* glXSwapBuffersMscOML could have a 0 target_msc, honor it */ - *swap_target = target_msc; - } pPriv->swapsPending++; ret = (*ds->ScheduleSwap) (client, pDraw, pDestBuffer, pSrcBuffer, - swap_target, divisor, remainder, func, data); + &target_msc, divisor, remainder, func, data); if (!ret) { pPriv->swapsPending--; /* didn't schedule */ xf86DrvMsg(pScreen->myNum, X_ERROR, @@ -1167,12 +1171,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, return BadDrawable; } - pPriv->last_swap_target = *swap_target; - - /* According to spec, return expected swapbuffers count SBC after this swap - * will complete. - */ - *swap_target = pPriv->swap_count + pPriv->swapsPending; + pPriv->last_swap_target = target_msc; DRI2InvalidateDrawableAll(pDraw); diff --git a/xorg-server/hw/xfree86/man/Makefile.am b/xorg-server/hw/xfree86/man/Makefile.am index f41d26c4e..5da404cbb 100644 --- a/xorg-server/hw/xfree86/man/Makefile.am +++ b/xorg-server/hw/xfree86/man/Makefile.am @@ -5,4 +5,6 @@ fileman_PRE = xorg.conf.man xorg.conf.d.man if SUID_WRAPPER appman_PRE += Xorg.wrap.man fileman_PRE += Xwrapper.config.man +else +EXTRA_DIST += Xorg.wrap.man Xwrapper.config.man endif diff --git a/xorg-server/hw/xfree86/man/Xorg.wrap.man b/xorg-server/hw/xfree86/man/Xorg.wrap.man index f2153e35b..58937c74b 100644 --- a/xorg-server/hw/xfree86/man/Xorg.wrap.man +++ b/xorg-server/hw/xfree86/man/Xorg.wrap.man @@ -1,4 +1,4 @@ -.\" Xwrapper.wrap.1 +.\" Xwrapper.wrap.__appmansuffix__ .\" .\" Copyright 2014 Red Hat, Inc. .\" @@ -26,7 +26,7 @@ .\" .\" shorthand for double quote that works everywhere. .ds q \N'34' -.TH Xorg.wrap 1 __xorgversion__ +.TH Xorg.wrap __appmansuffix__ __xorgversion__ .SH NAME Xorg.wrap \- Xorg X server binary wrapper .SH DESCRIPTION diff --git a/xorg-server/hw/xfree86/man/Xwrapper.config.man b/xorg-server/hw/xfree86/man/Xwrapper.config.man index 800947c55..5c777c940 100644 --- a/xorg-server/hw/xfree86/man/Xwrapper.config.man +++ b/xorg-server/hw/xfree86/man/Xwrapper.config.man @@ -1 +1 @@ -.so man1/Xorg.wrap.1 +.so man__appmansuffix__/Xorg.wrap.__appmansuffix__ diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c index 66139dcf0..8a04dfc2c 100644 --- a/xorg-server/hw/xfree86/modes/xf86RandR12.c +++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c @@ -1256,12 +1256,13 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) CARD16 *tmp_ptr; tmp_ptr = - realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof(CARD16)); + realloc(crtc->gamma_red, + 3 * randr_crtc->gammaSize * sizeof(CARD16)); if (!tmp_ptr) return FALSE; crtc->gamma_red = tmp_ptr; - crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; - crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; + crtc->gamma_green = crtc->gamma_red + randr_crtc->gammaSize; + crtc->gamma_blue = crtc->gamma_green + randr_crtc->gammaSize; } crtc->gamma_size = randr_crtc->gammaSize; diff --git a/xorg-server/hw/xfree86/shadowfb/shadow.c b/xorg-server/hw/xfree86/shadowfb/shadow.c index 43529398a..10f72cc99 100644 --- a/xorg-server/hw/xfree86/shadowfb/shadow.c +++ b/xorg-server/hw/xfree86/shadowfb/shadow.c @@ -1,8 +1,8 @@ /* Copyright (C) 1999. The XFree86 Project Inc. + Copyright 2014 Red Hat, Inc. Written by Mark Vojkovich (mvojkovi@ucsd.edu) - Pre-fb-write callbacks and RENDER support - Nolan Leake (nolan@vmware.com) */ @@ -29,107 +29,23 @@ #include "picturestr.h" static Bool ShadowCloseScreen(ScreenPtr pScreen); -static void ShadowCopyWindow(WindowPtr pWin, - DDXPointRec ptOldOrg, RegionPtr prgn); -static Bool ShadowCreateGC(GCPtr pGC); - -static Bool ShadowEnterVT(ScrnInfoPtr pScrn); -static void ShadowLeaveVT(ScrnInfoPtr pScrn); - -static void ShadowComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, CARD16 width, CARD16 height); +static Bool ShadowCreateScreenResources(ScreenPtr pScreen); typedef struct { ScrnInfoPtr pScrn; RefreshAreaFuncPtr preRefresh; RefreshAreaFuncPtr postRefresh; CloseScreenProcPtr CloseScreen; - CopyWindowProcPtr CopyWindow; - CreateGCProcPtr CreateGC; - ModifyPixmapHeaderProcPtr ModifyPixmapHeader; - CompositeProcPtr Composite; - Bool (*EnterVT) (ScrnInfoPtr); - void (*LeaveVT) (ScrnInfoPtr); - Bool vtSema; + CreateScreenResourcesProcPtr CreateScreenResources; } ShadowScreenRec, *ShadowScreenPtr; -typedef struct { - const GCOps *ops; - const GCFuncs *funcs; -} ShadowGCRec, *ShadowGCPtr; - static DevPrivateKeyRec ShadowScreenKeyRec; -#define ShadowScreenKey (&ShadowScreenKeyRec) - -static DevPrivateKeyRec ShadowGCKeyRec; - -#define ShadowGCKey (&ShadowGCKeyRec) - -#define GET_SCREEN_PRIVATE(pScreen) \ - (ShadowScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, ShadowScreenKey) -#define GET_GC_PRIVATE(pGC) \ - (ShadowGCPtr)dixLookupPrivate(&(pGC)->devPrivates, ShadowGCKey) - -#define SHADOW_GC_FUNC_PROLOGUE(pGC)\ - ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\ - (pGC)->funcs = pGCPriv->funcs;\ - if(pGCPriv->ops)\ - (pGC)->ops = pGCPriv->ops - -#define SHADOW_GC_FUNC_EPILOGUE(pGC)\ - pGCPriv->funcs = (pGC)->funcs;\ - (pGC)->funcs = &ShadowGCFuncs;\ - if(pGCPriv->ops) {\ - pGCPriv->ops = (pGC)->ops;\ - (pGC)->ops = &ShadowGCOps;\ - } - -#define SHADOW_GC_OP_PROLOGUE(pGC)\ - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \ - ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\ - const GCFuncs *oldFuncs = pGC->funcs;\ - pGC->funcs = pGCPriv->funcs;\ - pGC->ops = pGCPriv->ops - -#define SHADOW_GC_OP_EPILOGUE(pGC)\ - pGCPriv->ops = pGC->ops;\ - pGC->funcs = oldFuncs;\ - pGC->ops = &ShadowGCOps - -#define IS_VISIBLE(pWin) (pPriv->vtSema && \ - (((WindowPtr)pWin)->visibility != VisibilityFullyObscured)) - -#define TRIM_BOX(box, pGC) { \ - BoxPtr extents = &pGC->pCompositeClip->extents;\ - if(box.x1 < extents->x1) box.x1 = extents->x1; \ - if(box.x2 > extents->x2) box.x2 = extents->x2; \ - if(box.y1 < extents->y1) box.y1 = extents->y1; \ - if(box.y2 > extents->y2) box.y2 = extents->y2; \ - } - -#define TRANSLATE_BOX(box, pDraw) { \ - box.x1 += pDraw->x; \ - box.x2 += pDraw->x; \ - box.y1 += pDraw->y; \ - box.y2 += pDraw->y; \ - } - -#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \ - TRANSLATE_BOX(box, pDraw); \ - TRIM_BOX(box, pGC); \ - } - -#define BOX_NOT_EMPTY(box) \ - (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) +static ShadowScreenPtr +shadowfbGetScreenPrivate(ScreenPtr pScreen) +{ + return dixLookupPrivate(&(pScreen)->devPrivates, &ShadowScreenKeyRec); +} Bool ShadowFBInit2(ScreenPtr pScreen, @@ -138,7 +54,6 @@ ShadowFBInit2(ScreenPtr pScreen, { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); ShadowScreenPtr pPriv; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); if (!preRefreshArea && !postRefreshArea) return FALSE; @@ -146,39 +61,20 @@ ShadowFBInit2(ScreenPtr pScreen, if (!dixRegisterPrivateKey(&ShadowScreenKeyRec, PRIVATE_SCREEN, 0)) return FALSE; - if (!dixRegisterPrivateKey - (&ShadowGCKeyRec, PRIVATE_GC, sizeof(ShadowGCRec))) - return FALSE; - if (!(pPriv = (ShadowScreenPtr) malloc(sizeof(ShadowScreenRec)))) return FALSE; - dixSetPrivate(&pScreen->devPrivates, ShadowScreenKey, pPriv); + dixSetPrivate(&pScreen->devPrivates, &ShadowScreenKeyRec, pPriv); pPriv->pScrn = pScrn; pPriv->preRefresh = preRefreshArea; pPriv->postRefresh = postRefreshArea; - pPriv->vtSema = TRUE; pPriv->CloseScreen = pScreen->CloseScreen; - pPriv->CopyWindow = pScreen->CopyWindow; - pPriv->CreateGC = pScreen->CreateGC; - pPriv->ModifyPixmapHeader = pScreen->ModifyPixmapHeader; - - pPriv->EnterVT = pScrn->EnterVT; - pPriv->LeaveVT = pScrn->LeaveVT; + pPriv->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CloseScreen = ShadowCloseScreen; - pScreen->CopyWindow = ShadowCopyWindow; - pScreen->CreateGC = ShadowCreateGC; - - pScrn->EnterVT = ShadowEnterVT; - pScrn->LeaveVT = ShadowLeaveVT; - - if (ps) { - pPriv->Composite = ps->Composite; - ps->Composite = ShadowComposite; - } + pScreen->CreateScreenResources = ShadowCreateScreenResources; return TRUE; } @@ -189,1451 +85,83 @@ ShadowFBInit(ScreenPtr pScreen, RefreshAreaFuncPtr refreshArea) return ShadowFBInit2(pScreen, NULL, refreshArea); } -/**********************************************************/ - -static Bool -ShadowEnterVT(ScrnInfoPtr pScrn) -{ - Bool ret; - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen); - - pScrn->EnterVT = pPriv->EnterVT; - ret = (*pPriv->EnterVT) (pScrn); - pPriv->EnterVT = pScrn->EnterVT; - pScrn->EnterVT = ShadowEnterVT; - if (ret) { - pPriv->vtSema = TRUE; - return TRUE; - } - - return FALSE; -} - -static void -ShadowLeaveVT(ScrnInfoPtr pScrn) -{ - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen); - - pPriv->vtSema = FALSE; - - pScrn->LeaveVT = pPriv->LeaveVT; - (*pPriv->LeaveVT) (pScrn); - pPriv->LeaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = ShadowLeaveVT; -} - -/**********************************************************/ - -static Bool -ShadowCloseScreen(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen); - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - - pScreen->CloseScreen = pPriv->CloseScreen; - pScreen->CopyWindow = pPriv->CopyWindow; - pScreen->CreateGC = pPriv->CreateGC; - pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader; - - pScrn->EnterVT = pPriv->EnterVT; - pScrn->LeaveVT = pPriv->LeaveVT; - - if (ps) { - ps->Composite = pPriv->Composite; - } - - free((void *) pPriv); - - return (*pScreen->CloseScreen) (pScreen); -} +/* + * Note that we don't do DamageEmpty, or indeed look at the region inside the + * DamagePtr at all. This is an optimization, believe it or not. The + * incoming RegionPtr is the new damage, and if we were to empty the region + * miext/damage would just have to waste time reallocating and re-unioning + * it every time, whereas if we leave it around the union gets fast-pathed + * away. + */ static void -ShadowCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgn) +shadowfbReportPre(DamagePtr damage, RegionPtr reg, void *closure) { - ScreenPtr pScreen = pWin->drawable.pScreen; - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen); - int num = 0; - RegionRec rgnDst; - - if (pPriv->vtSema) { - RegionNull(&rgnDst); - RegionCopy(&rgnDst, prgn); - - RegionTranslate(&rgnDst, - pWin->drawable.x - ptOldOrg.x, - pWin->drawable.y - ptOldOrg.y); - RegionIntersect(&rgnDst, &pWin->borderClip, &rgnDst); - if ((num = RegionNumRects(&rgnDst))) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst)); - } - else { - RegionUninit(&rgnDst); - } - } + ShadowScreenPtr pPriv = closure; - pScreen->CopyWindow = pPriv->CopyWindow; - (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn); - pScreen->CopyWindow = ShadowCopyWindow; + if (!pPriv->pScrn->vtSema) + return; - if (num) { - if (pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst)); - RegionUninit(&rgnDst); - } + pPriv->preRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg)); } static void -ShadowComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) +shadowfbReportPost(DamagePtr damage, RegionPtr reg, void *closure) { - ScreenPtr pScreen = pDst->pDrawable->pScreen; - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen); - PictureScreenPtr ps = GetPictureScreen(pScreen); - BoxRec box; - BoxPtr extents; - Bool boxNotEmpty = FALSE; + ShadowScreenPtr pPriv = closure; - if (pPriv->vtSema && pDst->pDrawable->type == DRAWABLE_WINDOW) { + if (!pPriv->pScrn->vtSema) + return; - box.x1 = pDst->pDrawable->x + xDst; - box.y1 = pDst->pDrawable->y + yDst; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - extents = &pDst->pCompositeClip->extents; - if (box.x1 < extents->x1) - box.x1 = extents->x1; - if (box.x2 > extents->x2) - box.x2 = extents->x2; - if (box.y1 < extents->y1) - box.y1 = extents->y1; - if (box.y2 > extents->y2) - box.y2 = extents->y2; - - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - ps->Composite = pPriv->Composite; - (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height); - ps->Composite = ShadowComposite; - - if (pPriv->postRefresh && boxNotEmpty) { - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } + pPriv->postRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg)); } -/**********************************************************/ - -static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr); -static void ShadowChangeGC(GCPtr, unsigned long); -static void ShadowCopyGC(GCPtr, unsigned long, GCPtr); -static void ShadowDestroyGC(GCPtr); -static void ShadowChangeClip(GCPtr, int, void *, int); -static void ShadowDestroyClip(GCPtr); -static void ShadowCopyClip(GCPtr, GCPtr); - -GCFuncs ShadowGCFuncs = { - ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC, - ShadowChangeClip, ShadowDestroyClip, ShadowCopyClip -}; - -extern GCOps ShadowGCOps; - static Bool -ShadowCreateGC(GCPtr pGC) +ShadowCreateScreenResources(ScreenPtr pScreen) { - ScreenPtr pScreen = pGC->pScreen; - ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen); - ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC); Bool ret; + WindowPtr pWin = pScreen->root; + ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen); - pScreen->CreateGC = pPriv->CreateGC; - if ((ret = (*pScreen->CreateGC) (pGC))) { - pGCPriv->ops = NULL; - pGCPriv->funcs = pGC->funcs; - pGC->funcs = &ShadowGCFuncs; - } - pScreen->CreateGC = ShadowCreateGC; - - return ret; -} - -static void -ShadowValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw) -{ - SHADOW_GC_FUNC_PROLOGUE(pGC); - (*pGC->funcs->ValidateGC) (pGC, changes, pDraw); - if (pDraw->type == DRAWABLE_WINDOW) - pGCPriv->ops = pGC->ops; /* just so it's not NULL */ - else - pGCPriv->ops = NULL; - SHADOW_GC_FUNC_EPILOGUE(pGC); -} - -static void -ShadowDestroyGC(GCPtr pGC) -{ - SHADOW_GC_FUNC_PROLOGUE(pGC); - (*pGC->funcs->DestroyGC) (pGC); - SHADOW_GC_FUNC_EPILOGUE(pGC); -} - -static void -ShadowChangeGC(GCPtr pGC, unsigned long mask) -{ - SHADOW_GC_FUNC_PROLOGUE(pGC); - (*pGC->funcs->ChangeGC) (pGC, mask); - SHADOW_GC_FUNC_EPILOGUE(pGC); -} + pScreen->CreateScreenResources = pPriv->CreateScreenResources; + ret = pScreen->CreateScreenResources(pScreen); + pPriv->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = ShadowCreateScreenResources; -static void -ShadowCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) -{ - SHADOW_GC_FUNC_PROLOGUE(pGCDst); - (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - SHADOW_GC_FUNC_EPILOGUE(pGCDst); -} - -static void -ShadowChangeClip(GCPtr pGC, int type, void *pvalue, int nrects) -{ - SHADOW_GC_FUNC_PROLOGUE(pGC); - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - SHADOW_GC_FUNC_EPILOGUE(pGC); -} - -static void -ShadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - SHADOW_GC_FUNC_PROLOGUE(pgcDst); - (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc); - SHADOW_GC_FUNC_EPILOGUE(pgcDst); -} - -static void -ShadowDestroyClip(GCPtr pGC) -{ - SHADOW_GC_FUNC_PROLOGUE(pGC); - (*pGC->funcs->DestroyClip) (pGC); - SHADOW_GC_FUNC_EPILOGUE(pGC); -} - -/**********************************************************/ - -static void -ShadowFillSpans(DrawablePtr pDraw, - GC * pGC, - int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted) -{ - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nInit) { - DDXPointPtr ppt = pptInit; - int *pwidth = pwidthInit; - int i = nInit; - BoxRec box; - Bool boxNotEmpty = FALSE; - - box.x1 = ppt->x; - box.x2 = box.x1 + *pwidth; - box.y2 = box.y1 = ppt->y; - - while (--i) { - ppt++; - pwidth++; - if (box.x1 > ppt->x) - box.x1 = ppt->x; - if (box.x2 < (ppt->x + *pwidth)) - box.x2 = ppt->x + *pwidth; - if (box.y1 > ppt->y) - box.y1 = ppt->y; - else if (box.y2 < ppt->y) - box.y2 = ppt->y; - } - - box.y2++; - - if (!pGC->miTranslate) { - TRANSLATE_BOX(box, pDraw); - } - TRIM_BOX(box, pGC); - - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - - (*pGC->ops->FillSpans) (pDraw, pGC, nInit, pptInit, pwidthInit, - fSorted); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } - else - (*pGC->ops->FillSpans) (pDraw, pGC, nInit, pptInit, pwidthInit, - fSorted); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowSetSpans(DrawablePtr pDraw, - GCPtr pGC, - char *pcharsrc, - DDXPointPtr pptInit, int *pwidthInit, int nspans, int fSorted) -{ - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nspans) { - DDXPointPtr ppt = pptInit; - int *pwidth = pwidthInit; - int i = nspans; - BoxRec box; - Bool boxNotEmpty = FALSE; - - box.x1 = ppt->x; - box.x2 = box.x1 + *pwidth; - box.y2 = box.y1 = ppt->y; - - while (--i) { - ppt++; - pwidth++; - if (box.x1 > ppt->x) - box.x1 = ppt->x; - if (box.x2 < (ppt->x + *pwidth)) - box.x2 = ppt->x + *pwidth; - if (box.y1 > ppt->y) - box.y1 = ppt->y; - else if (box.y2 < ppt->y) - box.y2 = ppt->y; - } - - box.y2++; - - if (!pGC->miTranslate) { - TRANSLATE_BOX(box, pDraw); - } - TRIM_BOX(box, pGC); - - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - - (*pGC->ops->SetSpans) (pDraw, pGC, pcharsrc, pptInit, - pwidthInit, nspans, fSorted); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } - else - (*pGC->ops->SetSpans) (pDraw, pGC, pcharsrc, pptInit, - pwidthInit, nspans, fSorted); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPutImage(DrawablePtr pDraw, - GCPtr pGC, - int depth, - int x, int y, int w, int h, - int leftPad, int format, char *pImage) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw)) { - box.x1 = x + pDraw->x; - box.x2 = box.x1 + w; - box.y1 = y + pDraw->y; - box.y2 = box.y1 + h; + /* this might look like it leaks, but the damage code reaps listeners + * when their drawable disappears. + */ + if (ret) { + DamagePtr damage; - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; + if (pPriv->preRefresh) { + damage = DamageCreate(shadowfbReportPre, NULL, + DamageReportRawRegion, + TRUE, pScreen, pPriv); + DamageRegister(&pWin->drawable, damage); } - } - - (*pGC->ops->PutImage) (pDraw, pGC, depth, x, y, w, h, - leftPad, format, pImage); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static RegionPtr -ShadowCopyArea(DrawablePtr pSrc, - DrawablePtr pDst, - GC * pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - RegionPtr ret; - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDst)) { - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; + if (pPriv->postRefresh) { + damage = DamageCreate(shadowfbReportPost, NULL, + DamageReportRawRegion, + TRUE, pScreen, pPriv); + DamageSetReportAfterOp(damage, TRUE); + DamageRegister(&pWin->drawable, damage); } } - ret = (*pGC->ops->CopyArea) (pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); - return ret; } -static RegionPtr -ShadowCopyPlane(DrawablePtr pSrc, - DrawablePtr pDst, - GCPtr pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty, unsigned long bitPlane) -{ - RegionPtr ret; - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDst)) { - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - ret = (*pGC->ops->CopyPlane) (pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty, - bitPlane); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); - - return ret; -} - -static void -ShadowPolyPoint(DrawablePtr pDraw, - GCPtr pGC, int mode, int nptInit, xPoint * pptInit) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nptInit) { - xPoint *ppt = pptInit; - int npt = nptInit; - - box.x2 = box.x1 = pptInit->x; - box.y2 = box.y1 = pptInit->y; - - /* this could be slow if the points were spread out */ - - while (--npt) { - ppt++; - if (box.x1 > ppt->x) - box.x1 = ppt->x; - else if (box.x2 < ppt->x) - box.x2 = ppt->x; - if (box.y1 > ppt->y) - box.y1 = ppt->y; - else if (box.y2 < ppt->y) - box.y2 = ppt->y; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PolyPoint) (pDraw, pGC, mode, nptInit, pptInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolylines(DrawablePtr pDraw, - GCPtr pGC, int mode, int nptInit, DDXPointPtr pptInit) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nptInit) { - DDXPointPtr ppt = pptInit; - int npt = nptInit; - int extra = pGC->lineWidth >> 1; - - box.x2 = box.x1 = pptInit->x; - box.y2 = box.y1 = pptInit->y; - - if (npt > 1) { - if (pGC->joinStyle == JoinMiter) - extra = 6 * pGC->lineWidth; - else if (pGC->capStyle == CapProjecting) - extra = pGC->lineWidth; - } - - if (mode == CoordModePrevious) { - int x = box.x1; - int y = box.y1; - - while (--npt) { - ppt++; - x += ppt->x; - y += ppt->y; - if (box.x1 > x) - box.x1 = x; - else if (box.x2 < x) - box.x2 = x; - if (box.y1 > y) - box.y1 = y; - else if (box.y2 < y) - box.y2 = y; - } - } - else { - while (--npt) { - ppt++; - if (box.x1 > ppt->x) - box.x1 = ppt->x; - else if (box.x2 < ppt->x) - box.x2 = ppt->x; - if (box.y1 > ppt->y) - box.y1 = ppt->y; - else if (box.y2 < ppt->y) - box.y2 = ppt->y; - } - } - - box.x2++; - box.y2++; - - if (extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->Polylines) (pDraw, pGC, mode, nptInit, pptInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolySegment(DrawablePtr pDraw, - GCPtr pGC, int nsegInit, xSegment * pSegInit) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nsegInit) { - int extra = pGC->lineWidth; - xSegment *pSeg = pSegInit; - int nseg = nsegInit; - - if (pGC->capStyle != CapProjecting) - extra >>= 1; - - if (pSeg->x2 > pSeg->x1) { - box.x1 = pSeg->x1; - box.x2 = pSeg->x2; - } - else { - box.x2 = pSeg->x1; - box.x1 = pSeg->x2; - } - - if (pSeg->y2 > pSeg->y1) { - box.y1 = pSeg->y1; - box.y2 = pSeg->y2; - } - else { - box.y2 = pSeg->y1; - box.y1 = pSeg->y2; - } - - while (--nseg) { - pSeg++; - if (pSeg->x2 > pSeg->x1) { - if (pSeg->x1 < box.x1) - box.x1 = pSeg->x1; - if (pSeg->x2 > box.x2) - box.x2 = pSeg->x2; - } - else { - if (pSeg->x2 < box.x1) - box.x1 = pSeg->x2; - if (pSeg->x1 > box.x2) - box.x2 = pSeg->x1; - } - if (pSeg->y2 > pSeg->y1) { - if (pSeg->y1 < box.y1) - box.y1 = pSeg->y1; - if (pSeg->y2 > box.y2) - box.y2 = pSeg->y2; - } - else { - if (pSeg->y2 < box.y1) - box.y1 = pSeg->y2; - if (pSeg->y1 > box.y2) - box.y2 = pSeg->y1; - } - } - - box.x2++; - box.y2++; - - if (extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PolySegment) (pDraw, pGC, nsegInit, pSegInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolyRectangle(DrawablePtr pDraw, - GCPtr pGC, int nRectsInit, xRectangle *pRectsInit) -{ - BoxRec box; - BoxPtr pBoxInit = NULL; - Bool boxNotEmpty = FALSE; - int num = 0; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nRectsInit) { - xRectangle *pRects = pRectsInit; - int nRects = nRectsInit; - - if (nRects >= 32) { - int extra = pGC->lineWidth >> 1; - - box.x1 = pRects->x; - box.x2 = box.x1 + pRects->width; - box.y1 = pRects->y; - box.y2 = box.y1 + pRects->height; - - while (--nRects) { - pRects++; - if (box.x1 > pRects->x) - box.x1 = pRects->x; - if (box.x2 < (pRects->x + pRects->width)) - box.x2 = pRects->x + pRects->width; - if (box.y1 > pRects->y) - box.y1 = pRects->y; - if (box.y2 < (pRects->y + pRects->height)) - box.y2 = pRects->y + pRects->height; - } - - if (extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - else { - BoxPtr pbox; - int offset1, offset2, offset3; - - offset2 = pGC->lineWidth; - if (!offset2) - offset2 = 1; - offset1 = offset2 >> 1; - offset3 = offset2 - offset1; - - pBoxInit = (BoxPtr) malloc(nRects * 4 * sizeof(BoxRec)); - pbox = pBoxInit; - - while (nRects--) { - pbox->x1 = pRects->x - offset1; - pbox->y1 = pRects->y - offset1; - pbox->x2 = pbox->x1 + pRects->width + offset2; - pbox->y2 = pbox->y1 + offset2; - TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC); - if (BOX_NOT_EMPTY((*pbox))) { - num++; - pbox++; - } - - pbox->x1 = pRects->x - offset1; - pbox->y1 = pRects->y + offset3; - pbox->x2 = pbox->x1 + offset2; - pbox->y2 = pbox->y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC); - if (BOX_NOT_EMPTY((*pbox))) { - num++; - pbox++; - } - - pbox->x1 = pRects->x + pRects->width - offset1; - pbox->y1 = pRects->y + offset3; - pbox->x2 = pbox->x1 + offset2; - pbox->y2 = pbox->y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC); - if (BOX_NOT_EMPTY((*pbox))) { - num++; - pbox++; - } - - pbox->x1 = pRects->x - offset1; - pbox->y1 = pRects->y + pRects->height - offset1; - pbox->x2 = pbox->x1 + pRects->width + offset2; - pbox->y2 = pbox->y1 + offset2; - TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC); - if (BOX_NOT_EMPTY((*pbox))) { - num++; - pbox++; - } - - pRects++; - } - - if (num) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, num, pBoxInit); - } - else { - free(pBoxInit); - } - } - } - - (*pGC->ops->PolyRectangle) (pDraw, pGC, nRectsInit, pRectsInit); - - if (boxNotEmpty && pPriv->postRefresh) { - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } - else if (num) { - if (pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, num, pBoxInit); - free(pBoxInit); - } - - SHADOW_GC_OP_EPILOGUE(pGC); - -} - -static void -ShadowPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcsInit, xArc * parcsInit) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && narcsInit) { - int narcs = narcsInit; - xArc *parcs = parcsInit; - int extra = pGC->lineWidth >> 1; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - while (--narcs) { - parcs++; - if (box.x1 > parcs->x) - box.x1 = parcs->x; - if (box.x2 < (parcs->x + parcs->width)) - box.x2 = parcs->x + parcs->width; - if (box.y1 > parcs->y) - box.y1 = parcs->y; - if (box.y2 < (parcs->y + parcs->height)) - box.y2 = parcs->y + parcs->height; - } - - if (extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PolyArc) (pDraw, pGC, narcsInit, parcsInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); - -} - -static void -ShadowFillPolygon(DrawablePtr pDraw, - GCPtr pGC, - int shape, int mode, int count, DDXPointPtr pptInit) -{ - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && (count > 2)) { - DDXPointPtr ppt = pptInit; - int i = count; - BoxRec box; - Bool boxNotEmpty = FALSE; - - box.x2 = box.x1 = ppt->x; - box.y2 = box.y1 = ppt->y; - - if (mode != CoordModeOrigin) { - int x = box.x1; - int y = box.y1; - - while (--i) { - ppt++; - x += ppt->x; - y += ppt->y; - if (box.x1 > x) - box.x1 = x; - else if (box.x2 < x) - box.x2 = x; - if (box.y1 > y) - box.y1 = y; - else if (box.y2 < y) - box.y2 = y; - } - } - else { - while (--i) { - ppt++; - if (box.x1 > ppt->x) - box.x1 = ppt->x; - else if (box.x2 < ppt->x) - box.x2 = ppt->x; - if (box.y1 > ppt->y) - box.y1 = ppt->y; - else if (box.y2 < ppt->y) - box.y2 = ppt->y; - } - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - - (*pGC->ops->FillPolygon) (pDraw, pGC, shape, mode, count, pptInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } - else - (*pGC->ops->FillPolygon) (pDraw, pGC, shape, mode, count, pptInit); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolyFillRect(DrawablePtr pDraw, - GCPtr pGC, int nRectsInit, xRectangle *pRectsInit) -{ - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nRectsInit) { - BoxRec box; - Bool boxNotEmpty = FALSE; - xRectangle *pRects = pRectsInit; - int nRects = nRectsInit; - - box.x1 = pRects->x; - box.x2 = box.x1 + pRects->width; - box.y1 = pRects->y; - box.y2 = box.y1 + pRects->height; - - while (--nRects) { - pRects++; - if (box.x1 > pRects->x) - box.x1 = pRects->x; - if (box.x2 < (pRects->x + pRects->width)) - box.x2 = pRects->x + pRects->width; - if (box.y1 > pRects->y) - box.y1 = pRects->y; - if (box.y2 < (pRects->y + pRects->height)) - box.y2 = pRects->y + pRects->height; - } - - /* cfb messes with the pRectsInit so we have to do our - calculations first */ - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - - (*pGC->ops->PolyFillRect) (pDraw, pGC, nRectsInit, pRectsInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - } - else - (*pGC->ops->PolyFillRect) (pDraw, pGC, nRectsInit, pRectsInit); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcsInit, xArc * parcsInit) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && narcsInit) { - xArc *parcs = parcsInit; - int narcs = narcsInit; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - while (--narcs) { - parcs++; - if (box.x1 > parcs->x) - box.x1 = parcs->x; - if (box.x2 < (parcs->x + parcs->width)) - box.x2 = parcs->x + parcs->width; - if (box.y1 > parcs->y) - box.y1 = parcs->y; - if (box.y2 < (parcs->y + parcs->height)) - box.y2 = parcs->y + parcs->height; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PolyFillArc) (pDraw, pGC, narcsInit, parcsInit); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowTextExtent(FontPtr pFont, int count, char *chars, - FontEncoding fontEncoding, BoxPtr box) -{ - unsigned long n, i; - int w; - CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ - - GetGlyphs(pFont, (unsigned long) count, (unsigned char *) chars, - fontEncoding, &n, charinfo); - w = 0; - for (i = 0; i < n; i++) { - w += charinfo[i]->metrics.characterWidth; - } - if (i) { - w += charinfo[i - 1]->metrics.rightSideBearing; - } - - box->x1 = 0; - if (n) { - if (charinfo[0]->metrics.leftSideBearing < 0) { - box->x1 = charinfo[0]->metrics.leftSideBearing; - } - } - box->x2 = w; - box->y1 = -FONTMAXBOUNDS(pFont, ascent); - box->y2 = FONTMAXBOUNDS(pFont, descent); -} - -static void -ShadowFontToBox(BoxPtr BB, DrawablePtr pDrawable, GCPtr pGC, int x, int y, - int count, char *chars, int wide) -{ - FontPtr pFont; - - pFont = pGC->font; - if (pFont->info.constantWidth) { - int ascent, descent, left, right = 0; - - ascent = max(pFont->info.fontAscent, pFont->info.maxbounds.ascent); - descent = max(pFont->info.fontDescent, pFont->info.maxbounds.descent); - left = pFont->info.maxbounds.leftSideBearing; - if (count > 0) { - right = (count - 1) * pFont->info.maxbounds.characterWidth; - } - right += pFont->info.maxbounds.rightSideBearing; - BB->x1 = - max(pDrawable->x + x - left, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->x1); - BB->y1 = - max(pDrawable->y + y - ascent, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->y1); - BB->x2 = - min(pDrawable->x + x + right, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->x2); - BB->y2 = - min(pDrawable->y + y + descent, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->y2); - } - else { - ShadowTextExtent(pFont, count, chars, wide ? (FONTLASTROW(pFont) == 0) - ? Linear16Bit : TwoD16Bit : Linear8Bit, BB); - BB->x1 = - max(pDrawable->x + x + BB->x1, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->x1); - BB->y1 = - max(pDrawable->y + y + BB->y1, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->y1); - BB->x2 = - min(pDrawable->x + x + BB->x2, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->x2); - BB->y2 = - min(pDrawable->y + y + BB->y2, - RegionExtents(&((WindowPtr) pDrawable)->winSize)->y2); - } -} - -static int -ShadowPolyText8(DrawablePtr pDraw, - GCPtr pGC, int x, int y, int count, char *chars) -{ - int width; - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw)) { - ShadowFontToBox(&box, pDraw, pGC, x, y, count, chars, 0); - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - width = (*pGC->ops->PolyText8) (pDraw, pGC, x, y, count, chars); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); - - return width; -} - -static int -ShadowPolyText16(DrawablePtr pDraw, - GCPtr pGC, int x, int y, int count, unsigned short *chars) -{ - int width; - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw)) { - ShadowFontToBox(&box, pDraw, pGC, x, y, count, (char *) chars, 1); - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - width = (*pGC->ops->PolyText16) (pDraw, pGC, x, y, count, chars); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); - - return width; -} - -static void -ShadowImageText8(DrawablePtr pDraw, - GCPtr pGC, int x, int y, int count, char *chars) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && count) { - int top, bot, Min, Max; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if (Min > 0) - Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if (Max < 0) - Max = 0; - - /* ugh */ - box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->ImageText8) (pDraw, pGC, x, y, count, chars); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowImageText16(DrawablePtr pDraw, - GCPtr pGC, int x, int y, int count, unsigned short *chars) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && count) { - int top, bot, Min, Max; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if (Min > 0) - Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if (Max < 0) - Max = 0; - - /* ugh */ - box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->ImageText16) (pDraw, pGC, x, y, count, chars); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowImageGlyphBlt(DrawablePtr pDraw, - GCPtr pGC, - int x, int y, - unsigned int nglyphInit, - CharInfoPtr * ppciInit, void *pglyphBase) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nglyphInit) { - CharInfoPtr *ppci = ppciInit; - unsigned int nglyph = nglyphInit; - int top, bot, width = 0; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - box.x1 = ppci[0]->metrics.leftSideBearing; - if (box.x1 > 0) - box.x1 = 0; - box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing - - ppci[nglyph - 1]->metrics.characterWidth; - if (box.x2 < 0) - box.x2 = 0; - - box.x2 += pDraw->x + x; - box.x1 += pDraw->x + x; - - while (nglyph--) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if (width > 0) - box.x2 += width; - else - box.x1 += width; - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->ImageGlyphBlt) (pDraw, pGC, x, y, nglyphInit, - ppciInit, pglyphBase); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPolyGlyphBlt(DrawablePtr pDraw, - GCPtr pGC, - int x, int y, - unsigned int nglyphInit, - CharInfoPtr * ppciInit, void *pglyphBase) -{ - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw) && nglyphInit) { - CharInfoPtr *ppci = ppciInit; - unsigned int nglyph = nglyphInit; - - /* ugh */ - box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing; - box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing; - - if (nglyph > 1) { - int width = 0; - - while (--nglyph) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if (width > 0) - box.x2 += width; - else - box.x1 += width; - } - - box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PolyGlyphBlt) (pDraw, pGC, x, y, nglyphInit, - ppciInit, pglyphBase); - - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); - - SHADOW_GC_OP_EPILOGUE(pGC); -} - -static void -ShadowPushPixels(GCPtr pGC, - PixmapPtr pBitMap, - DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg) +static Bool +ShadowCloseScreen(ScreenPtr pScreen) { - BoxRec box; - Bool boxNotEmpty = FALSE; - - SHADOW_GC_OP_PROLOGUE(pGC); - - if (IS_VISIBLE(pDraw)) { - box.x1 = xOrg; - box.y1 = yOrg; - - if (!pGC->miTranslate) { - box.x1 += pDraw->x; - box.y1 += pDraw->y; - } + ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen); - box.x2 = box.x1 + dx; - box.y2 = box.y1 + dy; - - TRIM_BOX(box, pGC); - if (BOX_NOT_EMPTY(box)) { - if (pPriv->preRefresh) - (*pPriv->preRefresh) (pPriv->pScrn, 1, &box); - boxNotEmpty = TRUE; - } - } - - (*pGC->ops->PushPixels) (pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg); + pScreen->CloseScreen = pPriv->CloseScreen; + pScreen->CreateScreenResources = pPriv->CreateScreenResources; - if (boxNotEmpty && pPriv->postRefresh) - (*pPriv->postRefresh) (pPriv->pScrn, 1, &box); + free(pPriv); - SHADOW_GC_OP_EPILOGUE(pGC); + return (*pScreen->CloseScreen) (pScreen); } - -GCOps ShadowGCOps = { - ShadowFillSpans, ShadowSetSpans, - ShadowPutImage, ShadowCopyArea, - ShadowCopyPlane, ShadowPolyPoint, - ShadowPolylines, ShadowPolySegment, - ShadowPolyRectangle, ShadowPolyArc, - ShadowFillPolygon, ShadowPolyFillRect, - ShadowPolyFillArc, ShadowPolyText8, - ShadowPolyText16, ShadowImageText8, - ShadowImageText16, ShadowImageGlyphBlt, - ShadowPolyGlyphBlt, ShadowPushPixels, -}; diff --git a/xorg-server/hw/xfree86/xorg-wrapper.c b/xorg-server/hw/xfree86/xorg-wrapper.c index 90c8c11ef..4ea47331b 100644 --- a/xorg-server/hw/xfree86/xorg-wrapper.c +++ b/xorg-server/hw/xfree86/xorg-wrapper.c @@ -25,6 +25,7 @@ #include "dix-config.h" +#include <errno.h> #include <fcntl.h> #include <limits.h> #include <stdint.h> @@ -34,12 +35,17 @@ #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include <sys/consio.h> +#endif #include <unistd.h> -#include <drm/drm.h> +#include <drm.h> #include <xf86drm.h> /* For DRM_DEV_NAME */ #define CONFIG_FILE SYSCONFDIR "/X11/Xwrapper.config" +static const char *progname; + enum { ROOT_ONLY, CONSOLE_ONLY, ANYBODY }; /* KISS non locale / LANG parsing isspace version */ @@ -88,18 +94,21 @@ static void parse_config(int *allowed, int *needs_root_rights) /* Split in a key + value pair */ equals = strchr(stripped, '='); if (!equals) { - fprintf(stderr, "Syntax error at %s line %d\n", CONFIG_FILE, line); + fprintf(stderr, "%s: Syntax error at %s line %d\n", progname, + CONFIG_FILE, line); exit(1); } *equals = 0; key = strip(stripped); /* To remove trailing whitespace from key */ value = strip(equals + 1); /* To remove leading whitespace from val */ if (!key[0]) { - fprintf(stderr, "Missing key at %s line %d\n", CONFIG_FILE, line); + fprintf(stderr, "%s: Missing key at %s line %d\n", progname, + CONFIG_FILE, line); exit(1); } if (!value[0]) { - fprintf(stderr, "Missing value at %s line %d\n", CONFIG_FILE, line); + fprintf(stderr, "%s: Missing value at %s line %d\n", progname, + CONFIG_FILE, line); exit(1); } @@ -113,8 +122,8 @@ static void parse_config(int *allowed, int *needs_root_rights) *allowed = ANYBODY; else { fprintf(stderr, - "Invalid value '%s' for 'allowed_users' at %s line %d\n", - value, CONFIG_FILE, line); + "%s: Invalid value '%s' for 'allowed_users' at %s line %d\n", + progname, value, CONFIG_FILE, line); exit(1); } } @@ -127,8 +136,8 @@ static void parse_config(int *allowed, int *needs_root_rights) *needs_root_rights = -1; else { fprintf(stderr, - "Invalid value '%s' for 'needs_root_rights' at %s line %d\n", - value, CONFIG_FILE, line); + "%s: Invalid value '%s' for 'needs_root_rights' at %s line %d\n", + progname, value, CONFIG_FILE, line); exit(1); } } @@ -136,18 +145,45 @@ static void parse_config(int *allowed, int *needs_root_rights) /* Backward compatibility with older Debian Xwrapper, ignore */ } else { - fprintf(stderr, "Invalid key '%s' at %s line %d\n", key, - CONFIG_FILE, line); + fprintf(stderr, "%s: Invalid key '%s' at %s line %d\n", key, + progname, CONFIG_FILE, line); exit(1); } } fclose(f); } +static int on_console(int fd) +{ +#if defined(__linux__) + struct stat st; + int r; + + r = fstat(fd, &st); + if (r == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) + return 1; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + int idx; + + if (ioctl(fd, VT_GETINDEX, &idx) != -1) + return 1; +#else +#warning This program needs porting to your kernel. + static int seen; + + if (!seen) { + fprintf(stderr, "%s: Unable to determine if running on a console\n", + progname); + seen = 1; + } +#endif + + return 0; +} + int main(int argc, char *argv[]) { struct drm_mode_card_res res; - struct stat st; char buf[PATH_MAX]; int i, r, fd; int kms_cards = 0; @@ -155,6 +191,8 @@ int main(int argc, char *argv[]) int allowed = CONSOLE_ONLY; int needs_root_rights = -1; + progname = argv[0]; + parse_config(&allowed, &needs_root_rights); /* For non root users check if they are allowed to run the X server */ @@ -168,8 +206,7 @@ int main(int argc, char *argv[]) case CONSOLE_ONLY: /* Some of stdin / stdout / stderr maybe redirected to a file */ for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) { - r = fstat(i, &st); - if (r == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) + if (on_console(i)) break; } if (i > STDERR_FILENO) { @@ -207,11 +244,13 @@ int main(int argc, char *argv[]) uid_t realuid = getuid(); if (setresgid(-1, realgid, realgid) != 0) { - perror("Could not drop setgid privileges"); + fprintf(stderr, "%s: Could not drop setgid privileges: %s\n", + progname, strerror(errno)); exit(1); } if (setresuid(-1, realuid, realuid) != 0) { - perror("Could not drop setuid privileges"); + fprintf(stderr, "%s: Could not drop setuid privileges: %s\n", + progname, strerror(errno)); exit(1); } } @@ -220,12 +259,14 @@ int main(int argc, char *argv[]) /* Check if the server is executable by our real uid */ if (access(buf, X_OK) != 0) { - perror("Missing execute permissions for " SUID_WRAPPER_DIR "Xorg.bin"); + fprintf(stderr, "%s: Missing execute permissions for %s/Xorg.bin: %s\n", + progname, SUID_WRAPPER_DIR, strerror(errno)); exit(1); } argv[0] = buf; (void) execv(argv[0], argv); - perror("Failed to execute " SUID_WRAPPER_DIR "/Xorg.bin"); + fprintf(stderr, "%s: Failed to execute %s/Xorg.bin: %s\n", + progname, SUID_WRAPPER_DIR, strerror(errno)); exit(1); } |