URI:
       tx11-draw.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tx11-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 }