ref: 8e41616af560b69d176f9b3d4a5380e3220e8915
parent: ee60859199f151377a32b6932bde88cc6fe6007a
author: aap <aap@papnet.eu>
date: Sun Jan 29 19:52:03 EST 2023
cleanup; wctl
--- a/TODO
+++ b/TODO
@@ -1,9 +1,10 @@
rethink resizing and repainting
-implement all Qids
- wctl
+rethink hiding/unhiding
+file permissions
+attach names (none, new, ...)
border resize/move
write text
-wctl
+top/bottom/current seems to work a bit different in rio
release keys and buttons when unfocused
...
--- a/fs.c
+++ b/fs.c
@@ -16,8 +16,8 @@
Qsnarf,
Qtext,
Qwdir,
-// Qwctl,
Qwindow,
+ Qwctl,
Qtap,
NQids
@@ -47,6 +47,7 @@
Qcursor, QTFILE, "cursor",
Qscreen, QTFILE, "screen",
Qwindow, QTFILE, "window",
+ Qwctl, QTFILE, "wctl",
Qtap, QTFILE, "kbdtap",
};
@@ -169,9 +170,9 @@
w = nil;
if(strcmp(r->ifcall.aname, "new") == 0){
- w = wcreate(rectaddpt(newrect(), screen->r.min));
-wsetpid(w, -1, 1);
-wsetname(w);
+// TODO: parse
+ w = wcreate(rectaddpt(newrect(), screen->r.min), FALSE, scrolling);
+ wincmd(w, 0, nil, nil);
flushimage(display, 1);
decref(w); /* don't delete, xfid will take it */
}else if(id = strtol(r->ifcall.aname, &end, 10), *end == '\0'){
@@ -329,9 +330,12 @@
return;
}
+ /* only text can be truncated (not implemented yet) */
+ if(QFILE(r->fid->qid.path) != Qtext)
+ r->ifcall.mode &= (OREAD|OWRITE|ORDWR);
+
switch(QFILE(r->fid->qid.path)){
case Qsnarf:
- r->ifcall.mode &= ~OTRUNC;
if(r->ifcall.mode==ORDWR || r->ifcall.mode==OWRITE)
ntsnarf = 0;
break;
@@ -362,8 +366,20 @@
w->mouseopen = TRUE;
break;
+ case Qwctl:
+ if(r->ifcall.mode==ORDWR || r->ifcall.mode==OREAD){
+ /* can only have one reader of wctl */
+ if(w->wctlopen){
+ respond(r, Einuse);
+ return;
+ }
+ w->wctlopen = TRUE;
+ w->wctlready = TRUE;
+ wsendmsg(w, Wakeup);
+ }
+ break;
+
case Qtap:
- r->ifcall.mode &= (OREAD|OWRITE|ORDWR);
chanprint(ctltap, "%c%c", Tapon, r->ifcall.mode);
respond(r, recvp(resptap));
return;
@@ -397,11 +413,11 @@
case Qconsctl:
if(x->rawmode){
x->rawmode = 0;
- wsendmsg(w, Rawoff, ZR, nil);
+ wsendmsg(w, Rawoff);
}
if(w->holdmode > 0){
w->holdmode = 1;
- wsendmsg(w, Holdoff, ZR, nil);
+ wsendmsg(w, Holdoff);
}
w->consctlopen = FALSE;
break;
@@ -413,7 +429,7 @@
case Qmouse:
w->mouseopen = FALSE;
w->resized = FALSE;
- wsendmsg(w, Refresh, ZR, nil);
+ wsendmsg(w, Refresh);
break;
case Qcursor:
@@ -421,6 +437,11 @@
wsetcursor(w);
break;
+ case Qwctl:
+ if(fid->omode==ORDWR || fid->omode==OREAD)
+ w->wctlopen = FALSE;
+ break;
+
case Qtap:
chanprint(ctltap, "%c%c", Tapoff, fid->omode);
recvp(resptap);
@@ -575,6 +596,13 @@
case Qwindow:
respond(r, readimg(r, w->img));
return;
+ case Qwctl:
+ if(r->ifcall.count < 4*12){
+ respond(r, Etooshort);
+ return;
+ }
+ respond(r, readblocking(r, w->wctlread));
+ return;
case Qtap:
respond(r, readblocking(r, totap));
return;
@@ -638,25 +666,25 @@
case Qconsctl:
if(strncmp(data, "holdon", 6) == 0){
- wsendmsg(w, Holdon, ZR, nil);
+ wsendmsg(w, Holdon);
break;
}
if(strncmp(data, "holdoff", 7) == 0){
- wsendmsg(w, Holdoff, ZR, nil);
+ wsendmsg(w, Holdoff);
break;
}
if(strncmp(data, "rawon", 5) == 0){
if(w->holdmode){
w->holdmode = 1;
- wsendmsg(w, Holdoff, ZR, nil);
+ wsendmsg(w, Holdoff);
}
if(x->rawmode++ == 0)
- wsendmsg(w, Rawon, ZR, nil);
+ wsendmsg(w, Rawon);
break;
}
if(strncmp(data, "rawoff", 6) == 0){
if(--x->rawmode == 0)
- wsendmsg(w, Rawoff, ZR, nil);
+ wsendmsg(w, Rawoff);
break;
}
respond(r, "unknown control message");
@@ -735,6 +763,15 @@
free(w->dir);
w->dir = cleanname(p);
break;
+
+ case Qwctl:
+ /* sucks that we have no space for '\0' */
+ p = emalloc(count+1);
+ memmove(p, data, count);
+ p[count] = '\0';
+ respond(r, writewctl(w, p));
+ free(p);
+ return;
case Qtap:
if(count < 2){
--- a/inc.h
+++ b/inc.h
@@ -14,7 +14,9 @@
typedef uchar bool;
enum {
FALSE = 0,
- TRUE = 1
+ TRUE = 1,
+
+ BIG = 3
};
#define ALT(c, v, t) (Alt){ c, v, t, nil, nil, 0 }
@@ -153,7 +155,8 @@
enum
{
Closed,
- Reshaped,
+ Resized,
+ Moved,
Deleted,
Refresh,
Holdon,
@@ -163,14 +166,6 @@
Wakeup
};
-typedef struct Wctlmesg Wctlmesg;
-struct Wctlmesg
-{
- int type;
- Rectangle r;
- void *p;
-};
-
typedef struct Window Window;
struct Window
{
@@ -192,8 +187,10 @@
Text text;
Rectangle scrollr;
Rectangle textr;
- bool scrolling;
int holdmode;
+ bool scrolling;
+ bool wctlready;
+ bool wctlopen;
Mousectl mc;
Mousequeue mq;
@@ -208,13 +205,14 @@
bool consctlopen;
bool kbdopen;
- Channel *gone; // window gone
- Channel *ctl; // Wctlmesg
- /* channels to xfids */
+ Channel *gone; /* window gone */
+ Channel *ctl; /* Wctlmesg */
+ /* channels to xreqs */
Channel *conswrite;
Channel *consread;
Channel *kbdread;
Channel *mouseread;
+ Channel *wctlread;
Channel *complete;
};
@@ -227,9 +225,9 @@
void wdecor(Window *w);
void wresize(Window *w, Rectangle r);
-Window *wcreate(Rectangle r);
+Window *wcreate(Rectangle r, bool hidden, bool scrolling);
int wrelease(Window *w);
-void wsendmsg(Window *w, int type, Rectangle r, void *p);
+void wsendmsg(Window *w, int type);
Window *wfind(int id);
Window *wpointto(Point pt);
void wsetcursor(Window *w);
@@ -240,8 +238,8 @@
void wraise(Window *w);
void wlower(Window *w);
void wfocus(Window *w);
-void whide(Window *w);
-void wunhide(Window *w);
+int whide(Window *w);
+int wunhide(Window *w);
void wsethold(Window *w, int hold);
void wmovemouse(Window *w, Point pt);
void wtype(Window *w, Rune r);
@@ -248,6 +246,9 @@
void wsetname(Window *w);
void wsetpid(Window *w, int pid, int dolabel);
void winshell(void *args);
+int wincmd(Window *w, int pid, char *dir, char **argv);
+
+char *writewctl(Window *w, char *data);
enum{
Tapon = 'b',
--- a/main.c
+++ b/main.c
@@ -151,24 +151,6 @@
free(sn);
}
-Rectangle
-newrect(void)
-{
- static int i = 0;
- int minx, miny, dx, dy;
-
-// dx = min(600, Dx(screen->r) - 2*Borderwidth);
-// dy = min(400, Dy(screen->r) - 2*Borderwidth);
- dx = 600;
- dy = 400;
- minx = 32 + 16*i;
- miny = 32 + 16*i;
- i++;
- i %= 10;
-
- return Rect(minx, miny, minx+dx, miny+dy);
-}
-
static int overridecursor;
static Cursor *ovcursor;
static Cursor *normalcursor;
@@ -204,33 +186,11 @@
new(Rectangle r)
{
Window *w;
- Channel *cpid;
- void *args[5];
- int pid;
- w = wcreate(r);
+ w = wcreate(r, FALSE, scrolling);
assert(w);
- w->scrolling = scrolling;
- cpid = chancreate(sizeof(int), 0);
- assert(cpid);
-
- args[0] = w;
- args[1] = cpid;
- args[2] = "/bin/rc";
- args[3] = rcargv;
- args[4] = nil;
- proccreate(winshell, args, mainstacksize);
- pid = recvul(cpid);
- chanfree(cpid);
-
- if(pid == 0){
- print("proc create failed\n");
+ if(wincmd(w, 0, nil, rcargv) == 0)
return nil;
- }
-
- wsetpid(w, pid, 1);
- wsetname(w);
-
return w;
}
@@ -481,7 +441,7 @@
xshow(x, x->nr);
break;
}
- wsendmsg(w, Wakeup, ZR, nil);
+ wsendmsg(w, Wakeup);
}
void
@@ -515,7 +475,7 @@
break;
case Delete:
w = pick();
- if(w) wsendmsg(w, Deleted, ZR, nil);
+ if(w) wsendmsg(w, Deleted);
break;
case Hide:
w = pick();
--- a/mkfile
+++ b/mkfile
@@ -5,6 +5,7 @@
main.$O \
text.$O \
wind.$O \
+ wctl.$O \
fs.$O \
util.$O \
time.$O
--- a/text.c
+++ b/text.c
@@ -262,7 +262,6 @@
*/
static Image *scrtmp;
-enum { BIG = 3 };
static Image*
scrtemps(void)
@@ -924,7 +923,7 @@
if(fd < 0)
return 0;
m = emalloc(sizeof(Plumbmsg));
- m->src = estrdup("rio");
+ m->src = estrdup("lola"); /* TODO: argument? */
m->dst = nil;
m->wdir = estrdup(dir);
m->type = estrdup("text");
--- a/wind.c
+++ b/wind.c
@@ -81,12 +81,17 @@
static void
wsetsize(Window *w, Rectangle r)
{
+ Rectangle hr;
+
if(w->img)
freeimage(w->img);
- w->img = allocwindow(wscreen, r, Refbackup, DNofill);
+ if(w->hidden){
+ hr = rectaddpt(r, subpt(screen->r.max, r.min));
+ w->img = allocwindow(wscreen, hr, Refbackup, DNofill);
+ originwindow(w->img, r.min, hr.min);
+ }else
+ w->img = allocwindow(wscreen, r, Refbackup, DNofill);
wcalcrects(w);
-// might be worth a try!
-//replclipr(w->img,0,w->contrect);
draw(w->img, w->img->r, colors[BACK], nil, ZP);
xinit(&w->text, w->textr, w->scrollr, font, w->img, colors);
wdecor(w);
@@ -95,7 +100,7 @@
static int id = 1;
Window*
-wcreate(Rectangle r)
+wcreate(Rectangle r, bool hidden, bool scrolling)
{
Window *w;
@@ -105,6 +110,8 @@
w->notefd = -1;
w->label = estrdup("<unnamed>");
w->dir = estrdup(startdir);
+ w->hidden = hidden;
+ w->scrolling = scrolling;
wsetsize(w, r);
wlistpushfront(w);
// TMP - make dynamic
@@ -115,14 +122,17 @@
w->gone = chancreate(sizeof(int), 0);
w->kbd = chancreate(sizeof(char*), 16);
- w->ctl = chancreate(sizeof(Wctlmesg), 0);
+ w->ctl = chancreate(sizeof(int), 0);
w->conswrite = chancreate(sizeof(Channel**), 0);
w->consread = chancreate(sizeof(Channel**), 0);
w->kbdread = chancreate(sizeof(Channel**), 0);
w->mouseread = chancreate(sizeof(Channel**), 0);
+ w->wctlread = chancreate(sizeof(Channel**), 0);
w->complete = chancreate(sizeof(Completion*), 0);
threadcreate(winthread, w, mainstacksize);
+ wsetname(w);
+
return w;
}
@@ -141,6 +151,7 @@
chanclose(w->consread);
chanclose(w->kbdread);
chanclose(w->mouseread);
+ chanclose(w->wctlread);
chanclose(w->complete);
free(w->label);
free(w);
@@ -165,8 +176,8 @@
}
if(w->img){
-// rio does this, useful?
-// originwindow(w->img, w->img->r.min, screen->r.max);
+ /* rio does this, not sure if useful */
+ originwindow(w->img, w->img->r.min, screen->r.max);
freeimage(w->img);
}
w->img = nil;
@@ -184,19 +195,14 @@
if(i < 0)
panic("negative ref count");
wclose(w);
- wsendmsg(w, Closed, ZR, nil);
+ wsendmsg(w, Closed);
return 1;
}
void
-wsendmsg(Window *w, int type, Rectangle r, void *p)
+wsendmsg(Window *w, int type)
{
- Wctlmesg cm;
-
- cm.type = type;
- cm.r = r;
- cm.p = p;
- send(w->ctl, &cm);
+ sendul(w->ctl, type);
}
Window*
@@ -249,17 +255,29 @@
w->label = estrdup(label);
}
+/* restore window order after reshaping has disturbed it */
void
+worder(void)
+{
+ Window *w;
+ for(w = bottomwin; w; w = w->higher)
+ if(!w->hidden)
+ topwindow(w->img);
+}
+
+void
wresize(Window *w, Rectangle r)
{
-// TODO: maybe call wsetsize from Reshaped handler?
wsetsize(w, r);
- wsendmsg(w, Reshaped, w->img->r, nil);
+ if(w != topwin && !w->hidden)
+ worder();
+ wsendmsg(w, Resized);
}
void
wmove(Window *w, Point pos)
{
+ Point delta;
/* BUG: originwindow causes the old window rect to be drawn onto the new one
* with backing store of allocscreen
* happens in _freeimage1(*winp); in libdraw/init.c:gengetwindow
@@ -268,17 +286,15 @@
* We don't care if we're handling resizing ourselves though */
if(w->mouseopen){
- Point delta = subpt(pos, w->img->r.min);
+ delta = subpt(pos, w->img->r.min);
wresize(w, rectaddpt(w->img->r, delta));
}else{
- originwindow(w->img, pos, pos);
+ originwindow(w->img, pos, w->hidden ? screen->r.max : pos);
+ if(w != topwin && !w->hidden)
+ worder();
wcalcrects(w);
xsetrects(&w->text, w->textr, w->scrollr);
-
-// TODO: Reshaped changes winname, don't want that
- w->resized = TRUE;
- w->mc.buttons = 0; /* avoid re-triggering clicks on resize */
- w->mq.counter++; /* cause mouse to be re-read */
+ wsendmsg(w, Moved);
}
}
@@ -332,35 +348,49 @@
prev = focused;
focused = w;
sendp(wintap, w);
- if(prev)
+ /* TODO a bit ugly the repitition,
+ * but this might not stay anyways */
+ if(prev){
+ prev->wctlready = TRUE;
wrepaint(prev);
- if(focused)
+ wsendmsg(prev, Wakeup);
+ }
+ if(focused){
+ focused->wctlready = TRUE;
wrepaint(focused);
+ wsendmsg(focused, Wakeup);
+ }
}
-void
+int
whide(Window *w)
{
if(w->hidden)
- return;
+ return -1;
incref(w);
if(w == focused)
wfocus(nil);
w->hidden = TRUE;
+ w->wctlready = TRUE;
originwindow(w->img, w->img->r.min, screen->r.max);
+ wsendmsg(w, Wakeup);
wrelease(w);
+ return 1;
}
-void
+int
wunhide(Window *w)
{
if(!w->hidden)
- return;
+ return -1;
incref(w);
w->hidden = FALSE;
+ w->wctlready = TRUE;
originwindow(w->img, w->img->r.min, w->img->r.min);
+ wraise(w);
wfocus(w);
wrelease(w);
+ return 1;
}
void
@@ -652,15 +682,12 @@
}
int
-winctl(Window *w, int type, Rectangle r, void *p)
+winctl(Window *w, int type)
{
Text *x;
int i;
x = &w->text;
-/* TODO: this is kinda dumb right now. do we *really* need args? */
-(void)p;
-(void)r;
switch(type){
case Closed:
wfree(w);
@@ -672,10 +699,11 @@
wclose(w);
break;
- case Reshaped:
-/* TODO: all the resizing code is shit */
+ case Resized:
wsetname(w);
+ case Moved:
w->resized = TRUE;
+ w->wctlready = TRUE;
w->mc.buttons = 0; /* avoid re-triggering clicks on resize */
w->mq.counter++; /* cause mouse to be re-read */
wdecor(w);
@@ -724,8 +752,9 @@
Text *x;
Rune r, *rp;
char *s;
- Wctlmesg cm;
- enum { AKbd, AMouse, ACtl, AConsWrite, AConsRead, AKbdRead, AMouseRead, AComplete, Agone, NALT };
+ int cm;
+ enum { AKbd, AMouse, ACtl, AConsWrite, AConsRead,
+ AKbdRead, AMouseRead, AWctlRead, AComplete, Agone, NALT };
Alt alts[NALT+1];
Channel *fsc;
Stringpair pair;
@@ -749,6 +778,7 @@
alts[AConsRead] = ALT(w->consread, &fsc, CHANSND);
alts[AKbdRead] = ALT(w->kbdread, &fsc, CHANSND);
alts[AMouseRead] = ALT(w->mouseread, &fsc, CHANSND);
+ alts[AWctlRead] = ALT(w->wctlread, &fsc, CHANSND);
alts[AComplete] = ALT(w->complete, &comp, CHANRCV);
alts[Agone] = ALT(w->gone, nil, CHANNOP);
alts[NALT].op = CHANEND;
@@ -760,6 +790,7 @@
alts[AConsRead].op = CHANNOP;
alts[AKbdRead].op = CHANNOP;
alts[AMouseRead].op = CHANNOP;
+ alts[AWctlRead].op = CHANNOP;
}else{
nr = xninput(x);
if(!w->holdmode && (nr >= 0 || cnv.n > 0 || x->rawmode && x->nraw > 0))
@@ -778,6 +809,7 @@
alts[AMouseRead].op = CHANSND;
else
alts[AMouseRead].op = CHANNOP;
+ alts[AWctlRead].op = w->wctlready ? CHANSND : CHANNOP;
}
switch(alt(alts)){
@@ -887,8 +919,18 @@
send(fsc, &pair);
break;
+ case AWctlRead:
+ w->wctlready = FALSE;
+ recv(fsc, &pair);
+ pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %11s %11s ",
+ w->img->r.min.x, w->img->r.min.y, w->img->r.max.x, w->img->r.max.y,
+ w == focused ? "current" : "notcurrent",
+ w->hidden ? "hidden" : "visible");
+ send(fsc, &pair);
+ break;
+
case ACtl:
- if(winctl(w, cm.type, cm.r, cm.p)){
+ if(winctl(w, cm)){
free(cnv.buf);
return;
}
@@ -933,7 +975,7 @@
w->name[n+1] = 0;
}
w->name[0] = 0;
- fprint(2, "rio: setname failed: %s\n", err);
+ fprint(2, "lola: setname failed: %s\n", err);
}
void
@@ -999,4 +1041,36 @@
procexec(pidc, cmd, argv);
_exits("exec failed");
}
+}
+
+int
+wincmd(Window *w, int pid, char *dir, char **argv)
+{
+ Channel *cpid;
+ void *args[5];
+
+ if(argv){
+ cpid = chancreate(sizeof(int), 0);
+ assert(cpid);
+ args[0] = w;
+ args[1] = cpid;
+ args[2] = "/bin/rc";
+ args[3] = argv;
+ args[4] = dir;
+ proccreate(winshell, args, mainstacksize);
+ pid = recvul(cpid);
+ chanfree(cpid);
+ if(pid == 0){
+ wsendmsg(w, Deleted);
+ return 0;
+ }
+ }
+
+ wsetpid(w, pid, 1);
+ if(dir){
+ free(w->dir);
+ w->dir = estrdup(dir);
+ }
+
+ return pid;
}