fbwindow.c revision 6747b715
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{
344642e01fSmrg    dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(),
354642e01fSmrg		  fbGetScreenPixmap(pWin->drawable.pScreen));
3605b261ecSmrg#ifdef FB_SCREEN_PRIVATE
3705b261ecSmrg    if (pWin->drawable.bitsPerPixel == 32)
3805b261ecSmrg	pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
3905b261ecSmrg#endif
4005b261ecSmrg    return TRUE;
4105b261ecSmrg}
4205b261ecSmrg
4305b261ecSmrgBool
4405b261ecSmrgfbDestroyWindow(WindowPtr pWin)
4505b261ecSmrg{
4605b261ecSmrg    return TRUE;
4705b261ecSmrg}
4805b261ecSmrg
4905b261ecSmrgBool
5005b261ecSmrgfbMapWindow(WindowPtr pWindow)
5105b261ecSmrg{
5205b261ecSmrg    return TRUE;
5305b261ecSmrg}
5405b261ecSmrg
5505b261ecSmrgBool
5605b261ecSmrgfbPositionWindow(WindowPtr pWin, int x, int y)
5705b261ecSmrg{
5805b261ecSmrg    return TRUE;
5905b261ecSmrg}
6005b261ecSmrg
6105b261ecSmrgBool
6205b261ecSmrgfbUnmapWindow(WindowPtr pWindow)
6305b261ecSmrg{
6405b261ecSmrg    return TRUE;
6505b261ecSmrg}
6605b261ecSmrg
6705b261ecSmrgvoid
6805b261ecSmrgfbCopyWindowProc (DrawablePtr	pSrcDrawable,
6905b261ecSmrg		  DrawablePtr	pDstDrawable,
7005b261ecSmrg		  GCPtr		pGC,
7105b261ecSmrg		  BoxPtr	pbox,
7205b261ecSmrg		  int		nbox,
7305b261ecSmrg		  int		dx,
7405b261ecSmrg		  int		dy,
7505b261ecSmrg		  Bool		reverse,
7605b261ecSmrg		  Bool		upsidedown,
7705b261ecSmrg		  Pixel		bitplane,
7805b261ecSmrg		  void		*closure)
7905b261ecSmrg{
8005b261ecSmrg    FbBits	*src;
8105b261ecSmrg    FbStride	srcStride;
8205b261ecSmrg    int		srcBpp;
8305b261ecSmrg    int		srcXoff, srcYoff;
8405b261ecSmrg    FbBits	*dst;
8505b261ecSmrg    FbStride	dstStride;
8605b261ecSmrg    int		dstBpp;
8705b261ecSmrg    int		dstXoff, dstYoff;
8805b261ecSmrg
8905b261ecSmrg    fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
9005b261ecSmrg    fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
9105b261ecSmrg
9205b261ecSmrg    while (nbox--)
9305b261ecSmrg    {
9405b261ecSmrg	fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
9505b261ecSmrg	       srcStride,
9605b261ecSmrg	       (pbox->x1 + dx + srcXoff) * srcBpp,
9705b261ecSmrg
9805b261ecSmrg	       dst + (pbox->y1 + dstYoff) * dstStride,
9905b261ecSmrg	       dstStride,
10005b261ecSmrg	       (pbox->x1 + dstXoff) * dstBpp,
10105b261ecSmrg
10205b261ecSmrg	       (pbox->x2 - pbox->x1) * dstBpp,
10305b261ecSmrg	       (pbox->y2 - pbox->y1),
10405b261ecSmrg
10505b261ecSmrg	       GXcopy,
10605b261ecSmrg	       FB_ALLONES,
10705b261ecSmrg	       dstBpp,
10805b261ecSmrg
10905b261ecSmrg	       reverse,
11005b261ecSmrg	       upsidedown);
11105b261ecSmrg	pbox++;
11205b261ecSmrg    }
11305b261ecSmrg
11405b261ecSmrg    fbFinishAccess (pDstDrawable);
11505b261ecSmrg    fbFinishAccess (pSrcDrawable);
11605b261ecSmrg}
11705b261ecSmrg
1186747b715Smrgvoid
11905b261ecSmrgfbCopyWindow(WindowPtr	    pWin,
12005b261ecSmrg	     DDXPointRec    ptOldOrg,
12105b261ecSmrg	     RegionPtr	    prgnSrc)
12205b261ecSmrg{
12305b261ecSmrg    RegionRec	rgnDst;
12405b261ecSmrg    int		dx, dy;
12505b261ecSmrg
12605b261ecSmrg    PixmapPtr	pPixmap = fbGetWindowPixmap (pWin);
12705b261ecSmrg    DrawablePtr	pDrawable = &pPixmap->drawable;
12805b261ecSmrg
12905b261ecSmrg    dx = ptOldOrg.x - pWin->drawable.x;
13005b261ecSmrg    dy = ptOldOrg.y - pWin->drawable.y;
1316747b715Smrg    RegionTranslate(prgnSrc, -dx, -dy);
13205b261ecSmrg
1336747b715Smrg    RegionNull(&rgnDst);
13405b261ecSmrg
1356747b715Smrg    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
13605b261ecSmrg
13705b261ecSmrg#ifdef COMPOSITE
13805b261ecSmrg    if (pPixmap->screen_x || pPixmap->screen_y)
1396747b715Smrg	RegionTranslate(&rgnDst,
14005b261ecSmrg			  -pPixmap->screen_x, -pPixmap->screen_y);
14105b261ecSmrg#endif
14205b261ecSmrg
1436747b715Smrg    miCopyRegion (pDrawable, pDrawable,
14405b261ecSmrg		  0,
14505b261ecSmrg		  &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
14605b261ecSmrg
1476747b715Smrg    RegionUninit(&rgnDst);
14805b261ecSmrg    fbValidateDrawable (&pWin->drawable);
14905b261ecSmrg}
15005b261ecSmrg
15105b261ecSmrgBool
15205b261ecSmrgfbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
15305b261ecSmrg{
15405b261ecSmrg    PixmapPtr	pPixmap;
15505b261ecSmrg
15605b261ecSmrg    if (mask & CWBackPixmap)
15705b261ecSmrg    {
15805b261ecSmrg	if (pWin->backgroundState == BackgroundPixmap)
15905b261ecSmrg	{
16005b261ecSmrg	    pPixmap = pWin->background.pixmap;
16105b261ecSmrg#ifdef FB_24_32BIT
16205b261ecSmrg	    if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel)
16305b261ecSmrg	    {
16405b261ecSmrg		pPixmap = fb24_32ReformatTile (pPixmap,
16505b261ecSmrg					       pWin->drawable.bitsPerPixel);
16605b261ecSmrg		if (pPixmap)
16705b261ecSmrg		{
16805b261ecSmrg		    (*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.pixmap);
16905b261ecSmrg		    pWin->background.pixmap = pPixmap;
17005b261ecSmrg		}
17105b261ecSmrg	    }
17205b261ecSmrg#endif
17305b261ecSmrg	    if (FbEvenTile (pPixmap->drawable.width *
17405b261ecSmrg			    pPixmap->drawable.bitsPerPixel))
17505b261ecSmrg		fbPadPixmap (pPixmap);
17605b261ecSmrg	}
17705b261ecSmrg    }
17805b261ecSmrg    if (mask & CWBorderPixmap)
17905b261ecSmrg    {
18005b261ecSmrg	if (pWin->borderIsPixel == FALSE)
18105b261ecSmrg	{
18205b261ecSmrg	    pPixmap = pWin->border.pixmap;
18305b261ecSmrg#ifdef FB_24_32BIT
18405b261ecSmrg	    if (pPixmap->drawable.bitsPerPixel !=
18505b261ecSmrg		pWin->drawable.bitsPerPixel)
18605b261ecSmrg	    {
18705b261ecSmrg		pPixmap = fb24_32ReformatTile (pPixmap,
18805b261ecSmrg					       pWin->drawable.bitsPerPixel);
18905b261ecSmrg		if (pPixmap)
19005b261ecSmrg		{
19105b261ecSmrg		    (*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.pixmap);
19205b261ecSmrg		    pWin->border.pixmap = pPixmap;
19305b261ecSmrg		}
19405b261ecSmrg	    }
19505b261ecSmrg#endif
19605b261ecSmrg	    if (FbEvenTile (pPixmap->drawable.width *
19705b261ecSmrg			    pPixmap->drawable.bitsPerPixel))
19805b261ecSmrg		fbPadPixmap (pPixmap);
19905b261ecSmrg	}
20005b261ecSmrg    }
20105b261ecSmrg    return TRUE;
20205b261ecSmrg}
20305b261ecSmrg
20405b261ecSmrgvoid
20505b261ecSmrgfbFillRegionSolid (DrawablePtr	pDrawable,
20605b261ecSmrg		   RegionPtr	pRegion,
20705b261ecSmrg		   FbBits	and,
20805b261ecSmrg		   FbBits	xor)
20905b261ecSmrg{
21005b261ecSmrg    FbBits	*dst;
21105b261ecSmrg    FbStride	dstStride;
21205b261ecSmrg    int		dstBpp;
21305b261ecSmrg    int		dstXoff, dstYoff;
2146747b715Smrg    int		n = RegionNumRects(pRegion);
2156747b715Smrg    BoxPtr	pbox = RegionRects(pRegion);
21605b261ecSmrg
21705b261ecSmrg#ifndef FB_ACCESS_WRAPPER
21805b261ecSmrg    int try_mmx = 0;
21905b261ecSmrg    if (!and)
22005b261ecSmrg        try_mmx = 1;
22105b261ecSmrg#endif
22205b261ecSmrg
22305b261ecSmrg    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
22405b261ecSmrg
22505b261ecSmrg    while (n--)
22605b261ecSmrg    {
22705b261ecSmrg#ifndef FB_ACCESS_WRAPPER
2284642e01fSmrg	if (!try_mmx || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
22905b261ecSmrg				      pbox->x1 + dstXoff, pbox->y1 + dstYoff,
23005b261ecSmrg				      (pbox->x2 - pbox->x1),
23105b261ecSmrg				      (pbox->y2 - pbox->y1),
23205b261ecSmrg				      xor))
23305b261ecSmrg	{
23405b261ecSmrg#endif
23505b261ecSmrg	    fbSolid (dst + (pbox->y1 + dstYoff) * dstStride,
23605b261ecSmrg		     dstStride,
23705b261ecSmrg		     (pbox->x1 + dstXoff) * dstBpp,
23805b261ecSmrg		     dstBpp,
23905b261ecSmrg		     (pbox->x2 - pbox->x1) * dstBpp,
24005b261ecSmrg		     pbox->y2 - pbox->y1,
24105b261ecSmrg		     and, xor);
24205b261ecSmrg#ifndef FB_ACCESS_WRAPPER
24305b261ecSmrg	}
24405b261ecSmrg#endif
24505b261ecSmrg	fbValidateDrawable (pDrawable);
24605b261ecSmrg	pbox++;
24705b261ecSmrg    }
24805b261ecSmrg
24905b261ecSmrg    fbFinishAccess (pDrawable);
25005b261ecSmrg}
251