Yaroslav Kolomiietsgroup draw.h code togetherc0bcff610 years agoHistory
216 lines · 3.6 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <keyboard.h>#include <mouse.h>#include <cursor.h>#include <auth.h>#include "dat.h"#include "fns.h" #define	STACK	8192 Rdp conn = {	.fd = -1,	.depth = 16,	.windom = "",	.passwd = "",	.shell = "",	.rwd = "",};Mousectl		*mousectl;Keyboardctl	*keyboardctl; char Eshort[]=	"short data";char Esmall[]=	"buffer too small";char Ebignum[]=	"number too big"; void	sendmouse(Rdp* c, Mouse m); static void	keyboardthread(void*);static void	mousethread(void*);static void	snarfthread(void*); static voidusage(void){	fprint(2, "usage: rd [-0A] [-T title] [-a depth] [-c wdir] [-d dom] [-k keyspec] [-n term] [-s shell] [net!]server[!port]\n");	threadexitsall("usage");} voidthreadmain(int argc, char *argv[]){	int doauth;	char *server, *addr, *keyspec;	UserPasswd *creds;	Rdp* c; 	c = &conn;	keyspec = "";	doauth = 1; 	ARGBEGIN{	case 'A':		doauth = 0;		break;	case 'k':		keyspec = EARGF(usage());		break;	case 'T':		c->label = strdup(EARGF(usage()));		break;	case 'd':		c->windom = strdup(EARGF(usage()));		break;	case 's':		c->shell = strdup(EARGF(usage()));		break;	case 'c':		c->rwd = strdup(EARGF(usage()));		break;	case 'a':		c->depth = atol(EARGF(usage()));		break;	case '0':		c->wantconsole = 1;		break;	default:		usage();	}ARGEND 	if (argc != 1)		usage(); 	server = argv[0]; 	c->local = getenv("sysname");	c->user = getenv("user");	if(c->local == nil)		sysfatal("set $sysname\n");	if(c->user == nil)		sysfatal("set $user");	if(doauth){		creds = auth_getuserpasswd(auth_getkey, "proto=pass service=rdp %s", keyspec);		if(creds == nil)			fprint(2, "factotum: %r\n");		else {			c->user = creds->user;			c->passwd = creds->passwd;		}	}else		c->user = "";	if(c->label == nil)		c->label = smprint("rd %s", server); 	initvc(c); 	addr = netmkaddr(server, "tcp", "3389");	c->fd = dial(addr, nil, nil, nil);	if(c->fd < 0)		sysfatal("dial %s: %r", addr);	if(x224handshake(c) < 0)		sysfatal("X.224 handshake: %r");	initscreen(c);	if(rdphandshake(c) < 0)		sysfatal("handshake: %r"); 	mousectl = initmouse(nil, screen);	if(mousectl == nil){		fprint(2, "rd: can't initialize mouse: %r\n");		threadexitsall("mouse");	}	keyboardctl = initkeyboard(nil);	if(keyboardctl == nil){		fprint(2, "rd: can't initialize keyboard: %r\n");		threadexitsall("keyboard");	} 	proccreate(keyboardthread, c, STACK);	proccreate(mousethread, c, STACK);	proccreate(snarfthread, c, STACK); 	threadsetname("mainthread");	readnet(c); 	x224hangup(c);	if(!c->active)		threadexitsall(nil);	if(c->hupreason)		sysfatal("disconnect reason code %d", c->hupreason);	sysfatal("hangup");} static voidkeyboardthread(void* v){	Rune r;	Rdp* c; 	c = v;	threadsetname("keyboardthread");	for(;;){		recv(keyboardctl->c, &r);		sendkbd(c, r);	}} static voidmousethread(void* v){	Rdp* c;	enum { MResize, MMouse, NMALT };	static Alt alts[NMALT+1];	Mouse m; 	c = v;	threadsetname("mousethread");	alts[MResize].c = mousectl->resizec;	alts[MResize].v = nil;	alts[MResize].op = CHANRCV;	alts[MMouse].c = mousectl->c;	alts[MMouse].v = &m;	alts[MMouse].op = CHANRCV; 	for(;;){		switch(alt(alts)){		case MResize:			eresized(c, 1);			break;		case MMouse:			sendmouse(c, m);			break;		}	}} voidwarpmouse(int x, int y){	moveto(mousectl, Pt(x, y));} static voidsnarfthread(void* v){	Rdp* c; 	c = v;	threadsetname("snarfthread");	initsnarf();	pollsnarf(c);	threadexits("snarf eof");} voidreadnet(Rdp* c){	Msg r; 	for(;;){		if(readmsg(c, &r) <= 0)			break;		apply(c, &r);	}}