First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xf4bpp / ppcCpArea.c
blob891ba4b89c93f7d9ee77a57a1be65176cf9228fb
1 /*
2 * Copyright IBM Corporation 1987,1988,1989
4 * All Rights Reserved
6 * Permission to use, copy, modify, and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of IBM not be
11 * used in advertising or publicity pertaining to distribution of the
12 * software without specific, written prior permission.
14 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 * SOFTWARE.
24 /***********************************************************
25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27 All Rights Reserved
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Digital not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
37 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
45 ******************************************************************/
47 #ifdef HAVE_XORG_CONFIG_H
48 #include <xorg-config.h>
49 #endif
51 #include <stdlib.h>
53 #include "xf4bpp.h"
54 #include "mfbmap.h"
55 #define PSZ 8
56 #include "mfb.h"
57 #include "mergerop.h"
58 #include "mi.h"
59 #include "pixmapstr.h"
60 #include "scrnintstr.h"
63 * Graft in the DoBitblt from cfb. It does everything correctly.
65 static void
66 vga16DoBitblt
68 DrawablePtr pSrc,
69 DrawablePtr pDst,
70 int alu,
71 RegionPtr prgnDst,
72 DDXPointPtr pptSrc,
73 unsigned long planemask
76 int widthSrc, widthDst; /* add to get to same position in next line */
77 BoxPtr pbox;
78 int nbox;
79 BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
80 /* temporaries for shuffling rectangles */
81 DDXPointPtr pptTmp, pptNew1, pptNew2;
82 /* shuffling boxes entails shuffling the
83 source points too */
84 int w, h;
85 int careful;
87 widthSrc = mfbGetPixelWidth(pSrc);
88 widthDst = mfbGetPixelWidth(pDst);
90 /* XXX we have to err on the side of safety when both are windows,
91 * because we don't know if IncludeInferiors is being used.
93 careful = ((pSrc == pDst) ||
94 ((pSrc->type == DRAWABLE_WINDOW) &&
95 (pDst->type == DRAWABLE_WINDOW)));
97 pbox = REGION_RECTS(prgnDst);
98 nbox = REGION_NUM_RECTS(prgnDst);
100 pboxNew1 = NULL;
101 pptNew1 = NULL;
102 pboxNew2 = NULL;
103 pptNew2 = NULL;
104 if (careful && (pptSrc->y < pbox->y1))
106 /* walk source botttom to top */
107 widthSrc = -widthSrc;
108 widthDst = -widthDst;
110 if (nbox > 1)
112 /* keep ordering in each band, reverse order of bands */
113 pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
114 if(!pboxNew1)
115 return;
116 pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
117 if(!pptNew1)
119 DEALLOCATE_LOCAL(pboxNew1);
120 return;
122 pboxBase = pboxNext = pbox+nbox-1;
123 while (pboxBase >= pbox)
125 while ((pboxNext >= pbox) &&
126 (pboxBase->y1 == pboxNext->y1))
127 pboxNext--;
128 pboxTmp = pboxNext+1;
129 pptTmp = pptSrc + (pboxTmp - pbox);
130 while (pboxTmp <= pboxBase)
132 *pboxNew1++ = *pboxTmp++;
133 *pptNew1++ = *pptTmp++;
135 pboxBase = pboxNext;
137 pboxNew1 -= nbox;
138 pbox = pboxNew1;
139 pptNew1 -= nbox;
140 pptSrc = pptNew1;
144 if (careful && (pptSrc->x < pbox->x1))
146 if (nbox > 1)
148 /* reverse order of rects in each band */
149 pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
150 pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
151 if(!pboxNew2 || !pptNew2)
153 if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
154 if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
155 if (pboxNew1)
157 DEALLOCATE_LOCAL(pptNew1);
158 DEALLOCATE_LOCAL(pboxNew1);
160 return;
162 pboxBase = pboxNext = pbox;
163 while (pboxBase < pbox+nbox)
165 while ((pboxNext < pbox+nbox) &&
166 (pboxNext->y1 == pboxBase->y1))
167 pboxNext++;
168 pboxTmp = pboxNext;
169 pptTmp = pptSrc + (pboxTmp - pbox);
170 while (pboxTmp != pboxBase)
172 *pboxNew2++ = *--pboxTmp;
173 *pptNew2++ = *--pptTmp;
175 pboxBase = pboxNext;
177 pboxNew2 -= nbox;
178 pbox = pboxNew2;
179 pptNew2 -= nbox;
180 pptSrc = pptNew2;
184 while(nbox--)
186 w = pbox->x2 - pbox->x1;
187 h = pbox->y2 - pbox->y1;
189 if( pSrc->type == DRAWABLE_WINDOW )
190 xf4bppBitBlt( (WindowPtr)pDst, alu, planemask,
191 pptSrc->x, /* x0 */
192 pptSrc->y, /* y0 */
193 pbox->x1, /* x1 */
194 pbox->y1, /* y1 */
195 w, h ); /* w, h */
196 else /* DRAWABLE_PIXMAP */
197 xf4bppDrawColorImage( (WindowPtr)pDst,
198 pbox->x1, pbox->y1,
201 ((unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr
202 + pptSrc->x + (pptSrc->y*((PixmapPtr)pSrc)->devKind)),
203 ((PixmapPtr)pSrc)->devKind,
204 alu, planemask ) ;
205 pbox++;
206 pptSrc++;
208 if (pboxNew2)
210 DEALLOCATE_LOCAL(pptNew2);
211 DEALLOCATE_LOCAL(pboxNew2);
213 if (pboxNew1)
215 DEALLOCATE_LOCAL(pptNew1);
216 DEALLOCATE_LOCAL(pboxNew1);
222 * Graft in the CopyArea from mfb/cfb. It does everything correctly.
225 RegionPtr
226 xf4bppCopyArea(pSrcDrawable, pDstDrawable,
227 pGC, srcx, srcy, width, height, dstx, dsty)
228 register DrawablePtr pSrcDrawable;
229 register DrawablePtr pDstDrawable;
230 register GC *pGC;
231 int srcx, srcy;
232 int width, height;
233 int dstx, dsty;
235 RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
236 Bool freeSrcClip = FALSE;
238 RegionPtr prgnExposed;
239 RegionRec rgnDst;
240 DDXPointPtr pptSrc;
241 register DDXPointPtr ppt;
242 register BoxPtr pbox;
243 int i;
244 register int dx;
245 register int dy;
246 xRectangle origSource;
247 DDXPointRec origDest;
248 int numRects;
249 BoxRec fastBox;
250 int fastClip = 0; /* for fast clipping with pixmap source */
251 int fastExpose = 0; /* for fast exposures with pixmap source */
253 if ( pDstDrawable->type != DRAWABLE_WINDOW )
254 return miCopyArea( pSrcDrawable, pDstDrawable, pGC,
255 srcx, srcy, width, height, dstx, dsty ) ;
257 /* Begin code from mfb/cfbCopyArea */
259 origSource.x = srcx;
260 origSource.y = srcy;
261 origSource.width = width;
262 origSource.height = height;
263 origDest.x = dstx;
264 origDest.y = dsty;
266 if ((pSrcDrawable != pDstDrawable) &&
267 pSrcDrawable->pScreen->SourceValidate)
269 (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
272 srcx += pSrcDrawable->x;
273 srcy += pSrcDrawable->y;
275 /* clip the source */
277 if (pSrcDrawable->type == DRAWABLE_PIXMAP)
279 if ((pSrcDrawable == pDstDrawable) &&
280 (pGC->clientClipType == CT_NONE))
282 prgnSrcClip = pGC->pCompositeClip;
284 else
286 fastClip = 1;
289 else
291 if (pGC->subWindowMode == IncludeInferiors)
293 if (!((WindowPtr) pSrcDrawable)->parent)
296 * special case bitblt from root window in
297 * IncludeInferiors mode; just like from a pixmap
299 fastClip = 1;
301 else if ((pSrcDrawable == pDstDrawable) &&
302 (pGC->clientClipType == CT_NONE))
304 prgnSrcClip = pGC->pCompositeClip;
306 else
308 prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
309 freeSrcClip = TRUE;
312 else
314 prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
318 fastBox.x1 = srcx;
319 fastBox.y1 = srcy;
320 fastBox.x2 = srcx + width;
321 fastBox.y2 = srcy + height;
323 /* Don't create a source region if we are doing a fast clip */
324 if (fastClip)
326 fastExpose = 1;
328 * clip the source; if regions extend beyond the source size,
329 * make sure exposure events get sent
331 if (fastBox.x1 < pSrcDrawable->x)
333 fastBox.x1 = pSrcDrawable->x;
334 fastExpose = 0;
336 if (fastBox.y1 < pSrcDrawable->y)
338 fastBox.y1 = pSrcDrawable->y;
339 fastExpose = 0;
341 if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
343 fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
344 fastExpose = 0;
346 if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
348 fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
349 fastExpose = 0;
352 else
354 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
355 REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
358 dstx += pDstDrawable->x;
359 dsty += pDstDrawable->y;
361 if (pDstDrawable->type == DRAWABLE_WINDOW)
363 if (!((WindowPtr)pDstDrawable)->realized)
365 if (!fastClip)
366 REGION_UNINIT(pGC->pScreen, &rgnDst);
367 if (freeSrcClip)
368 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
369 return NULL;
373 dx = srcx - dstx;
374 dy = srcy - dsty;
376 /* Translate and clip the dst to the destination composite clip */
377 if (fastClip)
379 RegionPtr cclip;
381 /* Translate the region directly */
382 fastBox.x1 -= dx;
383 fastBox.x2 -= dx;
384 fastBox.y1 -= dy;
385 fastBox.y2 -= dy;
387 /* If the destination composite clip is one rectangle we can
388 do the clip directly. Otherwise we have to create a full
389 blown region and call intersect */
390 cclip = pGC->pCompositeClip;
391 if (REGION_NUM_RECTS(cclip) == 1)
393 BoxPtr pBox = REGION_RECTS(cclip);
395 if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
396 if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
397 if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
398 if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
400 /* Check to see if the region is empty */
401 if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
403 REGION_NULL(pGC->pScreen, &rgnDst);
405 else
407 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
410 else
412 /* We must turn off fastClip now, since we must create
413 a full blown region. It is intersected with the
414 composite clip below. */
415 fastClip = 0;
416 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
419 else
421 REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
424 if (!fastClip)
426 REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
429 /* Do bit blitting */
430 numRects = REGION_NUM_RECTS(&rgnDst);
431 if (numRects && width && height)
433 if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
434 sizeof(DDXPointRec))))
436 REGION_UNINIT(pGC->pScreen, &rgnDst);
437 if (freeSrcClip)
438 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
439 return NULL;
441 pbox = REGION_RECTS(&rgnDst);
442 ppt = pptSrc;
443 for (i = numRects; --i >= 0; pbox++, ppt++)
445 ppt->x = pbox->x1 + dx;
446 ppt->y = pbox->y1 + dy;
449 vga16DoBitblt(pSrcDrawable, pDstDrawable, pGC->alu,
450 &rgnDst, pptSrc, pGC->planemask );
451 DEALLOCATE_LOCAL(pptSrc);
454 prgnExposed = NULL;
455 if (pGC->fExpose)
457 /* Pixmap sources generate a NoExposed (we return NULL to do this) */
458 if (!fastExpose)
459 prgnExposed =
460 miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
461 origSource.x, origSource.y,
462 (int)origSource.width,
463 (int)origSource.height,
464 origDest.x, origDest.y, (unsigned long)0);
466 REGION_UNINIT(pGC->pScreen, &rgnDst);
467 if (freeSrcClip)
468 REGION_DESTROY(pGC->pScreen, prgnSrcClip);
469 return prgnExposed;