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

📄 control.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(cp->args[0][i] == ':'){		cp->sender = cp->args[0];		cp->sender[i] = '\0';		cp->args++;		cp->nargs--;	}	if(hasreceiver){		if(cp->nargs-- == 0)			return -1;		cp->receiver = *cp->args++;	}else		cp->receiver = nil;	for(i=0; i<cp->nargs; i++){		t = cp->args[i];		while(*t == '[')	/* %R gives [0 0] [1 1]; atoi will stop at closing ] */			t++;		cp->iargs[i] = atoi(t);	}	return cp->nargs;}void_ctlargcount(Control *c, CParse *cp, int n){	if(cp->nargs != n)		ctlerror("%q: wrong argument count in '%s'", c->name, cp->str);}static void_ctlcmd(Controlset *cs, char*s){	CParse cp;	char	*rcvrs[32];	int	ircvrs[32], n, i, hit;	Control *c;//	fprint(2, "_ctlcmd: %s\n", s);	cp.args = cp.pargs;	if (ctlparse(&cp, s, 1) < 0)		ctlerror("bad command string: %q", cp.str);	if (cp.nargs == 0 && strcmp(cp.receiver, "sync") == 0){		chanprint(cs->data, "sync");		return;	}	if (cp.nargs == 0)		ctlerror("no command in command string: %q", cp.str);	n = tokenize(cp.receiver, rcvrs, nelem(rcvrs));	// lookup type names: a receiver can be a named type or a named control	for (i = 0; i < n; i++)		ircvrs[i] = _ctllookup(rcvrs[i], ctltypenames, Ntypes);	for(c = cs->controls; c != nil; c = c->next){		/* if a control matches on more than one receiver element,		 * make sure it gets processed once; hence loop through controls		 * in the outer loop		 */		hit = 0;		for (i = 0; i < n; i++)			if(strcmp(c->name, rcvrs[i]) == 0 || c->type == ircvrs[i])				hit++;		if (hit && c->ctl)			c->ctl(c, &cp);	}}static void_ctlcontrol(Controlset *cs, char *s){	char *lines[16];	int i, n;	char *l;//	fprint(2, "_ctlcontrol: %s\n", s);	n = gettokens(s, lines, nelem(lines), "\n");	for(i=0; i<n; i++){		l = lines[i];		while(*l==' ' || *l=='\t')			l++;		if(*l != '\0')			_ctlcmd(cs, l);	}}Rune*_ctlgetsnarf(void){	int i, n;	char *sn, buf[512];	Rune *snarf;	if(_ctlsnarffd < 0)		return nil;	sn = nil;	i = 0;	seek(_ctlsnarffd, 0, 0);	while((n = read(_ctlsnarffd, buf, sizeof buf)) > 0){		sn = ctlrealloc(sn, i+n+1);		memmove(sn+i, buf, n);		i += n;		sn[i] = 0;	}	snarf = nil;	if(i > 0){		snarf = _ctlrunestr(sn);		free(sn);	}	return snarf;}void_ctlputsnarf(Rune *snarf){	int fd, i, n, nsnarf;	if(_ctlsnarffd<0 || snarf[0]==0)		return;	fd = open("/dev/snarf", OWRITE);	if(fd < 0)		return;	nsnarf = runestrlen(snarf);	/* snarf buffer could be huge, so fprint will truncate; do it in blocks */	for(i=0; i<nsnarf; i+=n){		n = nsnarf-i;		if(n >= 256)			n = 256;		if(fprint(fd, "%.*S", n, snarf+i) < 0)			break;	}	close(fd);}int_ctlalignment(char *s){	int i;	i = _ctllookup(s, alignnames, Nalignments);	if (i < 0)		ctlerror("unknown alignment: %s", s);	return i;}Point_ctlalignpoint(Rectangle r, int dx, int dy, int align){	Point p;	p = r.min;	/* in case of trouble */	switch(align%3){	case 0:	/* left */		p.x = r.min.x;		break;	case 1:	/* center */		p.x = r.min.x+(Dx(r)-dx)/2;		break;	case 2:	/* right */		p.x = r.max.x-dx;		break;	}	switch((align/3)%3){	case 0:	/* top */		p.y = r.min.y;		break;	case 1:	/* center */		p.y = r.min.y+(Dy(r)-dy)/2;		break;	case 2:	/* bottom */		p.y = r.max.y - dy;		break;	}	return p;}voidcontrolwire(Control *cfrom, char *name, Channel *chan){	Channel **p;	p = nil;	if(strcmp(name, "event") == 0){		p = &cfrom->event;		cfrom->wevent = 1;	}else if(strcmp(name, "data") == 0){		p = &cfrom->data;		cfrom->wdata = 1;	}else		ctlerror("%q: unknown controlwire channel %s", cfrom->name, name);	chanfree(*p);	*p = chan;}void_ctlfocus(Control *me, int set){	Controlset *cs;	cs = me->controlset;	if(set){		if(cs->focus == me)			return;		if(cs->focus != nil)			_ctlprint(cs->focus, "focus 0");		cs->focus = me;	}else{		if(cs->focus != me)			return;		cs->focus = nil;	}}static voidresizethread(void *v){	Controlset *cs;	char buf[64];	Alt alts[3];	cs = v;	snprint(buf, sizeof buf, "resizethread0x%p", cs);	threadsetname(buf);	alts[0].c = cs->resizec;	alts[0].v = nil;	alts[0].op = CHANRCV;	alts[1].c = cs->resizeexitc;	alts[1].v = nil;	alts[1].op = CHANRCV;	alts[2].op = CHANEND;	for(;;){		switch(alt(alts)){		case 0:			resizecontrolset(cs);			break;		case 1:			return;		}	}}voidactivate(Control *a){	Control *c;	for(c=a->controlset->actives; c; c=c->nextactive)		if(c == a)			ctlerror("%q already active\n", a->name);		if (a->activate){		a->activate(a, 1);		return;	}	/* prepend */	a->nextactive = a->controlset->actives;	a->controlset->actives = a;}voiddeactivate(Control *a){	Control *c, *prev;	/* if group, first deactivate kids, then self */	if (a->activate){		a->activate(a, 0);		return;	}	prev = nil;	for(c=a->controlset->actives; c; c=c->nextactive){		if(c == a){			if(a->controlset->focus == a)				a->controlset->focus = nil;			if(prev != nil)				prev->nextactive = a->nextactive;			else				a->controlset->actives = a->nextactive;			return;		}		prev = c;	}	ctlerror("%q not active\n", a->name);}static struct{	char	*name;	ulong	color;}coltab[] = {	"red",			DRed,	"green",			DGreen,	"blue",			DBlue,	"cyan",			DCyan,	"magenta",		DMagenta,	"yellow",			DYellow,	"paleyellow",		DPaleyellow,	"darkyellow",		DDarkyellow,	"darkgreen",		DDarkgreen,	"palegreen",		DPalegreen,	"medgreen",		DMedgreen,	"darkblue",		DDarkblue,	"palebluegreen",	DPalebluegreen,	"paleblue",		DPaleblue,	"bluegreen",		DBluegreen,	"greygreen",		DGreygreen,	"palegreygreen",	DPalegreygreen,	"yellowgreen",		DYellowgreen,	"medblue",		DMedblue,	"greyblue",		DGreyblue,	"palegreyblue",		DPalegreyblue,	"purpleblue",		DPurpleblue,	nil,	0};voidinitcontrols(void){	int i;	Image *im;	quotefmtinstall();	namectlimage(display->opaque, "opaque");	namectlimage(display->transparent, "transparent");	namectlimage(display->white, "white");	namectlimage(display->black, "black");	for(i=0; coltab[i].name!=nil; i++){		im = allocimage(display, Rect(0,0,1,1), RGB24, 1, coltab[i].color);		namectlimage(im, coltab[i].name);	}	namectlfont(font, "font");	_ctlsnarffd = open("/dev/snarf", OREAD);}Controlset*newcontrolset(Image *im, Channel *kbdc, Channel *mousec, Channel *resizec){	Controlset *cs;	if(im == nil)		im = screen;	if((mousec==nil && resizec!=nil) || (mousec!=nil && resizec==nil))		ctlerror("must specify either or both of mouse and resize channels");	cs = ctlmalloc(sizeof(Controlset));	cs->screen = im;	if(kbdc == nil){		cs->keyboardctl = initkeyboard(nil);		if(cs->keyboardctl == nil)			ctlerror("can't initialize keyboard: %r");		kbdc = cs->keyboardctl->c;	}	cs ->kbdc = kbdc;	if(mousec == nil){		cs->mousectl = initmouse(nil, im);		if(cs->mousectl == nil)			ctlerror("can't initialize mouse: %r");		mousec = cs->mousectl->c;		resizec = cs->mousectl->resizec;	}	cs->mousec = mousec;	cs->resizec = resizec;	cs->ctl = chancreate(sizeof(char*), 64);	/* buffer to prevent deadlock */	cs->data = chancreate(sizeof(char*), 0);	cs->resizeexitc = chancreate(sizeof(int), 0);	cs->csexitc = chancreate(sizeof(int), 0);	threadcreate(resizethread, cs, 32*1024);	threadcreate(controlsetthread, cs, 32*1024);	controlset = ctlrealloc(controlset, (ncontrolset+1)*sizeof(Controlset*));	controlset[ncontrolset++] = cs;	return cs;}voidclosecontrolset(Controlset *cs){	int i;	sendul(cs->resizeexitc, 0);	chanfree(cs->resizeexitc);	sendul(cs->csexitc, 0);	chanfree(cs->csexitc);	chanfree(cs->ctl);	chanfree(cs->data);	for(i=0; i<ncontrolset; i++)		if(cs == controlset[i]){			memmove(controlset+i, controlset+i+1, (ncontrolset-(i+1))*sizeof(Controlset*));			ncontrolset--;			goto Found;		}	if(i == ncontrolset)		ctlerror("closecontrolset: control set not found");    Found:	while(cs->controls != nil)		closecontrol(cs->controls);}

⌨️ 快捷键说明

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