1 /*
2  * Copyright © 1998 Keith Packard
3  * Copyright © 2012 Intel Corporation
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 #include <stdlib.h>
25 
26 #include "fb.h"
27 #include <mi.h>
28 
29 void
fbCopyNtoN(DrawablePtr src_drawable,DrawablePtr dst_drawable,GCPtr gc,BoxPtr box,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)30 fbCopyNtoN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
31            BoxPtr box, int nbox,
32            int dx, int dy,
33 	   Bool reverse, Bool upsidedown, Pixel bitplane,
34 	   void *closure)
35 {
36 	CARD8 alu = gc ? gc->alu : GXcopy;
37 	FbBits pm = gc ? fb_gc(gc)->pm : FB_ALLONES;
38 	FbBits *src, *dst;
39 	FbStride srcStride, dstStride;
40 	int dstBpp, srcBpp;
41 	int srcXoff, srcYoff;
42 	int dstXoff, dstYoff;
43 
44 	fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
45 	fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
46 
47 	src += (dy + srcYoff) * srcStride;
48 	srcXoff += dx;
49 	dst += dstYoff * dstStride;
50 	do {
51 		fbBlt(src + box->y1 * srcStride, srcStride,
52 		      (box->x1 + srcXoff) * srcBpp,
53 		      dst + box->y1 * dstStride, dstStride,
54 		      (box->x1 + dstXoff) * dstBpp,
55 		      (box->x2 - box->x1) * dstBpp,
56 		      (box->y2 - box->y1),
57 		      alu, pm, dstBpp, reverse, upsidedown);
58 	} while (box++, --nbox);
59 }
60 
61 void
fbCopy1toN(DrawablePtr src_drawable,DrawablePtr dst_drawable,GCPtr gc,BoxPtr box,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)62 fbCopy1toN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
63            BoxPtr box, int nbox,
64            int dx, int dy,
65 	   Bool reverse, Bool upsidedown, Pixel bitplane,
66 	   void *closure)
67 {
68 	FbGCPrivPtr pgc = fb_gc(gc);
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(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
79 	fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
80 
81 	while (nbox--) {
82 		if (dstBpp == 1) {
83 			fbBlt(src + (box->y1 + dy + srcYoff) * srcStride,
84 			      srcStride,
85 			      (box->x1 + dx + srcXoff) * srcBpp,
86 			      dst + (box->y1 + dstYoff) * dstStride,
87 			      dstStride,
88 			      (box->x1 + dstXoff) * dstBpp,
89 			      (box->x2 - box->x1) * dstBpp,
90 			      (box->y2 - box->y1),
91 			      FbOpaqueStipple1Rop(gc->alu,
92 						  gc->fgPixel, gc->bgPixel),
93 			      pgc->pm, dstBpp, reverse, upsidedown);
94 		} else {
95 			fbBltOne((FbStip *) (src + (box->y1 + dy + srcYoff) * srcStride),
96 				 srcStride * (FB_UNIT / FB_STIP_UNIT),
97 				 (box->x1 + dx + srcXoff),
98 				 dst + (box->y1 + dstYoff) * dstStride,
99 				 dstStride,
100 				 (box->x1 + dstXoff) * dstBpp,
101 				 dstBpp,
102 				 (box->x2 - box->x1) * dstBpp,
103 				 (box->y2 - box->y1),
104 				 pgc->and, pgc->xor, pgc->bgand, pgc->bgxor);
105 		}
106 		box++;
107 	}
108 }
109 
110 void
fbCopyNto1(DrawablePtr src_drawable,DrawablePtr dst_drawable,GCPtr gc,BoxPtr box,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)111 fbCopyNto1(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
112            BoxPtr box, int nbox,
113            int dx, int dy,
114 	   Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
115 {
116 	FbGCPrivPtr pgc = fb_gc(gc);
117 
118 	while (nbox--) {
119 		if (dst_drawable->bitsPerPixel == 1) {
120 			FbBits *src;
121 			FbStride srcStride;
122 			int srcBpp;
123 			int srcXoff, srcYoff;
124 
125 			FbStip *dst;
126 			FbStride dstStride;
127 			int dstBpp;
128 			int dstXoff, dstYoff;
129 
130 			fbGetDrawable(src_drawable, src,
131 				      srcStride, srcBpp, srcXoff, srcYoff);
132 			fbGetStipDrawable(dst_drawable,
133 					  dst, dstStride, dstBpp, dstXoff, dstYoff);
134 			fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride, srcStride,
135 				   (box->x1 + dx + srcXoff) * srcBpp, srcBpp,
136 				   dst + (box->y1 + dstYoff) * dstStride, dstStride,
137 				   (box->x1 + dstXoff) * dstBpp,
138 				   (box->x2 - box->x1) * srcBpp, (box->y2 - box->y1),
139 				   (FbStip) pgc->and, (FbStip) pgc->xor,
140 				   (FbStip) pgc->bgand, (FbStip) pgc->bgxor, bitplane);
141 		} else {
142 			FbBits *src;
143 			FbStride srcStride;
144 			int srcBpp;
145 			int srcXoff, srcYoff;
146 
147 			FbBits *dst;
148 			FbStride dstStride;
149 			int dstBpp;
150 			int dstXoff, dstYoff;
151 
152 			FbStip *tmp;
153 			FbStride tmpStride;
154 			int width, height;
155 
156 			width = box->x2 - box->x1;
157 			height = box->y2 - box->y1;
158 
159 			tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
160 			tmp = malloc(tmpStride * height * sizeof(FbStip));
161 			if (!tmp)
162 				return;
163 
164 			fbGetDrawable(src_drawable, src,
165 				      srcStride, srcBpp, srcXoff, srcYoff);
166 			fbGetDrawable(dst_drawable, dst,
167 				      dstStride, dstBpp, dstXoff, dstYoff);
168 
169 			fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride,
170 				   srcStride,
171 				   (box->x1 + dx + srcXoff) * srcBpp,
172 				   srcBpp,
173 				   tmp,
174 				   tmpStride,
175 				   0,
176 				   width * srcBpp,
177 				   height,
178 				   fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
179 				   fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
180 				   fbAndStip(GXcopy, 0, FB_ALLONES),
181 				   fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
182 			fbBltOne(tmp,
183 				 tmpStride,
184 				 0,
185 				 dst + (box->y1 + dstYoff) * dstStride,
186 				 dstStride,
187 				 (box->x1 + dstXoff) * dstBpp,
188 				 dstBpp,
189 				 width * dstBpp,
190 				 height,
191 				 pgc->and, pgc->xor, pgc->bgand, pgc->bgxor);
192 			free(tmp);
193 		}
194 		box++;
195 	}
196 }
197 
198 RegionPtr
fbCopyArea(DrawablePtr src,DrawablePtr dst,GCPtr gc,int sx,int sy,int width,int height,int dx,int dy)199 fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc,
200 	   int sx, int sy,
201 	   int width, int height,
202 	   int dx, int dy)
203 {
204 	return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
205 			fbCopyNtoN, 0, 0);
206 }
207 
208 RegionPtr
fbCopyPlane(DrawablePtr src,DrawablePtr dst,GCPtr gc,int sx,int sy,int width,int height,int dx,int dy,unsigned long bitplane)209 fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
210 	    int sx, int sy,
211 	    int width, int height,
212 	    int dx, int dy,
213 	    unsigned long bitplane)
214 {
215 	if (src->bitsPerPixel > 1)
216 		return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
217 				fbCopyNto1, (Pixel) bitplane, 0);
218 	else if (bitplane & 1)
219 		return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
220 				fbCopy1toN, (Pixel) bitplane, 0);
221 	else
222 		return miHandleExposures(src, dst, gc,
223 					 sx, sy, width, height, dx, dy,
224 					 bitplane);
225 }
226