Blob


1 #include <u.h>
2 #include "x11-inc.h"
3 #include <libc.h>
4 #include <draw.h>
5 #include <memdraw.h>
6 #include "x11-memdraw.h"
8 static int xdraw(Memdrawparam*);
10 /*
11 * The X acceleration doesn't fit into the standard hwaccel
12 * model because we have the extra steps of pulling the image
13 * data off the server and putting it back when we're done.
14 */
15 void
16 memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
17 Memimage *mask, Point mp, int op)
18 {
19 Memdrawparam *par;
21 if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil)
22 return;
24 /* only fetch dst data if we need it */
25 if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask))
26 _xgetxdata(par->dst, par->r);
28 /* always fetch source and mask */
29 _xgetxdata(par->src, par->sr);
30 _xgetxdata(par->mask, par->mr);
32 /* now can run memimagedraw on the in-memory bits */
33 _memimagedraw(par);
35 if(xdraw(par))
36 return;
38 /* put bits back on x server */
39 _xputxdata(par->dst, par->r);
40 }
42 static int
43 xdraw(Memdrawparam *par)
44 {
45 u32int sdval;
46 uint m, state;
47 Memimage *dst, *mask;
48 Point dp, mp;
49 Rectangle r;
50 Xmem *xdst, *xmask;
51 XGC gc;
53 if(par->dst->X == nil)
54 return 0;
56 dst = par->dst;
57 mask = par->mask;
58 r = par->r;
59 state = par->state;
61 /*
62 * If we have an opaque mask and source is one opaque pixel,
63 * we can convert to the destination format and just XFillRectangle.
64 */
65 m = Simplesrc|Fullsrc|Simplemask|Fullmask;
66 if((state&m) == m){
67 _xfillcolor(dst, r, par->sdval);
68 /* xdirtyxdata(dst, r); */
69 return 1;
70 }
72 /*
73 * If no source alpha and an opaque mask, we can just copy
74 * the source onto the destination. If the channels are the
75 * same and the source is not replicated, XCopyArea works.
76 *
77 * This is disabled because Ubuntu Precise seems to ship with
78 * a buggy X server that sometimes drops the XCopyArea
79 * requests on the floor.
80 m = Simplemask|Fullmask;
81 if((state&(m|Replsrc))==m && src->chan==dst->chan && src->X){
82 Xmem *xsrc;
83 Point sp;
85 xdst = dst->X;
86 xsrc = src->X;
87 dp = subpt(r.min, dst->r.min);
88 sp = subpt(par->sr.min, src->r.min);
89 gc = dst->chan==GREY1 ? _x.gccopy0 : _x.gccopy;
91 XCopyArea(_x.display, xsrc->pixmap, xdst->pixmap, gc,
92 sp.x, sp.y, Dx(r), Dy(r), dp.x, dp.y);
93 /* xdirtyxdata(dst, r); * /
94 return 1;
95 }
96 */
98 /*
99 * If no source alpha, a 1-bit mask, and a simple source,
100 * we can copy through the mask onto the destination.
101 */
102 if(dst->X && mask->X && !(mask->flags&Frepl)
103 && mask->chan==GREY1 && (state&Simplesrc)){
104 xdst = dst->X;
105 xmask = mask->X;
106 sdval = par->sdval;
108 dp = subpt(r.min, dst->r.min);
109 mp = subpt(r.min, subpt(par->mr.min, mask->r.min));
111 if(dst->chan == GREY1){
112 gc = _x.gcsimplesrc0;
113 if(_x.gcsimplesrc0color != sdval){
114 XSetForeground(_x.display, gc, sdval);
115 _x.gcsimplesrc0color = sdval;
117 if(_x.gcsimplesrc0pixmap != xmask->pixmap){
118 XSetStipple(_x.display, gc, xmask->pixmap);
119 _x.gcsimplesrc0pixmap = xmask->pixmap;
121 }else{
122 /* this doesn't work on rob's mac? */
123 return 0;
124 /* gc = _x.gcsimplesrc;
125 if(dst->chan == CMAP8 && _x.usetable)
126 sdval = _x.tox11[sdval];
128 if(_x.gcsimplesrccolor != sdval){
129 XSetForeground(_x.display, gc, sdval);
130 _x.gcsimplesrccolor = sdval;
132 if(_x.gcsimplesrcpixmap != xmask->pixmap){
133 XSetStipple(_x.display, gc, xmask->pixmap);
134 _x.gcsimplesrcpixmap = xmask->pixmap;
136 */
138 XSetTSOrigin(_x.display, gc, mp.x, mp.y);
139 XFillRectangle(_x.display, xdst->pixmap, gc, dp.x, dp.y,
140 Dx(r), Dy(r));
141 /* xdirtyxdata(dst, r); */
142 return 1;
145 /*
146 * Can't accelerate.
147 */
148 return 0;