2 * Copyright IBM Corporation 1987,1988,1989
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
24 /***********************************************************
25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
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
45 ******************************************************************/
47 #ifdef HAVE_XORG_CONFIG_H
48 #include <xorg-config.h>
59 #include "pixmapstr.h"
60 #include "scrnintstr.h"
63 * Graft in the DoBitblt from cfb. It does everything correctly.
73 unsigned long planemask
76 int widthSrc
, widthDst
; /* add to get to same position in next line */
79 BoxPtr pboxTmp
, pboxNext
, pboxBase
, pboxNew1
, pboxNew2
;
80 /* temporaries for shuffling rectangles */
81 DDXPointPtr pptTmp
, pptNew1
, pptNew2
;
82 /* shuffling boxes entails shuffling the
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
);
104 if (careful
&& (pptSrc
->y
< pbox
->y1
))
106 /* walk source botttom to top */
107 widthSrc
= -widthSrc
;
108 widthDst
= -widthDst
;
112 /* keep ordering in each band, reverse order of bands */
113 pboxNew1
= (BoxPtr
)ALLOCATE_LOCAL(sizeof(BoxRec
) * nbox
);
116 pptNew1
= (DDXPointPtr
)ALLOCATE_LOCAL(sizeof(DDXPointRec
) * nbox
);
119 DEALLOCATE_LOCAL(pboxNew1
);
122 pboxBase
= pboxNext
= pbox
+nbox
-1;
123 while (pboxBase
>= pbox
)
125 while ((pboxNext
>= pbox
) &&
126 (pboxBase
->y1
== pboxNext
->y1
))
128 pboxTmp
= pboxNext
+1;
129 pptTmp
= pptSrc
+ (pboxTmp
- pbox
);
130 while (pboxTmp
<= pboxBase
)
132 *pboxNew1
++ = *pboxTmp
++;
133 *pptNew1
++ = *pptTmp
++;
144 if (careful
&& (pptSrc
->x
< pbox
->x1
))
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
);
157 DEALLOCATE_LOCAL(pptNew1
);
158 DEALLOCATE_LOCAL(pboxNew1
);
162 pboxBase
= pboxNext
= pbox
;
163 while (pboxBase
< pbox
+nbox
)
165 while ((pboxNext
< pbox
+nbox
) &&
166 (pboxNext
->y1
== pboxBase
->y1
))
169 pptTmp
= pptSrc
+ (pboxTmp
- pbox
);
170 while (pboxTmp
!= pboxBase
)
172 *pboxNew2
++ = *--pboxTmp
;
173 *pptNew2
++ = *--pptTmp
;
186 w
= pbox
->x2
- pbox
->x1
;
187 h
= pbox
->y2
- pbox
->y1
;
189 if( pSrc
->type
== DRAWABLE_WINDOW
)
190 xf4bppBitBlt( (WindowPtr
)pDst
, alu
, planemask
,
196 else /* DRAWABLE_PIXMAP */
197 xf4bppDrawColorImage( (WindowPtr
)pDst
,
201 ((unsigned char *)((PixmapPtr
)pSrc
)->devPrivate
.ptr
202 + pptSrc
->x
+ (pptSrc
->y
*((PixmapPtr
)pSrc
)->devKind
)),
203 ((PixmapPtr
)pSrc
)->devKind
,
210 DEALLOCATE_LOCAL(pptNew2
);
211 DEALLOCATE_LOCAL(pboxNew2
);
215 DEALLOCATE_LOCAL(pptNew1
);
216 DEALLOCATE_LOCAL(pboxNew1
);
222 * Graft in the CopyArea from mfb/cfb. It does everything correctly.
226 xf4bppCopyArea(pSrcDrawable
, pDstDrawable
,
227 pGC
, srcx
, srcy
, width
, height
, dstx
, dsty
)
228 register DrawablePtr pSrcDrawable
;
229 register DrawablePtr pDstDrawable
;
235 RegionPtr prgnSrcClip
= NULL
; /* may be a new region, or just a copy */
236 Bool freeSrcClip
= FALSE
;
238 RegionPtr prgnExposed
;
241 register DDXPointPtr ppt
;
242 register BoxPtr pbox
;
246 xRectangle origSource
;
247 DDXPointRec origDest
;
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 */
261 origSource
.width
= width
;
262 origSource
.height
= height
;
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
;
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
301 else if ((pSrcDrawable
== pDstDrawable
) &&
302 (pGC
->clientClipType
== CT_NONE
))
304 prgnSrcClip
= pGC
->pCompositeClip
;
308 prgnSrcClip
= NotClippedByChildren((WindowPtr
)pSrcDrawable
);
314 prgnSrcClip
= &((WindowPtr
)pSrcDrawable
)->clipList
;
320 fastBox
.x2
= srcx
+ width
;
321 fastBox
.y2
= srcy
+ height
;
323 /* Don't create a source region if we are doing a fast clip */
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
;
336 if (fastBox
.y1
< pSrcDrawable
->y
)
338 fastBox
.y1
= pSrcDrawable
->y
;
341 if (fastBox
.x2
> pSrcDrawable
->x
+ (int) pSrcDrawable
->width
)
343 fastBox
.x2
= pSrcDrawable
->x
+ (int) pSrcDrawable
->width
;
346 if (fastBox
.y2
> pSrcDrawable
->y
+ (int) pSrcDrawable
->height
)
348 fastBox
.y2
= pSrcDrawable
->y
+ (int) pSrcDrawable
->height
;
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
)
366 REGION_UNINIT(pGC
->pScreen
, &rgnDst
);
368 REGION_DESTROY(pGC
->pScreen
, prgnSrcClip
);
376 /* Translate and clip the dst to the destination composite clip */
381 /* Translate the region directly */
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
);
407 REGION_INIT(pGC
->pScreen
, &rgnDst
, &fastBox
, 1);
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. */
416 REGION_INIT(pGC
->pScreen
, &rgnDst
, &fastBox
, 1);
421 REGION_TRANSLATE(pGC
->pScreen
, &rgnDst
, -dx
, -dy
);
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
);
438 REGION_DESTROY(pGC
->pScreen
, prgnSrcClip
);
441 pbox
= REGION_RECTS(&rgnDst
);
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
);
457 /* Pixmap sources generate a NoExposed (we return NULL to do this) */
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
);
468 REGION_DESTROY(pGC
->pScreen
, prgnSrcClip
);