⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devdraw.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 3 页
字号:
			scrnid = BGSHORT(a+5);			refresh = a[9];			chan = BGLONG(a+10);			repl = a[14];			drawrectangle(&r, a+15);			drawrectangle(&clipr, a+31);			value = BGLONG(a+47);			if(drawlookup(client, dstid, 0))				error(Eimageexists);			if(scrnid){				dscrn = drawlookupscreen(client, scrnid, &cs);				scrn = dscrn->screen;				if(repl || chan!=scrn->image->chan)					error("image parameters incompatible with screen");				reffn = nil;				switch(refresh){				case Refbackup:					break;				case Refnone:					reffn = memlnorefresh;					break;				case Refmesg:					reffn = drawrefresh;					break;				default:					error("unknown refresh method");				}				l = memlalloc(scrn, r, reffn, 0, value);				if(l == 0)					error(Edrawmem);				addflush(l->layer->screenr);				l->clipr = clipr;				rectclip(&l->clipr, r);				if(drawinstall(client, dstid, l, dscrn) == 0){					memldelete(l);					error(Edrawmem);				}				dscrn->ref++;				if(reffn){					refx = nil;					if(reffn == drawrefresh){						refx = malloc(sizeof(Refx));						if(refx == 0){							drawuninstall(client, dstid);							error(Edrawmem);						}						refx->client = client;						refx->dimage = drawlookup(client, dstid, 1);					}					memlsetrefresh(l, reffn, refx);				}				continue;			}			i = allocmemimage(r, chan);			if(i == 0)				error(Edrawmem);			if(repl)				i->flags |= Frepl;			i->clipr = clipr;			if(!repl)				rectclip(&i->clipr, r);			if(drawinstall(client, dstid, i, 0) == 0){				freememimage(i);				error(Edrawmem);			}			memfillcolor(i, value);			continue;		/* allocate screen: 'A' id[4] imageid[4] fillid[4] public[1] */		case 'A':			printmesg(fmt="LLLb", a, 1);			m = 1+4+4+4+1;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			if(dstid == 0)				error(Ebadarg);			if(drawlookupdscreen(dstid))				error(Escreenexists);			ddst = drawlookup(client, BGLONG(a+5), 1);			dsrc = drawlookup(client, BGLONG(a+9), 1);			if(ddst==0 || dsrc==0)				error(Enodrawimage);			if(drawinstallscreen(client, 0, dstid, ddst, dsrc, a[13]) == 0)				error(Edrawmem);			continue;		/* set repl and clip: 'c' dstid[4] repl[1] clipR[4*4] */		case 'c':			printmesg(fmt="LbR", a, 0);			m = 1+4+1+4*4;			if(n < m)				error(Eshortdraw);			ddst = drawlookup(client, BGLONG(a+1), 1);			if(ddst == nil)				error(Enodrawimage);			if(ddst->name)				error("cannot change repl/clipr of shared image");			dst = ddst->image;			if(a[5])				dst->flags |= Frepl;			drawrectangle(&dst->clipr, a+6);			continue;		/* draw: 'd' dstid[4] srcid[4] maskid[4] R[4*4] P[2*4] P[2*4] */		case 'd':			printmesg(fmt="LLLRPP", a, 0);			m = 1+4+4+4+4*4+2*4+2*4;			if(n < m)				error(Eshortdraw);			dst = drawimage(client, a+1);			dstid = BGLONG(a+1);			src = drawimage(client, a+5);			mask = drawimage(client, a+9);			drawrectangle(&r, a+13);			drawpoint(&p, a+29);			drawpoint(&q, a+37);			op = drawclientop(client);			memdraw(dst, r, src, p, mask, q, op);			dstflush(dstid, dst, r);			continue;		/* toggle debugging: 'D' val[1] */		case 'D':			printmesg(fmt="b", a, 0);			m = 1+1;			if(n < m)				error(Eshortdraw);			drawdebug = a[1];			continue;		/* ellipse: 'e' dstid[4] srcid[4] center[2*4] a[4] b[4] thick[4] sp[2*4] alpha[4] phi[4]*/		case 'e':		case 'E':			printmesg(fmt="LLPlllPll", a, 0);			m = 1+4+4+2*4+4+4+4+2*4+2*4;			if(n < m)				error(Eshortdraw);			dst = drawimage(client, a+1);			dstid = BGLONG(a+1);			src = drawimage(client, a+5);			drawpoint(&p, a+9);			e0 = BGLONG(a+17);			e1 = BGLONG(a+21);			if(e0<0 || e1<0)				error("invalid ellipse semidiameter");			j = BGLONG(a+25);			if(j < 0)				error("negative ellipse thickness");			drawpoint(&sp, a+29);			c = j;			if(*a == 'E')				c = -1;			ox = BGLONG(a+37);			oy = BGLONG(a+41);			op = drawclientop(client);			/* high bit indicates arc angles are present */			if(ox & (1<<31)){				if((ox & (1<<30)) == 0)					ox &= ~(1<<31);				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);			}else				memellipse(dst, p, e0, e1, c, src, sp, op);			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));			continue;		/* free: 'f' id[4] */		case 'f':			printmesg(fmt="L", a, 1);			m = 1+4;			if(n < m)				error(Eshortdraw);			ll = drawlookup(client, BGLONG(a+1), 0);			if(ll && ll->dscreen && ll->dscreen->owner != client)				ll->dscreen->owner->refreshme = 1;			drawuninstall(client, BGLONG(a+1));			continue;		/* free screen: 'F' id[4] */		case 'F':			printmesg(fmt="L", a, 1);			m = 1+4;			if(n < m)				error(Eshortdraw);			drawlookupscreen(client, BGLONG(a+1), &cs);			drawuninstallscreen(client, cs);			continue;		/* initialize font: 'i' fontid[4] nchars[4] ascent[1] */		case 'i':			printmesg(fmt="Llb", a, 1);			m = 1+4+4+1;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			if(dstid == 0)				error("cannot use display as font");			font = drawlookup(client, dstid, 1);			if(font == 0)				error(Enodrawimage);			if(font->image->layer)				error("cannot use window as font");			ni = BGLONG(a+5);			if(ni<=0 || ni>4096)				error("bad font size (4096 chars max)");			free(font->fchar);	/* should we complain if non-zero? */			font->fchar = malloc(ni*sizeof(FChar));			if(font->fchar == 0)				error("no memory for font");			memset(font->fchar, 0, ni*sizeof(FChar));			font->nfchar = ni;			font->ascent = a[9];			continue;		/* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */		case 'l':			printmesg(fmt="LLSRPbb", a, 0);			m = 1+4+4+2+4*4+2*4+1+1;			if(n < m)				error(Eshortdraw);			font = drawlookup(client, BGLONG(a+1), 1);			if(font == 0)				error(Enodrawimage);			if(font->nfchar == 0)				error(Enotfont);			src = drawimage(client, a+5);			ci = BGSHORT(a+9);			if(ci >= font->nfchar)				error(Eindex);			drawrectangle(&r, a+11);			drawpoint(&p, a+27);			memdraw(font->image, r, src, p, memopaque, p, S);			fc = &font->fchar[ci];			fc->minx = r.min.x;			fc->maxx = r.max.x;			fc->miny = r.min.y;			fc->maxy = r.max.y;			fc->left = a[35];			fc->width = a[36];			continue;		/* draw line: 'L' dstid[4] p0[2*4] p1[2*4] end0[4] end1[4] radius[4] srcid[4] sp[2*4] */		case 'L':			printmesg(fmt="LPPlllLP", a, 0);			m = 1+4+2*4+2*4+4+4+4+4+2*4;			if(n < m)				error(Eshortdraw);			dst = drawimage(client, a+1);			dstid = BGLONG(a+1);			drawpoint(&p, a+5);			drawpoint(&q, a+13);			e0 = BGLONG(a+21);			e1 = BGLONG(a+25);			j = BGLONG(a+29);			if(j < 0)				error("negative line width");			src = drawimage(client, a+33);			drawpoint(&sp, a+37);			op = drawclientop(client);			memline(dst, p, q, e0, e1, j, src, sp, op);			/* avoid memlinebbox if possible */			if(dstid==0 || dst->layer!=nil){				/* BUG: this is terribly inefficient: update maximal containing rect*/				r = memlinebbox(p, q, e0, e1, j);				dstflush(dstid, dst, insetrect(r, -(1+1+j)));			}			continue;		/* create image mask: 'm' newid[4] id[4] *//* *		case 'm':			printmesg("LL", a, 0);			m = 4+4;			if(n < m)				error(Eshortdraw);			break; * */		/* attach to a named image: 'n' dstid[4] j[1] name[j] */		case 'n':			printmesg(fmt="Lz", a, 0);			m = 1+4+1;			if(n < m)				error(Eshortdraw);			j = a[5];			if(j == 0)	/* give me a non-empty name please */				error(Eshortdraw);			m += j;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			if(drawlookup(client, dstid, 0))				error(Eimageexists);			dn = drawlookupname(j, (char*)a+6);			if(dn == nil)				error(Enoname);			if(drawinstall(client, dstid, dn->dimage->image, 0) == 0)				error(Edrawmem);			di = drawlookup(client, dstid, 0);			if(di == 0)				error("draw: cannot happen");			di->vers = dn->vers;			di->name = smalloc(j+1);			di->fromname = dn->dimage;			di->fromname->ref++;			memmove(di->name, a+6, j);			di->name[j] = 0;			client->infoid = dstid;			continue;		/* name an image: 'N' dstid[4] in[1] j[1] name[j] */		case 'N':			printmesg(fmt="Lbz", a, 0);			m = 1+4+1+1;			if(n < m)				error(Eshortdraw);			c = a[5];			j = a[6];			if(j == 0)	/* give me a non-empty name please */				error(Eshortdraw);			m += j;			if(n < m)				error(Eshortdraw);			di = drawlookup(client, BGLONG(a+1), 0);			if(di == 0)				error(Enodrawimage);			if(di->name)				error(Enamed);			if(c)				drawaddname(client, di, j, (char*)a+7);			else{				dn = drawlookupname(j, (char*)a+7);				if(dn == nil)					error(Enoname);				if(dn->dimage != di)					error(Ewrongname);				drawdelname(dn);			}			continue;		/* position window: 'o' id[4] r.min [2*4] screenr.min [2*4] */		case 'o':			printmesg(fmt="LPP", a, 0);			m = 1+4+2*4+2*4;			if(n < m)				error(Eshortdraw);			dst = drawimage(client, a+1);			if(dst->layer){				drawpoint(&p, a+5);				drawpoint(&q, a+13);				r = dst->layer->screenr;				ni = memlorigin(dst, p, q);				if(ni < 0)					error("image origin failed");				if(ni > 0){					addflush(r);					addflush(dst->layer->screenr);					ll = drawlookup(client, BGLONG(a+1), 1);					drawrefreshscreen(ll, client);				}			}			continue;		/* set compositing operator for next draw operation: 'O' op */		case 'O':			printmesg(fmt="b", a, 0);			m = 1+1;			if(n < m)				error(Eshortdraw);			client->op = a[1];			continue;		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */		case 'p':		case 'P':			printmesg(fmt="LslllLPP", a, 0);			m = 1+4+2+4+4+4+4+2*4;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			dst = drawimage(client, a+1);			ni = BGSHORT(a+5);			if(ni < 0)				error("negative count in polygon");			e0 = BGLONG(a+7);			e1 = BGLONG(a+11);			j = 0;			if(*a == 'p'){				j = BGLONG(a+15);				if(j < 0)					error("negative polygon line width");			}			src = drawimage(client, a+19);			drawpoint(&sp, a+23);			drawpoint(&p, a+31);			ni++;			pp = malloc(ni*sizeof(Point));			if(pp == nil)				error(Enomem);			doflush = 0;			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))				doflush = 1;	/* simplify test in loop */			ox = oy = 0;			esize = 0;			u = a+m;			for(y=0; y<ni; y++){				q = p;				oesize = esize;				u = drawcoord(u, a+n, ox, &p.x);				u = drawcoord(u, a+n, oy, &p.y);				ox = p.x;				oy = p.y;				if(doflush){					esize = j;					if(*a == 'p'){						if(y == 0){							c = memlineendsize(e0);							if(c > esize)								esize = c;						}						if(y == ni-1){							c = memlineendsize(e1);							if(c > esize)								esize = c;						}					}					if(*a=='P' && e0!=1 && e0 !=~0)						r = dst->clipr;					else if(y > 0){						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));					}					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */						dstflush(dstid, dst, r);				}				pp[y] = p;			}			if(y == 1)				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));			op = drawclientop(client);			if(*a == 'p')				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);			else				memfillpoly(dst, pp, ni, e0, src, sp, op);			free(pp);			m = u-a;			continue;		/* read: 'r' id[4] R[4*4] */		case 'r':			printmesg(fmt="LR", a, 0);			m = 1+4+4*4;			if(n < m)				error(Eshortdraw);			i = drawimage(client, a+1);			drawrectangle(&r, a+5);			if(!rectinrect(r, i->r))				error(Ereadoutside);			c = bytesperline(r, i->depth);			c *= Dy(r);			free(client->readdata);			client->readdata = mallocz(c, 0);			if(client->readdata == nil)				error("readimage malloc failed");			client->nreaddata = memunload(i, r, client->readdata, c);			if(client->nreaddata < 0){				free(client->readdata);				client->readdata = nil;				error("bad readimage call");			}			continue;		/* string: 's' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] ni*(index[2]) */		/* stringbg: 'x' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] bgid[4] bgpt[2*4] ni*(index[2]) */		case 's':		case 'x':			printmesg(fmt="LLLPRPs", a, 0);			m = 1+4+4+4+2*4+4*4+2*4+2;			if(*a == 'x')				m += 4+2*4;			if(n < m)				error(Eshortdraw);			dst = drawimage(client, a+1);			dstid = BGLONG(a+1);			src = drawimage(client, a+5);			font = drawlookup(client, BGLONG(a+9), 1);			if(font == 0)				error(Enodrawimage);			if(font->nfchar == 0)				error(Enotfont);			drawpoint(&p, a+13);			drawrectangle(&r, a+21);			drawpoint(&sp, a+37);			ni = BGSHORT(a+45);			u = a+m;			m += ni*2;			if(n < m)				error(Eshortdraw);			clipr = dst->clipr;			dst->clipr = r;			op = drawclientop(client);			bg = dst;			if(*a == 'x'){				/* paint background */				bg = drawimage(client, a+47);				drawpoint(&q, a+51);				r.min.x = p.x;				r.min.y = p.y-font->ascent;				r.max.x = p.x;				r.max.y = r.min.y+Dy(font->image->r);				j = ni;				while(--j >= 0){					ci = BGSHORT(u);					if(ci<0 || ci>=font->nfchar){						dst->clipr = clipr;						error(Eindex);					}					r.max.x += font->fchar[ci].width;					u += 2;				}				memdraw(dst, r, bg, q, memopaque, ZP, op);				u -= 2*ni;			}			q = p;			while(--ni >= 0){				ci = BGSHORT(u);				if(ci<0 || ci>=font->nfchar){					dst->clipr = clipr;					error(Eindex);				}				q = drawchar(dst, bg, q, src, &sp, font, ci, op);				u += 2;			}			dst->clipr = clipr;			p.y -= font->ascent;			dstflush(dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->image->r)));			continue;		/* use public screen: 'S' id[4] chan[4] */		case 'S':			printmesg(fmt="Ll", a, 0);			m = 1+4+4;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			if(dstid == 0)				error(Ebadarg);			dscrn = drawlookupdscreen(dstid);			if(dscrn==0 || (dscrn->public==0 && dscrn->owner!=client))				error(Enodrawscreen);			if(dscrn->screen->image->chan != BGLONG(a+5))				error("inconsistent chan");			if(drawinstallscreen(client, dscrn, 0, 0, 0, 0) == 0)				error(Edrawmem);			continue;		/* top or bottom windows: 't' top[1] nw[2] n*id[4] */		case 't':			printmesg(fmt="bsL", a, 0);			m = 1+1+2;			if(n < m)				error(Eshortdraw);			nw = BGSHORT(a+2);			if(nw < 0)				error(Ebadarg);			if(nw == 0)				continue;			m += nw*4;			if(n < m)				error(Eshortdraw);			lp = malloc(nw*sizeof(Memimage*));			if(lp == 0)				error(Enomem);			if(waserror()){				free(lp);				nexterror();			}			for(j=0; j<nw; j++)				lp[j] = drawimage(client, a+1+1+2+j*4);			if(lp[0]->layer == 0)				error("images are not windows");			for(j=1; j<nw; j++)				if(lp[j]->layer->screen != lp[0]->layer->screen)					error("images not on same screen");			if(a[1])				memltofrontn(lp, nw);			else				memltorearn(lp, nw);			if(lp[0]->layer->screen->image->data == screenimage->data)				for(j=0; j<nw; j++)					addflush(lp[j]->layer->screenr);			ll = drawlookup(client, BGLONG(a+1+1+2), 1);			drawrefreshscreen(ll, client);			poperror();			free(lp);			continue;		/* visible: 'v' */		case 'v':			printmesg(fmt="", a, 0);			m = 1;			drawflush();			continue;		/* write: 'y' id[4] R[4*4] data[x*1] */		/* write from compressed data: 'Y' id[4] R[4*4] data[x*1] */		case 'y':		case 'Y':			printmesg(fmt="LR", a, 0);		//	iprint("load %c\n", *a);			m = 1+4+4*4;			if(n < m)				error(Eshortdraw);			dstid = BGLONG(a+1);			dst = drawimage(client, a+1);			drawrectangle(&r, a+5);			if(!rectinrect(r, dst->r))				error(Ewriteoutside);			y = memload(dst, r, a+m, n-m, *a=='Y');			if(y < 0)				error("bad writeimage call");			dstflush(dstid, dst, r);			m += y;			continue;		}	}	poperror();}Dev drawdevtab = {	'i',	"draw",	devreset,	devinit,	devshutdown,	drawattach,	drawwalk,	drawstat,	drawopen,	devcreate,	drawclose,	drawread,	devbread,	drawwrite,	devbwrite,	devremove,	devwstat,};/* * On 8 bit displays, load the default color map */voiddrawcmap(void){	int r, g, b, cr, cg, cb, v;	int num, den;	int i, j;	drawactive(1);	/* to restore map from backup */	for(r=0,i=0; r!=4; r++)	    for(v=0; v!=4; v++,i+=16){		for(g=0,j=v-r; g!=4; g++)		    for(b=0;b!=4;b++,j++){			den = r;			if(g > den)				den = g;			if(b > den)				den = b;			if(den == 0)	/* divide check -- pick grey shades */				cr = cg = cb = v*17;			else{				num = 17*(4*den+v);				cr = r*num/den;				cg = g*num/den;				cb = b*num/den;			}			setcolor(i+(j&15),				cr*0x01010101, cg*0x01010101, cb*0x01010101);		    }	}}voiddrawblankscreen(int blank){	int i, nc;	ulong *p;	if(blank == sdraw.blanked)		return;	if(!drawcanqlock())		return;	if(!initscreenimage()){		drawqunlock();		return;	}	p = sdraw.savemap;	nc = screenimage->depth > 8 ? 256 : 1<<screenimage->depth;	/*	 * blankscreen uses the hardware to blank the screen	 * when possible.  to help in cases when it is not possible,	 * we set the color map to be all black.	 */	if(blank == 0){	/* turn screen on */		for(i=0; i<nc; i++, p+=3)			setcolor(i, p[0], p[1], p[2]);		blankscreen(0);	}else{	/* turn screen off */		blankscreen(1);		for(i=0; i<nc; i++, p+=3){			getcolor(i, &p[0], &p[1], &p[2]);			setcolor(i, 0, 0, 0);		}	}	sdraw.blanked = blank;	drawqunlock();}/* * record activity on screen, changing blanking as appropriate */voiddrawactive(int active){	if(active){		drawblankscreen(0);		sdraw.blanktime = msec();	}else{		if(blanktime && sdraw.blanktime && (msec() - sdraw.blanktime)/1000/60 >= blanktime)			drawblankscreen(1);	}}intdrawidletime(void){	return (msec() - sdraw.blanktime)/1000/60;}/* why is this here? why can't caller use drawqlock himself? */voiddrawflushr(Rectangle r){	drawqlock();	flushmemscreen(r);	drawqunlock();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -