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

📄 screen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <stdio.h>#include <X11/Xlib.h>#include <X11/Xatom.h>#include <X11/Xutil.h>#include <X11/keysym.h>#include "keysym2ucs.h"/* * alias defs for image types to overcome name conflicts */#define	Point	IPoint#define	Rectangle	IRectangle#define	Display	IDisplay#define	Font	IFont#define	Screen	IScreen#include	"u.h"#include	"lib.h"#include	"dat.h"#include	"fns.h"#include	"user.h"#include	"draw.h"#include	"memdraw.h"#include	"keyboard.h"#include	"screen.h"#undef time#undef Point#undef Rectangle#undef Display#undef Font#undef Screentypedef struct ICursor ICursor;struct ICursor{	int	w;	int	h;	int	hotx;	int	hoty;	char	*src;	char	*mask;};#define ABS(x) ((x) < 0 ? -(x) : (x))enum{	DblTime	= 300		/* double click time in msec */};XColor			map[256];	/* Plan 9 colormap array */XColor			map7[128];	/* Plan 9 colormap array */uchar			map7to8[128][2];Colormap		xcmap;		/* Default shared colormap  */int 			plan9tox11[256]; /* Values for mapping between */int 			x11toplan9[256]; /* X11 and Plan 9 */int				x24bitswap = 0;	/* swap endian for 24bit RGB */int				xtblbit;extern int mousequeue;/* for copy/paste, lifted from plan9ports */Atom clipboard; Atom utf8string;Atom targets;Atom text;Atom compoundtext;static	Drawable	xdrawable;/* static	Atom		wm_take_focus; */static	void		xexpose(XEvent*);static	void		xmouse(XEvent*);static	void		xkeyboard(XEvent*);static	void		xmapping(XEvent*);static	void		xdestroy(XEvent*);static	void		xselect(XEvent*, Display*);static	void		xproc(void*);static	Memimage*		xinitscreen(void);static	void		initmap(Window);static	GC		creategc(Drawable);static	void		graphicscmap(XColor*);	int		xscreendepth;	Drawable	xscreenid;	Display*	xdisplay;	/* used holding draw lock */	Display*	xkmcon;	/* used only in xproc */	Display*	xsnarfcon;	/* used holding clip.lk */	Visual		*xvis;	GC		xgcfill, xgccopy, xgcsimplesrc, xgczero, xgcreplsrc;	GC		xgcfill0, xgccopy0, xgcsimplesrc0, xgczero0, xgcreplsrc0;	ulong		xblack;	ulong		xwhite;	ulong	xscreenchan;static int putsnarf, assertsnarf;extern Memimage* xallocmemimage(IRectangle, ulong, int);Memimage *gscreen;Screeninfo screen;XImage *ximage;voidscreeninit(void){	_memmkcmap();	gscreen = xinitscreen();	kproc("xscreen", xproc, nil);	memimageinit();	terminit();	drawqlock();	flushmemscreen(gscreen->r);	drawqunlock();}uchar*attachscreen(IRectangle *r, ulong *chan, int *depth,	int *width, int *softscreen, void **X){	*r = gscreen->r;	*chan = gscreen->chan;	*depth = gscreen->depth;	*width = gscreen->width;	*X = gscreen->X;	*softscreen = 1;	return gscreen->data->bdata;}voidflushmemscreen(IRectangle r){	assert(!drawcanqlock());	if(r.min.x >= r.max.x || r.min.y >= r.max.y)		return;	XCopyArea(xdisplay, xscreenid, xdrawable, xgccopy, r.min.x, r.min.y, Dx(r), Dy(r), r.min.x, r.min.y);	XFlush(xdisplay);}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;}voidmouseset(IPoint xy){	drawqlock();	XWarpPointer(xdisplay, None, xdrawable, 0, 0, 0, 0, xy.x, xy.y);	XFlush(xdisplay);	drawqunlock();}static Cursor xcursor;voidsetcursor(void){	Cursor xc;	XColor fg, bg;	Pixmap xsrc, xmask;	int i;	uchar src[2*16], mask[2*16];	for(i=0; i<2*16; i++){		src[i] = revbyte(cursor.set[i]);		mask[i] = revbyte(cursor.set[i] | cursor.clr[i]);	}	drawqlock();	fg = map[0];	bg = map[255];	xsrc = XCreateBitmapFromData(xdisplay, xdrawable, (char*)src, 16, 16);	xmask = XCreateBitmapFromData(xdisplay, xdrawable, (char*)mask, 16, 16);	xc = XCreatePixmapCursor(xdisplay, xsrc, xmask, &fg, &bg, -cursor.offset.x, -cursor.offset.y);	if(xc != 0) {		XDefineCursor(xdisplay, xdrawable, xc);		if(xcursor != 0)			XFreeCursor(xdisplay, xcursor);		xcursor = xc;	}	XFreePixmap(xdisplay, xsrc);	XFreePixmap(xdisplay, xmask);	XFlush(xdisplay);	drawqunlock();}voidcursorarrow(void){	drawqlock();	if(xcursor != 0){		XFreeCursor(xdisplay, xcursor);		xcursor = 0;	}	XUndefineCursor(xdisplay, xdrawable);	XFlush(xdisplay);	drawqunlock();}static voidxproc(void *arg){	ulong mask;	XEvent event;	mask = 	KeyPressMask|		ButtonPressMask|		ButtonReleaseMask|		PointerMotionMask|		Button1MotionMask|		Button2MotionMask|		Button3MotionMask|		Button4MotionMask|		Button5MotionMask|		ExposureMask|		StructureNotifyMask;	XSelectInput(xkmcon, xdrawable, mask);	for(;;) {		//XWindowEvent(xkmcon, xdrawable, mask, &event);		XNextEvent(xkmcon, &event);		xselect(&event, xkmcon);		xkeyboard(&event);		xmouse(&event);		xexpose(&event);		xmapping(&event);		xdestroy(&event);	}}static intshutup(Display *d, XErrorEvent *e){	char buf[200];	iprint("X error: error code=%d, request_code=%d, minor=%d\n", e->error_code, e->request_code, e->minor_code);	XGetErrorText(d, e->error_code, buf, sizeof(buf));	iprint("%s\n", buf);	USED(d);	USED(e);	return 0;}static intpanicshutup(Display *d){	panic("x error");	return -1;}static Memimage*xinitscreen(void){	Memimage *gscreen;	int i, xsize, ysize, pmid;	char *argv[2];	char *disp_val;	Window rootwin;	IRectangle r;	XWMHints hints;	Screen *screen;	XVisualInfo xvi;	int rootscreennum;	XTextProperty name;	XClassHint classhints;	XSizeHints normalhints;	XSetWindowAttributes attrs;	XPixmapFormatValues *pfmt;	int n; 	xscreenid = 0;	xdrawable = 0;	xdisplay = XOpenDisplay(NULL);	if(xdisplay == 0){		disp_val = getenv("DISPLAY");		if(disp_val == 0)			disp_val = "not set";		iprint("drawterm: open %r, DISPLAY is %s\n", disp_val);		exit(0);	}	XSetErrorHandler(shutup);	XSetIOErrorHandler(panicshutup);	rootscreennum = DefaultScreen(xdisplay);	rootwin = DefaultRootWindow(xdisplay);		xscreendepth = DefaultDepth(xdisplay, rootscreennum);	if(XMatchVisualInfo(xdisplay, rootscreennum, 16, TrueColor, &xvi)	|| XMatchVisualInfo(xdisplay, rootscreennum, 16, DirectColor, &xvi)){		xvis = xvi.visual;		xscreendepth = 16;		xtblbit = 1;	}	else if(XMatchVisualInfo(xdisplay, rootscreennum, 24, TrueColor, &xvi)	|| XMatchVisualInfo(xdisplay, rootscreennum, 24, DirectColor, &xvi)){		xvis = xvi.visual;		xscreendepth = 24;		xtblbit = 1;	}	else if(XMatchVisualInfo(xdisplay, rootscreennum, 8, PseudoColor, &xvi)	|| XMatchVisualInfo(xdisplay, rootscreennum, 8, StaticColor, &xvi)){		if(xscreendepth > 8)			panic("drawterm: can't deal with colormapped depth %d screens\n", xscreendepth);		xvis = xvi.visual;		xscreendepth = 8;	}	else{		if(xscreendepth != 8)			panic("drawterm: can't deal with depth %d screens\n", xscreendepth);		xvis = DefaultVisual(xdisplay, rootscreennum);	}	/*	 * xscreendepth is only the number of significant pixel bits,	 * not the total.  We need to walk the display list to find	 * how many actual bits are being used per pixel.	 */	xscreenchan = 0; /* not a valid channel */	pfmt = XListPixmapFormats(xdisplay, &n);	for(i=0; i<n; i++){		if(pfmt[i].depth == xscreendepth){			switch(pfmt[i].bits_per_pixel){			case 1:	/* untested */				xscreenchan = GREY1;				break;			case 2:	/* untested */				xscreenchan = GREY2;				break;			case 4:	/* untested */				xscreenchan = GREY4;				break;			case 8:				xscreenchan = CMAP8;				break;			case 16: /* uses 16 rather than 15, empirically. */				xscreenchan = RGB16;				break;			case 24: /* untested (impossible?) */				xscreenchan = RGB24;				break;			case 32:				xscreenchan = CHAN4(CIgnore, 8, CRed, 8, CGreen, 8, CBlue, 8);				break;			}		}	}	if(xscreenchan == 0)		panic("drawterm: unknown screen pixel format\n");			screen = DefaultScreenOfDisplay(xdisplay);	xcmap = DefaultColormapOfScreen(screen);	if(xvis->class != StaticColor){		graphicscmap(map);		initmap(rootwin);	}	r.min = ZP;	r.max.x = WidthOfScreen(screen);	r.max.y = HeightOfScreen(screen);		xsize = Dx(r)*3/4;	ysize = Dy(r)*3/4;		attrs.colormap = xcmap;	attrs.background_pixel = 0;	attrs.border_pixel = 0;	/* attrs.override_redirect = 1;*/ /* WM leave me alone! |CWOverrideRedirect */	xdrawable = XCreateWindow(xdisplay, rootwin, 0, 0, xsize, ysize, 0, 		xscreendepth, InputOutput, xvis, CWBackPixel|CWBorderPixel|CWColormap, &attrs);	/*	 * set up property as required by ICCCM	 */	name.value = (uchar*)"drawterm";	name.encoding = XA_STRING;	name.format = 8;	name.nitems = strlen((char*)name.value);	normalhints.flags = USSize|PMaxSize;	normalhints.max_width = Dx(r);	normalhints.max_height = Dy(r);	normalhints.width = xsize;	normalhints.height = ysize;	hints.flags = InputHint|StateHint;	hints.input = 1;	hints.initial_state = NormalState;	classhints.res_name = "drawterm";	classhints.res_class = "Drawterm";	argv[0] = "drawterm";	argv[1] = nil;	XSetWMProperties(xdisplay, xdrawable,		&name,			/* XA_WM_NAME property for ICCCM */		&name,			/* XA_WM_ICON_NAME */		argv,			/* XA_WM_COMMAND */		1,			/* argc */		&normalhints,		/* XA_WM_NORMAL_HINTS */		&hints,			/* XA_WM_HINTS */		&classhints);		/* XA_WM_CLASS */	XFlush(xdisplay);		/*	 * put the window on the screen	 */	XMapWindow(xdisplay, xdrawable);	XFlush(xdisplay);	xscreenid = XCreatePixmap(xdisplay, xdrawable, Dx(r), Dy(r), xscreendepth);	gscreen = xallocmemimage(r, xscreenchan, xscreenid);		xgcfill = creategc(xscreenid);	XSetFillStyle(xdisplay, xgcfill, FillSolid);	xgccopy = creategc(xscreenid);	xgcsimplesrc = creategc(xscreenid);	XSetFillStyle(xdisplay, xgcsimplesrc, FillStippled);	xgczero = creategc(xscreenid);	xgcreplsrc = creategc(xscreenid);	XSetFillStyle(xdisplay, xgcreplsrc, FillTiled);	pmid = XCreatePixmap(xdisplay, xdrawable, 1, 1, 1);	xgcfill0 = creategc(pmid);	XSetForeground(xdisplay, xgcfill0, 0);	XSetFillStyle(xdisplay, xgcfill0, FillSolid);	xgccopy0 = creategc(pmid);	xgcsimplesrc0 = creategc(pmid);	XSetFillStyle(xdisplay, xgcsimplesrc0, FillStippled);	xgczero0 = creategc(pmid);	xgcreplsrc0 = creategc(pmid);	XSetFillStyle(xdisplay, xgcreplsrc0, FillTiled);	XFreePixmap(xdisplay, pmid);	XSetForeground(xdisplay, xgccopy, plan9tox11[0]);	XFillRectangle(xdisplay, xscreenid, xgccopy, 0, 0, xsize, ysize);	xkmcon = XOpenDisplay(NULL);	if(xkmcon == 0){		disp_val = getenv("DISPLAY");		if(disp_val == 0)			disp_val = "not set";		iprint("drawterm: open %r, DISPLAY is %s\n", disp_val);		exit(0);	}	xsnarfcon = XOpenDisplay(NULL);	if(xsnarfcon == 0){		disp_val = getenv("DISPLAY");		if(disp_val == 0)			disp_val = "not set";		iprint("drawterm: open %r, DISPLAY is %s\n", disp_val);		exit(0);	}	clipboard = XInternAtom(xkmcon, "CLIPBOARD", False);	utf8string = XInternAtom(xkmcon, "UTF8_STRING", False);	targets = XInternAtom(xkmcon, "TARGETS", False);	text = XInternAtom(xkmcon, "TEXT", False);	compoundtext = XInternAtom(xkmcon, "COMPOUND_TEXT", False);	xblack = screen->black_pixel;	xwhite = screen->white_pixel;	return gscreen;}static voidgraphicscmap(XColor *map){	int r, g, b, cr, cg, cb, v, num, den, idx, v7, idx7;	for(r=0; r!=4; r++) {		for(g = 0; g != 4; g++) {			for(b = 0; b!=4; b++) {				for(v = 0; v!=4; v++) {					den=r;					if(g > den)						den=g;					if(b > den)						den=b;					/* divide check -- pick grey shades */					if(den==0)						cr=cg=cb=v*17;					else {						num=17*(4*den+v);						cr=r*num/den;						cg=g*num/den;						cb=b*num/den;					}					idx = r*64 + v*16 + ((g*4 + b + v - r) & 15);					map[idx].red = cr*0x0101;					map[idx].green = cg*0x0101;					map[idx].blue = cb*0x0101;					map[idx].pixel = idx;					map[idx].flags = DoRed|DoGreen|DoBlue;					v7 = v >> 1;					idx7 = r*32 + v7*16 + g*4 + b;					if((v & 1) == v7){						map7to8[idx7][0] = idx;						if(den == 0) { 		/* divide check -- pick grey shades */							cr = ((255.0/7.0)*v7)+0.5;							cg = cr;							cb = cr;						}						else {							num=17*15*(4*den+v7*2)/14;							cr=r*num/den;							cg=g*num/den;							cb=b*num/den;						}						map7[idx7].red = cr*0x0101;						map7[idx7].green = cg*0x0101;						map7[idx7].blue = cb*0x0101;						map7[idx7].pixel = idx7;						map7[idx7].flags = DoRed|DoGreen|DoBlue;					}					else						map7to8[idx7][1] = idx;				}			}		}	}}/* * Initialize and install the drawterm colormap as a private colormap for this * application.  Drawterm gets the best colors here when it has the cursor focus. */  static void initmap(Window w){	XColor c;	int i;	ulong p, pp;	char buf[30];	if(xscreendepth <= 1)		return;	if(xscreendepth >= 24) {		/* The pixel value returned from XGetPixel needs to		 * be converted to RGB so we can call rgb2cmap()		 * to translate between 24 bit X and our color. Unfortunately,		 * the return value appears to be display server endian 		 * dependant. Therefore, we run some heuristics to later		 * determine how to mask the int value correctly.		 * Yeah, I know we can look at xvis->byte_order but 		 * some displays say MSB even though they run on LSB.		 * Besides, this is more anal.		 */		if(xscreendepth != DefaultDepth(xdisplay, DefaultScreen(xdisplay)))			xcmap = XCreateColormap(xdisplay, w, xvis, AllocNone);		c = map[19];		/* find out index into colormap for our RGB */		if(!XAllocColor(xdisplay, xcmap, &c))			panic("drawterm: screen-x11 can't alloc color");		p  = c.pixel;		pp = rgb2cmap((p>>16)&0xff,(p>>8)&0xff,p&0xff);		if(pp!=map[19].pixel) {			/* check if endian is other way */			pp = rgb2cmap(p&0xff,(p>>8)&0xff,(p>>16)&0xff);			if(pp!=map[19].pixel)				panic("cannot detect x server byte order");			switch(xscreenchan){			case RGB24:

⌨️ 快捷键说明

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