From: "José Miguel Sánchez García" <soy.jmi2k@gmail.com>
To: 9front@9front.org
Subject: Re: [9front] Mouse clipping patch
Date: Tue, 13 Jul 2021 14:00:43 +0200 [thread overview]
Message-ID: <CAA85C874gq8wK1hYEbAmpeytbshvNhGnricu1-MXe4V7F=BRzg@mail.gmail.com> (raw)
In-Reply-To: <CAA85C87qdQe6Bj6E4XvGwgOd7_cgQOJ4Yiv8tRhL4pEzzMTqQQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5229 bytes --]
Here are the fixed patches:
- The libdraw patch wouldn't compile due to a missing declaration. Oops!
- Fixed a bug where clicking a window border wouldn't focus it (kvik
noticed it right away).
- Fixed the rect parsing code in rio.
- Changed naming convention to clip/unclip.
- Documented my changes in mouse(2) and mouse(3).
I've included a patch for qwx's quake2
(https://shithub.us/qwx/qk2/HEAD/info.html) which, while not replacing
the old grabbing behavior, makes it impossible for the cursor to
escape the window. It relies on the forced unclip (no unclipmouse to
be seen in the code), so it also serves as a demonstration of that
feature.
Finally, I've also included a simple rc script to clip the mouse. I've
used it to test all the interactions of this new clip feature with
rio, as it's easy to invoke, easy to kill with Del, and you have
access to rio menus (so you can "exit the clip" by creating a new
window which unfocuses the current one).
On Tue, Jul 13, 2021 at 5:14 AM José Miguel Sánchez García
<soy.jmi2k@gmail.com> wrote:
>
> Let's see if I can do this quote thing correctly:
>
> First of all: I'm aware of some bugs (and you pointed out others)!
> I'll send the corrected patchset tomorrow.
> The naming scheme is a bit messy as a result of a dropped feature.
> I'll improve it too.
>
> > Don't do this to vncv! Not grabbing the mouse makes it
> > much more usable.
>
> I'm aware of someone who will respectfully disagree :-)
>
> > For the other programs that can use it, I assume the
> > patches will follow up once we're happy with this patch
> > set?
>
> Sure, they'll come later. I wanted to keep them separated from these.
>
> > Not sure that this is necessary. Your mouse being
> > constrained to the window is probably enough hint.
>
> Keep in mind that the border changes not only for the window currently
> grabbing the window, but for any non-current window "grabbing" it too
> (even if it doesn't apply because it's not focused). The different
> border color serves as an indicator that, when you focus it, it will
> grab your mouse. It might avoid an unpleasant surprise. However, if
> you feel like it's redundant, it can be easily removed.
>
> > But also, do we need to do it? Is there any case
> > where we want to constrain the grab to anything
> > other than the whole window? What if the ctl
> > messages were just
> >
> > trap
> > release
> >
> > with no further parameters?
>
> The point of allowing arbitrary clip rects is to make the grabbing
> program unaware of the existence of a window manager. Rio itself would
> be an example of a program which doesn't grab the whole "window" (the
> whole screen), but only subrects of it. In order to maintain an
> uniform interface which works regardless of the presence of rio or
> not, I've decided to go down the simplest route and just allow any
> subrect of the whole screen to be clipped. It didn't require more code
> or more complex handling, and it even allows future programs to take
> advantage of this feature.
>
> Hope it makes sense!
>
> On Tue, Jul 13, 2021 at 4:53 AM <ori@eigenstate.org> wrote:
> >
> > Quoth José Miguel Sánchez García <soy.jmi2k@gmail.com>:
> > > think about vncv, qwx's quake ports, screenlock
> >
> > Don't do this to vncv! Not grabbing the mouse makes it
> > much more usable.
> >
> > For the other programs that can use it, I assume the
> > patches will follow up once we're happy with this patch
> > set?
> >
> > > - Windows holding the mouse have a different border color,
> > > so they can be clearly identified.
> >
> > Not sure that this is necessary. Your mouse being
> > constrained to the window is probably enough hint.
> >
> > > + write(mousectl->mctlfd, x->data, cnt);
> >
> > This will hide all errors from the write, so
> > a malformed mousectl message will get silently
> > dropped.
> >
> > > +extern int clipmouse(Mousectl*, Rectangle);
> > > +extern void releasemouse(Mousectl*);
> >
> > This naming lacks symmetry.
> >
> > How about constrainmouse()/releasemouse()?
> > Or if you feel cute: mousetrap()/mouserelease()?
> >
> > Same with the ctl messages: trap/release, or clip/unclip?
> >
> > > + grabr.min.x = strtol(x->data+4, &p, 0);
> > > + if(p == nil){
> >
> > This isn't how strtol behaves -- if it can't convert
> > the number, it leaves p untouched. you need to do:
> >
> > grabr.min.x = strtol(p, &e, 0);
> > if(p == e || *e != ' ')
> > // error
> > p = e;
> >
> > You can probably clean it up a bit with tokenize(),
> > and then ensure that *e == '\0':
> >
> > if(tokenize(x->data+4, coords, 4) != 4)
> > error()
> > n = strtol(coords[0], &e, 0);
> > if(*e != 0)
> > error()
> >
> > But also, do we need to do it? Is there any case
> > where we want to constrain the grab to anything
> > other than the whole window? What if the ctl
> > messages were just
> >
> > trap
> > release
> >
> > with no further parameters?
> >
[-- Attachment #2: rio-mouseclip.diff --]
[-- Type: application/octet-stream, Size: 8225 bytes --]
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/dat.h
+++ /sys/src/cmd/rio/dat.h
@@ -10,6 +10,7 @@
Qlabel,
Qkbd,
Qmouse,
+ Qmousectl,
Qnew,
Qscreen,
Qsnarf,
@@ -154,6 +155,9 @@
* Now they're always the same but the code doesn't assume so.
*/
Rectangle screenr; /* screen coordinates of window */
+ Rectangle mclipr;
+ Fid *mclipfid;
+ int mclip;
int resized;
int wctlready;
Rectangle lastsr;
@@ -304,11 +308,14 @@
Image *lightholdcol;
Image *paleholdcol;
Image *paletextcol;
+Image *grabcol;
+Image *lightgrabcol;
Image *sizecol;
int reverse; /* there are no pastel paints in the dungeons and dragons world -- rob pike */
Window **window;
Window *wkeyboard; /* window of simulated keyboard */
+Window *wclip;
int nwindow;
int snarffd;
int gotscreen;
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/data.c
+++ /sys/src/cmd/rio/data.c
@@ -195,6 +195,8 @@
lightholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreyblue);
paleholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreyblue);
paletextcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x666666FF^reverse);
+ grabcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xB22222FF);
+ lightgrabcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCD5C5CFF);
sizecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DRed);
if(reverse == 0)
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/fns.h
+++ /sys/src/cmd/rio/fns.h
@@ -5,6 +5,7 @@
int writewctl(Xfid*, char*);
Window *new(Image*, int, int, int, char*, char*, char**);
void riosetcursor(Cursor*);
+void updatemclip(void);
int min(int, int);
int max(int, int);
Rune* strrune(Rune*, Rune);
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/fsys.c
+++ /sys/src/cmd/rio/fsys.c
@@ -30,6 +30,7 @@
{ "label", QTFILE, Qlabel, 0600 },
{ "kbd", QTFILE, Qkbd, 0600 },
{ "mouse", QTFILE, Qmouse, 0600 },
+ { "mousectl", QTFILE, Qmousectl, 0600 },
{ "screen", QTFILE, Qscreen, 0400 },
{ "snarf", QTFILE, Qsnarf, 0600 },
{ "text", QTFILE, Qtext, 0600 },
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/rio.c
+++ /sys/src/cmd/rio/rio.c
@@ -327,6 +327,27 @@
}
void
+updatemclip(void)
+{
+ Window *w;
+
+ if(input == nil || !input->mclip || menuing || sweeping)
+ w = nil;
+ else
+ w = input;
+ if(w == wclip)
+ return;
+ if(w != nil){
+ clipmouse(mousectl, w->mclipr);
+ wsendctlmesg(w, Repaint, ZR, nil);
+ }else
+ unclipmouse(mousectl);
+ if(wclip)
+ wsendctlmesg(wclip, Repaint, ZR, nil);
+ wclip = w;
+}
+
+void
killprocs(void)
{
int i;
@@ -489,6 +510,9 @@
wtopme(wkeyboard);
winput = wkeyboard;
}
+ w = wpointto(mouse->xy);
+ if(sending == FALSE && !scrolling && w!=nil && !w->deleted && inborder(w->screenr, mouse->xy))
+ moving = TRUE;
if(winput!=nil && !winput->deleted && winput->i!=nil){
/* convert to logical coordinates */
xy.x = mouse->xy.x + (winput->i->r.min.x-winput->screenr.min.x);
@@ -505,10 +529,7 @@
scrolling = mouse->buttons;
else
scrolling = mouse->buttons && ptinrect(xy, winput->scrollr);
- /* topped will be zero or less if window has been bottomed */
- if(sending == FALSE && !scrolling && inborder(winput->screenr, mouse->xy) && winput->topped>0)
- moving = TRUE;
- else if(inside && (scrolling || winput->mouseopen || (mouse->buttons&1)))
+ if(inside && (scrolling || winput->mouseopen || (mouse->buttons&1)))
sending = TRUE;
}else
sending = FALSE;
@@ -523,21 +544,21 @@
continue;
}
if(moving && (mouse->buttons&7)){
- incref(winput);
+ incref(w);
sweeping = TRUE;
if(mouse->buttons & 3)
- i = bandsize(winput);
+ i = bandsize(w);
else
- i = drag(winput);
+ i = drag(w);
sweeping = FALSE;
- if(i != nil){
- wcurrent(winput);
- wsendctlmesg(winput, Reshaped, i->r, i);
- }
- wclose(winput);
+ if(i != nil)
+ wsendctlmesg(w, Reshaped, i->r, i);
+ wcurrent(w);
+ wtopme(w);
+ wsendctlmesg(w, Topped, ZR, nil);
+ wclose(w);
continue;
}
- w = wpointto(mouse->xy);
if(w!=nil && inborder(w->screenr, mouse->xy))
riosetcursor(corners[whichcorner(w->screenr, mouse->xy)]);
else
@@ -715,6 +736,7 @@
menu3str[i] = nil;
}
sweeping = TRUE;
+ updatemclip();
switch(i = menuhit(3, mousectl, &menu3, wscreen)){
case -1:
break;
@@ -744,6 +766,7 @@
break;
}
sweeping = FALSE;
+ updatemclip();
}
void
@@ -753,6 +776,8 @@
menu2str[Scroll] = "noscroll";
else
menu2str[Scroll] = "scroll";
+ sweeping = TRUE;
+ updatemclip();
switch(menuhit(2, mousectl, &menu2, wscreen)){
case Cut:
wsnarf(w);
@@ -787,6 +812,8 @@
wshow(w, w->nr);
break;
}
+ sweeping = FALSE;
+ updatemclip();
flushimage(display, 1);
wsendctlmesg(w, Wakeup, ZR, nil);
}
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/wind.c
+++ /sys/src/cmd/rio/wind.c
@@ -302,6 +302,11 @@
col = holdcol;
else
col = paleholdcol;
+ }else if(w->mclip){
+ if(type == Selborder)
+ col = grabcol;
+ else
+ col = lightgrabcol;
}else{
if(type == Selborder)
col = titlecol;
@@ -358,6 +363,8 @@
w->scrollr.max.x = r.min.x+Scrollwid;
w->lastsr = ZR;
r.min.x += Scrollwid+Scrollgap;
+ w->mclip = FALSE;
+ updatemclip();
frclear(w, FALSE);
frinit(w, r, w->font, w->i, cols);
wsetcols(w, w == input);
@@ -1264,6 +1271,7 @@
w->gone = chancreate(sizeof(char*), 0);
w->scrollr = r;
w->scrollr.max.x = r.min.x+Scrollwid;
+ w->mclip = FALSE;
w->lastsr = ZR;
r.min.x += Scrollwid+Scrollgap;
frinit(w, r, font, i, cols);
@@ -1306,6 +1314,7 @@
input = nil;
riosetcursor(nil);
}
+ updatemclip();
if(w == wkeyboard)
wkeyboard = nil;
for(i=0; i<nhidden; i++)
@@ -1390,6 +1399,7 @@
sendp(c, w);
}
+ updatemclip();
if(w->i==nil || Dx(w->screenr)<=0)
break;
wrepaint(w);
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/cmd/rio/xfid.c
+++ /sys/src/cmd/rio/xfid.c
@@ -18,6 +18,7 @@
char Elong[] = "snarf buffer too long";
char Eunkid[] = "unknown id in attach";
char Ebadrect[] = "bad rectangle in attach";
+char Eclip[] = "invalid clip rectangle";
char Ewindow[] = "cannot make window";
char Enowindow[] = "window has no image";
char Ebadmouse[] = "bad format on /dev/mouse";
@@ -342,6 +343,14 @@
case Qkbd:
w->kbdopen = FALSE;
break;
+ case Qmousectl:
+ if(w->mclip && w->mclipfid == x->f){
+ w->mclip = FALSE;
+ w->mclipfid = nil;
+ updatemclip();
+ wsendctlmesg(w, Repaint, ZR, nil);
+ }
+ break;
case Qmouse:
w->resized = FALSE;
w->mouseopen = FALSE;
@@ -371,7 +380,8 @@
{
Fcall fc;
int cnt, qid, nb, off, nr;
- char err[ERRMAX], *p;
+ char err[ERRMAX], *coords[4], *p;
+ Rectangle mclipr;
Point pt;
Window *w;
Rune *r;
@@ -500,6 +510,50 @@
w->label = p;
w->label[cnt] = 0;
memmove(w->label, x->data, cnt);
+ break;
+
+ case Qmousectl:
+ if(strncmp(x->data, "clip", 4)==0){
+ if(tokenize(x->data+4, coords, 4)!=4){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ mclipr.min.x = strtol(coords[0], &p, 0);
+ if(*p != '\0'){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ mclipr.min.y = strtol(coords[1], &p, 0);
+ if(*p != '\0'){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ mclipr.max.x = strtol(coords[2], &p, 0);
+ if(*p != '\0'){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ mclipr.max.y = strtol(coords[3], &p, 0);
+ if(*p != '\0'){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ if(!rectinrect(mclipr, w->screenr)){
+ filsysrespond(x->fs, x, &fc, Eclip);
+ return;
+ }
+ w->mclipr = mclipr;
+ w->mclipfid = x->f;
+ w->mclip = TRUE;
+ updatemclip();
+ wsendctlmesg(w, Repaint, ZR, nil);
+ }else if(strncmp(x->data, "unclip", 6)==0){
+ w->mclip = FALSE;
+ w->mclipfid = nil;
+ updatemclip();
+ wsendctlmesg(w, Repaint, ZR, nil);
+ }else
+ write(mousectl->mctlfd, x->data, cnt);
break;
case Qmouse:
[-- Attachment #3: devmouse-clip.diff --]
[-- Type: application/octet-stream, Size: 2407 bytes --]
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/9/port/devmouse.c
+++ /sys/src/9/port/devmouse.c
@@ -18,6 +18,8 @@
ScrollRight = 0x40,
};
+char Eclip[] = "invalid clip rectangle";
+
typedef struct Mouseinfo Mouseinfo;
typedef struct Mousestate Mousestate;
@@ -53,6 +55,8 @@
CMbuttonmap,
CMscrollswap,
CMswap,
+ CMclip,
+ CMunclip,
CMblank,
CMblanktime,
CMtwitch,
@@ -64,6 +68,8 @@
CMbuttonmap, "buttonmap", 0,
CMscrollswap, "scrollswap", 0,
CMswap, "swap", 1,
+ CMclip, "clip", 0,
+ CMunclip, "unclip", 1,
CMblank, "blank", 1,
CMblanktime, "blanktime", 2,
CMtwitch, "twitch", 1,
@@ -95,6 +101,9 @@
static uchar buttonmap[8] = {
0, 1, 2, 3, 4, 5, 6, 7,
};
+static Rectangle clipr;
+static Chan *clipchan;
+static int clip;
static int mouseswap;
static int scrollswap;
static ulong mousetime;
@@ -206,6 +215,10 @@
if((c->qid.type&QTDIR)!=0 || (c->flag&COPEN)==0)
return;
switch((ulong)c->qid.path){
+ case Qmousectl:
+ if(c == clipchan)
+ clip = 0;
+ break;
case Qmousein:
mouse.inbuttons &= ~((Mousestate*)c->aux)->buttons;
free(c->aux); /* Mousestate */
@@ -344,6 +357,7 @@
mousewrite(Chan *c, void *va, long n, vlong)
{
char *p;
+ Rectangle r;
Point pt;
Cmdbuf *cb;
Cmdtab *ct;
@@ -403,6 +417,37 @@
mouseblankscreen(1);
break;
+ case CMclip:
+ if(cb->nf < 5)
+ error(Eshort);
+ if(!gscreen)
+ break;
+ r.min.x = strtol(cb->f[1], &p, 0);
+ if(p == nil)
+ error(Eclip);
+ r.min.y = strtol(cb->f[2], &p, 0);
+ if(p == nil)
+ error(Eclip);
+ r.max.x = strtol(cb->f[3], &p, 0);
+ if(p == nil)
+ error(Eclip);
+ r.max.y = strtol(cb->f[4], &p, 0);
+ if(p == nil)
+ error(Eclip);
+ if(!rectinrect(r, gscreen->clipr))
+ error(Eclip);
+ clipr = r;
+ clipchan = c;
+ clip = 1;
+ if(!ptinrect(mouse.xy, clipr))
+ absmousetrack(mouse.xy.x, mouse.xy.y, 0, 0);
+ break;
+
+ case CMunclip:
+ clip = 0;
+ clipchan = nil;
+ break;
+
case CMblanktime:
blanktime = strtoul(cb->f[1], 0, 0);
/* wet floor */
@@ -609,6 +654,17 @@
y = gscreen->clipr.min.y;
if(y >= gscreen->clipr.max.y)
y = gscreen->clipr.max.y-1;
+
+ if(clip){
+ if(x < clipr.min.x)
+ x = clipr.min.x;
+ if(x >= clipr.max.x)
+ x = clipr.max.x-1;
+ if(y < clipr.min.y)
+ y = clipr.min.y;
+ if(y >= clipr.max.y)
+ y = clipr.max.y-1;
+ }
ilock(&mouse);
[-- Attachment #4: grab.rc --]
[-- Type: application/octet-stream, Size: 120 bytes --]
#!/bin/rc
read -c 59 /dev/window | awk '{print "clip", $2+4, $3+4, $4-4, $5-4}' |[3=1] cat /fd/3 /fd/0 >>/dev/mousectl
[-- Attachment #5: man-mouseclip.diff --]
[-- Type: application/octet-stream, Size: 1826 bytes --]
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/man/2/mouse
+++ /sys/man/2/mouse
@@ -29,6 +29,12 @@
void moveto(Mousectl *mc, Point pt)
.PP
.B
+int clipmouse(Mousectl *mc, Rectangle r)
+.PP
+.B
+void unclipmouse(Mousectl *mc)
+.PP
+.B
void setcursor(Mousectl *mc, Cursor *c)
.PP
.B
@@ -96,6 +102,7 @@
char *file;
int mfd; /* to mouse file */
+ int mctlfd; /* to mousectl file */
int cfd; /* to cursor file */
int pid; /* of slave proc */
Image* image; /* of associated window/display */
@@ -164,6 +171,12 @@
.I Moveto
moves the mouse cursor on the display to the position specified by
.IR pt .
+.PP
+.I Clipmouse
+restricts the mouse movement to the area inside
+.IR r .
+.I Unclipmouse
+frees the mouse of any previous clip operation.
.PP
.I Setcursor
sets the image of the cursor to that specified by
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/man/3/mouse
+++ /sys/man/3/mouse
@@ -171,6 +171,15 @@
.B twitch
unblanks the screen and resets the idle timeout as if the
mouse was twitched.
+.TP
+.BI clip " x0" " y0" " x1" " y1"
+restricts the mouse movement to the area inside the provided rectangle.
+The provided rectangle must be fully contained inside the screen.
+.TP
+.BI unclip
+undoes any previous
+.I clip
+operations, letting the mouse move freely across the screen.
.PD
.PP
Not all mice interpret all messages; with some devices,
@@ -203,6 +212,13 @@
file sets the current cursor information.
A write of fewer than 72 bytes sets the
cursor to the default, an arrow.
+.PP
+A
+.I clip
+is valid as long as the file that requested it is kept open.
+When it's closed, the clip is forcibly released.
+This is a security mechanism against crashing apps,
+which would otherwise leave an unwanted active grab.
.PP
The
.B mouse
[-- Attachment #6: libdraw-mouseclip.diff --]
[-- Type: application/octet-stream, Size: 2061 bytes --]
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/include/mouse.h
+++ /sys/include/mouse.h
@@ -22,6 +22,7 @@
char *file;
int mfd; /* to mouse file */
+ int mctlfd; /* to mousectl file */
int cfd; /* to cursor file */
int pid; /* of slave proc */
Image* image; /* of associated window/display */
@@ -39,6 +40,8 @@
*/
extern Mousectl* initmouse(char*, Image*);
extern void moveto(Mousectl*, Point);
+extern int clipmouse(Mousectl*, Rectangle);
+extern void unclipmouse(Mousectl*);
extern int readmouse(Mousectl*);
extern void closemouse(Mousectl*);
extern void setcursor(Mousectl*, Cursor*);
--- //.git/fs/object/2f8a59f4b5bfe028c022855acc19666d69eed909/tree//sys/src/libdraw/mouse.c
+++ /sys/src/libdraw/mouse.c
@@ -12,14 +12,35 @@
m->xy = pt;
}
+int
+clipmouse(Mousectl *m, Rectangle r)
+{
+ char buf[128];
+ long n;
+
+ n = snprint(buf, sizeof(buf), "clip %d %d %d %d",
+ r.min.x, r.min.y,
+ r.max.x, r.max.y);
+ if(write(m->mctlfd, buf, n) != n)
+ return -1;
+ return 0;
+}
+
void
+unclipmouse(Mousectl *m)
+{
+ fprint(m->mctlfd, "unclip");
+}
+
+void
closemouse(Mousectl *mc)
{
if(mc == nil)
return;
close(mc->mfd);
+ close(mc->mctlfd);
close(mc->cfd);
- mc->mfd = mc->cfd = -1;
+ mc->mfd = mc->mctlfd = mc->cfd = -1;
threadint(mc->pid);
}
@@ -96,6 +117,7 @@
{
Mousectl *mc;
char *t, *sl;
+ long n;
mc = mallocz(sizeof(Mousectl), 1);
if(file == nil)
@@ -106,18 +128,25 @@
free(mc);
return nil;
}
- t = malloc(strlen(file)+16);
+ n = strlen(file)+16;
+ t = malloc(n);
if (t == nil) {
close(mc->mfd);
free(mc);
return nil;
}
- strcpy(t, file);
+ seprint(t, t+n, "%s", file);
+ strcat(t, "ctl");
sl = utfrrune(t, '/');
if(sl)
- strcpy(sl, "/cursor");
+ seprint(sl, t+n, "/mousectl");
else
- strcpy(t, "/dev/cursor");
+ seprint(t, t+n, "/dev/mousectl");
+ mc->mctlfd = open(t, ORDWR|OCEXEC);
+ if(sl)
+ seprint(sl, t+n, "/cursor");
+ else
+ seprint(t, t+n, "/dev/cursor");
mc->cfd = open(t, ORDWR|OCEXEC);
free(t);
mc->image = i;
[-- Attachment #7: qk2-mouseclip.diff --]
[-- Type: application/octet-stream, Size: 1113 bytes --]
--- /usr/glenda/qk2/.git/fs/object/a4c4b45d8b2136733c76a4b86c7896bfa939ad25/tree/dat.h
+++ dat.h
@@ -2930,3 +2930,4 @@
extern edict_t *sv_player;
extern char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
+extern int mctlfd;
--- /usr/glenda/qk2/.git/fs/object/a4c4b45d8b2136733c76a4b86c7896bfa939ad25/tree/sys.c
+++ sys.c
@@ -7,6 +7,7 @@
#include "fns.h"
void KBD_Update(void);
+int mctlfd;
mainstacksize = 512*1024;
int curtime;
@@ -398,6 +399,7 @@
int time, oldtime, newtime;
setfcr(getfcr() & ~(FPOVFL|FPUNFL|FPINVAL|FPZDIV)); /* assumed ignored in code */
+ mctlfd = open("/dev/mousectl", OWRITE);
notify(croak);
srand(getpid());
--- /usr/glenda/qk2/.git/fs/object/a4c4b45d8b2136733c76a4b86c7896bfa939ad25/tree/vid.c
+++ vid.c
@@ -86,6 +86,7 @@
sysfatal("allocimage: %r");
vid.buffer = fb;
vid.rowbytes = vid.width * sizeof *fbpal;
+ fprint(mctlfd, "clip %d %d %d %d", screen->r.min.x, screen->r.min.y, screen->r.max.x, screen->r.max.y);
center = addpt(screen->r.min, Pt(vid.width/2, vid.height/2));
p = Pt(vid.width/4, vid.height/4);
grabr = Rpt(subpt(center, p), addpt(center, p));
next prev parent reply other threads:[~2021-07-13 14:55 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-12 19:50 José Miguel Sánchez García
2021-07-13 2:36 ` ori
2021-07-13 2:45 ` ori
2021-07-13 14:03 ` Stuart Morrow
2021-08-11 0:56 ` Stuart Morrow
2021-07-13 3:14 ` José Miguel Sánchez García
2021-07-13 8:25 ` hiro
2021-07-13 10:27 ` José Miguel Sánchez García
2021-07-13 14:05 ` Stuart Morrow
[not found] ` <CAFSF3XPhDeKiKXdsL0Abnderm45Uc2GCPYsi6ygSaBkf7gDBmA@mail.gmail.com>
2021-07-13 15:09 ` José Miguel Sánchez García
2021-07-13 15:34 ` José Miguel Sánchez García
2021-07-14 12:04 ` Stuart Morrow
2021-07-15 2:06 ` Xiao-Yong Jin
2021-07-13 15:11 ` Stuart Morrow
2021-07-13 16:16 ` José Miguel Sánchez García
2021-07-13 16:27 ` Stuart Morrow
2021-07-13 17:42 ` José Miguel Sánchez García
2021-07-13 21:20 ` hiro
2021-07-13 21:57 ` ori
2021-07-14 11:55 ` Stuart Morrow
2021-07-13 17:26 ` Xiao-Yong Jin
2021-07-13 17:45 ` Stuart Morrow
2021-07-13 18:29 ` José Miguel Sánchez García
2021-07-13 21:32 ` hiro
2021-07-13 21:22 ` Benjamin Purcell
2021-07-13 16:21 ` hiro
2021-07-13 16:29 ` ori
2021-07-14 8:42 ` hiro
2021-07-14 11:52 ` Stuart Morrow
2021-07-14 12:17 ` hiro
2021-07-15 3:13 ` ori
2021-07-14 12:53 ` José Miguel Sánchez García
2021-07-15 7:36 ` hiro
2021-07-14 14:26 ` ori
2021-07-13 15:27 ` kvik
2021-07-13 16:28 ` ori
2021-07-13 12:00 ` José Miguel Sánchez García [this message]
2021-07-13 12:43 ` kvik
2021-07-13 13:36 ` hiro
2021-07-13 13:40 ` hiro
2021-07-14 22:57 ` ori
2021-07-15 7:40 ` hiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAA85C874gq8wK1hYEbAmpeytbshvNhGnricu1-MXe4V7F=BRzg@mail.gmail.com' \
--to=soy.jmi2k@gmail.com \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).