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

📄 tweak.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <u.h>#include <libc.h>#include <draw.h>#include <cursor.h>#include <event.h>#include <bio.h>typedef struct	Thing	Thing;struct Thing{	Image	*b;	Subfont 	*s;	char		*name;	/* file name */	int		face;		/* is 48x48 face file or cursor file*/	Rectangle r;		/* drawing region */	Rectangle tr;		/* text region */	Rectangle er;		/* entire region */	long		c;		/* character number in subfont */	int		mod;	/* modified */	int		mag;		/* magnification */	Rune		off;		/* offset for subfont indices */	Thing	*parent;	/* thing of which i'm an edit */	Thing	*next;};enum{	Border	= 1,	Up		= 1,	Down	= 0,	Mag		= 4,	Maxmag	= 10,};enum{	NORMAL	=0,	FACE	=1,	CURSOR	=2};enum{	Mopen,	Mread,	Mwrite,	Mcopy,	Mchar,	Mpixels,	Mclose,	Mexit,};enum{	Blue	= 54,};char	*menu3str[] = {	[Mopen]	"open",	[Mread]	"read",	[Mwrite]	"write",	[Mcopy]	"copy",	[Mchar]	"char",	[Mpixels]	"pixels",	[Mclose]	"close",	[Mexit]	"exit",	0,};Menu	menu3 = {	menu3str};Cursor sweep0 = {	{-7, -7},	{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,	 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,	 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,	 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0},	{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,	 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00}};Cursor box = {	{-7, -7},	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,	 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},	{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}};Cursor sight = {	{-7, -7},	{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,	 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,	 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,	 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},	{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,	 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,	 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,	 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}};Cursor pixel = {	{-7, -7},	{0x1f, 0xf8, 0x3f, 0xfc,  0x7f, 0xfe,  0xf8, 0x1f,	0xf0, 0x0f,  0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f, 	0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f, 	0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },	{0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84, 	0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02, 	0x40, 0x02, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 	0x21, 0x84, 0x31, 0x8c, 0x0f, 0xf0, 0x00, 0x00, }};Cursor busy = {	{-7, -7},	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,	 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe, 	 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,	 0x04, 0x41, 0xff, 0xe1, 0x5f, 0xf1, 0x3f, 0xfe, 	 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,}};Cursor skull = {	{-7,-7},	{0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7, 	 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8, 	 0x0f, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 	 0xef, 0xf7, 0xc7, 0xe3, 0x00, 0x00, 0x00, 0x00,},	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,	 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,	 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,	 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}};Rectangle	cntlr;		/* control region */Rectangle	editr;		/* editing region */Rectangle	textr;		/* text region */Thing		*thing;Mouse		mouse;char		hex[] = "0123456789abcdefABCDEF";jmp_buf		err;char		*file;int		mag;int		but1val = 0;int		but2val = 255;int		invert = 0;Image		*values[256];Image		*greyvalues[256];uchar		data[8192];Thing*	tget(char*);void	mesg(char*, ...);void	drawthing(Thing*, int);void	select(void);void	menu(void);void	error(Display*, char*);void	buttons(int);void	drawall(void);void	tclose1(Thing*);voidmain(int argc, char *argv[]){	int i;	Event e;	Thing *t;	mag = Mag;	if(initdraw(error, 0, "tweak") < 0){		fprint(2, "tweak: initdraw failed: %r\n");		exits("initdraw");	}	for(i=0; i<256; i++){		values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));		greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);		if(values[i] == 0 || greyvalues[i] == 0)			drawerror(display, "can't allocate image");	}	einit(Emouse|Ekeyboard);	eresized(0);	i = 1;	setjmp(err);	for(; i<argc; i++){		file = argv[i];		t = tget(argv[i]);		if(t)			drawthing(t, 1);		flushimage(display, 1);	}	file = 0;	setjmp(err);	for(;;)		switch(event(&e)){		case Ekeyboard:			break;		case Emouse:			mouse = e.mouse;			if(mouse.buttons & 3){				select();				break;			}			if(mouse.buttons & 4)				menu();		}}voiderror(Display*, char *s){	if(file)		mesg("can't read %s: %s: %r", file, s);	else		mesg("/dev/bitblt error: %s", s);	if(err[0])		longjmp(err, 1);	exits(s);}voidredraw(Thing *t){	Thing *nt;	Point p;	if(thing==0 || thing==t)		draw(screen, editr, display->white, nil, ZP);	if(thing == 0)		return;	if(thing != t){		for(nt=thing; nt->next!=t; nt=nt->next)			;		draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),			display->white, nil, ZP);	}	for(nt=t; nt; nt=nt->next){		drawthing(nt, 0);		if(nt->next == 0){			p = Pt(editr.min.x, nt->er.max.y);			draw(screen, Rpt(p, editr.max), display->white, nil, ZP);		}	}	mesg("");}voideresized(int new){	if(new && getwindow(display, Refnone) < 0)		error(display, "can't reattach to window");	cntlr = insetrect(screen->clipr, 1);	editr = cntlr;	textr = editr;	textr.min.y = textr.max.y - font->height;	cntlr.max.y = cntlr.min.y + font->height;	editr.min.y = cntlr.max.y+1;	editr.max.y = textr.min.y-1;	draw(screen, screen->clipr, display->white, nil, ZP);	draw(screen, Rect(editr.min.x, editr.max.y, editr.max.x+1, editr.max.y+1), display->black, nil, ZP);	replclipr(screen, 0, editr);	drawall();}voidmesgstr(Point p, int line, char *s){	Rectangle c, r;	r.min = p;	r.min.y += line*font->height;	r.max.y = r.min.y+font->height;	r.max.x = editr.max.x;	c = screen->clipr;	replclipr(screen, 0, r);	draw(screen, r, values[0xDD], nil, ZP);	r.min.x++;	string(screen, r.min, display->black, ZP, font, s);	replclipr(screen, 0, c);	flushimage(display, 1);}voidmesg(char *fmt, ...){	char buf[1024];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	mesgstr(textr.min, 0, buf);}voidtmesg(Thing *t, int line, char *fmt, ...){	char buf[1024];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	mesgstr(t->tr.min, line, buf);}voidscntl(char *l){	sprint(l, "mag: %d  but1: %d  but2: %d  invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);}voidcntl(void){	char buf[256];	scntl(buf);	mesgstr(cntlr.min, 0, buf);}voidstext(Thing *t, char *l0, char *l1){	Fontchar *fc;	char buf[256];	l1[0] = 0;	sprint(buf, "depth:%d r:%d %d  %d %d ", 		t->b->depth, t->b->r.min.x, t->b->r.min.y,		t->b->r.max.x, t->b->r.max.y);	if(t->parent)		sprint(buf+strlen(buf), "mag: %d ", t->mag);	sprint(l0, "%s file: %s", buf, t->name);	if(t->c >= 0){		fc = &t->parent->s->info[t->c];		sprint(l1, "c(hex): %x c(char): %C x: %d "			   "top: %d bottom: %d left: %d width: %d iwidth: %d",			(int)(t->c+t->parent->off), (int)(t->c+t->parent->off),			fc->x, fc->top, fc->bottom, fc->left,			fc->width, Dx(t->b->r));	}else if(t->s)		sprint(l1, "offset(hex): %ux n:%d  height:%d  ascent:%d",			t->off, t->s->n, t->s->height, t->s->ascent);}voidtext(Thing *t){	char l0[256], l1[256];	stext(t, l0, l1);	tmesg(t, 0, l0);	if(l1[0])		tmesg(t, 1, l1);}voiddrawall(void){	Thing *t;	cntl();	for(t=thing; t; t=t->next)		drawthing(t, 0);}intvalue(Image *b, int x){	int v, l, w;	uchar mask;	w = b->depth;	if(w > 8){		mesg("ldepth too large");		return 0;	}	l = log2[w];	mask = (1<<w)-1;		/* ones at right end of word */	x -= b->r.min.x&~(7>>l);	/* adjust x relative to first pixel */	v = data[x>>(3-l)];	v >>= ((7>>l)<<l) - ((x&(7>>l))<<l);	/* pixel at right end of word */	v &= mask;			/* pixel at right end of word */	return v;}intbvalue(int v, int d){	v &= (1<<d)-1;	if(d > screen->depth)		v >>= d - screen->depth;	else		while(d < screen->depth && d < 8){			v |= v << d;			d <<= 1;		}	if(v<0 || v>255){		mesg("internal error: bad color");		return Blue;	}	return v;}voiddrawthing(Thing *nt, int link){	int nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;	Thing *t;	Subfont *s;	Image *b, *col;	Point p, p1, p2;	if(link){		nt->next = 0;		if(thing == 0){			thing = nt;			y = editr.min.y;		}else{			for(t=thing; t->next; t=t->next)				;			t->next = nt;			y = t->er.max.y;		}	}else{		if(thing == nt)			y = editr.min.y;		else{			for(t=thing; t->next!=nt; t=t->next)				;			y = t->er.max.y;		}	}	s = nt->s;	b = nt->b;	nl = font->height;	if(s || nt->c>=0)		nl += font->height;	fdx = Dx(editr) - 2*Border;	dx = Dx(b->r);	dy = Dy(b->r);	if(nt->mag > 1){		dx *= nt->mag;		dy *= nt->mag;		fdx -= fdx%nt->mag;	}	nf = 1 + dx/fdx;	nt->er.min.y = y;	nt->er.min.x = editr.min.x;	nt->er.max.x = nt->er.min.x + Border + dx + Border;	if(nt->er.max.x > editr.max.x)		nt->er.max.x = editr.max.x;	nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);	nt->r = insetrect(nt->er, Border);	nt->er.max.x = editr.max.x;	draw(screen, nt->er, display->white, nil, ZP);	for(i=0; i<nf; i++){		p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));		/* draw portion of bitmap */		p = Pt(p1.x+1, p1.y);		if(nt->mag == 1)			draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),				b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));		else{			for(y=b->r.min.y; y<b->r.max.y; y++){				sy = p.y+(y-b->r.min.y)*nt->mag;				unloadimage(b, Rect(b->r.min.x, y, b->r.max.x, y+1), data, sizeof data);				for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){					sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;					if(sx >= nt->r.max.x)						break;					v = bvalue(value(b, x), b->depth);					if(v == 255)						continue;					if(b->chan == GREY8)						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),							greyvalues[v], nil, ZP);					else						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),							values[v], nil, ZP);				}			}		}		/* line down left */		if(i == 0)			col = display->black;		else			col = display->white;		draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);		/* line across top */		draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);		p2 = p1;		if(i == nf-1){			p2.x += 1 + dx%fdx;			col = display->black;		}else{			p2.x = nt->r.max.x;			col = display->white;		}		/* line down right */		draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);		/* line across bottom */		if(i == nf-1){			p1.y += Border+dy;			draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);		}	}	nt->tr.min.x = editr.min.x;	nt->tr.max.x = editr.max.x;	nt->tr.min.y = nt->er.max.y + Border;	nt->tr.max.y = nt->tr.min.y + nl;	nt->er.max.y = nt->tr.max.y + Border;	text(nt);}inttohex(int c){	if('0'<=c && c<='9')		return c - '0';	if('a'<=c && c<='f')		return 10 + (c - 'a');	if('A'<=c && c<='F')		return 10 + (c - 'A');	return 0;}Thing*tget(char *file){	int i, j, fd, face, x, y, c, chan;	Image *b;	Subfont *s;	Thing *t;	Dir *d;	jmp_buf oerr;	uchar buf[256];	char *data;	buf[0] = '\0';	errstr((char*)buf, sizeof buf);	/* flush pending error message */	memmove(oerr, err, sizeof err);	d = nil;	if(setjmp(err)){   Err:		free(d);		memmove(err, oerr, sizeof err);		return 0;	}	fd = open(file, OREAD);	if(fd < 0){		mesg("can't open %s: %r", file);		goto Err;	}	d = dirfstat(fd);	if(d == nil){		mesg("can't stat bitmap file %s: %r", file);		close(fd);		goto Err;	}	if(read(fd, buf, 11) != 11){		mesg("can't read %s: %r", file);		close(fd);		goto Err;	}	seek(fd, 0, 0);	data = (char*)buf;	if(*data == '{')		data++;	if(memcmp(data, "0x", 2)==0 && data[4]==','){		/*		 * cursor file		 */		face = CURSOR;		s = 0;		data = malloc(d->length+1);		if(data == 0){			mesg("can't malloc buffer: %r");			close(fd);			goto Err;		}		data[d->length] = 0;		if(read(fd, data, d->length) != d->length){			mesg("can't read cursor file %s: %r", file);			close(fd);			goto Err;		}		b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill);		if(b == 0){			mesg("image alloc failed file %s: %r", file);			free(data);			close(fd);			goto Err;		}		i = 0;		for(x=0;x<64; ){			if((c=data[i]) == '\0')				goto ill;			if(c=='0' && data[i+1] == 'x'){				i += 2;				continue;			}			if(strchr(hex, c)){				buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);				i += 2;				continue;			}			i++;		}		loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf);		free(data);	}else if(memcmp(buf, "0x", 2)==0){		/*		 * face file		 */		face = FACE;		s = 0;		data = malloc(d->length+1);		if(data == 0){			mesg("can't malloc buffer: %r");			close(fd);			goto Err;		}		data[d->length] = 0;		if(read(fd, data, d->length) != d->length){			mesg("can't read bitmap file %s: %r", file);			close(fd);			goto Err;		}		for(y=0,i=0; i<d->length; i++)			if(data[i] == '\n')				y++;		if(y == 0){	ill:			mesg("ill-formed face file %s", file);			close(fd);			free(data);			goto Err;		}		for(x=0,i=0; (c=data[i])!='\n'; ){			if(c==',' || c==' ' || c=='\t'){				i++;				continue;			}			if(c=='0' && data[i+1] == 'x'){				i += 2;				continue;			}			if(strchr(hex, c)){				x += 4;				i++;				continue;			}			goto ill;		}		if(x % y)			goto ill;		switch(x / y){		default:			goto ill;		case 1:			chan = GREY1;			break;		case 2:			chan = GREY2;			break;		case 4:

⌨️ 快捷键说明

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