1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
4706f2543Smrg *
5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
7706f2543Smrg * the above copyright notice appear in all copies and that both that
8706f2543Smrg * copyright notice and this permission notice appear in supporting
9706f2543Smrg * documentation, and that the name of Keith Packard not be used in
10706f2543Smrg * advertising or publicity pertaining to distribution of the software without
11706f2543Smrg * specific, written prior permission.  Keith Packard makes no
12706f2543Smrg * representations about the suitability of this software for any purpose.  It
13706f2543Smrg * is provided "as is" without express or implied warranty.
14706f2543Smrg *
15706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
22706f2543Smrg */
23706f2543Smrg
24706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
25706f2543Smrg#include <dix-config.h>
26706f2543Smrg#endif
27706f2543Smrg
28706f2543Smrg#include "scrnintstr.h"
29706f2543Smrg#include "gcstruct.h"
30706f2543Smrg#include "pixmapstr.h"
31706f2543Smrg#include "windowstr.h"
32706f2543Smrg#include "mi.h"
33706f2543Smrg#include "picturestr.h"
34706f2543Smrg#include "mipict.h"
35706f2543Smrg
36706f2543Smrgstatic void
37706f2543SmrgmiColorRects (PicturePtr    pDst,
38706f2543Smrg	      PicturePtr    pClipPict,
39706f2543Smrg	      xRenderColor  *color,
40706f2543Smrg	      int	    nRect,
41706f2543Smrg	      xRectangle    *rects,
42706f2543Smrg	      int	    xoff,
43706f2543Smrg	      int	    yoff)
44706f2543Smrg{
45706f2543Smrg    CARD32		pixel;
46706f2543Smrg    GCPtr		pGC;
47706f2543Smrg    ChangeGCVal		tmpval[5];
48706f2543Smrg    RegionPtr		pClip;
49706f2543Smrg    unsigned long	mask;
50706f2543Smrg
51706f2543Smrg    miRenderColorToPixel (pDst->pFormat, color, &pixel);
52706f2543Smrg
53706f2543Smrg    pGC = GetScratchGC (pDst->pDrawable->depth, pDst->pDrawable->pScreen);
54706f2543Smrg    if (!pGC)
55706f2543Smrg	return;
56706f2543Smrg    tmpval[0].val = GXcopy;
57706f2543Smrg    tmpval[1].val = pixel;
58706f2543Smrg    tmpval[2].val = pDst->subWindowMode;
59706f2543Smrg    mask = GCFunction | GCForeground | GCSubwindowMode;
60706f2543Smrg    if (pClipPict->clientClipType == CT_REGION)
61706f2543Smrg    {
62706f2543Smrg	tmpval[3].val = pDst->clipOrigin.x - xoff;
63706f2543Smrg	tmpval[4].val = pDst->clipOrigin.y - yoff;
64706f2543Smrg	mask |= GCClipXOrigin|GCClipYOrigin;
65706f2543Smrg
66706f2543Smrg	pClip = RegionCreate(NULL, 1);
67706f2543Smrg	RegionCopy(pClip,
68706f2543Smrg		     (RegionPtr) pClipPict->clientClip);
69706f2543Smrg	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
70706f2543Smrg    }
71706f2543Smrg
72706f2543Smrg    ChangeGC (NullClient, pGC, mask, tmpval);
73706f2543Smrg    ValidateGC (pDst->pDrawable, pGC);
74706f2543Smrg    if (xoff || yoff)
75706f2543Smrg    {
76706f2543Smrg	int	i;
77706f2543Smrg	for (i = 0; i < nRect; i++)
78706f2543Smrg	{
79706f2543Smrg	    rects[i].x -= xoff;
80706f2543Smrg	    rects[i].y -= yoff;
81706f2543Smrg	}
82706f2543Smrg    }
83706f2543Smrg    (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
84706f2543Smrg    if (xoff || yoff)
85706f2543Smrg    {
86706f2543Smrg	int	i;
87706f2543Smrg	for (i = 0; i < nRect; i++)
88706f2543Smrg	{
89706f2543Smrg	    rects[i].x += xoff;
90706f2543Smrg	    rects[i].y += yoff;
91706f2543Smrg	}
92706f2543Smrg    }
93706f2543Smrg    FreeScratchGC (pGC);
94706f2543Smrg}
95706f2543Smrg
96706f2543Smrgvoid
97706f2543SmrgmiCompositeRects (CARD8		op,
98706f2543Smrg		  PicturePtr	pDst,
99706f2543Smrg		  xRenderColor  *color,
100706f2543Smrg		  int		nRect,
101706f2543Smrg		  xRectangle    *rects)
102706f2543Smrg{
103706f2543Smrg    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
104706f2543Smrg
105706f2543Smrg    if (color->alpha == 0xffff)
106706f2543Smrg    {
107706f2543Smrg	if (op == PictOpOver)
108706f2543Smrg	    op = PictOpSrc;
109706f2543Smrg    }
110706f2543Smrg    if (op == PictOpClear)
111706f2543Smrg	color->red = color->green = color->blue = color->alpha = 0;
112706f2543Smrg
113706f2543Smrg    if (op == PictOpSrc || op == PictOpClear)
114706f2543Smrg    {
115706f2543Smrg	miColorRects (pDst, pDst, color, nRect, rects, 0, 0);
116706f2543Smrg	if (pDst->alphaMap)
117706f2543Smrg	    miColorRects (pDst->alphaMap, pDst,
118706f2543Smrg			  color, nRect, rects,
119706f2543Smrg			  pDst->alphaOrigin.x,
120706f2543Smrg			  pDst->alphaOrigin.y);
121706f2543Smrg    }
122706f2543Smrg    else
123706f2543Smrg    {
124706f2543Smrg	PictFormatPtr	rgbaFormat;
125706f2543Smrg	PixmapPtr	pPixmap;
126706f2543Smrg	PicturePtr	pSrc;
127706f2543Smrg	xRectangle	one;
128706f2543Smrg	int		error;
129706f2543Smrg	Pixel		pixel;
130706f2543Smrg	GCPtr		pGC;
131706f2543Smrg	ChangeGCVal	gcvals[2];
132706f2543Smrg	XID		tmpval[1];
133706f2543Smrg
134706f2543Smrg	rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
135706f2543Smrg	if (!rgbaFormat)
136706f2543Smrg	    goto bail1;
137706f2543Smrg
138706f2543Smrg	pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth,
139706f2543Smrg					    CREATE_PIXMAP_USAGE_SCRATCH);
140706f2543Smrg	if (!pPixmap)
141706f2543Smrg	    goto bail2;
142706f2543Smrg
143706f2543Smrg	miRenderColorToPixel (rgbaFormat, color, &pixel);
144706f2543Smrg
145706f2543Smrg	pGC = GetScratchGC (rgbaFormat->depth, pScreen);
146706f2543Smrg	if (!pGC)
147706f2543Smrg	    goto bail3;
148706f2543Smrg	gcvals[0].val = GXcopy;
149706f2543Smrg	gcvals[1].val = pixel;
150706f2543Smrg
151706f2543Smrg	ChangeGC (NullClient, pGC, GCFunction | GCForeground, gcvals);
152706f2543Smrg	ValidateGC (&pPixmap->drawable, pGC);
153706f2543Smrg	one.x = 0;
154706f2543Smrg	one.y = 0;
155706f2543Smrg	one.width = 1;
156706f2543Smrg	one.height = 1;
157706f2543Smrg	(*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
158706f2543Smrg
159706f2543Smrg	tmpval[0] = xTrue;
160706f2543Smrg	pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat,
161706f2543Smrg			      CPRepeat, tmpval, serverClient, &error);
162706f2543Smrg
163706f2543Smrg	if (!pSrc)
164706f2543Smrg	    goto bail4;
165706f2543Smrg
166706f2543Smrg	while (nRect--)
167706f2543Smrg	{
168706f2543Smrg	    CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0,
169706f2543Smrg			      rects->x,
170706f2543Smrg			      rects->y,
171706f2543Smrg			      rects->width,
172706f2543Smrg			      rects->height);
173706f2543Smrg	    rects++;
174706f2543Smrg	}
175706f2543Smrg
176706f2543Smrg	FreePicture ((pointer) pSrc, 0);
177706f2543Smrgbail4:
178706f2543Smrg	FreeScratchGC (pGC);
179706f2543Smrgbail3:
180706f2543Smrg	(*pScreen->DestroyPixmap) (pPixmap);
181706f2543Smrgbail2:
182706f2543Smrgbail1:
183706f2543Smrg	;
184706f2543Smrg    }
185706f2543Smrg}
186