From: Stuart Morrow <morrow.stuart@gmail.com>
To: 9front@9front.org
Subject: [9front] speaking of screenlock
Date: Tue, 13 Jul 2021 15:27:09 +0100 [thread overview]
Message-ID: <CABB-WO9cLWnt62EbCQx8SSx=2s_mJJtB7GpjaUi5f15cSNAs=A@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 713 bytes --]
I noticed (i.e. I failed to notice months ago) that my screenlock
patch causes rio to redraw the green border. An attempt to
getwindow-and-redraw in the topper proc to fix this is attached, but
fails because screen image r is malloc'd. But I am asking for :130,142
to be merged as
1. it kind of fixes this anyway (as popups never happen in practice), and
2. it's just more efficient.
Further thoughts on screenlock: There's actually no need to discover
the screen size using /dev/screen OR /dev/draw - you can just invoke
newwindow with constants (e.g. 0 0 10000 10000) and rio forces it to
the real screen size. But then you're depending on an unmodded rio
with in principle other window managers could exist.
[-- Attachment #2: screenlock.c --]
[-- Type: text/x-csrc, Size: 5269 bytes --]
/* screenlock - lock a terminal */
#include <u.h>
#include <libc.h>
#include <libsec.h>
#include <draw.h>
#include <thread.h>
#include <auth.h>
void redraw(void);
void appendix(void);
char pic[] = "/lib/bunny.bit";
char notice[28+14]; /* KNAMELEN + length of a string */
int debug;
long blank;
void
usage(void)
{
fprint(2, "usage: %s [-d]\n", argv0);
exits("usage");
}
/* ^D, Delete, Enter, Backspace, ^U */
void
readline(char *buf, int nbuf)
{
char c;
int i;
i = 0;
while(i < nbuf-1){
if(read(0, &c, 1) != 1 || c == '\04' || c == '\177'){
i = 0;
break;
} else if(c == '\n')
break;
else if(c == '\b' && i > 0)
--i;
else if(c == ('u' & 037))
i = 0;
else
buf[i++] = c;
blank = time(0);
}
buf[i] = '\0';
}
void
checkpassword(void)
{
char buf[256];
AuthInfo *ai;
for(;;){
memset(buf, 0, sizeof buf);
readline(buf, sizeof buf);
border(screen, screen->r, 8, display->white, ZP);
flushimage(display, 1);
/* authenticate */
ai = auth_userpasswd(getuser(), buf);
if(ai != nil && ai->cap != nil)
break;
rerrstr(buf, sizeof buf);
if(strncmp(buf, "needkey ", 8) == 0)
break;
auth_freeAI(ai);
border(screen, screen->r, 8, display->black, ZP);
flushimage(display, 1);
}
auth_freeAI(ai);
memset(buf, 0, sizeof buf);
}
void
blanker(void *)
{
int fd;
threadsetname("blanker");
if((fd = open("/dev/mousectl", OWRITE)) < 0)
return;
for(;;){
if(blank != 0 && ((ulong)time(0) - (ulong)blank) >= 5){
blank = 0;
write(fd, "blank", 5);
}
sleep(1000);
}
}
void
grabmouse(void*)
{
int fd, x, y;
char ibuf[256], obuf[256];
threadsetname("grabmouse");
if((fd = open("/dev/mouse", ORDWR)) < 0)
sysfatal("can't open /dev/mouse: %r");
snprint(obuf, sizeof obuf, "m %d %d",
screen->r.min.x + Dx(screen->r)/2,
screen->r.min.y + Dy(screen->r)/2);
while(read(fd, ibuf, sizeof ibuf) > 0){
ibuf[12] = 0;
ibuf[24] = 0;
x = atoi(ibuf+1);
y = atoi(ibuf+13);
if(x != screen->r.min.x + Dx(screen->r)/2 ||
y != screen->r.min.y + Dy(screen->r)/2){
if(!debug)
fprint(fd, "%s", obuf);
blank = time(0);
}
}
}
void
top(void*)
{
int fd, n;
char buf[128];
threadsetname("top");
if((fd = open("/dev/wctl", ORDWR)) < 0)
return;
for(;;){
n = read(fd, buf, sizeof buf);
if(n > 48)
if(strstr(buf+48, "notcurrent")){
write(fd, "current", 7); /* rio redraws border… */
getwindow(display, 1);
redraw();
}
}
}
void
redraw(void)
{
int fd, dx, dy;
static Image *i;
Point p, q;
Rectangle r;
screen = _screen->image; /* fullscreen */
if(i == nil){
fd = open(pic, OREAD);
if(fd >= 0)
i = readimage(display, fd, 0);
close(fd);
}
if(i != nil){
fprint(2, "_screen"":%p\n", _screen);
fprint(2, "_screen image"":%p\n", _screen->image);
fprint(2, "_screen image r"":%p\n", &_screen->image->r);
r = screen->r;
p = Pt(r.max.x / 2, r.max.y * 2 / 3);
dx = (Dx(screen->r) - Dx(i->r)) / 2;
r.min.x += dx;
r.max.x -= dx;
dy = (Dy(screen->r) - Dy(i->r)) / 2;
r.min.y += dy;
r.max.y -= dy;
draw(screen, screen->r, display->black, nil, ZP);
draw(screen, r, i, nil, i->r.min);
}
/* identify the user on screen, centered */
q = stringsize(font, notice);
q.x /= 2;
p = subpt(p, q);
stringbg(
screen, p, display->white, ZP, font, notice,
display->black, ZP
);
flushimage(display, 1);
}
void
lockscreen(void)
{
enum { Cursorlen = 2*4 + 2*2*16 };
char newcmd[128], cbuf[Cursorlen];
Rectangle r;
int fd;
Tm *tm;
display = initdisplay(nil, nil, nil);
if(display == nil)
sysfatal("can't open /dev/draw: %r");
r = display->image->r;
snprint(newcmd, sizeof newcmd, "-r %d %d %d %d",
r.min.x, r.min.y, r.max.x, r.max.y);
closedisplay(display);
newwindow(newcmd);
if((fd = open("/dev/consctl", OWRITE)) >= 0)
write(fd, "rawon", 5);
if((fd = open("/dev/cons", OREAD)) < 0)
sysfatal("can't open cons: %r");
dup(fd, 0);
if((fd = open("/dev/cons", OWRITE)) < 0)
sysfatal("can't open cons: %r");
dup(fd, 1);
dup(fd, 2);
if(initdraw(nil, nil, "screenlock") < 0)
sysfatal("initdraw failed");
tm = localtime(time(&blank));
sprint(notice, "user %s at %d:%02.2d", getuser(), tm->hour, tm->min);
redraw();
/* screen is now open and covered. grab mouse and hold on tight */
procrfork(top, nil, 8*1024, RFFDG);
procrfork(grabmouse, nil, 8*1024, RFFDG);
procrfork(blanker, nil, 8*1024, RFFDG);
/* clear the cursor */
if((fd = open("/dev/cursor", OWRITE)) >= 0){
memset(cbuf, 0, sizeof cbuf);
write(fd, cbuf, sizeof cbuf);
/* leave it open */
}
/* do the top-getwindow-redraw cycle *here in the main proc*
to show that it can actuall work */
// :232 and this call can't be uncommented at the same time - there
// can be only one wctl reader
//appendix();
}
void
threadmain(int argc, char *argv[])
{
ARGBEGIN{
case 'd':
debug++;
break;
default:
usage();
}ARGEND
if(argc != 0)
usage();
lockscreen();
checkpassword();
threadexitsall(nil);
}
void
appendix(void)
{
int fd;//, n;
// char buf[128];
if((fd = open("/dev/wctl", ORDWR)) < 0)
fprint(2, "%r");
sleep(1000);
write(fd, "new echo", 8);
sleep(1000);
// if(strstr(buf+48, "notcurrent")){
write(fd, "current", 7); /* rio redraws border… */
getwindow(display, 1);
redraw();
// }
}
next reply other threads:[~2021-07-13 15:00 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-13 14:27 Stuart Morrow [this message]
2021-07-15 21:47 ` [9front] " Stuart Morrow
2021-07-15 23:04 ` ori
2021-07-16 9:07 ` Stuart Morrow
2021-07-16 10:01 ` cinap_lenrek
2021-07-16 10:50 ` Stuart Morrow
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='CABB-WO9cLWnt62EbCQx8SSx=2s_mJJtB7GpjaUi5f15cSNAs=A@mail.gmail.com' \
--to=morrow.stuart@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).