plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }