upgrade for xorg-server 1.12.99.905 (for 1.13 RC)
[framework/uifw/xorg/server/xorg-server.git] / fb / fbcopy.c
1 /*
2  * Copyright © 1998 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Keith Packard not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Keith Packard makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
25 #endif
26
27 #include <stdlib.h>
28
29 #include "fb.h"
30
31 /* Compatibility wrapper, to be removed at next ABI change. */
32 void
33 fbCopyRegion(DrawablePtr pSrcDrawable,
34              DrawablePtr pDstDrawable,
35              GCPtr pGC,
36              RegionPtr pDstRegion,
37              int dx, int dy, fbCopyProc copyProc, Pixel bitPlane, void *closure)
38 {
39     miCopyRegion(pSrcDrawable, pDstDrawable, pGC, pDstRegion, dx, dy, copyProc,
40                  bitPlane, closure);
41 }
42
43 /* Compatibility wrapper, to be removed at next ABI change. */
44 RegionPtr
45 fbDoCopy(DrawablePtr pSrcDrawable,
46          DrawablePtr pDstDrawable,
47          GCPtr pGC,
48          int xIn,
49          int yIn,
50          int widthSrc,
51          int heightSrc,
52          int xOut, int yOut, fbCopyProc copyProc, Pixel bitPlane, void *closure)
53 {
54     return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc,
55                     heightSrc, xOut, yOut, copyProc, bitPlane, closure);
56 }
57
58 void
59 fbCopyNtoN(DrawablePtr pSrcDrawable,
60            DrawablePtr pDstDrawable,
61            GCPtr pGC,
62            BoxPtr pbox,
63            int nbox,
64            int dx,
65            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
66 {
67     CARD8 alu = pGC ? pGC->alu : GXcopy;
68     FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
69     FbBits *src;
70     FbStride srcStride;
71     int srcBpp;
72     int srcXoff, srcYoff;
73     FbBits *dst;
74     FbStride dstStride;
75     int dstBpp;
76     int dstXoff, dstYoff;
77
78     fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
79     fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
80
81     while (nbox--) {
82 #ifndef FB_ACCESS_WRAPPER       /* pixman_blt() doesn't support accessors yet */
83         if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) {
84             if (!pixman_blt
85                 ((uint32_t *) src, (uint32_t *) dst, srcStride, dstStride,
86                  srcBpp, dstBpp, (pbox->x1 + dx + srcXoff),
87                  (pbox->y1 + dy + srcYoff), (pbox->x1 + dstXoff),
88                  (pbox->y1 + dstYoff), (pbox->x2 - pbox->x1),
89                  (pbox->y2 - pbox->y1)))
90                 goto fallback;
91             else
92                 goto next;
93         }
94  fallback:
95 #endif
96         fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
97               srcStride,
98               (pbox->x1 + dx + srcXoff) * srcBpp,
99               dst + (pbox->y1 + dstYoff) * dstStride,
100               dstStride,
101               (pbox->x1 + dstXoff) * dstBpp,
102               (pbox->x2 - pbox->x1) * dstBpp,
103               (pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown);
104 #ifndef FB_ACCESS_WRAPPER
105  next:
106 #endif
107         pbox++;
108     }
109     fbFinishAccess(pDstDrawable);
110     fbFinishAccess(pSrcDrawable);
111 }
112
113 void
114 fbCopy1toN(DrawablePtr pSrcDrawable,
115            DrawablePtr pDstDrawable,
116            GCPtr pGC,
117            BoxPtr pbox,
118            int nbox,
119            int dx,
120            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
121 {
122     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
123     FbBits *src;
124     FbStride srcStride;
125     int srcBpp;
126     int srcXoff, srcYoff;
127     FbBits *dst;
128     FbStride dstStride;
129     int dstBpp;
130     int dstXoff, dstYoff;
131
132     fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
133     fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
134
135     while (nbox--) {
136         if (dstBpp == 1) {
137             fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
138                   srcStride,
139                   (pbox->x1 + dx + srcXoff) * srcBpp,
140                   dst + (pbox->y1 + dstYoff) * dstStride,
141                   dstStride,
142                   (pbox->x1 + dstXoff) * dstBpp,
143                   (pbox->x2 - pbox->x1) * dstBpp,
144                   (pbox->y2 - pbox->y1),
145                   FbOpaqueStipple1Rop(pGC->alu,
146                                       pGC->fgPixel, pGC->bgPixel),
147                   pPriv->pm, dstBpp, reverse, upsidedown);
148         }
149         else {
150             fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
151                      srcStride * (FB_UNIT / FB_STIP_UNIT),
152                      (pbox->x1 + dx + srcXoff),
153                      dst + (pbox->y1 + dstYoff) * dstStride,
154                      dstStride,
155                      (pbox->x1 + dstXoff) * dstBpp,
156                      dstBpp,
157                      (pbox->x2 - pbox->x1) * dstBpp,
158                      (pbox->y2 - pbox->y1),
159                      pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
160         }
161         pbox++;
162     }
163
164     fbFinishAccess(pDstDrawable);
165     fbFinishAccess(pSrcDrawable);
166 }
167
168 void
169 fbCopyNto1(DrawablePtr pSrcDrawable,
170            DrawablePtr pDstDrawable,
171            GCPtr pGC,
172            BoxPtr pbox,
173            int nbox,
174            int dx,
175            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
176 {
177     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
178
179     while (nbox--) {
180         if (pDstDrawable->bitsPerPixel == 1) {
181             FbBits *src;
182             FbStride srcStride;
183             int srcBpp;
184             int srcXoff, srcYoff;
185
186             FbStip *dst;
187             FbStride dstStride;
188             int dstBpp;
189             int dstXoff, dstYoff;
190
191             fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
192                           srcYoff);
193             fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
194                               dstYoff);
195             fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride,
196                        (pbox->x1 + dx + srcXoff) * srcBpp, srcBpp,
197                        dst + (pbox->y1 + dstYoff) * dstStride, dstStride,
198                        (pbox->x1 + dstXoff) * dstBpp,
199                        (pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1),
200                        (FbStip) pPriv->and, (FbStip) pPriv->xor,
201                        (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane);
202             fbFinishAccess(pDstDrawable);
203             fbFinishAccess(pSrcDrawable);
204         }
205         else {
206             FbBits *src;
207             FbStride srcStride;
208             int srcBpp;
209             int srcXoff, srcYoff;
210
211             FbBits *dst;
212             FbStride dstStride;
213             int dstBpp;
214             int dstXoff, dstYoff;
215
216             FbStip *tmp;
217             FbStride tmpStride;
218             int width, height;
219
220             width = pbox->x2 - pbox->x1;
221             height = pbox->y2 - pbox->y1;
222
223             tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
224             tmp = malloc(tmpStride * height * sizeof(FbStip));
225             if (!tmp)
226                 return;
227
228             fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
229                           srcYoff);
230             fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
231                           dstYoff);
232
233             fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride,
234                        srcStride,
235                        (pbox->x1 + dx + srcXoff) * srcBpp,
236                        srcBpp,
237                        tmp,
238                        tmpStride,
239                        0,
240                        width * srcBpp,
241                        height,
242                        fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
243                        fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
244                        fbAndStip(GXcopy, 0, FB_ALLONES),
245                        fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
246             fbBltOne(tmp,
247                      tmpStride,
248                      0,
249                      dst + (pbox->y1 + dstYoff) * dstStride,
250                      dstStride,
251                      (pbox->x1 + dstXoff) * dstBpp,
252                      dstBpp,
253                      width * dstBpp,
254                      height,
255                      pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
256             free(tmp);
257
258             fbFinishAccess(pDstDrawable);
259             fbFinishAccess(pSrcDrawable);
260         }
261         pbox++;
262     }
263 }
264
265 RegionPtr
266 fbCopyArea(DrawablePtr pSrcDrawable,
267            DrawablePtr pDstDrawable,
268            GCPtr pGC,
269            int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut)
270 {
271     miCopyProc copy;
272
273     if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
274         copy = fb24_32CopyMtoN;
275     else
276         copy = fbCopyNtoN;
277     return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
278                     widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
279 }
280
281 RegionPtr
282 fbCopyPlane(DrawablePtr pSrcDrawable,
283             DrawablePtr pDstDrawable,
284             GCPtr pGC,
285             int xIn,
286             int yIn,
287             int widthSrc,
288             int heightSrc, int xOut, int yOut, unsigned long bitplane)
289 {
290     if (pSrcDrawable->bitsPerPixel > 1)
291         return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
292                         xIn, yIn, widthSrc, heightSrc,
293                         xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
294     else if (bitplane & 1)
295         return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
296                         widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
297                         (Pixel) bitplane, 0);
298     else
299         return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
300                                  xIn, yIn,
301                                  widthSrc, heightSrc, xOut, yOut, bitplane);
302 }