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

📄 mesg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <plumb.h>#include "flayer.h"#include "samterm.h"#define	HSIZE	3	/* Type + short count */Header	h;uchar	indata[DATASIZE+1];	/* room for NUL */uchar	outdata[DATASIZE];short	outcount;int	hversion;int	exiting;void	inmesg(Hmesg, int);int	inshort(int);long	inlong(int);vlong	invlong(int);void	hsetdot(int, long, long);void	hmoveto(int, long);void	hsetsnarf(int);void	hplumb(int);void	clrlock(void);int	snarfswap(char*, int, char**);voidrcv(void){	int c;	static state = 0;	static count = 0;	static i = 0;	static int errs = 0;	while((c=rcvchar()) != -1)		switch(state){		case 0:			h.type = c;			state++;			break;		case 1:			h.count0 = c;			state++;			break;		case 2:			h.count1 = c;			count = h.count0|(h.count1<<8);			i = 0;			if(count > DATASIZE){				if(++errs < 5){					dumperrmsg(count, h.type, h.count0, c);					state = 0;					continue;				}				fprint(2, "type %d count %d\n", h.type, count);				panic("count>DATASIZE");			}			if(count == 0)				goto zerocount;			state++;			break;		case 3:			indata[i++] = c;			if(i == count){		zerocount:				indata[i] = 0;				inmesg(h.type, count);				state = count = 0;				continue;			}			break;		}}Text *whichtext(int tg){	int i;	for(i=0; i<nname; i++)		if(tag[i] == tg)			return text[i];	panic("whichtext");	return 0;}voidinmesg(Hmesg type, int count){	Text *t;	int i, m;	long l;	Flayer *lp;	m = inshort(0);	l = inlong(2);	switch(type){	case -1:		panic("rcv error");	default:		fprint(2, "type %d\n", type);		panic("rcv unknown");	case Hversion:		hversion = m;		break;	case Hbindname:		l = invlong(2);		/* for 64-bit pointers */		if((i=whichmenu(m)) < 0)			break;		/* in case of a race, a bindname may already have occurred */		if((t=whichtext(m)) == 0)			t=(Text *)l;		else	/* let the old one win; clean up the new one */			while(((Text *)l)->nwin>0)				closeup(&((Text *)l)->l[((Text *)l)->front]);		text[i] = t;		text[i]->tag = m;		break;	case Hcurrent:		if(whichmenu(m)<0)			break;		t = whichtext(m);		i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;		if(t==0 && (t = sweeptext(0, m))==0)			break;		if(t->l[t->front].textfn==0)			panic("Hcurrent");		lp = &t->l[t->front];		if(i){			flupfront(lp);			flborder(lp, 0);			work = lp;		}else			current(lp);		break;	case Hmovname:		if((m=whichmenu(m)) < 0)			break;		t = text[m];		l = tag[m];		i = name[m][0];		text[m] = 0;	/* suppress panic in menudel */		menudel(m);		if(t == &cmd)			m = 0;		else{			if (nname>0 && text[0]==&cmd)				m = 1;			else m = 0;			for(; m<nname; m++)				if(strcmp((char*)indata+2, (char*)name[m]+1)<0)					break;		}		menuins(m, indata+2, t, i, (int)l);		break;	case Hgrow:		if(whichmenu(m) >= 0)			hgrow(m, l, inlong(6), 1);		break;	case Hnewname:		menuins(0, (uchar *)"", (Text *)0, ' ', m);		break;	case Hcheck0:		i = whichmenu(m);		if(i>=0) {			t = text[i];			if(t)				t->lock++;			outTs(Tcheck, m);		}		break;	case Hcheck:		i = whichmenu(m);		if(i>=0) {			t = text[i];			if(t && t->lock)				t->lock--;			hcheck(m);		}		break;	case Hunlock:		clrlock();		break;	case Hdata:		if(whichmenu(m) >= 0)			l += hdata(m, l, indata+6, count-6);	Checkscroll:		if(m == cmd.tag){			for(i=0; i<NL; i++){				lp = &cmd.l[i];				if(lp->textfn)					center(lp, l>=0? l : lp->p1);			}		}		break;	case Horigin:		if(whichmenu(m) >= 0)			horigin(m, l);		break;	case Hunlockfile:		if(whichmenu(m)>=0 && (t = whichtext(m))->lock){			--t->lock;			l = -1;			goto Checkscroll;		}		break;	case Hsetdot:		if(whichmenu(m) >= 0)			hsetdot(m, l, inlong(6));		break;	case Hgrowdata:		if(whichmenu(m)<0)			break;		hgrow(m, l, inlong(6), 0);		whichtext(m)->lock++;	/* fake the request */		l += hdata(m, l, indata+10, count-10);		goto Checkscroll;	case Hmoveto:		if(whichmenu(m)>=0)			hmoveto(m, l);		break;	case Hclean:		if((m = whichmenu(m)) >= 0)			name[m][0] = ' ';		break;	case Hdirty:		if((m = whichmenu(m))>=0)			name[m][0] = '\'';		break;	case Hdelname:		if((m=whichmenu(m)) >= 0)			menudel(m);		break;	case Hcut:		if(whichmenu(m) >= 0)			hcut(m, l, inlong(6));		break;	case Hclose:		if(whichmenu(m)<0 || (t = whichtext(m))==0)			break;		l = t->nwin;		for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)			if(lp->textfn){				closeup(lp);				--l;			}		break;	case Hsetpat:		setpat((char *)indata);		break;	case Hsetsnarf:		hsetsnarf(m);		break;	case Hsnarflen:		snarflen = inlong(0);		break;	case Hack:		outT0(Tack);		break;	case Hexit:		exiting = 1;		outT0(Texit);		threadexitsall(nil);		break;	case Hplumb:		hplumb(m);		break;	}}voidsetlock(void){	hostlock++;	setcursor(mousectl, cursor = &lockarrow);}voidclrlock(void){	hasunlocked = 1;	if(hostlock > 0)		hostlock--;	if(hostlock == 0)		setcursor(mousectl, cursor=(Cursor *)0);}voidstartfile(Text *t){	outTsv(Tstartfile, t->tag, (vlong)t);	/* for 64-bit pointers */	setlock();}voidstartnewfile(int type, Text *t){	t->tag = Untagged;	outTv(type, (vlong)t);			/* for 64-bit pointers */}intinshort(int n){	return indata[n]|(indata[n+1]<<8);}longinlong(int n){	return indata[n]|(indata[n+1]<<8)|		((long)indata[n+2]<<16)|((long)indata[n+3]<<24);}vlonginvlong(int n){	vlong v;	v = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indata[n+4];	v = (v<<16) | (indata[n+3]<<8) | indata[n+2];	v = (v<<16) | (indata[n+1]<<8) | indata[n];	return v;}voidoutT0(Tmesg type){	outstart(type);	outsend();}voidoutTl(Tmesg type, long l){	outstart(type);	outlong(l);	outsend();}voidoutTs(Tmesg type, int s){	outstart(type);	outshort(s);	outsend();}voidoutTss(Tmesg type, int s1, int s2){	outstart(type);	outshort(s1);	outshort(s2);	outsend();}voidoutTsll(Tmesg type, int s1, long l1, long l2){	outstart(type);	outshort(s1);	outlong(l1);	outlong(l2);	outsend();}voidoutTsl(Tmesg type, int s1, long l1){	outstart(type);	outshort(s1);	outlong(l1);	outsend();}voidoutTsv(Tmesg type, int s1, vlong v1){	outstart(type);	outshort(s1);	outvlong(v1);	outsend();}voidoutTv(Tmesg type, vlong v1){	outstart(type);	outvlong(v1);	outsend();}voidoutTslS(Tmesg type, int s1, long l1, Rune *s){	char buf[DATASIZE*3+1];	char *c;	outstart(type);	outshort(s1);	outlong(l1);	c = buf;	while(*s)		c += runetochar(c, s++);	*c++ = 0;	outcopy(c-buf, (uchar *)buf);	outsend();}voidoutTsls(Tmesg type, int s1, long l1, int s2){	outstart(type);	outshort(s1);	outlong(l1);	outshort(s2);	outsend();}voidoutstart(Tmesg type){	outdata[0] = type;	outcount = 0;}voidoutcopy(int count, uchar *data){	while(count--)		outdata[HSIZE+outcount++] = *data++;	}voidoutshort(int s){	uchar buf[2];	buf[0]=s;	buf[1]=s>>8;	outcopy(2, buf);}voidoutlong(long l){	uchar buf[4];	buf[0]=l;	buf[1]=l>>8;	buf[2]=l>>16;	buf[3]=l>>24;	outcopy(4, buf);}voidoutvlong(vlong v){	int i;	uchar buf[8];	for(i = 0; i < sizeof(buf); i++){		buf[i] = v;		v >>= 8;	}	outcopy(8, buf);}voidoutsend(void){	if(outcount>DATASIZE-HSIZE)		panic("outcount>sizeof outdata");	outdata[1]=outcount;	outdata[2]=outcount>>8;	if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)		panic("write error");}voidhsetdot(int m, long p0, long p1){	Text *t = whichtext(m);	Flayer *l = &t->l[t->front];	flushtyping(1);	flsetselect(l, p0, p1);}voidhorigin(int m, long p0){	Text *t = whichtext(m);	Flayer *l = &t->l[t->front];	long a;	ulong n;	Rune *r;	if(!flprepare(l)){		l->origin = p0;		return;	}	a = p0-l->origin;	if(a>=0 && a<l->f.nchars)		frdelete(&l->f, 0, a);	else if(a<0 && -a<l->f.nchars){		r = rload(&t->rasp, p0, l->origin, &n);		frinsert(&l->f, r, r+n, 0);	}else		frdelete(&l->f, 0, l->f.nchars);	l->origin = p0;	scrdraw(l, t->rasp.nrunes);	if(l->visible==Some)		flrefresh(l, l->entire, 0);	hcheck(m);}voidhmoveto(int m, long p0){	Text *t = whichtext(m);	Flayer *l = &t->l[t->front];	if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)		outTsll(Torigin, m, p0, 2L);}voidhcheck(int m){	Flayer *l;	Text *t;	int reqd = 0, i;	long n, nl, a;	Rune *r;	if(m == Untagged)		return;	t = whichtext(m);	if(t == 0)		/* possible in a half-built window */		return;	for(l = &t->l[0], i = 0; i<NL; i++, l++){		if(l->textfn==0 || !flprepare(l))	/* BUG: don't							   need this if BUG below							   is fixed */			continue;		a = t->l[i].origin;		n = rcontig(&t->rasp, a, a+l->f.nchars, 1);		if(n<l->f.nchars)	/* text missing in middle of screen */			a+=n;		else{			/* text missing at end of screen? */        Again:		 	if(l->f.lastlinefull)				goto Checksel;	/* all's well */			a = t->l[i].origin+l->f.nchars;			n = t->rasp.nrunes-a;			if(n==0)				goto Checksel;			if(n>TBLOCKSIZE)				n = TBLOCKSIZE;			n = rcontig(&t->rasp, a, a+n, 1);			if(n>0){				rload(&t->rasp, a, a+n, 0);				nl = l->f.nchars;				r = scratch;				flinsert(l, r, r+n, l->origin+nl);				if(nl == l->f.nchars)	/* made no progress */					goto Checksel;				goto Again;			}		}		if(!reqd){			n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);			if(n <= 0)				panic("hcheck request==0");			outTsls(Trequest, m, a, (int)n);			outTs(Tcheck, m);			t->lock++;	/* for the Trequest */			t->lock++;	/* for the Tcheck */			reqd++;		}	    Checksel:		flsetselect(l, l->p0, l->p1);	}}voidflnewlyvisible(Flayer *l){	hcheck(((Text *)l->user1)->tag);}voidhsetsnarf(int nc){	char *s2;	char *s1;	int i;	int n;	setcursor(mousectl, &deadmouse);	s2 = alloc(nc+1);	for(i=0; i<nc; i++)		s2[i] = getch();	s2[nc] = 0;	n = snarfswap(s2, nc, &s1);	if(n >= 0){		if(!s1)			n = 0;		s1 = realloc(s1, n+1);		if (!s1)			panic("realloc");		s1[n] = 0;		snarflen = n;		outTs(Tsetsnarf, n);		if(n>0 && write(1, s1, n)!=n)			panic("snarf write error");		free(s1);	}else		outTs(Tsetsnarf, 0);	free(s2);	setcursor(mousectl, cursor);}voidhplumb(int nc){	int i;	char *s;	Plumbmsg *m;	s = alloc(nc);	for(i=0; i<nc; i++)		s[i] = getch();	if(plumbfd > 0){		m = plumbunpack(s, nc);		if(m != 0)			plumbsend(plumbfd, m);		plumbfree(m);	}	free(s);}voidhgrow(int m, long a, long new, int req){	int i;	Flayer *l;	Text *t = whichtext(m);	long o, b;	if(new <= 0)		panic("hgrow");	rresize(&t->rasp, a, 0L, new);	for(l = &t->l[0], i = 0; i<NL; i++, l++){		if(l->textfn == 0)			continue;		o = l->origin;		b = a-o-rmissing(&t->rasp, o, a);		if(a < o)			l->origin+=new;		if(a < l->p0)			l->p0+=new;		if(a < l->p1)			l->p1+=new;		/* must prevent b temporarily becoming unsigned */		if(!req || a<o || (b>0 && b>l->f.nchars) ||		    (l->f.nchars==0 && a-o>0))			continue;		if(new>TBLOCKSIZE)			new = TBLOCKSIZE;		outTsls(Trequest, m, a, (int)new);		t->lock++;		req = 0;	}}inthdata1(Text *t, long a, Rune *r, int len){	int i;	Flayer *l;	long o, b;	for(l = &t->l[0], i=0; i<NL; i++, l++){		if(l->textfn==0)			continue;		o = l->origin;		b = a-o-rmissing(&t->rasp, o, a);		/* must prevent b temporarily becoming unsigned */		if(a<o || (b>0 && b>l->f.nchars))			continue;		flinsert(l, r, r+len, o+b);	}	rdata(&t->rasp, a, a+len, r);	rclean(&t->rasp);	return len;}inthdata(int m, long a, uchar *s, int len){	int i, w;	Text *t = whichtext(m);	Rune buf[DATASIZE], *r;	if(t->lock)		--t->lock;	if(len == 0)		return 0;	r = buf;	for(i=0; i<len; i+=w,s+=w)		w = chartorune(r++, (char*)s);	return hdata1(t, a, buf, r-buf);}inthdatarune(int m, long a, Rune *r, int len){	Text *t = whichtext(m);	if(t->lock)		--t->lock;	if(len == 0)		return 0;	return hdata1(t, a, r, len);}voidhcut(int m, long a, long old){	Flayer *l;	Text *t = whichtext(m);	int i;	long o, b;	if(t->lock)		--t->lock;	for(l = &t->l[0], i = 0; i<NL; i++, l++){		if(l->textfn == 0)			continue;		o = l->origin;		b = a-o-rmissing(&t->rasp, o, a);		/* must prevent b temporarily becoming unsigned */		if((b<0 || b<l->f.nchars) && a+old>=o){			fldelete(l, b<0? o : o+b,			    a+old-rmissing(&t->rasp, o, a+old));		}		if(a+old<o)			l->origin-=old;		else if(a<=o)			l->origin = a;		if(a+old<l->p0)			l->p0-=old;		else if(a<=l->p0)			l->p0 = a;		if(a+old<l->p1)			l->p1-=old;		else if(a<=l->p1)			l->p1 = a;	}	rresize(&t->rasp, a, old, 0L);	rclean(&t->rasp);}

⌨️ 快捷键说明

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