📄 control.c
字号:
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 + -