x11-draw.c (3594B)
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" 7 8 static int xdraw(Memdrawparam*); 9 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; 20 21 if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil) 22 return; 23 24 /* only fetch dst data if we need it */ 25 if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask)) 26 _xgetxdata(par->dst, par->r); 27 28 /* always fetch source and mask */ 29 _xgetxdata(par->src, par->sr); 30 _xgetxdata(par->mask, par->mr); 31 32 /* now can run memimagedraw on the in-memory bits */ 33 _memimagedraw(par); 34 35 if(xdraw(par)) 36 return; 37 38 /* put bits back on x server */ 39 _xputxdata(par->dst, par->r); 40 } 41 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; 52 53 if(par->dst->X == nil) 54 return 0; 55 56 dst = par->dst; 57 mask = par->mask; 58 r = par->r; 59 state = par->state; 60 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 } 71 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; 84 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; 90 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 */ 97 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; 107 108 dp = subpt(r.min, dst->r.min); 109 mp = subpt(r.min, subpt(par->mr.min, mask->r.min)); 110 111 if(dst->chan == GREY1){ 112 gc = _x.gcsimplesrc0; 113 if(_x.gcsimplesrc0color != sdval){ 114 XSetForeground(_x.display, gc, sdval); 115 _x.gcsimplesrc0color = sdval; 116 } 117 if(_x.gcsimplesrc0pixmap != xmask->pixmap){ 118 XSetStipple(_x.display, gc, xmask->pixmap); 119 _x.gcsimplesrc0pixmap = xmask->pixmap; 120 } 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]; 127 128 if(_x.gcsimplesrccolor != sdval){ 129 XSetForeground(_x.display, gc, sdval); 130 _x.gcsimplesrccolor = sdval; 131 } 132 if(_x.gcsimplesrcpixmap != xmask->pixmap){ 133 XSetStipple(_x.display, gc, xmask->pixmap); 134 _x.gcsimplesrcpixmap = xmask->pixmap; 135 } 136 */ 137 } 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; 143 } 144 145 /* 146 * Can't accelerate. 147 */ 148 return 0; 149 }