Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/oscreen.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <omero.h>
#include <error.h>
#include <b.h>

typedef struct Scr Scr;


enum {
	Nscr = 10,
};

struct Scr {
	char*	name;
	char*	addr;
	Panel*	g;
};

Panel*	gcol;
Scr	scr[Nscr];
int	nscr;
char*	current;
int	refresh;

Scr	adds[Nscr];
int	nadds;

void
init(int nsc, char* sc[])
{
	int	i, j;
	char*	e;
	char*	p;

	for(i = 0; i < nscr; i++){
		if (scr[i].name == nil)
			break;
		free(scr[i].name);
		free(scr[i].addr);
		scr[i].name = nil;
		scr[i].addr = nil;
	}
	if (nsc > Nscr){
		nsc = Nscr;
		fprint(2, "screen: Nscr overflow\n");
	}
	for(i=0; i<nsc; i++){
		if (e = strchr(sc[i], '='))
			*e++ = 0;
		scr[i].name = estrdup(sc[i]);
		if (e){
			scr[i].addr = estrdup(e);
			p = strstr(scr[i].addr, "mouse");
			if (p)
				strcpy(p, "11000");
		}
	}
	nscr = nsc;
	for (i = 0; i < nadds; i++){
		for(j = 0; j < nscr; j++)
			if (scr[j].name && !strcmp(scr[j].name, adds[i].name)){
				free(scr[j].addr);
				scr[j].addr = estrdup(adds[i].addr);
				break;
			}
		if (j == nscr){
			scr[nscr].name = estrdup(adds[i].name);
			scr[nscr].addr = estrdup(adds[i].addr);
			nscr++;
		}
	}
}

void
update(void)
{
	char	out[200];
	char*	sc[Nscr];
	int	nsc, n;

	n = tcmdoutput("/bin/env/terms -m", out, sizeof(out)-1);
	if (n < 0)
		return;
	out[n] = 0;
	nsc = tokenize(out, sc, nelem(sc));
	init(nsc, sc);
}

int
setscr(char *name)
{
	int fd;

	if((fd = open("/dev/mousectl", OWRITE)) < 0){
		fprint(2, "cannot open /dev/mousectl: %r");
		return -1;
	}
	fprint(fd, "call %s\n", name);
	close(fd);
	return 0;
}

int
setkbd(char *name)
{
	int fd;

	if((fd = open("/dev/kbdctl", OWRITE)) < 0){
		fprint(2, "cannot open /dev/kbdctl: %r");
		return -1;
	}
	fprint(fd, "call %s\n", name);
	close(fd);
	return 0;
}

void
updateui(void)
{
	int	i;
	char	nm[40];

	for (i = 0; i < Nscr; i++){
		if (scr[i].name){
			if (!scr[i].g){
				seprint(nm, nm+40, "label:m%d", i);
				scr[i].g = createsubpanel(gcol, nm);
			}
			if (scr[i].g == nil)
				continue;
			openpanel(scr[i].g, OWRITE|OTRUNC);
			writepanel(scr[i].g, scr[i].name, strlen(scr[i].name));
			closepanel(scr[i].g);
		} else if (scr[i].g){
			removepanel(scr[i].g);
			scr[i].g = nil;
		}
	}
}

void
click(int i)
{
	char*	ld;
	char	old;

	free(current);
	current = estrdup(scr[i].name);
	if (scr[i].addr){
		setscr(scr[i].addr);
		ld = scr[i].addr + strlen(scr[i].addr) - 1;
		old = *ld;
		*ld = old + 1;
		setkbd(scr[i].addr);
		*ld = old;
	} else
		setscr(scr[i].name);
	openpanelctl(gcol);
	panelctl(gcol, "hold");
	if (refresh)
		update();
	updateui();
	closepanelctl(gcol);
}

void
usage(void)
{
	fprint(2, "usage: %s [-a machine=addr] [machine...]\n", argv0);
	exits("usage");
}

int
omerogone(void)
{
	sysfatal("terminated");
	return 0;
}

void
threadmain(int argc, char **argv)
{
	Oev	e;
	char	dir[80];
	Channel*	c;
	int	i;
	char*	p;

	ARGBEGIN{
	case 'a':
		strecpy(dir, dir+sizeof(dir), EARGF(usage()));
		p = strchr(dir, '=');
		if (!p)
			usage();
		*p++ = 0;
		adds[nadds].name = strdup(dir);
		adds[nadds++].addr = strdup(p);
		break;
	default:
		usage();
	}ARGEND;
	if (argc != 0)
		init(argc, argv);
	else {
		update();
		refresh = 1;
	}
	current = estrdup(sysname());
	c = omeroeventchan(nil);
	gcol = createpanel("oscreen", "row",  nil);
	if (gcol == nil)
		sysfatal("createpanel: %r\n");
	updateui();
	closepanelctl(gcol);
	while(recv(c, &e) != -1){
		if (!strcmp(e.ev, "exit")){
			threadexitsall(nil);
		} else if (!strcmp(e.ev, "look") || !strcmp(e.ev, "exec")){
			for (i = 0; i < nscr; i++)
				if (e.panel == scr[i].g){
					click(i);
					break;
				}
		}
		clearoev(&e);
	}
	threadexitsall(nil);
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.