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

📄 acme.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			 */			m = mousectl->Mouse;			qlock(&row);			t = rowwhich(&row, m.xy);			if(t!=mousetext && mousetext!=nil && mousetext->w!=nil){				winlock(mousetext->w, 'M');				mousetext->eq0 = ~0;				wincommit(mousetext->w, mousetext);				winunlock(mousetext->w);			}			mousetext = t;			if(t == nil)				goto Continue;			w = t->w;			if(t==nil || m.buttons==0)				goto Continue;			but = 0;			if(m.buttons == 1)				but = 1;			else if(m.buttons == 2)				but = 2;			else if(m.buttons == 4)				but = 3;			barttext = t;			if(t->what==Body && ptinrect(m.xy, t->scrollr)){				if(but){					winlock(w, 'M');					t->eq0 = ~0;					textscroll(t, but);					winunlock(w);				}				goto Continue;			}			/* scroll buttons, wheels, etc. */			if(t->what==Body && w != nil && (m.buttons & (8|16))){				if(m.buttons & 8)					but = Kscrolloneup;				else					but = Kscrollonedown;				winlock(w, 'M');				t->eq0 = ~0;				texttype(t, but);				winunlock(w);				goto Continue;			}			if(ptinrect(m.xy, t->scrollr)){				if(but){					if(t->what == Columntag)						rowdragcol(&row, t->col, but);					else if(t->what == Tag){						coldragwin(t->col, t->w, but);						if(t->w)							barttext = &t->w->body;					}					if(t->col)						activecol = t->col;				}				goto Continue;			}			if(m.buttons){				if(w)					winlock(w, 'M');				t->eq0 = ~0;				if(w)					wincommit(w, t);				else					textcommit(t, TRUE);				if(m.buttons & 1){					textselect(t);					if(w)						winsettag(w);					argtext = t;					seltext = t;					if(t->col)						activecol = t->col;	/* button 1 only */					if(t->w!=nil && t==&t->w->body)						activewin = t->w;				}else if(m.buttons & 2){					if(textselect2(t, &q0, &q1, &argt))						execute(t, q0, q1, FALSE, argt);				}else if(m.buttons & 4){					if(textselect3(t, &q0, &q1))						look3(t, q0, q1, FALSE);				}				if(w)					winunlock(w);				goto Continue;			}    Continue:			qunlock(&row);			break;		}	}}/* * There is a race between process exiting and our finding out it was ever created. * This structure keeps a list of processes that have exited we haven't heard of. */typedef struct Pid Pid;struct Pid{	int	pid;	char	msg[ERRMAX];	Pid	*next;};voidwaitthread(void *){	Waitmsg *w;	Command *c, *lc;	uint pid;	int found, ncmd;	Rune *cmd;	char *err;	Text *t;	Pid *pids, *p, *lastp;	enum { WErr, WKill, WWait, WCmd, NWALT };	Alt alts[NWALT+1];	threadsetname("waitthread");	pids = nil;	alts[WErr].c = cerr;	alts[WErr].v = &err;	alts[WErr].op = CHANRCV;	alts[WKill].c = ckill;	alts[WKill].v = &cmd;	alts[WKill].op = CHANRCV;	alts[WWait].c = cwait;	alts[WWait].v = &w;	alts[WWait].op = CHANRCV;	alts[WCmd].c = ccommand;	alts[WCmd].v = &c;	alts[WCmd].op = CHANRCV;	alts[NWALT].op = CHANEND;	command = nil;	for(;;){		switch(alt(alts)){		case WErr:			qlock(&row);			warning(nil, "%s", err);			free(err);			flushimage(display, 1);			qunlock(&row);			break;		case WKill:			found = FALSE;			ncmd = runestrlen(cmd);			for(c=command; c; c=c->next){				/* -1 for blank */				if(runeeq(c->name, c->nname-1, cmd, ncmd) == TRUE){					if(postnote(PNGROUP, c->pid, "kill") < 0)						warning(nil, "kill %S: %r\n", cmd);					found = TRUE;				}			}			if(!found)				warning(nil, "Kill: no process %S\n", cmd);			free(cmd);			break;		case WWait:			pid = w->pid;			lc = nil;			for(c=command; c; c=c->next){				if(c->pid == pid){					if(lc)						lc->next = c->next;					else						command = c->next;					break;				}				lc = c;			}			qlock(&row);			t = &row.tag;			textcommit(t, TRUE);			if(c == nil){				/* helper processes use this exit status */				if(strncmp(w->msg, "libthread", 9) != 0){					p = emalloc(sizeof(Pid));					p->pid = pid;					strncpy(p->msg, w->msg, sizeof(p->msg));					p->next = pids;					pids = p;				}			}else{				if(search(t, c->name, c->nname)){					textdelete(t, t->q0, t->q1, TRUE);					textsetselect(t, 0, 0);				}				if(w->msg[0])					warning(c->md, "%s\n", w->msg);				flushimage(display, 1);			}			qunlock(&row);			free(w);    Freecmd:			if(c){				if(c->iseditcmd)					sendul(cedit, 0);				free(c->text);				free(c->name);				fsysdelid(c->md);				free(c);			}			break;		case WCmd:			/* has this command already exited? */			lastp = nil;			for(p=pids; p!=nil; p=p->next){				if(p->pid == c->pid){					if(p->msg[0])						warning(c->md, "%s\n", p->msg);					if(lastp == nil)						pids = p->next;					else						lastp->next = p->next;					free(p);					goto Freecmd;				}				lastp = p;			}			c->next = command;			command = c;			qlock(&row);			t = &row.tag;			textcommit(t, TRUE);			textinsert(t, 0, c->name, c->nname, TRUE);			textsetselect(t, 0, 0);			flushimage(display, 1);			qunlock(&row);			break;		}	}}voidxfidallocthread(void*){	Xfid *xfree, *x;	enum { Alloc, Free, N };	static Alt alts[N+1];	threadsetname("xfidallocthread");	alts[Alloc].c = cxfidalloc;	alts[Alloc].v = nil;	alts[Alloc].op = CHANRCV;	alts[Free].c = cxfidfree;	alts[Free].v = &x;	alts[Free].op = CHANRCV;	alts[N].op = CHANEND;	xfree = nil;	for(;;){		switch(alt(alts)){		case Alloc:			x = xfree;			if(x)				xfree = x->next;			else{				x = emalloc(sizeof(Xfid));				x->c = chancreate(sizeof(void(*)(Xfid*)), 0);				x->arg = x;				threadcreate(xfidctl, x->arg, STACK);			}			sendp(cxfidalloc, x);			break;		case Free:			x->next = xfree;			xfree = x;			break;		}	}}/* this thread, in the main proc, allows fsysproc to get a window made without doing graphics */voidnewwindowthread(void*){	Window *w;	threadsetname("newwindowthread");	for(;;){		/* only fsysproc is talking to us, so synchronization is trivial */		recvp(cnewwindow);		w = makenewwindow(nil);		winsettag(w);		sendp(cnewwindow, w);	}}Reffont*rfget(int fix, int save, int setfont, char *name){	Reffont *r;	Font *f;	int i;	r = nil;	if(name == nil){		name = fontnames[fix];		r = reffonts[fix];	}	if(r == nil){		for(i=0; i<nfontcache; i++)			if(strcmp(name, fontcache[i]->f->name) == 0){				r = fontcache[i];				goto Found;			}		f = openfont(display, name);		if(f == nil){			warning(nil, "can't open font file %s: %r\n", name);			return nil;		}		r = emalloc(sizeof(Reffont));		r->f = f;		fontcache = erealloc(fontcache, (nfontcache+1)*sizeof(Reffont*));		fontcache[nfontcache++] = r;	}    Found:	if(save){		incref(r);		if(reffonts[fix])			rfclose(reffonts[fix]);		reffonts[fix] = r;		if(name != fontnames[fix]){			free(fontnames[fix]);			fontnames[fix] = estrdup(name);		}	}	if(setfont){		reffont.f = r->f;		incref(r);		rfclose(reffonts[0]);		font = r->f;		reffonts[0] = r;		incref(r);		iconinit();	}	incref(r);	return r;}voidrfclose(Reffont *r){	int i;	if(decref(r) == 0){		for(i=0; i<nfontcache; i++)			if(r == fontcache[i])				break;		if(i >= nfontcache)			warning(nil, "internal error: can't find font in cache\n");		else{			nfontcache--;			memmove(fontcache+i, fontcache+i+1, (nfontcache-i)*sizeof(Reffont*));		}		freefont(r->f);		free(r);	}}Cursor boxcursor = {	{-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}};voidiconinit(void){	Rectangle r;	Image *tmp;	/* Blue */	tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);	tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);	tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);	tagcols[TEXT] = display->black;	tagcols[HTEXT] = display->black;	/* Yellow */	textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);	textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);	textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);	textcols[TEXT] = display->black;	textcols[HTEXT] = display->black;	if(button){		freeimage(button);		freeimage(modbutton);		freeimage(colbutton);	}	r = Rect(0, 0, Scrollwid+2, font->height+1);	button = allocimage(display, r, screen->chan, 0, DNofill);	draw(button, r, tagcols[BACK], nil, r.min);	r.max.x -= 2;	border(button, r, 2, tagcols[BORD], ZP);	r = button->r;	modbutton = allocimage(display, r, screen->chan, 0, DNofill);	draw(modbutton, r, tagcols[BACK], nil, r.min);	r.max.x -= 2;	border(modbutton, r, 2, tagcols[BORD], ZP);	r = insetrect(r, 2);	tmp = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedblue);	draw(modbutton, r, tmp, nil, ZP);	freeimage(tmp);	r = button->r;	colbutton = allocimage(display, r, screen->chan, 0, DPurpleblue);	but2col = allocimage(display, r, screen->chan, 1, 0xAA0000FF);	but3col = allocimage(display, r, screen->chan, 1, 0x006600FF);}/* * /dev/snarf updates when the file is closed, so we must open our own * fd here rather than use snarffd *//* rio truncates larges snarf buffers, so this avoids using the * service if the string is huge */#define MAXSNARF 100*1024voidputsnarf(void){	int fd, i, n;	if(snarffd<0 || snarfbuf.nc==0)		return;	if(snarfbuf.nc > MAXSNARF)		return;	fd = open("/dev/snarf", OWRITE);	if(fd < 0)		return;	for(i=0; i<snarfbuf.nc; i+=n){		n = snarfbuf.nc-i;		if(n >= NSnarf)			n = NSnarf;		bufread(&snarfbuf, i, snarfrune, n);		if(fprint(fd, "%.*S", n, snarfrune) < 0)			break;	}	close(fd);}voidgetsnarf(){	int nulls;	if(snarfbuf.nc > MAXSNARF)		return;	if(snarffd < 0)		return;	seek(snarffd, 0, 0);	bufreset(&snarfbuf);	bufload(&snarfbuf, 0, snarffd, &nulls);}

⌨️ 快捷键说明

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