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

📄 x11-itrans.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
字号:
#include "u.h"#include "lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "error.h"#define Image IMAGE	/* kernel has its own Image */#include <draw.h>#include <memdraw.h>#include <keyboard.h>#include <cursor.h>#include "mouse.h"#include "screen.h"#include "x11-inc.h"static KeySym_xkeysym(XEvent *e){	KeySym k;	if(e->xany.type != KeyPress)		return -1;//	needstack(64*1024);	/* X has some *huge* buffers in openobject */		/* and they're even bigger on SuSE */	XLookupString((XKeyEvent*)e,NULL,0,&k,NULL);	if(k == XK_Multi_key || k == NoSymbol)		return -1;	if(k&0xFF00){		switch(k){		case XK_BackSpace:		case XK_Tab:		case XK_Escape:		case XK_Delete:		case XK_KP_0:		case XK_KP_1:		case XK_KP_2:		case XK_KP_3:		case XK_KP_4:		case XK_KP_5:		case XK_KP_6:		case XK_KP_7:		case XK_KP_8:		case XK_KP_9:		case XK_KP_Divide:		case XK_KP_Multiply:		case XK_KP_Subtract:		case XK_KP_Add:		case XK_KP_Decimal:			k &= 0x7F;			break;		case XK_Linefeed:			k = '\r';			break;		case XK_KP_Space:			k = ' ';			break;		case XK_Home:		case XK_KP_Home:			k = Khome;			break;		case XK_Left:		case XK_KP_Left:			k = Kleft;			break;		case XK_Up:		case XK_KP_Up:			k = Kup;			break;		case XK_Down:		case XK_KP_Down:			k = Kdown;			break;		case XK_Right:		case XK_KP_Right:			k = Kright;			break;		case XK_Page_Down:		case XK_KP_Page_Down:			k = Kpgdown;			break;		case XK_End:		case XK_KP_End:			k = Kend;			break;		case XK_Page_Up:			case XK_KP_Page_Up:			k = Kpgup;			break;		case XK_Insert:		case XK_KP_Insert:			k = Kins;			break;		case XK_KP_Enter:		case XK_Return:			k = '\n';			break;		case XK_Alt_L:		case XK_Meta_L:	/* Shift Alt on PCs */		case XK_Alt_R:		case XK_Meta_R:	/* Shift Alt on PCs */			k = Kalt;			break;		default:		/* not ISO-1 or tty control */			if(k>0xff)				return _xkeysym2rune(k);			break;		}	}	/* Compensate for servers that call a minus a hyphen */	if(k == XK_hyphen)		k = XK_minus;	/* Do control mapping ourselves if translator doesn't */	if(e->xkey.state&ControlMask)		k &= 0x9f;	if(k == NoSymbol)		return -1;	return k;}static voidxputc(int c){	kbdputc(kbdq, c);}void_xtoplan9kbd(XEvent *e){	int r;	r = _xkeysym(e);	if(r > 0)		latin1putc(r, xputc);}int_xtoplan9mouse(XEvent *e, Mouse *m){	int s;	XButtonEvent *be;	XMotionEvent *me;	if(_x.putsnarf != _x.assertsnarf){		_x.assertsnarf = _x.putsnarf;		XSetSelectionOwner(_x.kmcon, XA_PRIMARY, _x.drawable, CurrentTime);		if(_x.clipboard != None)			XSetSelectionOwner(_x.kmcon, _x.clipboard, _x.drawable, CurrentTime);		XFlush(_x.kmcon);	}	switch(e->type){	case ButtonPress:		be = (XButtonEvent*)e;		/* 		 * Fake message, just sent to make us announce snarf.		 * Apparently state and button are 16 and 8 bits on		 * the wire, since they are truncated by the time they		 * get to us.		 */		if(be->send_event		&& (~be->state&0xFFFF)==0		&& (~be->button&0xFF)==0)			return -1;		/* BUG? on mac need to inherit these from elsewhere? */		m->xy.x = be->x;		m->xy.y = be->y;		s = be->state;		m->msec = be->time;		switch(be->button){		case 1:			s |= Button1Mask;			break;		case 2:			s |= Button2Mask;			break;		case 3:			s |= Button3Mask;			break;		case 4:			s |= Button4Mask;			break;		case 5:			s |= Button5Mask;			break;		}		break;	case ButtonRelease:		be = (XButtonEvent*)e;		m->xy.x = be->x;		m->xy.y = be->y;		s = be->state;		m->msec = be->time;		switch(be->button){		case 1:			s &= ~Button1Mask;			break;		case 2:			s &= ~Button2Mask;			break;		case 3:			s &= ~Button3Mask;			break;		case 4:			s &= ~Button4Mask;			break;		case 5:			s &= ~Button5Mask;			break;		}		break;	case MotionNotify:		me = (XMotionEvent*)e;		s = me->state;		m->xy.x = me->x;		m->xy.y = me->y;		m->msec = me->time;		break;	default:		return -1;	}	m->buttons = 0;	if(s & Button1Mask)		m->buttons |= 1;	if(s & Button2Mask)		m->buttons |= 2;	if(s & Button3Mask)		m->buttons |= 4;	if(s & Button4Mask)		m->buttons |= 8;	if(s & Button5Mask)		m->buttons |= 16;	return 0;}void_xmoveto(Point p){	XWarpPointer(_x.display, None, _x.drawable, 0, 0, 0, 0, p.x, p.y);	XFlush(_x.display);}static intrevbyte(int b){	int r;	r = 0;	r |= (b&0x01) << 7;	r |= (b&0x02) << 5;	r |= (b&0x04) << 3;	r |= (b&0x08) << 1;	r |= (b&0x10) >> 1;	r |= (b&0x20) >> 3;	r |= (b&0x40) >> 5;	r |= (b&0x80) >> 7;	return r;}static voidxcursorarrow(void){	if(_x.cursor != 0){		XFreeCursor(_x.display, _x.cursor);		_x.cursor = 0;	}	XUndefineCursor(_x.display, _x.drawable);	XFlush(_x.display);}void_xsetcursor(Cursor *c){	XColor fg, bg;	XCursor xc;	Pixmap xsrc, xmask;	int i;	uchar src[2*16], mask[2*16];	if(_x.display == nil)		return;	if(c == nil){		xcursorarrow();		return;	}	for(i=0; i<2*16; i++){		src[i] = revbyte(c->set[i]);		mask[i] = revbyte(c->set[i] | c->clr[i]);	}	fg = _x.map[0];	bg = _x.map[255];	xsrc = XCreateBitmapFromData(_x.display, _x.drawable, (char*)src, 16, 16);	xmask = XCreateBitmapFromData(_x.display, _x.drawable, (char*)mask, 16, 16);	xc = XCreatePixmapCursor(_x.display, xsrc, xmask, &fg, &bg, -c->offset.x, -c->offset.y);	if(xc != 0) {		XDefineCursor(_x.display, _x.drawable, xc);		if(_x.cursor != 0)			XFreeCursor(_x.display, _x.cursor);		_x.cursor = xc;	}	XFreePixmap(_x.display, xsrc);	XFreePixmap(_x.display, xmask);	XFlush(_x.display);}voidsetcursor(Cursor *c){	drawqlock();	_xsetcursor(c);	drawqunlock();}struct {	QLock lk;	char buf[SnarfSize];#ifdef APPLESNARF	Rune rbuf[SnarfSize];	PasteboardRef apple;#endif} clip;static uchar*_xgetsnarffrom(XWindow w, Atom clipboard, Atom target, int timeout0, int timeout){	Atom prop, type;	ulong len, lastlen, dummy;	int fmt, i;	uchar *data, *xdata;	/*	 * We should be waiting for SelectionNotify here, but it might never	 * come, and we have no way to time out.  Instead, we will clear	 * local property #1, request our buddy to fill it in for us, and poll	 * until he's done or we get tired of waiting.	 */	prop = 1;	XChangeProperty(_x.display, _x.drawable, prop, target, 8, PropModeReplace, (uchar*)"", 0);	XConvertSelection(_x.display, clipboard, target, prop, _x.drawable, CurrentTime);	XFlush(_x.display);	lastlen = 0;	timeout0 = (timeout0 + 9)/10;	timeout = (timeout + 9)/10;	for(i=0; i<timeout0 || (lastlen!=0 && i<timeout); i++){		usleep(10*1000);		XGetWindowProperty(_x.display, _x.drawable, prop, 0, 0, 0, AnyPropertyType,			&type, &fmt, &dummy, &len, &xdata);		if(lastlen == len && len > 0)			break;		lastlen = len;		XFree(xdata);	}	if(len == 0)		return nil;	/* get the property */	xdata = nil;	XGetWindowProperty(_x.display, _x.drawable, prop, 0, SnarfSize/sizeof(ulong), 0, 		AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);	if((type != target && type != XA_STRING && type != _x.utf8string) || len == 0){		if(xdata)			XFree(xdata);		return nil;	}	if(xdata){		data = (uchar*)strdup((char*)xdata);		XFree(xdata);		return data;	}	return nil;}char*_xgetsnarf(void){	uchar *data;	Atom clipboard;	XWindow w;	qlock(&clip.lk);	/*	 * Have we snarfed recently and the X server hasn't caught up?	 */	if(_x.putsnarf != _x.assertsnarf)		goto mine;	/*	 * Is there a primary selection (highlighted text in an xterm)?	 */	clipboard = XA_PRIMARY;	w = XGetSelectionOwner(_x.display, XA_PRIMARY);	if(w == _x.drawable){	mine:		data = (uchar*)strdup(clip.buf);		goto out;	}	/*	 * If not, is there a clipboard selection?	 */	if(w == None && _x.clipboard != None){		clipboard = _x.clipboard;		w = XGetSelectionOwner(_x.display, _x.clipboard);		if(w == _x.drawable)			goto mine;	}	/*	 * If not, give up.	 */	if(w == None){		data = nil;		goto out;	}			if((data = _xgetsnarffrom(w, clipboard, _x.utf8string, 10, 100)) == nil)	if((data = _xgetsnarffrom(w, clipboard, XA_STRING, 10, 100)) == nil){		/* nothing left to do */	}out:	qunlock(&clip.lk);	return (char*)data;}void__xputsnarf(char *data){	XButtonEvent e;	if(strlen(data) >= SnarfSize)		return;	qlock(&clip.lk);	strcpy(clip.buf, data);	/* leave note for mouse proc to assert selection ownership */	_x.putsnarf++;	/* send mouse a fake event so snarf is announced */	memset(&e, 0, sizeof e);	e.type = ButtonPress;	e.window = _x.drawable;	e.state = ~0;	e.button = ~0;	XSendEvent(_x.snarfcon, _x.drawable, True, ButtonPressMask, (XEvent*)&e);	XFlush(_x.snarfcon);	qunlock(&clip.lk);}int_xselect(XEvent *e){	char *name;	XEvent r;	XSelectionRequestEvent *xe;	Atom a[4];	memset(&r, 0, sizeof r);	xe = (XSelectionRequestEvent*)e;if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n",	xe->target, xe->requestor, xe->property, xe->selection);	r.xselection.property = xe->property;	if(xe->target == _x.targets){		a[0] = _x.utf8string;		a[1] = XA_STRING;		a[2] = _x.text;		a[3] = _x.compoundtext;		XChangeProperty(_x.kmcon, xe->requestor, xe->property, xe->target,			8*sizeof(a[0]), PropModeReplace, (uchar*)a, nelem(a));	}else if(xe->target == XA_STRING 	|| xe->target == _x.utf8string 	|| xe->target == _x.text 	|| xe->target == _x.compoundtext	|| ((name = XGetAtomName(_x.kmcon, xe->target)) && strcmp(name, "text/plain;charset=UTF-8") == 0)){		/* text/plain;charset=UTF-8 seems nonstandard but is used by Synergy */		/* if the target is STRING we're supposed to reply with Latin1 XXX */		qlock(&clip.lk);		XChangeProperty(_x.kmcon, xe->requestor, xe->property, xe->target,			8, PropModeReplace, (uchar*)clip.buf, strlen(clip.buf));		qunlock(&clip.lk);	}else{		if(strcmp(name, "TIMESTAMP") != 0)			fprint(2, "9vx: cannot handle selection request for '%s' (%d)\n", name, (int)xe->target);		r.xselection.property = None;	}	r.xselection.display = xe->display;	/* r.xselection.property filled above */	r.xselection.target = xe->target;	r.xselection.type = SelectionNotify;	r.xselection.requestor = xe->requestor;	r.xselection.time = xe->time;	r.xselection.send_event = True;	r.xselection.selection = xe->selection;	XSendEvent(_x.kmcon, xe->requestor, False, 0, &r);	XFlush(_x.kmcon);	return 0;}#ifdef APPLESNARFchar*_applegetsnarf(void){	char *s, *t;	CFArrayRef flavors;	CFDataRef data;	CFIndex nflavor, ndata, j;	CFStringRef type;	ItemCount nitem;	PasteboardItemID id;	PasteboardSyncFlags flags;	UInt32 i;/*	fprint(2, "applegetsnarf\n"); */	qlock(&clip.lk);	if(clip.apple == nil){		if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){			fprint(2, "apple pasteboard create failed\n");			qunlock(&clip.lk);			return nil;		}	}	flags = PasteboardSynchronize(clip.apple);	if(flags&kPasteboardClientIsOwner){		s = strdup(clip.buf);		qunlock(&clip.lk);		return s;	}	if(PasteboardGetItemCount(clip.apple, &nitem) != noErr){		fprint(2, "apple pasteboard get item count failed\n");		qunlock(&clip.lk);		return nil;	}	for(i=1; i<=nitem; i++){		if(PasteboardGetItemIdentifier(clip.apple, i, &id) != noErr)			continue;		if(PasteboardCopyItemFlavors(clip.apple, id, &flavors) != noErr)			continue;		nflavor = CFArrayGetCount(flavors);		for(j=0; j<nflavor; j++){			type = (CFStringRef)CFArrayGetValueAtIndex(flavors, j);			if(!UTTypeConformsTo(type, CFSTR("public.utf16-plain-text")))				continue;			if(PasteboardCopyItemFlavorData(clip.apple, id, type, &data) != noErr)				continue;			ndata = CFDataGetLength(data);			qunlock(&clip.lk);			s = smprint("%.*S", ndata/2, (Rune*)CFDataGetBytePtr(data));			CFRelease(flavors);			CFRelease(data);			for(t=s; *t; t++)				if(*t == '\r')					*t = '\n';			return s;		}		CFRelease(flavors);	}	qunlock(&clip.lk);	return nil;		}void_appleputsnarf(char *s){	CFDataRef cfdata;	PasteboardSyncFlags flags;/*	fprint(2, "appleputsnarf\n"); */	if(strlen(s) >= SnarfSize)		return;	qlock(&clip.lk);	strcpy(clip.buf, s);	runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s);	if(clip.apple == nil){		if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){			fprint(2, "apple pasteboard create failed\n");			qunlock(&clip.lk);			return;		}	}	if(PasteboardClear(clip.apple) != noErr){		fprint(2, "apple pasteboard clear failed\n");		qunlock(&clip.lk);		return;	}	flags = PasteboardSynchronize(clip.apple);	if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){		fprint(2, "apple pasteboard cannot assert ownership\n");		qunlock(&clip.lk);		return;	}	cfdata = CFDataCreate(kCFAllocatorDefault, 		(uchar*)clip.rbuf, runestrlen(clip.rbuf)*2);	if(cfdata == nil){		fprint(2, "apple pasteboard cfdatacreate failed\n");		qunlock(&clip.lk);		return;	}	if(PasteboardPutItemFlavor(clip.apple, (PasteboardItemID)1,		CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){		fprint(2, "apple pasteboard putitem failed\n");		CFRelease(cfdata);		qunlock(&clip.lk);		return;	}	/* CFRelease(cfdata); ??? */	qunlock(&clip.lk);}#endif	/* APPLESNARF */void_xputsnarf(char *data){#ifdef APPLESNARF	_appleputsnarf(data);#endif	__xputsnarf(data);}

⌨️ 快捷键说明

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