code: drawterm

Download patch

ref: 395d4c927521243b6ea05acfb46abfd2f2f6a6ad
parent: 1c709767b27d295d7df975a3e441191a4c8fcba1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Jan 29 18:41:52 EST 2019

screen: add screensize() function to reallocate the gscreen

previously, we where allocating the gscreen once with the
maximum screen size as its dimensions and then adjust
gscreen->clipr for the window size.

this is simple, but doesnt play well with multi-monitor
systems where there is no maximum screen size.
so instead, we reallocate the gscreen image to the actual
window size using the new screensize() function.

screensize() can be a no-op (x11), then gscreen->clipr
is adjusted just as before.

when screensize() reallocated the screen, then it should
set gscreen->clipr to the zero rect.

--- a/gui-cocoa/screen.m
+++ b/gui-cocoa/screen.m
@@ -35,15 +35,25 @@
 void
 screeninit(void)
 {
-	NSRect r;
-
 	memimageinit();
-	r = [[NSScreen mainScreen] frame];
-	gscreen = allocmemimage(Rect(0, 0, r.size.width, r.size.height), ABGR32);
+	screensize(Rect(0, 0, winsize.width, winsize.height), ABGR32);
 	gscreen->clipr = Rect(0, 0, winsize.width, winsize.height);
 	terminit();
 }
 
+void
+screensize(Rectangle r, ulong chan)
+{
+	Memimage *i;
+
+	if((i = allocmemimage(r, chan)) == nil)
+		return;
+	if(gscreen != nil)
+		freememimage(gscreen);
+	gscreen = i;
+	gscreen->clipr = ZR;
+}
+
 uchar *
 attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
 {
@@ -51,7 +61,10 @@
 	*chan = gscreen->chan;
 	*depth = gscreen->depth;
 	*width = gscreen->width;
-	*softscreen = 1;
+
+	*softscreen = 0xa110c;
+	gscreen->data->ref++;
+
 	return gscreen->data->bdata;
 }
 
--- a/gui-osx/screen.c
+++ b/gui-osx/screen.c
@@ -77,6 +77,13 @@
 
 void winproc(void *a);
 
+void
+screensize(Rectangle r, ulong chan)
+{
+	USED(r);
+	USED(chan);
+}
+
 void screeninit(void)
 {
 	int fmt;
--- a/gui-win32/screen.c
+++ b/gui-win32/screen.c
@@ -37,8 +37,6 @@
 static int readybit;
 static Rendez	rend;
 
-Point	ZP;
-
 static int
 isready(void*a)
 {
@@ -48,11 +46,12 @@
 void
 screeninit(void)
 {
-	int fmt;
 	int dx, dy;
+	ulong chan;
 
 	FreeConsole();
 	memimageinit();
+
 	if(depth == 0)
 		depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL);
 	switch(depth){
@@ -59,17 +58,17 @@
 	case 32:
 		screen.dibtype = DIB_RGB_COLORS;
 		screen.depth = 32;
-		fmt = XRGB32;
+		chan = XRGB32;
 		break;
 	case 24:
 		screen.dibtype = DIB_RGB_COLORS;
 		screen.depth = 24;
-		fmt = RGB24;
+		chan = RGB24;
 		break;
 	case 16:
 		screen.dibtype = DIB_RGB_COLORS;
 		screen.depth = 16;
-		fmt = RGB15;	/* [sic] */
+		chan = RGB15;	/* [sic] */
 		break;
 	case 8:
 	default:
@@ -76,18 +75,29 @@
 		screen.dibtype = DIB_PAL_COLORS;
 		screen.depth = 8;
 		depth = 8;
-		fmt = CMAP8;
+		chan = CMAP8;
 		break;
 	}
 	dx = GetDeviceCaps(GetDC(NULL), HORZRES);
 	dy = GetDeviceCaps(GetDC(NULL), VERTRES);
-
-	gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);
-	gscreen->clipr = ZR;
+	screensize(Rect(0,0,dx,dy), chan);
 	kproc("winscreen", winproc, 0);
 	ksleep(&rend, isready, 0);
 }
 
+void
+screensize(Rectangle r, ulong chan)
+{
+	Memimage *i;
+
+	if((i = allocmemimage(r, chan)) == nil)
+		return;
+	if(gscreen != nil)
+		freememimage(gscreen);
+	gscreen = i;
+	gscreen->clipr = ZR;
+}
+
 uchar*
 attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
 {
@@ -95,7 +105,9 @@
 	*chan = gscreen->chan;
 	*depth = gscreen->depth;
 	*width = gscreen->width;
-	*softscreen = 1;
+
+	*softscreen = 0xa110c;
+	gscreen->data->ref++;
 
 	return gscreen->data->bdata;
 }
--- a/gui-x11/x11.c
+++ b/gui-x11/x11.c
@@ -179,6 +179,13 @@
 	qunlock(&drawlock);
 }
 
+void
+screensize(Rectangle r, ulong chan)
+{
+	USED(r);
+	USED(chan);
+}
+
 uchar*
 attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
 {
--- a/kern/screen.h
+++ b/kern/screen.h
@@ -59,6 +59,7 @@
 
 void	terminit(void);
 void	screenresize(Rectangle);
+void	screensize(Rectangle, ulong);
 
 void	mouseresize(void);
 void	mousetrack(int, int, int, ulong);
--- a/kern/term.c
+++ b/kern/term.c
@@ -100,6 +100,12 @@
 		resize.f = 0;
 		if(gscreen == nil
 		|| badrect(resize.r)
+		|| eqrect(resize.r, gscreen->clipr)){
+			qunlock(&drawlock);
+			continue;
+		}
+		screensize(resize.r, gscreen->chan);
+		if(gscreen == nil
 		|| rectclip(&resize.r, gscreen->r) == 0
 		|| eqrect(resize.r, gscreen->clipr)){
 			qunlock(&drawlock);