📄 xfid.c
字号:
qunlock(&x->active); return; case Qconsctl: if(strncmp(x->data, "holdon", 6)==0){ if(w->holding++ == 0) wsendctlmesg(w, Holdon, ZR, nil); break; } if(strncmp(x->data, "holdoff", 7)==0 && w->holding){ if(--w->holding == FALSE) wsendctlmesg(w, Holdoff, ZR, nil); break; } if(strncmp(x->data, "rawon", 5)==0){ if(w->holding){ w->holding = FALSE; wsendctlmesg(w, Holdoff, ZR, nil); } if(w->rawing++ == 0) wsendctlmesg(w, Rawon, ZR, nil); break; } if(strncmp(x->data, "rawoff", 6)==0 && w->rawing){ if(--w->rawing == 0) wsendctlmesg(w, Rawoff, ZR, nil); break; } filsysrespond(x->fs, x, &fc, "unknown control message"); return; case Qcursor: if(cnt < 2*4+2*2*16) w->cursorp = nil; else{ w->cursor.offset.x = BGLONG(x->data+0*4); w->cursor.offset.y = BGLONG(x->data+1*4); memmove(w->cursor.clr, x->data+2*4, 2*2*16); w->cursorp = &w->cursor; } wsetcursor(w, !sweeping); break; case Qlabel: if(off != 0){ filsysrespond(x->fs, x, &fc, "non-zero offset writing label"); return; } free(w->label); w->label = emalloc(cnt+1); memmove(w->label, x->data, cnt); w->label[cnt] = 0; break; case Qmouse: if(w!=input || Dx(w->screenr)<=0) break; if(x->data[0] != 'm'){ filsysrespond(x->fs, x, &fc, Ebadmouse); return; } p = nil; pt.x = strtoul(x->data+1, &p, 0); if(p == nil){ filsysrespond(x->fs, x, &fc, Eshort); return; } pt.y = strtoul(p, nil, 0); if(w==input && wpointto(mouse->xy)==w) wsendctlmesg(w, Movemouse, Rpt(pt, pt), nil); break; case Qsnarf: /* always append only */ if(ntsnarf > MAXSNARF){ /* avoid thrashing when people cut huge text */ filsysrespond(x->fs, x, &fc, Elong); return; } tsnarf = erealloc(tsnarf, ntsnarf+cnt+1); /* room for NUL */ memmove(tsnarf+ntsnarf, x->data, cnt); ntsnarf += cnt; snarfversion++; break; case Qwdir: if(cnt == 0) break; if(x->data[cnt-1] == '\n'){ if(cnt == 1) break; x->data[cnt-1] = '\0'; } /* assume data comes in a single write */ /* * Problem: programs like dossrv, ftp produce illegal UTF; * we must cope by converting it first. */ snprint(buf, sizeof buf, "%.*s", cnt, x->data); if(buf[0] == '/'){ free(w->dir); w->dir = estrdup(buf); }else{ p = emalloc(strlen(w->dir) + 1 + strlen(buf) + 1); sprint(p, "%s/%s", w->dir, buf); free(w->dir); w->dir = cleanname(p); } break; case Qkbdin: keyboardsend(x->data, cnt); break; case Qwctl: if(writewctl(x, buf) < 0){ filsysrespond(x->fs, x, &fc, buf); return; } flushimage(display, 1); break; default: fprint(2, buf, "unknown qid %d in write\n", qid); sprint(buf, "unknown qid in write"); filsysrespond(x->fs, x, &fc, buf); return; } fc.count = cnt; filsysrespond(x->fs, x, &fc, nil);}intreadwindow(Image *i, char *t, Rectangle r, int offset, int n){ int ww, y; offset -= 5*12; ww = bytesperline(r, screen->depth); r.min.y += offset/ww; if(r.min.y >= r.max.y) return 0; y = r.min.y + n/ww; if(y < r.max.y) r.max.y = y; if(r.max.y <= r.min.y) return 0; return unloadimage(i, r, (uchar*)t, n);}voidxfidread(Xfid *x){ Fcall fc; int n, off, cnt, c; uint qid; char buf[128], *t; char cbuf[30]; Window *w; Mouse ms; Rectangle r; Image *i; Channel *c1, *c2; /* chan (tuple(char*, int)) */ Consreadmesg crm; Mousereadmesg mrm; Consreadmesg cwrm; Stringpair pair; enum { CRdata, CRflush, NCR }; enum { MRdata, MRflush, NMR }; enum { WCRdata, WCRflush, NWCR }; Alt alts[NCR+1]; w = x->f->w; if(w->deleted){ filsysrespond(x->fs, x, &fc, Edeleted); return; } qid = FILE(x->f->qid); off = x->offset; cnt = x->count; switch(qid){ case Qcons: x->flushtag = x->tag; alts[CRdata].c = w->consread; alts[CRdata].v = &crm; alts[CRdata].op = CHANRCV; alts[CRflush].c = x->flushc; alts[CRflush].v = nil; alts[CRflush].op = CHANRCV; alts[NMR].op = CHANEND; switch(alt(alts)){ case CRdata: break; case CRflush: filsyscancel(x); return; } /* received data */ x->flushtag = -1; c1 = crm.c1; c2 = crm.c2; t = malloc(cnt+UTFmax+1); /* room to unpack partial rune plus */ pair.s = t; pair.ns = cnt; send(c1, &pair); if(x->flushing){ recv(x->flushc, nil); /* wake up flushing xfid */ recv(c2, nil); /* wake up window and toss data */ free(t); filsyscancel(x); return; } qlock(&x->active); recv(c2, &pair); fc.data = pair.s; fc.count = pair.ns; filsysrespond(x->fs, x, &fc, nil); free(t); qunlock(&x->active); break; case Qlabel: n = strlen(w->label); if(off > n) off = n; if(off+cnt > n) cnt = n-off; fc.data = w->label+off; fc.count = cnt; filsysrespond(x->fs, x, &fc, nil); break; case Qmouse: x->flushtag = x->tag; alts[MRdata].c = w->mouseread; alts[MRdata].v = &mrm; alts[MRdata].op = CHANRCV; alts[MRflush].c = x->flushc; alts[MRflush].v = nil; alts[MRflush].op = CHANRCV; alts[NMR].op = CHANEND; switch(alt(alts)){ case MRdata: break; case MRflush: filsyscancel(x); return; } /* received data */ x->flushtag = -1; if(x->flushing){ recv(x->flushc, nil); /* wake up flushing xfid */ recv(mrm.cm, nil); /* wake up window and toss data */ filsyscancel(x); return; } qlock(&x->active); recv(mrm.cm, &ms); c = 'm'; if(w->resized) c = 'r'; n = sprint(buf, "%c%11d %11d %11d %11ld ", c, ms.xy.x, ms.xy.y, ms.buttons, ms.msec); w->resized = 0; fc.data = buf; fc.count = min(n, cnt); filsysrespond(x->fs, x, &fc, nil); qunlock(&x->active); break; case Qcursor: filsysrespond(x->fs, x, &fc, "cursor read not implemented"); break; /* The algorithm for snarf and text is expensive but easy and rarely used */ case Qsnarf: getsnarf(); if(nsnarf) t = runetobyte(snarf, nsnarf, &n); else { t = nil; n = 0; } goto Text; case Qtext: t = wcontents(w, &n); goto Text; Text: if(off > n){ off = n; cnt = 0; } if(off+cnt > n) cnt = n-off; fc.data = t+off; fc.count = cnt; filsysrespond(x->fs, x, &fc, nil); free(t); break; case Qwdir: t = estrdup(w->dir); n = strlen(t); goto Text; case Qwinid: n = sprint(buf, "%11d ", w->id); t = estrdup(buf); goto Text; case Qwinname: n = strlen(w->name); if(n == 0){ filsysrespond(x->fs, x, &fc, "window has no name"); break; } t = estrdup(w->name); goto Text; case Qwindow: i = w->i; if(i == nil || Dx(w->screenr)<=0){ filsysrespond(x->fs, x, &fc, Enowindow); return; } r = w->screenr; goto caseImage; case Qscreen: i = display->image; if(i == nil){ filsysrespond(x->fs, x, &fc, "no top-level screen"); break; } r = i->r; /* fall through */ caseImage: if(off < 5*12){ n = sprint(buf, "%11s %11d %11d %11d %11d ", chantostr(cbuf, screen->chan), i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y); t = estrdup(buf); goto Text; } t = malloc(cnt); fc.data = t; n = readwindow(i, t, r, off, cnt); /* careful; fc.count is unsigned */ if(n < 0){ buf[0] = 0; errstr(buf, sizeof buf); filsysrespond(x->fs, x, &fc, buf); }else{ fc.count = n; filsysrespond(x->fs, x, &fc, nil); } free(t); return; case Qwctl: /* read returns rectangle, hangs if not resized */ if(cnt < 4*12){ filsysrespond(x->fs, x, &fc, Etooshort); break; } x->flushtag = x->tag; alts[WCRdata].c = w->wctlread; alts[WCRdata].v = &cwrm; alts[WCRdata].op = CHANRCV; alts[WCRflush].c = x->flushc; alts[WCRflush].v = nil; alts[WCRflush].op = CHANRCV; alts[NMR].op = CHANEND; switch(alt(alts)){ case WCRdata: break; case WCRflush: filsyscancel(x); return; } /* received data */ x->flushtag = -1; c1 = cwrm.c1; c2 = cwrm.c2; t = malloc(cnt+1); /* be sure to have room for NUL */ pair.s = t; pair.ns = cnt+1; send(c1, &pair); if(x->flushing){ recv(x->flushc, nil); /* wake up flushing xfid */ recv(c2, nil); /* wake up window and toss data */ free(t); filsyscancel(x); return; } qlock(&x->active); recv(c2, &pair); fc.data = pair.s; if(pair.ns > cnt) pair.ns = cnt; fc.count = pair.ns; filsysrespond(x->fs, x, &fc, nil); free(t); qunlock(&x->active); break; default: fprint(2, "unknown qid %d in read\n", qid); sprint(buf, "unknown qid in read"); filsysrespond(x->fs, x, &fc, buf); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -