code: drawterm

Download patch

ref: 69161a85c9a2ba11aeee2d2cfe151b12248597a0
parent: 966e3f1dfee844a76b71567bdd7f2e02155df767
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Nov 23 14:13:57 EST 2017

drawterm: implement window resize for gui-x11 and gui-win32

--- a/gui-win32/screen.c
+++ b/gui-win32/screen.c
@@ -83,6 +83,7 @@
 	dy = GetDeviceCaps(GetDC(NULL), VERTRES);
 
 	gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);
+	gscreen->clipr = ZR;
 	kproc("winscreen", winproc, 0);
 	ksleep(&rend, isready, 0);
 }
@@ -90,7 +91,7 @@
 uchar*
 attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
 {
-	*r = gscreen->r;
+	*r = gscreen->clipr;
 	*chan = gscreen->chan;
 	*depth = gscreen->depth;
 	*width = gscreen->width;
@@ -111,7 +112,6 @@
 {
 	int dx, dy, delx;
 	HDC hdc;
-	RECT winr;
 
 	if(depth != gscreen->depth)
 		panic("screenload: bad ldepth");
@@ -121,13 +121,8 @@
 	 * screen to the negative axes, for example, when
 	 * dragging around a window border in a Move operation.
 	 */
-	if(rectclip(&r, gscreen->r) == 0)
+	if(rectclip(&r, gscreen->clipr) == 0)
 		return;
-	if(GetWindowRect(window, &winr)==0)
-		return;
-	if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0)
-		return;
-
 	if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0)
 		panic("screenload: bad params %d %d %ux", step, pt.x, p);
 
@@ -344,6 +339,7 @@
 	HDC hdc;
 	LONG x, y, b;
 	int i;
+	RECT winr;
 	Rectangle r;
 	Rune k;
 
@@ -352,6 +348,7 @@
 	switch(msg) {
 	case WM_CREATE:
 		break;
+
 	case WM_SETCURSOR:
 		/* User set */
 		if(hcursor != NULL) {
@@ -444,6 +441,22 @@
 		flushmemscreen(r);
 		EndPaint(hwnd, &paint);
 		break;
+
+	case WM_SIZE:
+		if(GetClientRect(hwnd, &winr) == 0)
+			break;
+		r = Rect(0, 0, winr.right - winr.left, winr.bottom - winr.top);
+		if(rectclip(&r, gscreen->r) == 0 || badrect(r))
+			break;
+		qlock(&drawlock);
+		gscreen->clipr = r;
+		qunlock(&drawlock);
+		screenwin();
+		deletescreenimage();
+		resetscreenimage();
+		mouseresize();
+		break;
+
 	case WM_COMMAND:
 	case WM_SETFOCUS:
 	case WM_DEVMODECHANGE:
--- a/gui-x11/x11.c
+++ b/gui-x11/x11.c
@@ -120,6 +120,7 @@
 
 static	Drawable	xdrawable;
 static	void		xexpose(XEvent*);
+static	void		xresize(XEvent*);
 static	void		xmouse(XEvent*);
 static	void		xkeyboard(XEvent*);
 static	void		xmapping(XEvent*);
@@ -146,7 +147,7 @@
 	uchar *p;
 
 	assert(!canqlock(&drawlock));
-	if(r.min.x >= r.max.x || r.min.y >= r.max.y)
+	if(rectclip(&r, gscreen->clipr) == 0)
 		return;
 
 	if(xtblbit && gscreen->chan == CMAP8)
@@ -176,7 +177,7 @@
 	memimageinit();
 	terminit();
 	qlock(&drawlock);
-	flushmemscreen(gscreen->r);
+	flushmemscreen(gscreen->clipr);
 	qunlock(&drawlock);
 }
 
@@ -183,7 +184,7 @@
 uchar*
 attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
 {
-	*r = gscreen->r;
+	*r = gscreen->clipr;
 	*chan = gscreen->chan;
 	*depth = gscreen->depth;
 	*width = gscreen->width;
@@ -294,6 +295,7 @@
 		xselect(&event, xkmcon);
 		xkeyboard(&event);
 		xmouse(&event);
+		xresize(&event);
 		xexpose(&event);
 		xmapping(&event);
 		xdestroy(&event);
@@ -480,6 +482,7 @@
 
 	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);
 
 	xkmcon = XOpenDisplay(NULL);
@@ -647,6 +650,25 @@
 	xe = (XDestroyWindowEvent*)e;
 	if(xe->window == xdrawable)
 		exit(0);
+}
+
+static void
+xresize(XEvent *e)
+{
+	Rectangle r;
+
+	if(e->type != ConfigureNotify)
+		return;
+	r = Rect(0, 0, ((XConfigureEvent*)e)->width, ((XConfigureEvent*)e)->height);
+	if(rectclip(&r, gscreen->r) == 0 || badrect(r) || eqrect(r, gscreen->clipr))
+		return;
+	qlock(&drawlock);
+	gscreen->clipr = r;
+	qunlock(&drawlock);
+	screenwin();
+	deletescreenimage();
+	resetscreenimage();
+	mouseresize();
 }
 
 static void
--- a/kern/devmouse.c
+++ b/kern/devmouse.c
@@ -96,6 +96,7 @@
 	case Qmouse:
 		if(tas(&mouse.open) != 0)
 			error(Einuse);
+		mouse.resize = 0;
 		mouse.lastcounter = mouse.state.counter;
 		break;
 	}
@@ -170,6 +171,10 @@
 			m.xy.x, m.xy.y, b, m.msec);
 
 		mouse.lastcounter = m.counter;
+		if(mouse.resize){
+			mouse.resize = 0;
+			buf[0] = 'r';
+		}
 
 		if(n > 1+4*12)
 			n = 1+4*12;
@@ -304,11 +309,21 @@
 	return -1;
 }
 
+/*
+ * notify reader that screen has been resized
+ */
+void
+mouseresize(void)
+{
+	mouse.resize = 1;
+	wakeup(&mouse.r);
+}
+
 int
 mousechanged(void *a)
 {
 	USED(a);
-	return mouse.lastcounter != mouse.state.counter;
+	return mouse.lastcounter != mouse.state.counter || mouse.resize;
 }
 
 void
--- a/kern/screen.h
+++ b/kern/screen.h
@@ -14,6 +14,7 @@
 	Lock		lk;
 	Mousestate	state;
 	ulong		lastcounter;
+	int		resize;		/* generate resize event */
 	Rendez		r;
 	int		open;
 	Mousestate	queue[16];	/* circular buffer of click events */
@@ -50,11 +51,15 @@
 void	mouseset(Point);
 void	flushmemscreen(Rectangle);
 uchar*	attachscreen(Rectangle*, ulong*, int*, int*, int*);
+void	deletescreenimage(void);
+void	resetscreenimage(void);
 
 extern	QLock drawlock;
 #define	ishwimage(i)	0
 
 void	terminit(void);
+void	screenwin(void);
 
+void	mouseresize(void);
 void	mousetrack(int, int, int, ulong);
 void	absmousetrack(int, int, int, ulong);
--- a/kern/term.c
+++ b/kern/term.c
@@ -47,7 +47,7 @@
 		combinerect(&flushr, r);
 }
 
-static void
+void
 screenwin(void)
 {
 	Point p;
@@ -61,10 +61,7 @@
 	
 	h = memdefont->height;
 
-	window.min = addpt(gscreen->r.min, Pt(20,20));
-	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
-	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
-
+	window = insetrect(gscreen->clipr, 20);
 	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
 	window = insetrect(window, 4);
 	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);