1/* 2 * 3 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28#include "scrnintstr.h" 29#include "gcstruct.h" 30#include "pixmapstr.h" 31#include "windowstr.h" 32#include "mi.h" 33#include "picturestr.h" 34#include "mipict.h" 35 36static void 37miColorRects (PicturePtr pDst, 38 PicturePtr pClipPict, 39 xRenderColor *color, 40 int nRect, 41 xRectangle *rects, 42 int xoff, 43 int yoff) 44{ 45 CARD32 pixel; 46 GCPtr pGC; 47 ChangeGCVal tmpval[5]; 48 RegionPtr pClip; 49 unsigned long mask; 50 51 miRenderColorToPixel (pDst->pFormat, color, &pixel); 52 53 pGC = GetScratchGC (pDst->pDrawable->depth, pDst->pDrawable->pScreen); 54 if (!pGC) 55 return; 56 tmpval[0].val = GXcopy; 57 tmpval[1].val = pixel; 58 tmpval[2].val = pDst->subWindowMode; 59 mask = GCFunction | GCForeground | GCSubwindowMode; 60 if (pClipPict->clientClipType == CT_REGION) 61 { 62 tmpval[3].val = pDst->clipOrigin.x - xoff; 63 tmpval[4].val = pDst->clipOrigin.y - yoff; 64 mask |= GCClipXOrigin|GCClipYOrigin; 65 66 pClip = RegionCreate(NULL, 1); 67 RegionCopy(pClip, 68 (RegionPtr) pClipPict->clientClip); 69 (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); 70 } 71 72 ChangeGC (NullClient, pGC, mask, tmpval); 73 ValidateGC (pDst->pDrawable, pGC); 74 if (xoff || yoff) 75 { 76 int i; 77 for (i = 0; i < nRect; i++) 78 { 79 rects[i].x -= xoff; 80 rects[i].y -= yoff; 81 } 82 } 83 (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects); 84 if (xoff || yoff) 85 { 86 int i; 87 for (i = 0; i < nRect; i++) 88 { 89 rects[i].x += xoff; 90 rects[i].y += yoff; 91 } 92 } 93 FreeScratchGC (pGC); 94} 95 96void 97miCompositeRects (CARD8 op, 98 PicturePtr pDst, 99 xRenderColor *color, 100 int nRect, 101 xRectangle *rects) 102{ 103 ScreenPtr pScreen = pDst->pDrawable->pScreen; 104 105 if (color->alpha == 0xffff) 106 { 107 if (op == PictOpOver) 108 op = PictOpSrc; 109 } 110 if (op == PictOpClear) 111 color->red = color->green = color->blue = color->alpha = 0; 112 113 if (op == PictOpSrc || op == PictOpClear) 114 { 115 miColorRects (pDst, pDst, color, nRect, rects, 0, 0); 116 if (pDst->alphaMap) 117 miColorRects (pDst->alphaMap, pDst, 118 color, nRect, rects, 119 pDst->alphaOrigin.x, 120 pDst->alphaOrigin.y); 121 } 122 else 123 { 124 PictFormatPtr rgbaFormat; 125 PixmapPtr pPixmap; 126 PicturePtr pSrc; 127 xRectangle one; 128 int error; 129 Pixel pixel; 130 GCPtr pGC; 131 ChangeGCVal gcvals[2]; 132 XID tmpval[1]; 133 134 rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); 135 if (!rgbaFormat) 136 goto bail1; 137 138 pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth, 139 CREATE_PIXMAP_USAGE_SCRATCH); 140 if (!pPixmap) 141 goto bail2; 142 143 miRenderColorToPixel (rgbaFormat, color, &pixel); 144 145 pGC = GetScratchGC (rgbaFormat->depth, pScreen); 146 if (!pGC) 147 goto bail3; 148 gcvals[0].val = GXcopy; 149 gcvals[1].val = pixel; 150 151 ChangeGC (NullClient, pGC, GCFunction | GCForeground, gcvals); 152 ValidateGC (&pPixmap->drawable, pGC); 153 one.x = 0; 154 one.y = 0; 155 one.width = 1; 156 one.height = 1; 157 (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one); 158 159 tmpval[0] = xTrue; 160 pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat, 161 CPRepeat, tmpval, serverClient, &error); 162 163 if (!pSrc) 164 goto bail4; 165 166 while (nRect--) 167 { 168 CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0, 169 rects->x, 170 rects->y, 171 rects->width, 172 rects->height); 173 rects++; 174 } 175 176 FreePicture ((pointer) pSrc, 0); 177bail4: 178 FreeScratchGC (pGC); 179bail3: 180 (*pScreen->DestroyPixmap) (pPixmap); 181bail2: 182bail1: 183 ; 184 } 185} 186