fbwindow.c revision 05b261ec
105b261ecSmrg/* 205b261ecSmrg * Copyright © 1998 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include <stdlib.h> 2805b261ecSmrg 2905b261ecSmrg#include "fb.h" 3005b261ecSmrg 3105b261ecSmrgBool 3205b261ecSmrgfbCreateWindow(WindowPtr pWin) 3305b261ecSmrg{ 3405b261ecSmrg#ifndef FB_NO_WINDOW_PIXMAPS 3505b261ecSmrg pWin->devPrivates[fbWinPrivateIndex].ptr = 3605b261ecSmrg (pointer) fbGetScreenPixmap(pWin->drawable.pScreen); 3705b261ecSmrg#endif 3805b261ecSmrg#ifdef FB_SCREEN_PRIVATE 3905b261ecSmrg if (pWin->drawable.bitsPerPixel == 32) 4005b261ecSmrg pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp; 4105b261ecSmrg#endif 4205b261ecSmrg return TRUE; 4305b261ecSmrg} 4405b261ecSmrg 4505b261ecSmrgBool 4605b261ecSmrgfbDestroyWindow(WindowPtr pWin) 4705b261ecSmrg{ 4805b261ecSmrg return TRUE; 4905b261ecSmrg} 5005b261ecSmrg 5105b261ecSmrgBool 5205b261ecSmrgfbMapWindow(WindowPtr pWindow) 5305b261ecSmrg{ 5405b261ecSmrg return TRUE; 5505b261ecSmrg} 5605b261ecSmrg 5705b261ecSmrgBool 5805b261ecSmrgfbPositionWindow(WindowPtr pWin, int x, int y) 5905b261ecSmrg{ 6005b261ecSmrg return TRUE; 6105b261ecSmrg} 6205b261ecSmrg 6305b261ecSmrgBool 6405b261ecSmrgfbUnmapWindow(WindowPtr pWindow) 6505b261ecSmrg{ 6605b261ecSmrg return TRUE; 6705b261ecSmrg} 6805b261ecSmrg 6905b261ecSmrgvoid 7005b261ecSmrgfbCopyWindowProc (DrawablePtr pSrcDrawable, 7105b261ecSmrg DrawablePtr pDstDrawable, 7205b261ecSmrg GCPtr pGC, 7305b261ecSmrg BoxPtr pbox, 7405b261ecSmrg int nbox, 7505b261ecSmrg int dx, 7605b261ecSmrg int dy, 7705b261ecSmrg Bool reverse, 7805b261ecSmrg Bool upsidedown, 7905b261ecSmrg Pixel bitplane, 8005b261ecSmrg void *closure) 8105b261ecSmrg{ 8205b261ecSmrg FbBits *src; 8305b261ecSmrg FbStride srcStride; 8405b261ecSmrg int srcBpp; 8505b261ecSmrg int srcXoff, srcYoff; 8605b261ecSmrg FbBits *dst; 8705b261ecSmrg FbStride dstStride; 8805b261ecSmrg int dstBpp; 8905b261ecSmrg int dstXoff, dstYoff; 9005b261ecSmrg 9105b261ecSmrg fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 9205b261ecSmrg fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 9305b261ecSmrg 9405b261ecSmrg while (nbox--) 9505b261ecSmrg { 9605b261ecSmrg fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, 9705b261ecSmrg srcStride, 9805b261ecSmrg (pbox->x1 + dx + srcXoff) * srcBpp, 9905b261ecSmrg 10005b261ecSmrg dst + (pbox->y1 + dstYoff) * dstStride, 10105b261ecSmrg dstStride, 10205b261ecSmrg (pbox->x1 + dstXoff) * dstBpp, 10305b261ecSmrg 10405b261ecSmrg (pbox->x2 - pbox->x1) * dstBpp, 10505b261ecSmrg (pbox->y2 - pbox->y1), 10605b261ecSmrg 10705b261ecSmrg GXcopy, 10805b261ecSmrg FB_ALLONES, 10905b261ecSmrg dstBpp, 11005b261ecSmrg 11105b261ecSmrg reverse, 11205b261ecSmrg upsidedown); 11305b261ecSmrg pbox++; 11405b261ecSmrg } 11505b261ecSmrg 11605b261ecSmrg fbFinishAccess (pDstDrawable); 11705b261ecSmrg fbFinishAccess (pSrcDrawable); 11805b261ecSmrg} 11905b261ecSmrg 12005b261ecSmrgvoid 12105b261ecSmrgfbCopyWindow(WindowPtr pWin, 12205b261ecSmrg DDXPointRec ptOldOrg, 12305b261ecSmrg RegionPtr prgnSrc) 12405b261ecSmrg{ 12505b261ecSmrg RegionRec rgnDst; 12605b261ecSmrg int dx, dy; 12705b261ecSmrg 12805b261ecSmrg PixmapPtr pPixmap = fbGetWindowPixmap (pWin); 12905b261ecSmrg DrawablePtr pDrawable = &pPixmap->drawable; 13005b261ecSmrg 13105b261ecSmrg dx = ptOldOrg.x - pWin->drawable.x; 13205b261ecSmrg dy = ptOldOrg.y - pWin->drawable.y; 13305b261ecSmrg REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); 13405b261ecSmrg 13505b261ecSmrg REGION_NULL (pWin->drawable.pScreen, &rgnDst); 13605b261ecSmrg 13705b261ecSmrg REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); 13805b261ecSmrg 13905b261ecSmrg#ifdef COMPOSITE 14005b261ecSmrg if (pPixmap->screen_x || pPixmap->screen_y) 14105b261ecSmrg REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, 14205b261ecSmrg -pPixmap->screen_x, -pPixmap->screen_y); 14305b261ecSmrg#endif 14405b261ecSmrg 14505b261ecSmrg fbCopyRegion (pDrawable, pDrawable, 14605b261ecSmrg 0, 14705b261ecSmrg &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); 14805b261ecSmrg 14905b261ecSmrg REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); 15005b261ecSmrg fbValidateDrawable (&pWin->drawable); 15105b261ecSmrg} 15205b261ecSmrg 15305b261ecSmrgBool 15405b261ecSmrgfbChangeWindowAttributes(WindowPtr pWin, unsigned long mask) 15505b261ecSmrg{ 15605b261ecSmrg PixmapPtr pPixmap; 15705b261ecSmrg 15805b261ecSmrg if (mask & CWBackPixmap) 15905b261ecSmrg { 16005b261ecSmrg if (pWin->backgroundState == BackgroundPixmap) 16105b261ecSmrg { 16205b261ecSmrg pPixmap = pWin->background.pixmap; 16305b261ecSmrg#ifdef FB_24_32BIT 16405b261ecSmrg if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel) 16505b261ecSmrg { 16605b261ecSmrg pPixmap = fb24_32ReformatTile (pPixmap, 16705b261ecSmrg pWin->drawable.bitsPerPixel); 16805b261ecSmrg if (pPixmap) 16905b261ecSmrg { 17005b261ecSmrg (*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.pixmap); 17105b261ecSmrg pWin->background.pixmap = pPixmap; 17205b261ecSmrg } 17305b261ecSmrg } 17405b261ecSmrg#endif 17505b261ecSmrg if (FbEvenTile (pPixmap->drawable.width * 17605b261ecSmrg pPixmap->drawable.bitsPerPixel)) 17705b261ecSmrg fbPadPixmap (pPixmap); 17805b261ecSmrg } 17905b261ecSmrg } 18005b261ecSmrg if (mask & CWBorderPixmap) 18105b261ecSmrg { 18205b261ecSmrg if (pWin->borderIsPixel == FALSE) 18305b261ecSmrg { 18405b261ecSmrg pPixmap = pWin->border.pixmap; 18505b261ecSmrg#ifdef FB_24_32BIT 18605b261ecSmrg if (pPixmap->drawable.bitsPerPixel != 18705b261ecSmrg pWin->drawable.bitsPerPixel) 18805b261ecSmrg { 18905b261ecSmrg pPixmap = fb24_32ReformatTile (pPixmap, 19005b261ecSmrg pWin->drawable.bitsPerPixel); 19105b261ecSmrg if (pPixmap) 19205b261ecSmrg { 19305b261ecSmrg (*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.pixmap); 19405b261ecSmrg pWin->border.pixmap = pPixmap; 19505b261ecSmrg } 19605b261ecSmrg } 19705b261ecSmrg#endif 19805b261ecSmrg if (FbEvenTile (pPixmap->drawable.width * 19905b261ecSmrg pPixmap->drawable.bitsPerPixel)) 20005b261ecSmrg fbPadPixmap (pPixmap); 20105b261ecSmrg } 20205b261ecSmrg } 20305b261ecSmrg return TRUE; 20405b261ecSmrg} 20505b261ecSmrg 20605b261ecSmrgvoid 20705b261ecSmrgfbFillRegionSolid (DrawablePtr pDrawable, 20805b261ecSmrg RegionPtr pRegion, 20905b261ecSmrg FbBits and, 21005b261ecSmrg FbBits xor) 21105b261ecSmrg{ 21205b261ecSmrg FbBits *dst; 21305b261ecSmrg FbStride dstStride; 21405b261ecSmrg int dstBpp; 21505b261ecSmrg int dstXoff, dstYoff; 21605b261ecSmrg int n = REGION_NUM_RECTS(pRegion); 21705b261ecSmrg BoxPtr pbox = REGION_RECTS(pRegion); 21805b261ecSmrg 21905b261ecSmrg#ifndef FB_ACCESS_WRAPPER 22005b261ecSmrg int try_mmx = 0; 22105b261ecSmrg if (!and) 22205b261ecSmrg try_mmx = 1; 22305b261ecSmrg#endif 22405b261ecSmrg 22505b261ecSmrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 22605b261ecSmrg 22705b261ecSmrg while (n--) 22805b261ecSmrg { 22905b261ecSmrg#ifndef FB_ACCESS_WRAPPER 23005b261ecSmrg if (!try_mmx || !pixman_fill (dst, dstStride, dstBpp, 23105b261ecSmrg pbox->x1 + dstXoff, pbox->y1 + dstYoff, 23205b261ecSmrg (pbox->x2 - pbox->x1), 23305b261ecSmrg (pbox->y2 - pbox->y1), 23405b261ecSmrg xor)) 23505b261ecSmrg { 23605b261ecSmrg#endif 23705b261ecSmrg fbSolid (dst + (pbox->y1 + dstYoff) * dstStride, 23805b261ecSmrg dstStride, 23905b261ecSmrg (pbox->x1 + dstXoff) * dstBpp, 24005b261ecSmrg dstBpp, 24105b261ecSmrg (pbox->x2 - pbox->x1) * dstBpp, 24205b261ecSmrg pbox->y2 - pbox->y1, 24305b261ecSmrg and, xor); 24405b261ecSmrg#ifndef FB_ACCESS_WRAPPER 24505b261ecSmrg } 24605b261ecSmrg#endif 24705b261ecSmrg fbValidateDrawable (pDrawable); 24805b261ecSmrg pbox++; 24905b261ecSmrg } 25005b261ecSmrg 25105b261ecSmrg fbFinishAccess (pDrawable); 25205b261ecSmrg} 25305b261ecSmrg 25405b261ecSmrg#ifdef PANORAMIX 25505b261ecSmrg#include "panoramiX.h" 25605b261ecSmrg#include "panoramiXsrv.h" 25705b261ecSmrg#endif 25805b261ecSmrg 25905b261ecSmrgvoid 26005b261ecSmrgfbFillRegionTiled (DrawablePtr pDrawable, 26105b261ecSmrg RegionPtr pRegion, 26205b261ecSmrg PixmapPtr pTile) 26305b261ecSmrg{ 26405b261ecSmrg FbBits *dst; 26505b261ecSmrg FbStride dstStride; 26605b261ecSmrg int dstBpp; 26705b261ecSmrg int dstXoff, dstYoff; 26805b261ecSmrg FbBits *tile; 26905b261ecSmrg FbStride tileStride; 27005b261ecSmrg int tileBpp; 27105b261ecSmrg int tileXoff, tileYoff; /* XXX assumed to be zero */ 27205b261ecSmrg int tileWidth, tileHeight; 27305b261ecSmrg int n = REGION_NUM_RECTS(pRegion); 27405b261ecSmrg BoxPtr pbox = REGION_RECTS(pRegion); 27505b261ecSmrg int xRot = pDrawable->x; 27605b261ecSmrg int yRot = pDrawable->y; 27705b261ecSmrg 27805b261ecSmrg#ifdef PANORAMIX 27905b261ecSmrg if(!noPanoramiXExtension) 28005b261ecSmrg { 28105b261ecSmrg int index = pDrawable->pScreen->myNum; 28205b261ecSmrg if(&WindowTable[index]->drawable == pDrawable) 28305b261ecSmrg { 28405b261ecSmrg xRot -= panoramiXdataPtr[index].x; 28505b261ecSmrg yRot -= panoramiXdataPtr[index].y; 28605b261ecSmrg } 28705b261ecSmrg } 28805b261ecSmrg#endif 28905b261ecSmrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 29005b261ecSmrg fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); 29105b261ecSmrg tileWidth = pTile->drawable.width; 29205b261ecSmrg tileHeight = pTile->drawable.height; 29305b261ecSmrg xRot += dstXoff; 29405b261ecSmrg yRot += dstYoff; 29505b261ecSmrg 29605b261ecSmrg while (n--) 29705b261ecSmrg { 29805b261ecSmrg fbTile (dst + (pbox->y1 + dstYoff) * dstStride, 29905b261ecSmrg dstStride, 30005b261ecSmrg (pbox->x1 + dstXoff) * dstBpp, 30105b261ecSmrg (pbox->x2 - pbox->x1) * dstBpp, 30205b261ecSmrg pbox->y2 - pbox->y1, 30305b261ecSmrg tile, 30405b261ecSmrg tileStride, 30505b261ecSmrg tileWidth * dstBpp, 30605b261ecSmrg tileHeight, 30705b261ecSmrg GXcopy, 30805b261ecSmrg FB_ALLONES, 30905b261ecSmrg dstBpp, 31005b261ecSmrg xRot * dstBpp, 31105b261ecSmrg yRot - (pbox->y1 + dstYoff)); 31205b261ecSmrg pbox++; 31305b261ecSmrg } 31405b261ecSmrg 31505b261ecSmrg fbFinishAccess (&pTile->drawable); 31605b261ecSmrg fbFinishAccess (pDrawable); 31705b261ecSmrg} 31805b261ecSmrg 31905b261ecSmrgvoid 32005b261ecSmrgfbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) 32105b261ecSmrg{ 32205b261ecSmrg WindowPtr pBgWin; 32305b261ecSmrg 32405b261ecSmrg switch (what) { 32505b261ecSmrg case PW_BACKGROUND: 32605b261ecSmrg switch (pWin->backgroundState) { 32705b261ecSmrg case None: 32805b261ecSmrg break; 32905b261ecSmrg case ParentRelative: 33005b261ecSmrg do { 33105b261ecSmrg pWin = pWin->parent; 33205b261ecSmrg } while (pWin->backgroundState == ParentRelative); 33305b261ecSmrg (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, 33405b261ecSmrg what); 33505b261ecSmrg break; 33605b261ecSmrg case BackgroundPixmap: 33705b261ecSmrg fbFillRegionTiled (&pWin->drawable, 33805b261ecSmrg pRegion, 33905b261ecSmrg pWin->background.pixmap); 34005b261ecSmrg break; 34105b261ecSmrg case BackgroundPixel: 34205b261ecSmrg fbFillRegionSolid (&pWin->drawable, 34305b261ecSmrg pRegion, 34405b261ecSmrg 0, 34505b261ecSmrg fbReplicatePixel (pWin->background.pixel, 34605b261ecSmrg pWin->drawable.bitsPerPixel)); 34705b261ecSmrg break; 34805b261ecSmrg } 34905b261ecSmrg break; 35005b261ecSmrg case PW_BORDER: 35105b261ecSmrg if (pWin->borderIsPixel) 35205b261ecSmrg { 35305b261ecSmrg fbFillRegionSolid (&pWin->drawable, 35405b261ecSmrg pRegion, 35505b261ecSmrg 0, 35605b261ecSmrg fbReplicatePixel (pWin->border.pixel, 35705b261ecSmrg pWin->drawable.bitsPerPixel)); 35805b261ecSmrg } 35905b261ecSmrg else 36005b261ecSmrg { 36105b261ecSmrg for (pBgWin = pWin; 36205b261ecSmrg pBgWin->backgroundState == ParentRelative; 36305b261ecSmrg pBgWin = pBgWin->parent); 36405b261ecSmrg 36505b261ecSmrg fbFillRegionTiled (&pBgWin->drawable, 36605b261ecSmrg pRegion, 36705b261ecSmrg pWin->border.pixmap); 36805b261ecSmrg } 36905b261ecSmrg break; 37005b261ecSmrg } 37105b261ecSmrg fbValidateDrawable (&pWin->drawable); 37205b261ecSmrg} 373