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

📄 tweak.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
				y += t->s->height;				if(fc[1].x > fc[0].x)					goto again;			}			x += fc[1].x - fc[0].x;		}		return;	   found:		r = br;		r.min.x = fc[0].x;		r.max.x = fc[1].x;	}	nt = malloc(sizeof(Thing));	if(nt == 0){   nomem:		mesg("can't allocate: %r");		return;	}	memset(nt, 0, sizeof(Thing));	nt->c = c;	nt->b = allocimage(display, r, t->b->chan, 0, DNofill);	if(nt->b == 0){		free(nt);		goto nomem;	}	draw(nt->b, r, t->b, nil, r.min);	nt->name = strdup(t->name);	if(nt->name == 0){		freeimage(nt->b);		free(nt);		goto nomem;	}	nt->parent = t;	nt->mag = mag;	drawthing(nt, 1);}voidckinfo(Thing *t, Rectangle mod){	int i, j, k, top, bot, n, zero;	Fontchar *fc;	Rectangle r;	Image *b;	Thing *nt;	if(t->parent)		t = t->parent;	if(t->s==0 || Dy(t->b->r)==0)		return;	b = 0;	/* check bounding boxes */	fc = &t->s->info[0];	r.min.y = t->b->r.min.y;	r.max.y = t->b->r.max.y;	for(i=0; i<t->s->n; i++, fc++){		r.min.x = fc[0].x;		r.max.x = fc[1].x;		if(!rectXrect(mod, r))			continue;		if(b==0 || Dx(b->r)<Dx(r)){			if(b)				freeimage(b);			b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);			if(b == 0){				mesg("can't alloc image");				break;			}		}		draw(b, b->r, display->white, nil, ZP);		draw(b, b->r, t->b, nil, r.min);		top = 100000;		bot = 0;		n = 2+((Dx(r)/8)*t->b->depth);		for(j=0; j<b->r.max.y; j++){			memset(data, 0, n);			unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);			zero = 1;			for(k=0; k<n; k++)				if(data[k]){					zero = 0;					break;				}			if(!zero){				if(top > j)					top = j;				bot = j+1;			}		}		if(top > j)			top = 0;		if(top!=fc->top || bot!=fc->bottom){			fc->top = top;			fc->bottom = bot;			for(nt=thing; nt; nt=nt->next)				if(nt->parent==t && nt->c==i)					text(nt);		}	}	if(b)		freeimage(b);}voidtwidpix(Thing *t, Point p, int set){	Image *b, *v;	int c;	b = t->b;	if(!ptinrect(p, b->r))		return;	if(set)		c = but1val;	else		c = but2val;	if(b->chan == GREY8)		v = greyvalues[c];	else		v = values[c];	draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);	p = screenpt(t, p);	draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);}voidtwiddle(Thing *t){	int set;	Point p, lastp;	Image *b;	Thing *nt;	Rectangle mod;	if(mouse.buttons!=1 && mouse.buttons!=2){		buttons(Up);		return;	}	set = mouse.buttons==1;	b = t->b;	lastp = addpt(b->r.min, Pt(-1, -1));	mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);	while(mouse.buttons){		p = realpt(t, mouse.xy);		if(!eqpt(p, lastp)){			lastp = p;			if(ptinrect(p, b->r)){				for(nt=thing; nt; nt=nt->next)					if(nt->parent==t->parent || nt==t->parent)						twidpix(nt, p, set);				if(t->parent)					t->parent->mod = 1;				else					t->mod = 1;				if(p.x < mod.min.x)					mod.min.x = p.x;				if(p.y < mod.min.y)					mod.min.y = p.y;				if(p.x >= mod.max.x)					mod.max.x = p.x+1;				if(p.y >= mod.max.y)					mod.max.y = p.y+1;			}		}		mouse = emouse();	}	ckinfo(t, mod);}voidselect(void){	Thing *t;	char line[128], buf[128];	Point p;	if(ptinrect(mouse.xy, cntlr)){		scntl(line);		if(atline(cntlr.min.x, mouse.xy, line, buf)){			if(mouse.buttons == 1)				cntledit(buf);			else				buttons(Up);			return;		}		return;	}	for(t=thing; t; t=t->next){		if(attext(t, mouse.xy, buf)){			if(mouse.buttons == 1)				textedit(t, buf);			else				buttons(Up);			return;		}		if(ptinrect(mouse.xy, t->r)){			if(t->parent == 0){				if(mouse.buttons == 1){					p = mouse.xy;					buttons(Up);					openedit(t, p, -1);				}else					buttons(Up);				return;			}			twiddle(t);			return;		}	}}voidtwrite(Thing *t){	int i, j, x, y, fd, ws, ld;	Biobuf buf;	Rectangle r;	if(t->parent)		t = t->parent;	esetcursor(&busy);	fd = create(t->name, OWRITE, 0666);	if(fd < 0){		mesg("can't write %s: %r", t->name);		return;	}	if(t->face && t->b->depth <= 4){		r = t->b->r;		ld = log2[t->b->depth];		/* This heuristic reflects peculiarly different formats */		ws = 4;		if(t->face == 2)	/* cursor file */			ws = 1;		else if(Dx(r)<32 || ld==0)			ws = 2;		Binit(&buf, fd, OWRITE);		if(t->face == CURSOR)			Bprint(&buf, "{");		for(y=r.min.y; y<r.max.y; y++){			unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);			j = 0;			for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){				Bprint(&buf, "0x");				for(i=0; i<ws; i++)					Bprint(&buf, "%.2x", data[i+j]);				Bprint(&buf, ", ");			}			if(t->face == CURSOR){				switch(y){				case 3: case 7: case 11: case 19: case 23: case 27:					Bprint(&buf, "\n ");					break;				case 15:					Bprint(&buf, "},\n{");					break;				case 31:					Bprint(&buf, "}\n");					break;				}			}else				Bprint(&buf, "\n");		}		Bterm(&buf);	}else		if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){			close(fd);			mesg("can't write %s: %r", t->name);		}	t->mod = 0;	close(fd);	mesg("wrote %s", t->name);}voidtpixels(void){	Thing *t;	Point p, lastp;	esetcursor(&pixel);	for(;;){		buttons(Down);		if(mouse.buttons != 4)			break;		for(t=thing; t; t=t->next){			lastp = Pt(-1, -1);			if(ptinrect(mouse.xy, t->r)){				while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){					p = realpt(t, mouse.xy);					if(!eqpt(p, lastp)){						if(p.y != lastp.y)							unloadimage(t->b, Rect(t->b->r.min.x, p.y, t->b->r.max.x, p.y+1), data, sizeof data);						mesg("[%d,%d] = %d=0x%ux", p.x, p.y, value(t->b, p.x), value(t->b, p.x));						lastp = p;					}					mouse = emouse();				}				goto Continue;			}		}		mouse = emouse();    Continue:;	}	buttons(Up);	esetcursor(0);}voidtclose1(Thing *t){	Thing *nt;	if(t == thing)		thing = t->next;	else{		for(nt=thing; nt->next!=t; nt=nt->next)			;		nt->next = t->next;	}	do		for(nt=thing; nt; nt=nt->next)			if(nt->parent == t){				tclose1(nt);				break;			}	while(nt);	if(t->s)		freesubfont(t->s);	else		freeimage(t->b);	free(t->name);	free(t);}voidtclose(Thing *t){	Thing *ct;	if(t->mod){		mesg("%s modified", t->name);		t->mod = 0;		return;	}	/* fiddle to save redrawing unmoved things */	if(t == thing)		ct = 0;	else		for(ct=thing; ct; ct=ct->next)			if(ct->next==t || ct->next->parent==t)				break;	tclose1(t);	if(ct)		ct = ct->next;	else		ct = thing;	redraw(ct);}voidtread(Thing *t){	Thing *nt, *new;	Fontchar *i;	Rectangle r;	int nclosed;	if(t->parent)		t = t->parent;	new = tget(t->name);	if(new == 0)		return;	nclosed = 0;    again:	for(nt=thing; nt; nt=nt->next)		if(nt->parent == t){			if(!rectinrect(nt->b->r, new->b->r)			|| new->b->depth!=nt->b->depth){    closeit:				nclosed++;				nt->parent = 0;				tclose1(nt);				goto again;			}			if((t->s==0) != (new->s==0))				goto closeit;			if((t->face==0) != (new->face==0))				goto closeit;			if(t->s){	/* check same char */				if(nt->c >= new->s->n)					goto closeit;				i = &new->s->info[nt->c];				r.min.x = i[0].x;				r.max.x = i[1].x;				r.min.y = new->b->r.min.y;				r.max.y = new->b->r.max.y;				if(!eqrect(r, nt->b->r))					goto closeit;			}			nt->parent = new;			draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);		}	new->next = t->next;	if(t == thing)		thing = new;	else{		for(nt=thing; nt->next!=t; nt=nt->next)			;		nt->next = new;	}	if(t->s)		freesubfont(t->s);	else		freeimage(t->b);	free(t->name);	free(t);	for(nt=thing; nt; nt=nt->next)		if(nt==new || nt->parent==new)			if(nclosed == 0)				drawthing(nt, 0);	/* can draw in place */			else{				redraw(nt);	/* must redraw all below */				break;			}}voidtchar(Thing *t){	char buf[256], *p;	Rune r;	ulong c, d;	if(t->s == 0){		t = t->parent;		if(t==0 || t->s==0){			mesg("not a subfont");			return;		}	}	if(type(buf, "char (hex or character or hex-hex)") == 0)		return;	if(utflen(buf) == 1){		chartorune(&r, buf);		c = r;		d = r;	}else{		if(!strchr(hex, buf[0])){			mesg("illegal hex character");			return;		}		c = strtoul(buf, 0, 16);		d = c;		p = utfrune(buf, '-');		if(p){			d = strtoul(p+1, 0, 16);			if(d < c){				mesg("invalid range");				return;			}		}	}	c -= t->off;	d -= t->off;	while(c <= d){		if(c<0 || c>=t->s->n){			mesg("0x%lux not in font %s", c+t->off, t->name);			return;		}		openedit(t, Pt(0, 0), c);		c++;	}}voidapply(void (*f)(Thing*)){	Thing *t;	esetcursor(&sight);	buttons(Down);	if(mouse.buttons == 4)		for(t=thing; t; t=t->next)			if(ptinrect(mouse.xy, t->er)){				buttons(Up);				f(t);				break;			}	buttons(Up);	esetcursor(0);}intcomplement(Image *t){	int i, n;	uchar *buf;	n = Dy(t->r)*bytesperline(t->r, t->depth);	buf = malloc(n);	if(buf == 0)		return 0;	unloadimage(t, t->r, buf, n);	for(i=0; i<n; i++)		buf[i] = ~buf[i];	loadimage(t, t->r, buf, n);	free(buf);	return 1;}voidcopy(void){	Thing *st, *dt, *nt;	Rectangle sr, dr, fr;	Image *tmp;	Point p1, p2;	int but, up;	if(!sweep(3, &sr))		return;	for(st=thing; st; st=st->next)		if(rectXrect(sr, st->r))			break;	if(st == 0)		return;	/* click gives full rectangle */	if(Dx(sr)<4 && Dy(sr)<4)		sr = st->r;	rectclip(&sr, st->r);	p1 = realpt(st, sr.min);	p2 = realpt(st, Pt(sr.min.x, sr.max.y));	up = 0;	if(p1.x != p2.x){	/* swept across a fold */   onafold:		mesg("sweep spans a fold");		goto Return;	}	p2 = realpt(st, sr.max);	sr.min = p1;	sr.max = p2;	fr.min = screenpt(st, sr.min);	fr.max = screenpt(st, sr.max);	p1 = subpt(p2, p1);	/* diagonal */	if(p1.x==0 || p1.y==0)		return;	border(screen, fr, -1, values[Blue], ZP);	esetcursor(&box);	for(; mouse.buttons==0; mouse=emouse()){		for(dt=thing; dt; dt=dt->next)			if(ptinrect(mouse.xy, dt->er))				break;		if(up)			edrawgetrect(insetrect(dr, -Borderwidth), 0);		up = 0;		if(dt == 0)			continue;		dr.max = screenpt(dt, realpt(dt, mouse.xy));		dr.min = subpt(dr.max, mulpt(p1, dt->mag));		if(!rectXrect(dr, dt->r))			continue;		edrawgetrect(insetrect(dr, -Borderwidth), 1);		up = 1;	}	/* if up==1, we had a hit */	esetcursor(0);	if(up)		edrawgetrect(insetrect(dr, -Borderwidth), 0);	but = mouse.buttons;	buttons(Up);	if(!up || but!=4)		goto Return;	dt = 0;	for(nt=thing; nt; nt=nt->next)		if(rectXrect(dr, nt->r)){			if(dt){				mesg("ambiguous sweep");				return;			}			dt = nt;		}	if(dt == 0)		goto Return;	p1 = realpt(dt, dr.min);	p2 = realpt(dt, Pt(dr.min.x, dr.max.y));	if(p1.x != p2.x)		goto onafold;	p2 = realpt(dt, dr.max);	dr.min = p1;	dr.max = p2;	if(invert){		tmp = allocimage(display, dr, dt->b->chan, 0, 255);		if(tmp == 0){    nomem:			mesg("can't allocate temporary");			goto Return;		}		draw(tmp, dr, st->b, nil, sr.min);		if(!complement(tmp))			goto nomem;		draw(dt->b, dr, tmp, nil, dr.min);		freeimage(tmp);	}else		draw(dt->b, dr, st->b, nil, sr.min);	if(dt->parent){		draw(dt->parent->b, dr, dt->b, nil, dr.min);		dt = dt->parent;	}	drawthing(dt, 0);	for(nt=thing; nt; nt=nt->next)		if(nt->parent==dt && rectXrect(dr, nt->b->r)){			draw(nt->b, dr, dt->b, nil, dr.min);			drawthing(nt, 0);		}	ckinfo(dt, dr);	dt->mod = 1;Return:	/* clear blue box */	drawthing(st, 0);}voidmenu(void){	Thing *t;	char *mod;	int sel;	char buf[256];	sel = emenuhit(3, &mouse, &menu3);	switch(sel){	case Mopen:		if(type(buf, "file")){			t = tget(buf);			if(t)				drawthing(t, 1);		}		break;	case Mwrite:		apply(twrite);		break;	case Mread:		apply(tread);		break;	case Mchar:		apply(tchar);		break;	case Mcopy:		copy();		break;	case Mpixels:		tpixels();		break;	case Mclose:		apply(tclose);		break;	case Mexit:		mod = 0;		for(t=thing; t; t=t->next)			if(t->mod){				mod = t->name;				t->mod = 0;			}		if(mod){			mesg("%s modified", mod);			break;		}		esetcursor(&skull);		buttons(Down);		if(mouse.buttons == 4){			buttons(Up);			exits(0);		}		buttons(Up);		esetcursor(0);		break;	}}

⌨️ 快捷键说明

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