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