ref: f42ae8d3b918c57f5c82d192aef0b9feccd7a313
parent: 1049552fb14efa811ca879b35244b8ea684995c1
author: aap <[email protected]>
date: Sat Jan 28 11:24:30 EST 2023
mouse fixes; Xreqs
--- a/TODO
+++ b/TODO
@@ -4,7 +4,6 @@
tap
tap
border resize/move
-move mouse
write text
wctl
release keys and buttons when unfocused
--- a/fs.c
+++ b/fs.c
@@ -68,21 +68,29 @@
char Enowindow[] = "window has no image";
char Ebadmouse[] = "bad format on /dev/mouse";
+/* Extension of a Req, req->aux. also has a thread. */
+typedef struct Xreq Xreq;
+struct Xreq
+{
+ Req *req;
+ Channel *xc;
+ Channel *flush; /* cancel read/write */
+ Xreq *next;
+};
+#define XR(req) ((Xreq*)(req)->aux)
+static Xreq *xreqfree;
+
/* Extension of a Fid, fid->aux */
typedef struct Xfid Xfid;
struct Xfid
{
- Fid *fid;
- Channel *xc;
- Channel *flush; // cancel read/write
Window *w;
RuneConvBuf cnv;
- Xfid *next;
};
-static Xfid *xfidfree;
+#define XF(fid) ((Xfid*)(fid)->aux)
-typedef struct XfidMsg XfidMsg;
-struct XfidMsg
+typedef struct XreqMsg XreqMsg;
+struct XreqMsg
{
Req *r;
void (*f)(Req*);
@@ -89,61 +97,63 @@
};
static void
-xfidthread(void *a)
+xreqthread(void *a)
{
- Xfid *xf = a;
- XfidMsg xm;
+ Xreq *xr = a;
+ XreqMsg xm;
for(;;){
- recv(xf->xc, &xm);
+ recv(xr->xc, &xm);
+ xr->req = xm.r;
+ xm.r->aux = xr;
(*xm.f)(xm.r);
+ /* return to pool */
+ xr->req = nil;
+ xr->next = xreqfree;
+ xreqfree = xr;
}
}
+static Xreq*
+getxreq(void)
+{
+ Xreq *xr;
+ if(xreqfree){
+ xr = xreqfree;
+ xreqfree = xr->next;
+ }else{
+ xr = emalloc(sizeof(Xreq));
+ xr->xc = chancreate(sizeof(XreqMsg), 0);
+ xr->flush = chancreate(sizeof(int), 0);
+ threadcreate(xreqthread, xr, mainstacksize);
+ }
+ xr->next = nil;
+ return xr;
+}
+
static void
-toxfid(Req *r, void (*f)(Req*))
+toxreq(Req *r, void (*f)(Req*))
{
- Xfid *xf;
- XfidMsg xm;
+ Xreq *xr;
+ XreqMsg xm;
- xf = r->fid->aux;
+ xr = getxreq();
xm.r = r;
xm.f = f;
- send(xf->xc, &xm);
+ send(xr->xc, &xm);
}
static Xfid*
-getxfid(Fid *fid, Window *w)
+getxfid(Window *w)
{
Xfid *xf;
- if(xfidfree){
- xf = xfidfree;
- xfidfree = xf->next;
- }else{
- xf = emalloc(sizeof(Xfid));
- xf->xc = chancreate(sizeof(XfidMsg), 0);
- xf->flush = chancreate(sizeof(int), 0);
- threadcreate(xfidthread, xf, mainstacksize);
- }
+ xf = emalloc(sizeof(Xfid));
memset(&xf->cnv, 0, sizeof(xf->cnv));
- xf->fid = fid;
xf->w = w;
incref(w);
- xf->next = nil;
return xf;
}
-static void
-freexfid(Xfid *xf)
-{
- wrelease(xf->w);
- free(xf->cnv.buf);
- xf->fid = nil;
- xf->w = nil;
- xf->next = xfidfree;
- xfidfree = xf;
-}
-
#define QID(w, q) ((w)<<8|(q))
#define QWIN(q) ((q)>>8)
#define QFILE(q) ((q)&0xFF)
@@ -170,7 +180,7 @@
return;
}
- r->fid->aux = getxfid(r->fid, w);
+ r->fid->aux = getxfid(w);
r->fid->qid = (Qid){QID(w->id,Qroot),0,QTDIR};
r->ofcall.qid = r->fid->qid;
respond(r, nil);
@@ -179,11 +189,8 @@
static char*
fsclone(Fid *fid, Fid *newfid)
{
- Xfid *xf;
-
- xf = fid->aux;
- if(xf)
- newfid->aux = getxfid(newfid, xf->w);
+ if(XF(fid))
+ newfid->aux = getxfid(XF(fid)->w);
return nil;
}
@@ -307,13 +314,11 @@
static char *tsnarf;
static void
-xfopen(Req *r)
+fsopen(Req *r)
{
- Xfid *xf;
Window *w;
- xf = r->fid->aux;
- w = xf->w;
+ w = XF(r->fid)->w;
if(w == nil || w->deleted){
respond(r, Edeleted);
@@ -320,7 +325,7 @@
return;
}
- switch(QFILE(xf->fid->qid.path)){
+ switch(QFILE(r->fid->qid.path)){
case Qsnarf:
r->ifcall.mode &= ~OTRUNC;
if(r->ifcall.mode==ORDWR || r->ifcall.mode==OWRITE)
@@ -358,18 +363,22 @@
}
static void
-xfclose(Xfid *xf)
+fsclose(Fid *fid)
{
+ Xfid *xf;
Window *w;
Text *x;
+ xf = XF(fid);
+ if(xf == nil)
+ return;
w = xf->w;
x = &w->text;
- switch(QFILE(xf->fid->qid.path)){
+ switch(QFILE(fid->qid.path)){
/* replace snarf buffer when /dev/snarf is closed */
case Qsnarf:
- if(xf->fid->omode==ORDWR || xf->fid->omode==OWRITE){
+ if(fid->omode==ORDWR || fid->omode==OWRITE){
setsnarf(tsnarf, ntsnarf);
ntsnarf = 0;
}
@@ -402,6 +411,11 @@
wsetcursor(w);
break;
}
+
+ wrelease(xf->w);
+ free(xf->cnv.buf);
+ free(xf);
+ fid->aux = nil;
}
static int
@@ -462,7 +476,6 @@
static char*
readblocking(Req *r, Channel *readchan)
{
- Xfid *xf;
Window *w;
Channel *chan;
Stringpair pair;
@@ -469,12 +482,11 @@
enum { Adata, Agone, Aflush, NALT };
Alt alts[NALT+1];
- xf = r->fid->aux;
- w = xf->w;
+ w = XF(r->fid)->w;
alts[Adata] = ALT(readchan, &chan, CHANRCV);
alts[Agone] = ALT(w->gone, nil, CHANRCV);
- alts[Aflush] = ALT(xf->flush, nil, CHANRCV);
+ alts[Aflush] = ALT(XR(r)->flush, nil, CHANRCV);
alts[NALT].op = CHANEND;
switch(alt(alts)){
case Adata:
@@ -493,14 +505,12 @@
}
static void
-xfread(Req *r)
+xread(Req *r)
{
- Xfid *xf;
Window *w;
char *data;
- xf = r->fid->aux;
- w = xf->w;
+ w = XF(r->fid)->w;
if(w == nil || w->deleted){
respond(r, Edeleted);
@@ -507,7 +517,7 @@
return;
}
- switch(QFILE(xf->fid->qid.path)){
+ switch(QFILE(r->fid->qid.path)){
case Qwinid:
data = smprint("%11d ", w->id);
readstr(r, data);
@@ -555,7 +565,7 @@
}
static void
-xfwrite(Req *r)
+xwrite(Req *r)
{
Xfid *xf;
Window *w;
@@ -563,12 +573,13 @@
vlong offset;
u32int count;
char *data, *p;
+ Point pt;
Channel *kbd;
Stringpair pair;
enum { Adata, Agone, Aflush, NALT };
Alt alts[NALT+1];
- xf = r->fid->aux;
+ xf = XF(r->fid);
w = xf->w;
x = &w->text;
offset = r->ifcall.offset;
@@ -584,7 +595,7 @@
case Qcons:
alts[Adata] = ALT(w->conswrite, &kbd, CHANRCV);
alts[Agone] = ALT(w->gone, nil, CHANRCV);
- alts[Aflush] = ALT(xf->flush, nil, CHANRCV);
+ alts[Aflush] = ALT(XR(r)->flush, nil, CHANRCV);
alts[NALT].op = CHANEND;
switch(alt(alts)){
case Adata:
@@ -614,7 +625,10 @@
break;
}
if(strncmp(data, "rawon", 5) == 0){
-// TODO: apparently we turn of hold mode here
+ if(w->holdmode){
+ w->holdmode = 1;
+ wsendmsg(w, Holdoff, ZR, nil);
+ }
if(x->rawmode++ == 0)
wsendmsg(w, Rawon, ZR, nil);
break;
@@ -627,6 +641,21 @@
respond(r, "unknown control message");
return;
+ case Qmouse:
+ if(data[0] != 'm'){
+ respond(r, Ebadmouse);
+ return;
+ }
+ p = nil;
+ pt.x = strtoul(data+1, &p, 0);
+ if(p == nil){
+ respond(r, Eshort);
+ return;
+ }
+ pt.y = strtoul(p, nil, 0);
+ wmovemouse(w, pt);
+ break;
+
case Qcursor:
if(count < 2*4+2*2*16)
w->cursorp = nil;
@@ -694,38 +723,16 @@
}
static void
-fsopen(Req *r)
-{
- toxfid(r, xfopen);
-}
-
-static void
-freefid(Fid *fid)
-{
- Xfid *xf;
-
- xf = fid->aux;
- if(xf){
- xfclose(xf);
- freexfid(xf);
- }
- fid->aux = nil;
-}
-
-static void
fsread(Req *r)
{
- Xfid *xf;
-
if((r->fid->qid.type & QTDIR) == 0){
- toxfid(r, xfread);
+ toxreq(r, xread);
return;
}
switch(QFILE(r->fid->qid.path)){
case Qroot:
- xf = r->fid->aux;
- dirread9p(r, genrootdir, xf->w);
+ dirread9p(r, genrootdir, XF(r->fid)->w);
break;
case Qwsys:
dirread9p(r, genwsysdir, nil);
@@ -737,23 +744,21 @@
static void
fswrite(Req *r)
{
- toxfid(r, xfwrite);
+ toxreq(r, xwrite);
}
static void
fsflush(Req *r)
{
- Req *or;
- Xfid *xf;
+ Xreq *xr;
int dummy = 0;
- or = r->oldreq;
- xf = or->fid->aux;
- assert(xf);
+ xr = XR(r->oldreq);
+ assert(xr);
/* TODO: not entirely sure this is right.
* is it possible no-one is listening? */
- send(xf->flush, &dummy);
+ send(xr->flush, &dummy);
respond(r, nil);
}
@@ -760,12 +765,10 @@
static void
fsstat(Req *r)
{
- Xfid *xf;
int f;
- xf = r->fid->aux;
f = QFILE(r->fid->qid.path);
- genrootdir(f-1, &r->d, xf->w);
+ genrootdir(f-1, &r->d, XF(r->fid)->w);
respond(r, nil);
}
@@ -778,7 +781,7 @@
.flush fsflush,
.walk1 fswalk1,
.clone fsclone,
- .destroyfid freefid,
+ .destroyfid fsclose,
nil
};
--- a/inc.h
+++ b/inc.h
@@ -11,6 +11,7 @@
#include <complete.h>
#include <plumb.h>
+typedef uchar bool;
enum {
FALSE = 0,
TRUE = 1
@@ -43,7 +44,7 @@
uint qh; /* host point, output here */
/* not entirely happy with this in here */
- int rawmode;
+ bool rawmode;
Rune *raw;
int nraw;
@@ -137,7 +138,7 @@
ulong counter; /* serial no. of last mouse event we received */
ulong lastcounter; /* serial no. of last mouse event sent to client */
int lastb; /* last button state we received */
- uchar full; /* filled the queue; no more recording until client comes back */
+ bool full; /* filled the queue; no more recording until client comes back */
};
typedef struct Kbdqueue Kbdqueue;
@@ -146,7 +147,7 @@
char *q[32];
int ri;
int wi;
- uchar full;
+ bool full;
};
enum
@@ -174,8 +175,8 @@
struct Window
{
Ref;
- int deleted;
- int hidden;
+ bool deleted;
+ bool hidden;
Window *lower;
Window *higher;
Image *img;
@@ -183,6 +184,7 @@
char name[32];
int namecount;
char *label;
+ bool noborder;
Rectangle contrect;
int notefd;
char *dir;
@@ -190,7 +192,7 @@
Text text;
Rectangle scrollr;
Rectangle textr;
- int scrolling;
+ bool scrolling;
int holdmode;
Mousectl mc;
@@ -203,8 +205,8 @@
Channel *kbd;
Kbdqueue kq;
- int consctlopen;
- int kbdopen;
+ bool consctlopen;
+ bool kbdopen;
Channel *gone; // window gone
Channel *ctl; // Wctlmesg
@@ -241,6 +243,7 @@
void whide(Window *w);
void wunhide(Window *w);
void wsethold(Window *w, int hold);
+void wmovemouse(Window *w, Point pt);
void wtype(Window *w, Rune r);
void wsetname(Window *w);
void wsetpid(Window *w, int pid, int dolabel);
--- a/wind.c
+++ b/wind.c
@@ -15,6 +15,7 @@
w->higher = bottomwin;
if(bottomwin) bottomwin->lower = w;
w->lower = nil;
+ if(topwin == nil) topwin = w;
bottomwin = w;
}
@@ -24,6 +25,7 @@
w->lower = topwin;
if(topwin) topwin->higher = w;
w->higher = nil;
+ if(bottomwin == nil) bottomwin = w;
topwin = w;
}
@@ -45,7 +47,10 @@
void
wcalcrects(Window *w)
{
- w->contrect = insetrect(w->img->r, Borderwidth);
+ if(w->noborder)
+ w->contrect = w->img->r;
+ else
+ w->contrect = insetrect(w->img->r, Borderwidth);
Rectangle r = insetrect(w->contrect, 1);
w->scrollr = r;
w->scrollr.max.x = w->scrollr.min.x + 12;
@@ -56,6 +61,8 @@
void
wdecor(Window *w)
{
+ if(w->noborder)
+ return;
int c = w->holdmode ?
w == focused ? TITLEHOLD : LTITLEHOLD :
w == focused ? TITLE : LTITLE;
@@ -370,6 +377,15 @@
}
}
+void
+wmovemouse(Window *w, Point pt)
+{
+ if(w != focused || wpointto(mctl->xy) != w)
+ return;
+ // TODO? rio also checks menuing and such
+ moveto(mctl, pt);
+}
+
/*
* Need to do this in a separate proc because if process we're interrupting
* is dying and trying to print tombstone, kernel is blocked holding p->debug lock.
@@ -641,6 +657,7 @@
int i;
x = &w->text;
+/* TODO: this is kinda dumb right now. do we *really* need args? */
(void)p;
(void)r;
switch(type){
@@ -665,6 +682,8 @@
case Refresh:
/* TODO: clean this up? */
+ if(w->deleted)
+ break;
draw(w->img, w->img->r, x->cols[BACK], nil, ZP);
wdecor(w);
xfill(x);
@@ -902,7 +921,7 @@
int i, n;
char err[ERRMAX];
- n = snprint(w->name, sizeof(w->name)-2, "window.%d.%d", w->id, w->namecount++);
+ n = snprint(w->name, sizeof(w->name)-2, "%s.%d.%d", w->noborder ? "noborder" : "window", w->id, w->namecount++);
for(i='A'; i<='Z'; i++){
if(nameimage(w->img, w->name, 1) > 0)
return;