9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] speaking of screenlock
@ 2021-07-13 14:27 Stuart Morrow
  2021-07-15 21:47 ` [9front] " Stuart Morrow
  0 siblings, 1 reply; 6+ messages in thread
From: Stuart Morrow @ 2021-07-13 14:27 UTC (permalink / raw)
  To: 9front

[-- 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();
//	}
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [9front] Re: speaking of screenlock
  2021-07-13 14:27 [9front] speaking of screenlock Stuart Morrow
@ 2021-07-15 21:47 ` Stuart Morrow
  2021-07-15 23:04   ` ori
  0 siblings, 1 reply; 6+ messages in thread
From: Stuart Morrow @ 2021-07-15 21:47 UTC (permalink / raw)
  To: 9front

Actually, I don't get what it is about screenlock in the first place
that different procs can't access each other's malloc'd objects. It
seems other programs can do this just fine.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [9front] Re: speaking of screenlock
  2021-07-15 21:47 ` [9front] " Stuart Morrow
@ 2021-07-15 23:04   ` ori
  2021-07-16  9:07     ` Stuart Morrow
  0 siblings, 1 reply; 6+ messages in thread
From: ori @ 2021-07-15 23:04 UTC (permalink / raw)
  To: 9front

Quoth Stuart Morrow <morrow.stuart@gmail.com>:
> Actually, I don't get what it is about screenlock in the first place
> that different procs can't access each other's malloc'd objects. It
> seems other programs can do this just fine.
> 

See RFMEM in rfork(2). Though, I don't see
anything in screenlock that would prevent
it. What makes you think they can't access
each other's malloc'ed objects?


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [9front] Re: speaking of screenlock
  2021-07-15 23:04   ` ori
@ 2021-07-16  9:07     ` Stuart Morrow
  2021-07-16 10:01       ` cinap_lenrek
  0 siblings, 1 reply; 6+ messages in thread
From: Stuart Morrow @ 2021-07-16  9:07 UTC (permalink / raw)
  To: 9front

> What makes you think they can't access
> each other's malloc'ed objects?

Because it crashes in the second call to redraw (new function, only in
the first of this thread, assuming you got that), and moreover, I can
get past the killer 'r = screen->r' using a trick:

redraw(void)
{
	int fd, dx, dy;
	static Image *i;
	static Rectangle r, unusedr, screenr;
	Point p, q;

	screen = _screen->image;	/* fullscreen */

	/* we can access screen->r the first time. */
	/* getwindow doesn't change it… fullscreen is fullscreen… */
	if(eqrect(screenr, unusedr))
		screenr = screen->r;

(and then s/screen->r/screenr/g for the rest of the function)

just to then get killed by, I guess, draw(screen, ...).

So it seems like just touching certain objects is killing me.

Regardless, the following should replace what's in current screenlock:

void
top(void*)
{
	int fd, n;
	char buf[128];

	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-redraw is right here in the crashing version)
			}
	}
}

Stuart

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [9front] Re: speaking of screenlock
  2021-07-16  9:07     ` Stuart Morrow
@ 2021-07-16 10:01       ` cinap_lenrek
  2021-07-16 10:50         ` Stuart Morrow
  0 siblings, 1 reply; 6+ messages in thread
From: cinap_lenrek @ 2021-07-16 10:01 UTC (permalink / raw)
  To: 9front

this whole mousetrap and screenlock thread drives me mad.

what is WRONG with you people?

like wheres the problem statement? its alot of noise
and "design" changes without any reason or justification.
now patches being sent of apparent crashes in screenlock?
i can't even tell if this is a bug report or not...

i'll not waste my time decoding this nonsense.

i'll refuse all patches on this topic as clearly
nobody involved has their shit together.

stop this thread and go to the beach instead of
bikeshedding screenlock and devdraw.

--
cinap

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [9front] Re: speaking of screenlock
  2021-07-16 10:01       ` cinap_lenrek
@ 2021-07-16 10:50         ` Stuart Morrow
  0 siblings, 0 replies; 6+ messages in thread
From: Stuart Morrow @ 2021-07-16 10:50 UTC (permalink / raw)
  To: 9front

lol

> now patches being sent of apparent crashes in screenlock?
> i can't even tell if this is a bug report or not...

The blocking top() fixes the spamming top() (which was also introduced
by me, sorry)

It doesn't crash. An attempt to *further* fix the green border issue
crashes. And I don't really want to pursue that (end result would
*still* be a "screenlock" you can just alt-F4 out of), just understand
it.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-16 11:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-13 14:27 [9front] speaking of screenlock Stuart Morrow
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

9front - general discussion about 9front

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/9front

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 9front 9front/ http://inbox.vuxu.org/9front \
		9front@9front.org
	public-inbox-index 9front

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.9front


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git