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

📄 main.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 "flayer.h"#include "samterm.h"Text	cmd;Rune	*scratch;long	nscralloc;Cursor	*cursor;Flayer	*which = 0;Flayer	*work = 0;long	snarflen;long	typestart = -1;long	typeend = -1;long	typeesc = -1;long	modified = 0;		/* strange lookahead for menus */char	hostlock = 1;char	hasunlocked = 0;int	maxtab = 8;int	autoindent;voidthreadmain(int argc, char *argv[]){	int i, got, scr;	Text *t;	Rectangle r;	Flayer *nwhich;	getscreen(argc, argv);	iconinit();	initio();	scratch = alloc(100*RUNESIZE);	nscralloc = 100;	r = screen->r;	r.max.y = r.min.y+Dy(r)/5;	flstart(screen->clipr);	rinit(&cmd.rasp);	flnew(&cmd.l[0], gettext, 1, &cmd);	flinit(&cmd.l[0], r, font, cmdcols);	cmd.nwin = 1;	which = &cmd.l[0];	cmd.tag = Untagged;	outTs(Tversion, VERSION);	startnewfile(Tstartcmdfile, &cmd);	got = 0;	for(;;got = waitforio()){		if(hasunlocked && RESIZED())			resize();		if(got&(1<<RHost))			rcv();		if(got&(1<<RPlumb)){			for(i=0; cmd.l[i].textfn==0; i++)				;			current(&cmd.l[i]);			flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);			type(which, RPlumb);		}		if(got&(1<<RKeyboard))			if(which)				type(which, RKeyboard);			else				kbdblock();		if(got&(1<<RMouse)){			if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){				mouseunblock();				continue;			}			nwhich = flwhich(mousep->xy);			scr = which && ptinrect(mousep->xy, which->scroll);			if(mousep->buttons)				flushtyping(1);			if(mousep->buttons&1){				if(nwhich){					if(nwhich!=which)						current(nwhich);					else if(scr)						scroll(which, 1);					else{						t=(Text *)which->user1;						if(flselect(which)){							outTsl(Tdclick, t->tag, which->p0);							t->lock++;						}else if(t!=&cmd)							outcmd();					}				}			}else if((mousep->buttons&2) && which){				if(scr)					scroll(which, 2);				else					menu2hit();			}else if((mousep->buttons&4)){				if(scr)					scroll(which, 3);				else					menu3hit();			}			mouseunblock();		}	}}voidresize(void){	int i;	flresize(screen->clipr);	for(i = 0; i<nname; i++)		if(text[i])			hcheck(text[i]->tag);}voidcurrent(Flayer *nw){	Text *t;	if(which)		flborder(which, 0);	if(nw){		flushtyping(1);		flupfront(nw);		flborder(nw, 1);		buttons(Up);		t = (Text *)nw->user1;		t->front = nw-&t->l[0];		if(t != &cmd)			work = nw;	}	which = nw;}voidcloseup(Flayer *l){	Text *t=(Text *)l->user1;	int m;	m = whichmenu(t->tag);	if(m < 0)		return;	flclose(l);	if(l == which){		which = 0;		current(flwhich(Pt(0, 0)));	}	if(l == work)		work = 0;	if(--t->nwin == 0){		rclear(&t->rasp);		free((uchar *)t);		text[m] = 0;	}else if(l == &t->l[t->front]){		for(m=0; m<NL; m++)	/* find one; any one will do */			if(t->l[m].textfn){				t->front = m;				return;			}		panic("close");	}}Flayer *findl(Text *t){	int i;	for(i = 0; i<NL; i++)		if(t->l[i].textfn==0)			return &t->l[i];	return 0;}voidduplicate(Flayer *l, Rectangle r, Font *f, int close){	Text *t=(Text *)l->user1;	Flayer *nl = findl(t);	Rune *rp;	ulong n;	if(nl){		flnew(nl, gettext, l->user0, (char *)t);		flinit(nl, r, f, l->f.cols);		nl->origin = l->origin;		rp = (*l->textfn)(l, l->f.nchars, &n);		flinsert(nl, rp, rp+n, l->origin);		flsetselect(nl, l->p0, l->p1);		if(close){			flclose(l);			if(l==which)				which = 0;		}else			t->nwin++;		current(nl);		hcheck(t->tag);	}	setcursor(mousectl, cursor);}voidbuttons(int updown){	while(((mousep->buttons&7)!=0) != updown)		getmouse();}intgetr(Rectangle *rp){	Point p;	Rectangle r;	*rp = getrect(3, mousectl);	if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){		p = rp->min;		r = cmd.l[cmd.front].entire;		*rp = screen->r;		if(cmd.nwin==1){			if (p.y <= r.min.y)				rp->max.y = r.min.y;			else if (p.y >= r.max.y)				rp->min.y = r.max.y;			if (p.x <= r.min.x)				rp->max.x = r.min.x;			else if (p.x >= r.max.x)				rp->min.x = r.max.x;		}	}	return rectclip(rp, screen->r) &&	   rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;}voidsnarf(Text *t, int w){	Flayer *l = &t->l[w];	if(l->p1>l->p0){		snarflen = l->p1-l->p0;		outTsll(Tsnarf, t->tag, l->p0, l->p1);	}}voidcut(Text *t, int w, int save, int check){	long p0, p1;	Flayer *l;	l = &t->l[w];	p0 = l->p0;	p1 = l->p1;	if(p0 == p1)		return;	if(p0 < 0)		panic("cut");	if(save)		snarf(t, w);	outTsll(Tcut, t->tag, p0, p1);	flsetselect(l, p0, p0);	t->lock++;	hcut(t->tag, p0, p1-p0);	if(check)		hcheck(t->tag);}voidpaste(Text *t, int w){	if(snarflen){		cut(t, w, 0, 0);		t->lock++;		outTsl(Tpaste, t->tag, t->l[w].p0);	}}voidscrorigin(Flayer *l, int but, long p0){	Text *t=(Text *)l->user1;	switch(but){	case 1:		outTsll(Torigin, t->tag, l->origin, p0);		break;	case 2:		outTsll(Torigin, t->tag, p0, 1L);		break;	case 3:		horigin(t->tag,p0);	}}intalnum(int c){	/*	 * Hard to get absolutely right.  Use what we know about ASCII	 * and assume anything above the Latin control characters is	 * potentially an alphanumeric.	 */	if(c<=' ')		return 0;	if(0x7F<=c && c<=0xA0)		return 0;	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))		return 0;	return 1;}intraspc(Rasp *r, long p){	ulong n;	rload(r, p, p+1, &n);	if(n)		return scratch[0];	return 0;}longctlw(Rasp *r, long o, long p){	int c;	if(--p < o)		return o;	if(raspc(r, p)=='\n')		return p;	for(; p>=o && !alnum(c=raspc(r, p)); --p)		if(c=='\n')			return p+1;	for(; p>o && alnum(raspc(r, p-1)); --p)		;	return p>=o? p : o;}longctlu(Rasp *r, long o, long p){	if(--p < o)		return o;	if(raspc(r, p)=='\n')		return p;	for(; p-1>=o && raspc(r, p-1)!='\n'; --p)		;	return p>=o? p : o;}intcenter(Flayer *l, long a){	Text *t;	t = l->user1;	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){		if(a > t->rasp.nrunes)			a = t->rasp.nrunes;		outTsll(Torigin, t->tag, a, 2L);		return 1;	}	return 0;}intonethird(Flayer *l, long a){	Text *t;	Rectangle s;	long lines;	t = l->user1;	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){		if(a > t->rasp.nrunes)			a = t->rasp.nrunes;		s = insetrect(l->scroll, 1);		lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3;		if (lines < 2)			lines = 2;		outTsll(Torigin, t->tag, a, lines);		return 1;	}	return 0;}voidflushtyping(int clearesc){	Text *t;	ulong n;	if(clearesc)		typeesc = -1;		if(typestart == typeend) {		modified = 0;		return;	}	t = which->user1;	if(t != &cmd)		modified = 1;	rload(&t->rasp, typestart, typeend, &n);	scratch[n] = 0;	if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){		setlock();		outcmd();	}	outTslS(Ttype, t->tag, typestart, scratch);	typestart = -1;	typeend = -1;}#define	BACKSCROLLKEY	Kup#define	ENDKEY	Kend#define	ESC		0x1B#define	HOMEKEY	Khome#define	LEFTARROW	Kleft#define	LINEEND	0x05#define	LINESTART	0x01#define	PAGEDOWN	Kpgdown#define	PAGEUP	Kpgup#define	RIGHTARROW	Kright#define	SCROLLKEY	Kdownintnontypingkey(int c){	switch(c){	case BACKSCROLLKEY:	case ENDKEY:	case HOMEKEY:	case LEFTARROW:	case LINEEND:	case LINESTART:	case PAGEDOWN:	case PAGEUP:	case RIGHTARROW:	case SCROLLKEY:		return 1;	}	return 0;}voidtype(Flayer *l, int res)	/* what a bloody mess this is */{	Text *t = (Text *)l->user1;	Rune buf[100];	Rune *p = buf;	int c, backspacing;	long a, a0;	int scrollkey;	scrollkey = 0;	if(res == RKeyboard)		scrollkey = nontypingkey(qpeekc());	/* ICK */	if(hostlock || t->lock){		kbdblock();		return;	}	a = l->p0;	if(a!=l->p1 && !scrollkey){		flushtyping(1);		cut(t, t->front, 1, 1);		return;	/* it may now be locked */	}	backspacing = 0;	while((c = kbdchar())>0){		if(res == RKeyboard){			if(nontypingkey(c) || c==ESC)				break;			/* backspace, ctrl-u, ctrl-w, del */			if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){				backspacing = 1;				break;			}		}		*p++ = c;		if(autoindent)		if(c == '\n'){			/* autoindent */			int cursor, ch;			cursor = ctlu(&t->rasp, 0, a+(p-buf)-1);			while(p < buf+nelem(buf)){				ch = raspc(&t->rasp, cursor++);				if(ch == ' ' || ch == '\t')					*p++ = ch;				else					break;			}		}		if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))			break;	}	if(p > buf){		if(typestart < 0)			typestart = a;		if(typeesc < 0)			typeesc = a;		hgrow(t->tag, a, p-buf, 0);		t->lock++;	/* pretend we Trequest'ed for hdatarune*/		hdatarune(t->tag, a, buf, p-buf);		a += p-buf;		l->p0 = a;		l->p1 = a;		typeend = a;		if(c=='\n' || typeend-typestart>100)			flushtyping(0);		onethird(l, a);	}	if(c==SCROLLKEY || c==PAGEDOWN){		flushtyping(0);		center(l, l->origin+l->f.nchars+1);		/* backspacing immediately after outcmd(): sorry */	}else if(c==BACKSCROLLKEY || c==PAGEUP){		flushtyping(0);		a0 = l->origin-l->f.nchars;		if(a0 < 0)			a0 = 0;		center(l, a0);	}else if(c == RIGHTARROW){		flushtyping(0);		a0 = l->p0;		if(a0 < t->rasp.nrunes)			a0++;		flsetselect(l, a0, a0);		center(l, a0);	}else if(c == LEFTARROW){		flushtyping(0);		a0 = l->p0;		if(a0 > 0)			a0--;		flsetselect(l, a0, a0);		center(l, a0);	}else if(c == HOMEKEY){		flushtyping(0);		center(l, 0);	}else if(c == ENDKEY){		flushtyping(0);		center(l, t->rasp.nrunes);	}else if(c == LINESTART || c == LINEEND){		flushtyping(1);		if(c == LINESTART)			while(a > 0 && raspc(&t->rasp, a-1)!='\n')				a--;		else			while(a < t->rasp.nrunes && raspc(&t->rasp, a)!='\n')				a++;		l->p0 = l->p1 = a;		for(l=t->l; l<&t->l[NL]; l++)			if(l->textfn)				flsetselect(l, l->p0, l->p1);	}else if(backspacing && !hostlock){		/* backspacing immediately after outcmd(): sorry */		if(l->f.p0>0 && a>0){			switch(c){			case '\b':			case 0x7F:	/* del */				l->p0 = a-1;				break;			case 0x15:	/* ctrl-u */				l->p0 = ctlu(&t->rasp, l->origin, a);				break;			case 0x17:	/* ctrl-w */				l->p0 = ctlw(&t->rasp, l->origin, a);				break;			}			l->p1 = a;			if(l->p1 != l->p0){				/* cut locally if possible */				if(typestart<=l->p0 && l->p1<=typeend){					t->lock++;	/* to call hcut */					hcut(t->tag, l->p0, l->p1-l->p0);					/* hcheck is local because we know rasp is contiguous */					hcheck(t->tag);				}else{					flushtyping(0);					cut(t, t->front, 0, 1);				}			}			if(typeesc >= l->p0)				typeesc = l->p0;			if(typestart >= 0){				if(typestart >= l->p0)					typestart = l->p0;				typeend = l->p0;				if(typestart == typeend){					typestart = -1;					typeend = -1;					modified = 0;				}			}		}	}else{		if(c==ESC && typeesc>=0){			l->p0 = typeesc;			l->p1 = a;			flushtyping(1);		}		for(l=t->l; l<&t->l[NL]; l++)			if(l->textfn)				flsetselect(l, l->p0, l->p1);	}}voidoutcmd(void){	if(work)		outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);}voidpanic(char *s){	panic1(display, s);}voidpanic1(Display*, char *s){	fprint(2, "samterm:panic: ");	perror(s);	abort();}Rune*gettext(Flayer *l, long n, ulong *np){	Text *t;	t = l->user1;	rload(&t->rasp, l->origin, l->origin+n, np);	return scratch;}longscrtotal(Flayer *l){	return ((Text *)l->user1)->rasp.nrunes;}void*alloc(ulong n){	void *p;	p = malloc(n);	if(p == 0)		panic("alloc");	memset(p, 0, n);	return p;}

⌨️ 快捷键说明

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