code: drawterm

Download patch

ref: 5689c790ad6e428ad640051d399f5966c995f978
parent: d68a62124bd18f9fe74efe8555ed0f00a52cd08f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Feb 1 11:33:45 EST 2019

gui-x11: implement screensize()

--- a/gui-x11/x11.c
+++ b/gui-x11/x11.c
@@ -43,7 +43,7 @@
 static int 		plan9tox11[256]; /* Values for mapping between */
 static int 		x11toplan9[256]; /* X11 and Plan 9 */
 static	GC		xgccopy;
-static	ulong	xscreenchan;
+static	ulong		xscreenchan;
 static	Drawable	xscreenid;
 static	XImage*		xscreenimage;
 static	Visual		*xvis;
@@ -125,7 +125,6 @@
 static	void		xdestroy(XEvent*);
 static	void		xselect(XEvent*, XDisplay*);
 static	void		xproc(void*);
-static	Memimage*		xinitscreen(void);
 static	void		initmap(Window);
 static	GC		creategc(Drawable);
 static	void		graphicscmap(XColor*);
@@ -138,6 +137,27 @@
 Memimage *gscreen;
 Screeninfo screen;
 
+static int
+shutup(XDisplay *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 int
+panicshutup(XDisplay *d)
+{
+	screenputs = 0;
+	panic("x error");
+	return -1;
+}
+
+
 void
 flushmemscreen(Rectangle r)
 {
@@ -167,171 +187,7 @@
 void
 screeninit(void)
 {
-	_memmkcmap();
-
-	gscreen = xinitscreen();
-	kproc("xscreen", xproc, nil);
-
-	memimageinit();
-	terminit();
-	qlock(&drawlock);
-	flushmemscreen(gscreen->clipr);
-	qunlock(&drawlock);
-}
-
-void
-screensize(Rectangle r, ulong chan)
-{
-	USED(chan);
-}
-
-Memdata*
-attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
-{
-	*r = gscreen->clipr;
-	*chan = gscreen->chan;
-	*depth = gscreen->depth;
-	*width = gscreen->width;
-	*softscreen = 1;
-
-	gscreen->data->ref++;
-	return gscreen->data;
-}
-
-static int
-revbyte(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;
-}
-
-void
-mouseset(Point xy)
-{
-	qlock(&drawlock);
-	XWarpPointer(xdisplay, None, xdrawable, 0, 0, 0, 0, xy.x, xy.y);
-	XFlush(xdisplay);
-	qunlock(&drawlock);
-}
-
-static XCursor xcursor;
-
-void
-setcursor(void)
-{
-	XCursor 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]);
-	}
-
-	qlock(&drawlock);
-	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);
-	qunlock(&drawlock);
-}
-
-void
-cursorarrow(void)
-{
-	qlock(&drawlock);
-	if(xcursor != 0){
-		XFreeCursor(xdisplay, xcursor);
-		xcursor = 0;
-	}
-	XUndefineCursor(xdisplay, xdrawable);
-	XFlush(xdisplay);
-	qunlock(&drawlock);
-}
-
-static void
-xproc(void *arg)
-{
-	ulong mask;
-	XEvent event;
-
-	mask = 	KeyPressMask|
-		KeyReleaseMask|
-		ButtonPressMask|
-		ButtonReleaseMask|
-		PointerMotionMask|
-		Button1MotionMask|
-		Button2MotionMask|
-		Button3MotionMask|
-		Button4MotionMask|
-		Button5MotionMask|
-		ExposureMask|
-		EnterWindowMask|
-		LeaveWindowMask|
-		FocusChangeMask|
-		StructureNotifyMask;
-
-	XSelectInput(xkmcon, xdrawable, mask);
-	for(;;) {
-		//XWindowEvent(xkmcon, xdrawable, mask, &event);
-		XNextEvent(xkmcon, &event);
-		xselect(&event, xkmcon);
-		xkeyboard(&event);
-		xmouse(&event);
-		xresize(&event);
-		xexpose(&event);
-		xmapping(&event);
-		xdestroy(&event);
-	}
-}
-
-static int
-shutup(XDisplay *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 int
-panicshutup(XDisplay *d)
-{
-	screenputs = 0;
-	panic("x error");
-	return -1;
-}
-
-static Memimage*
-xinitscreen(void)
-{
-	Memimage *gscreen;
-	int i, xsize, ysize;
+	int i, n;
 	char *argv[2];
 	Window rootwin;
 	Rectangle r;
@@ -344,11 +200,9 @@
 	XSizeHints normalhints;
 	XSetWindowAttributes attrs;
 	XPixmapFormatValues *pfmt;
-	int n;
 	Pixmap icon_pixmap;
 
-	xscreenid = 0;
-	xdrawable = 0;
+	memimageinit();
 
 	xdisplay = XOpenDisplay(NULL);
 	if(xdisplay == 0)
@@ -356,6 +210,23 @@
 
 	XSetErrorHandler(shutup);
 	XSetIOErrorHandler(panicshutup);
+
+	xkmcon = XOpenDisplay(NULL);
+	if(xkmcon == 0)
+		panic("XOpenDisplay: %r [DISPLAY=%s]", getenv("DISPLAY"));
+
+	XkbSetDetectableAutoRepeat(xkmcon, True, NULL);
+
+	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);
+
+	xsnarfcon = XOpenDisplay(NULL);
+	if(xsnarfcon == 0)
+		panic("XOpenDisplay: %r [DISPLAY=%s]", getenv("DISPLAY"));
+
 	rootscreennum = DefaultScreen(xdisplay);
 	rootwin = DefaultRootWindow(xdisplay);
 	
@@ -431,17 +302,14 @@
 	}
 
 	r.min = ZP;
-	r.max.x = WidthOfScreen(screen);
-	r.max.y = HeightOfScreen(screen);
-
-	xsize = Dx(r)*3/4;
-	ysize = Dy(r)*3/4;
+	r.max.x = WidthOfScreen(screen)*3/4;
+	r.max.y = HeightOfScreen(screen)*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, 
+	xdrawable = XCreateWindow(xdisplay, rootwin, 0, 0, Dx(r), Dy(r), 0, 
 		xscreendepth, InputOutput, xvis, CWBackPixel|CWBorderPixel|CWColormap, &attrs);
 
 	/* load the given bitmap data and create an X pixmap containing it. */
@@ -456,11 +324,9 @@
 	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;
+	normalhints.flags = USSize;
+	normalhints.width = Dx(r);
+	normalhints.height = Dy(r);
 	hints.flags = IconPixmapHint |InputHint|StateHint;
 	hints.input = 1;
 	hints.initial_state = NormalState;
@@ -486,27 +352,182 @@
 	XMapWindow(xdisplay, xdrawable);
 	XFlush(xdisplay);
 
-	xscreenid = XCreatePixmap(xdisplay, xdrawable, Dx(r), Dy(r), xscreendepth);
-	gscreen = xallocmemimage(r, xscreenchan, xscreenid, &xscreenimage);
-	gscreen->clipr = Rect(0,0,xsize,ysize);
-	xgccopy = creategc(xscreenid);
+	screensize(r, xscreenchan);
+	if(gscreen == nil)
+		panic("screensize failed");
 
-	xkmcon = XOpenDisplay(NULL);
-	if(xkmcon == 0)
-		panic("XOpenDisplay: %r [DISPLAY=%s]", getenv("DISPLAY"));
-	XkbSetDetectableAutoRepeat(xkmcon, True, NULL);
+	gscreen->clipr = r;
+	kproc("xscreen", xproc, nil);
 
-	xsnarfcon = XOpenDisplay(NULL);
-	if(xsnarfcon == 0)
-		panic("XOpenDisplay: %r [DISPLAY=%s]", getenv("DISPLAY"));
+	terminit();
 
-	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);
+	qlock(&drawlock);
+	flushmemscreen(gscreen->clipr);
+	qunlock(&drawlock);
+}
 
-	return gscreen;
+void
+screensize(Rectangle r, ulong chan)
+{
+	Drawable pix;
+	Memimage *mi;
+	XImage *xi;
+	GC gc;
+
+	pix = XCreatePixmap(xdisplay, xdrawable, Dx(r), Dy(r), xscreendepth);
+	if(pix == 0)
+		return;
+
+	gc = creategc(pix);
+	if(gc == NULL){
+		XFreePixmap(xdisplay, pix);
+		return;
+	}
+
+	mi = xallocmemimage(r, chan, pix, &xi);
+	if(mi == nil){
+		XFreeGC(xdisplay, xgccopy);
+		XFreePixmap(xdisplay, pix);
+		return;
+	}
+
+	if(gscreen != nil){
+		xscreenimage->data = NULL;	/* free'd by freememimage() */
+		XDestroyImage(xscreenimage);
+		freememimage(gscreen);
+
+		XFreeGC(xdisplay, xgccopy);
+		XFreePixmap(xdisplay, xscreenid);
+	}
+
+	xscreenimage = xi;
+	xscreenid = pix;
+	xgccopy = gc;
+
+	gscreen = mi;
+	gscreen->clipr = ZR;
+}
+
+Memdata*
+attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
+{
+	*r = gscreen->clipr;
+	*chan = gscreen->chan;
+	*depth = gscreen->depth;
+	*width = gscreen->width;
+	*softscreen = 1;
+
+	gscreen->data->ref++;
+	return gscreen->data;
+}
+
+static int
+revbyte(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;
+}
+
+void
+mouseset(Point xy)
+{
+	qlock(&drawlock);
+	XWarpPointer(xdisplay, None, xdrawable, 0, 0, 0, 0, xy.x, xy.y);
+	XFlush(xdisplay);
+	qunlock(&drawlock);
+}
+
+static XCursor xcursor;
+
+void
+setcursor(void)
+{
+	XCursor 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]);
+	}
+
+	qlock(&drawlock);
+	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);
+	qunlock(&drawlock);
+}
+
+void
+cursorarrow(void)
+{
+	qlock(&drawlock);
+	if(xcursor != 0){
+		XFreeCursor(xdisplay, xcursor);
+		xcursor = 0;
+	}
+	XUndefineCursor(xdisplay, xdrawable);
+	XFlush(xdisplay);
+	qunlock(&drawlock);
+}
+
+static void
+xproc(void *arg)
+{
+	ulong mask;
+	XEvent event;
+
+	mask = 	KeyPressMask|
+		KeyReleaseMask|
+		ButtonPressMask|
+		ButtonReleaseMask|
+		PointerMotionMask|
+		Button1MotionMask|
+		Button2MotionMask|
+		Button3MotionMask|
+		Button4MotionMask|
+		Button5MotionMask|
+		ExposureMask|
+		EnterWindowMask|
+		LeaveWindowMask|
+		FocusChangeMask|
+		StructureNotifyMask;
+
+	XSelectInput(xkmcon, xdrawable, mask);
+	for(;;) {
+		//XWindowEvent(xkmcon, xdrawable, mask, &event);
+		XNextEvent(xkmcon, &event);
+		xselect(&event, xkmcon);
+		xkeyboard(&event);
+		xmouse(&event);
+		xresize(&event);
+		xexpose(&event);
+		xmapping(&event);
+		xdestroy(&event);
+	}
 }
 
 static void