⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fgui.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "dat.h"#include <draw.h>#include <mouse.h>#include <keyboard.h>#include <control.h>int ctldeletequits = 1;typedef struct RequestType RequestType;typedef struct Request Request;typedef struct Memory Memory;struct RequestType{	char		*file;			/* file to read requests from */	void		(*f)(Request*);		/* request handler */	void		(*r)(Controlset*);	/* resize handler */	int		fd;			/* fd = open(file, ORDWR) */	Channel		*rc;			/* channel requests are multiplexed to */	Controlset	*cs;};struct Request{	RequestType	*rt;	Attr		*a;	Attr		*tag;};struct Memory{	Memory	*next;	Attr	*a;	Attr	*val;};Memory *mem;static void	readreq(void*);static void	hide(void);static void	unhide(void);static void	openkmr(void);static void	closekmr(void);static Memory*	searchmem(Attr*);static void	addmem(Attr*, Attr*);static void	confirm(Request*);static void	resizeconfirm(Controlset*);static void	needkey(Request*);static void	resizeneedkey(Controlset*);Control *b_remember;Control *b_accept;Control *b_refuse;RequestType rt[] = {	{ "/mnt/factotum/confirm",	confirm,	resizeconfirm, },	{ "/mnt/factotum/needkey",	needkey,	resizeneedkey, },	{ 0 },};enum{	ButtonDim=	15,};voidthreadmain(int argc, char *argv[]){	Request r;	Channel *rc;	RequestType *p;	Font *invis;		ARGBEGIN{	}ARGEND;	if(newwindow("-hide") < 0)		sysfatal("newwindow: %r");	fmtinstall('A', _attrfmt);	/* create the proc's that read */	rc = chancreate(sizeof(Request), 0);	for(p = rt;  p->file != 0; p++){		p->fd = -1;		p->rc = rc;		proccreate(readreq, p, 16*1024);	}	/* gui initialization */	initdraw(0, 0, "auth/fgui");	initcontrols();	hide();	/* get an invisible font for passwords */	invis = openfont(display, "/lib/font/bit/lucm/passwd.9.font");	if (invis == nil)		sysfatal("fgui: %s: %r", "/lib/font/bit/lucm/passwd.9.font");	namectlfont(invis, "invisible");	/* serialize all requests */	for(;;){		if(recv(rc, &r) < 0)			break;		(*r.rt->f)(&r);		_freeattr(r.a);		_freeattr(r.tag);	}	threadexitsall(nil);}/* *  read requests and pass them to the main loop */enum{	Requestlen=4096,};static voidreadreq(void *a){	RequestType *rt = a;	char *buf, *p;	int n;	Request r;	Attr **l;	rt->fd = open(rt->file, ORDWR);	if(rt->fd < 0)		sysfatal("opening %s: %r", rt->file);	rt->cs = nil;	buf = malloc(Requestlen);	if(buf == nil)		sysfatal("allocating read buffer: %r");	r.rt = rt;	for(;;){		n = read(rt->fd, buf, Requestlen-1);		if(n < 0)			break;		buf[n] = 0;		/* skip verb, parse attributes, and remove tag */		p = strchr(buf, ' ');		if(p != nil)			p++;		else			p = buf;		r.a = _parseattr(p);		/* separate out the tag */		r.tag = nil;		for(l = &r.a; *l != nil; l = &(*l)->next)			if(strcmp((*l)->name, "tag") == 0){				r.tag = *l;				*l = r.tag->next;				r.tag->next = nil;				break;			}		/* if no tag, forget it */		if(r.tag == nil){			_freeattr(r.a);			continue;		}		send(rt->rc, &r);	}}#ifdef asdfstatic voidreadreq(void *a){	RequestType *rt = a;	char *buf, *p;	int n;	Request r;	rt->fd = -1;	rt->cs = nil;	buf = malloc(Requestlen);	if(buf == nil)		sysfatal("allocating read buffer: %r");	r.rt = rt;	for(;;){		strcpy(buf, "adfasdf=afdasdf asdfasdf=asdfasdf");		r.a = _parseattr(buf);		send(rt->rc, &r);		sleep(5000);	}}#endif asdf/* *  open/close the keyboard, mouse and resize channels */static Channel *kbdc;static Channel *mousec;static Channel *resizec;static Keyboardctl *kctl;static Mousectl *mctl;static voidopenkmr(void){	/* get channels for subsequent newcontrolset calls  */	kctl = initkeyboard(nil);	if(kctl == nil)		sysfatal("can't initialize keyboard: %r");	kbdc = kctl->c;	mctl = initmouse(nil, screen);	if(mctl == nil)		sysfatal("can't initialize mouse: %r");	mousec = mctl->c;	resizec = mctl->resizec;}static voidclosekmr(void){	Mouse m;	while(nbrecv(kbdc, &m) > 0)		;	closekeyboard(kctl);	while(nbrecv(mousec, &m) > 0)		;	closemouse(mctl);}/* *  called when the window is resized */voidresizecontrolset(Controlset *cs){	RequestType *p;	for(p = rt;  p->file != 0; p++){		if(p->cs == cs){			(*p->r)(cs);			break;		}	}}/* *  hide window when not in use */static voidunhide(void){	int wctl;	wctl = open("/dev/wctl", OWRITE);	if(wctl < 0)		return;	fprint(wctl, "unhide");	close(wctl);}static voidhide(void){	int wctl;	int tries;	wctl = open("/dev/wctl", OWRITE);	if(wctl < 0)		return;	for(tries = 0; tries < 10; tries++){		if(fprint(wctl, "hide") >= 0)			break;		sleep(100);	}	close(wctl);}/* *  set up the controls for the confirmation window */static Channel*setupconfirm(Request *r){	Controlset *cs;	Channel *c;	Attr *a;	/* create a new control set for the confirmation */	openkmr();	cs = newcontrolset(screen, kbdc, mousec, resizec);	createtext(cs, "msg");	chanprint(cs->ctl, "msg image paleyellow");	chanprint(cs->ctl, "msg border 1");	chanprint(cs->ctl, "msg add 'The following key is being used:'");	for(a = r->a; a != nil; a = a->next)		chanprint(cs->ctl, "msg add '    %s = %s'", a->name,				a->val);	namectlimage(display->white, "i_white");	namectlimage(display->black, "i_black");	b_remember = createbutton(cs, "b_remember");	chanprint(cs->ctl, "b_remember border 1");	chanprint(cs->ctl, "b_remember mask i_white");	chanprint(cs->ctl, "b_remember image i_white");	chanprint(cs->ctl, "b_remember light i_black");	createtext(cs, "t_remember");	chanprint(cs->ctl, "t_remember image white");	chanprint(cs->ctl, "t_remember bordercolor white");	chanprint(cs->ctl, "t_remember add 'Remember this answer for future confirmations'");	b_accept = createtextbutton(cs, "b_accept");	chanprint(cs->ctl, "b_accept border 1");	chanprint(cs->ctl, "b_accept align center");	chanprint(cs->ctl, "b_accept text Accept");	chanprint(cs->ctl, "b_accept image i_white");	chanprint(cs->ctl, "b_accept light i_black");	b_refuse = createtextbutton(cs, "b_refuse");	chanprint(cs->ctl, "b_refuse border 1");	chanprint(cs->ctl, "b_refuse align center");	chanprint(cs->ctl, "b_refuse text Refuse");	chanprint(cs->ctl, "b_refuse image i_white");	chanprint(cs->ctl, "b_refuse light i_black");	c = chancreate(sizeof(char*), 0);	controlwire(b_remember, "event", c);	controlwire(b_accept, "event", c);	controlwire(b_refuse, "event", c);	/* make the controls interactive */	activate(b_remember);	activate(b_accept);	activate(b_refuse);	r->rt->cs = cs;	unhide();	resizecontrolset(cs);	return c;}/* *  resize the controls for the confirmation window */static voidresizeconfirm(Controlset *cs){	Rectangle r, mr, nr, ntr, ar, rr;	int fontwidth;	fontwidth = font->height;	/* get usable window rectangle */	if(getwindow(display, Refnone) < 0)		ctlerror("resize failed: %r");	r = insetrect(screen->r, 10);	/* message box fills everything not needed for buttons */	mr = r;	mr.max.y = mr.min.y + font->height*((Dy(mr)-3*ButtonDim-font->height-4)/font->height);	/* remember button */	nr.min = Pt(mr.min.x, mr.max.y+ButtonDim);	nr.max = Pt(mr.max.x, r.max.y);	if(Dx(nr) > ButtonDim)		nr.max.x = nr.min.x+ButtonDim;	if(Dy(nr) > ButtonDim)		nr.max.y = nr.min.y+ButtonDim;	ntr.min = Pt(nr.max.x+ButtonDim, nr.min.y);	ntr.max = Pt(r.max.x, nr.min.y+font->height);	/* accept/refuse buttons */	ar.min = Pt(r.min.x+Dx(r)/2-ButtonDim-6*fontwidth, nr.max.y+ButtonDim);	ar.max = Pt(ar.min.x+6*fontwidth, ar.min.y+font->height+4);	rr.min = Pt(r.min.x+Dx(r)/2+ButtonDim, nr.max.y+ButtonDim);	rr.max = Pt(rr.min.x+6*fontwidth, rr.min.y+font->height+4);	/* make the controls visible */	chanprint(cs->ctl, "msg rect %R\nmsg show", mr);	chanprint(cs->ctl, "b_remember rect %R\nb_remember show", nr);	chanprint(cs->ctl, "t_remember rect %R\nt_remember show", ntr);	chanprint(cs->ctl, "b_accept rect %R\nb_accept show", ar);	chanprint(cs->ctl, "b_refuse rect %R\nb_refuse show", rr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -