Module Name:    src
Committed By:   macallan
Date:           Fri May 19 19:22:33 UTC 2017

Modified Files:
        src/sys/dev/wscons: files.wscons wsdisplay.c wsdisplay_vcons.c
            wsdisplay_vconsvar.h wsdisplayvar.h wsemul_dumb.c wsemul_sun.c
            wsemul_vt100.c wsemul_vt100_subr.c wsemulvar.h

Log Message:
add support for loading fonts in vcons and subsequently resizing screens
- drivers can use this by setting VCONS_LOADFONT and WSSCREEN_RESIZE
- each vcons screen can now have its own font and geometry
- while there, add support for xterm's ESC[18t to report the text buffer's
  size

With this tou can:
wsfontload -N foo  /usr/share/wscons/fonts/flori.816
wsconsctl -dw font=foo
currently this is limited to drivers that don't use the glyph cache, like genfb


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/dev/wscons/files.wscons
cvs rdiff -u -r1.141 -r1.142 src/sys/dev/wscons/wsdisplay.c
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/wscons/wsdisplay_vcons.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/wscons/wsdisplay_vconsvar.h
cvs rdiff -u -r1.51 -r1.52 src/sys/dev/wscons/wsdisplayvar.h
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/wscons/wsemul_dumb.c \
    src/sys/dev/wscons/wsemulvar.h
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/wscons/wsemul_sun.c
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/wscons/wsemul_vt100.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/wscons/wsemul_vt100_subr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/wscons/files.wscons
diff -u src/sys/dev/wscons/files.wscons:1.49 src/sys/dev/wscons/files.wscons:1.50
--- src/sys/dev/wscons/files.wscons:1.49	Fri Oct 17 10:09:21 2014
+++ src/sys/dev/wscons/files.wscons	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.49 2014/10/17 10:09:21 uebayasi Exp $
+# $NetBSD: files.wscons,v 1.50 2017/05/19 19:22:33 macallan Exp $
 
 #
 # "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -76,7 +76,7 @@ defflag opt_tpcalib.h		TPCALIBDEBUG
 # generic virtual console support on bitmapped framebuffers
 file	dev/wscons/wsdisplay_vcons.c		vcons
 file	dev/wscons/wsdisplay_vcons_util.c	vcons
-defflag	opt_vcons.h		VCONS_DRAW_INTR VCONS_INTR_DEBUG
+defflag	opt_vcons.h		VCONS_DRAW_INTR VCONS_INTR_DEBUG VCONS_DEBUG
 
 # generic support code for caching rendered glyphs in video memory
 define	glyphcache

Index: src/sys/dev/wscons/wsdisplay.c
diff -u src/sys/dev/wscons/wsdisplay.c:1.141 src/sys/dev/wscons/wsdisplay.c:1.142
--- src/sys/dev/wscons/wsdisplay.c:1.141	Wed Jan 25 15:40:31 2017
+++ src/sys/dev/wscons/wsdisplay.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.141 2017/01/25 15:40:31 jakllsch Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.142 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.141 2017/01/25 15:40:31 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.142 2017/05/19 19:22:33 macallan Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_wsdisplay_compat.h"
@@ -257,6 +257,9 @@ static void wsdisplay_switch2_cb(void *,
 static int wsdisplay_switch3(device_t, int, int);
 static void wsdisplay_switch3_cb(void *, int, int);
 
+static void wsdisplay_swdone_cb(void *, int, int);
+static int wsdisplay_dosync(struct wsdisplay_softc *, int);
+
 int wsdisplay_clearonclose;
 
 struct wsscreen *
@@ -331,6 +334,8 @@ wsscreen_detach(struct wsscreen *scr)
 						  &ccol, &crow);
 		wsemul_drop(scr->scr_dconf->wsemul);
 	}
+	if (scr->scr_dconf->scrdata->capabilities & WSSCREEN_FREE)
+		free(__UNCONST(scr->scr_dconf->scrdata), M_DEVBUF);
 	free(scr->scr_dconf, M_DEVBUF);
 	free(scr, M_DEVBUF);
 }
@@ -342,7 +347,6 @@ wsdisplay_screentype_pick(const struct w
 	const struct wsscreen_descr *scr;
 
 	KASSERT(scrdata->nscreens > 0);
-
 	if (name == NULL)
 		return (scrdata->screens[0]);
 
@@ -377,6 +381,7 @@ wsdisplay_addscreen(struct wsdisplay_sof
 	const char *screentype, const char *emul)
 {
 	const struct wsscreen_descr *scrdesc;
+	struct wsscreen_descr *scrdescr2;
 	int error;
 	void *cookie;
 	int ccol, crow;
@@ -388,10 +393,24 @@ wsdisplay_addscreen(struct wsdisplay_sof
 		return (EINVAL);
 	if (sc->sc_scr[idx] != NULL)
 		return (EBUSY);
-
 	scrdesc = wsdisplay_screentype_pick(sc->sc_scrdata, screentype);
 	if (!scrdesc)
 		return (ENXIO);
+
+	/*
+	 * if this screen can resize we need to copy the descr so each screen
+	 * gets its own
+	 */
+	if (scrdesc->capabilities & WSSCREEN_RESIZE) {
+		/* we want per screen wsscreen_descr */
+		scrdescr2 = malloc(sizeof(struct wsscreen_descr), M_DEVBUF, M_NOWAIT);
+		if (scrdescr2 == NULL)
+			return ENOMEM;
+		memcpy(scrdescr2, scrdesc, sizeof(struct wsscreen_descr));
+		scrdescr2->capabilities |= WSSCREEN_FREE;
+		scrdesc = scrdescr2;
+	}
+
 	error = (*sc->sc_accessops->alloc_screen)(sc->sc_accesscookie,
 			scrdesc, &cookie, &ccol, &crow, &defattr);
 	if (error)
@@ -1187,13 +1206,11 @@ wsdisplayioctl(dev_t dev, u_long cmd, vo
 	if (WSSCREEN_HAS_TTY(scr)) {
 		tp = scr->scr_tty;
 
-/* printf("disc\n"); */
 		/* do the line discipline ioctls first */
 		error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
 		if (error != EPASSTHROUGH)
 			return (error);
 
-/* printf("tty\n"); */
 		/* then the tty ioctls */
 		error = ttioctl(tp, cmd, data, flag, l);
 		if (error != EPASSTHROUGH)
@@ -1328,9 +1345,29 @@ wsdisplay_internal_ioctl(struct wsdispla
 		fd.data = 0;
 		error = (*sc->sc_accessops->load_font)(sc->sc_accesscookie,
 					scr->scr_dconf->emulcookie, &fd);
-		if (!error && WSSCREEN_HAS_EMULATOR(scr))
+		if (!error && WSSCREEN_HAS_EMULATOR(scr)) {
 			(*scr->scr_dconf->wsemul->reset)
 				(scr->scr_dconf->wsemulcookie, WSEMUL_SYNCFONT);
+#ifdef DEBUG
+			printf("resize: %d %d\n",
+			    scr->scr_dconf->scrdata->nrows,
+			    scr->scr_dconf->scrdata->ncols); 
+#endif
+			if (scr->scr_dconf->wsemul->resize) {
+				(*scr->scr_dconf->wsemul->resize)
+					(scr->scr_dconf->wsemulcookie,
+					 scr->scr_dconf->scrdata);
+				/* update the tty's size */
+				scr->scr_tty->t_winsize.ws_row =
+				    scr->scr_dconf->scrdata->nrows;
+				scr->scr_tty->t_winsize.ws_col =
+				    scr->scr_dconf->scrdata->ncols;
+				/* send SIGWINCH to the process group on our tty */
+				kpreempt_disable();
+				ttysig(scr->scr_tty, TTYSIG_PG1, SIGWINCH);
+				kpreempt_enable();
+			}
+		}
 		return (error);
 #undef d
 

Index: src/sys/dev/wscons/wsdisplay_vcons.c
diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.36 src/sys/dev/wscons/wsdisplay_vcons.c:1.37
--- src/sys/dev/wscons/wsdisplay_vcons.c:1.36	Wed Apr 26 21:03:52 2017
+++ src/sys/dev/wscons/wsdisplay_vcons.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vcons.c,v 1.36 2017/04/26 21:03:52 macallan Exp $ */
+/*	$NetBSD: wsdisplay_vcons.c,v 1.37 2017/05/19 19:22:33 macallan Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.36 2017/04/26 21:03:52 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.37 2017/05/19 19:22:33 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +57,12 @@ __KERNEL_RCSID(0, "$NetBSD: wsdisplay_vc
 #include "opt_vcons.h"
 #endif
 
+#ifdef VCONS_DEBUG
+#define DPRINTF printf
+#else
+#define DPRINTF if (0) printf
+#endif
+
 static void vcons_dummy_init_screen(void *, struct vcons_screen *, int, 
 	    long *);
 
@@ -66,6 +72,7 @@ static int  vcons_alloc_screen(void *, c
 static void vcons_free_screen(void *, void *);
 static int  vcons_show_screen(void *, void *, int, void (*)(void *, int, int),
 	    void *);
+static int  vcons_load_font(void *, void *, struct wsdisplay_font *);
 
 #ifdef WSDISPLAY_SCROLLSUPPORT
 static void vcons_scroll(void *, void *, int);
@@ -139,6 +146,7 @@ vcons_init(struct vcons_data *vd, void *
 	ao->alloc_screen = vcons_alloc_screen;
 	ao->free_screen = vcons_free_screen;
 	ao->show_screen = vcons_show_screen;
+	ao->load_font = vcons_load_font;
 #ifdef WSDISPLAY_SCROLLSUPPORT
 	ao->scroll = vcons_scroll;
 #endif
@@ -147,6 +155,7 @@ vcons_init(struct vcons_data *vd, void *
 	vd->active = NULL;
 	vd->wanted = NULL;
 	vd->currenttype = def;
+	vd->defaulttype = def;
 	callout_init(&vd->switch_callout, 0);
 	callout_setfunc(&vd->switch_callout, vcons_do_switch, vd);
 #ifdef VCONS_DRAW_INTR
@@ -220,9 +229,8 @@ vcons_dummy_init_screen(void *cookie,
 	       "supposed to supply a replacement for proper operation\n");
 }
 
-int
-vcons_init_screen(struct vcons_data *vd, struct vcons_screen *scr,
-    int existing, long *defattr)
+static int
+vcons_alloc_buffers(struct vcons_data *vd, struct vcons_screen *scr)
 {
 	struct rasops_info *ri = &scr->scr_ri;
 	int cnt, i;
@@ -230,9 +238,69 @@ vcons_init_screen(struct vcons_data *vd,
 	int size;
 #endif
 
+	/* 
+	 * we allocate both chars and attributes in one chunk, attributes first 
+	 * because they have the (potentially) bigger alignment 
+	 */
+#ifdef WSDISPLAY_SCROLLSUPPORT
+	cnt = (ri->ri_rows + WSDISPLAY_SCROLLBACK_LINES) * ri->ri_cols;
+	scr->scr_lines_in_buffer = WSDISPLAY_SCROLLBACK_LINES;
+	scr->scr_current_line = 0;
+	scr->scr_line_wanted = 0;
+	scr->scr_offset_to_zero = ri->ri_cols * WSDISPLAY_SCROLLBACK_LINES;
+	scr->scr_current_offset = scr->scr_offset_to_zero;
+#else
+	cnt = ri->ri_rows * ri->ri_cols;
+#endif
+	scr->scr_attrs = malloc(cnt * (sizeof(long) + 
+	    sizeof(uint32_t)), M_DEVBUF, M_WAITOK);
+	if (scr->scr_attrs == NULL)
+		return ENOMEM;
+
+	scr->scr_chars = (uint32_t *)&scr->scr_attrs[cnt];
+
+	/* 
+	 * fill the attribute buffer with *defattr, chars with 0x20 
+	 * since we don't know if the driver tries to mimic firmware output or
+	 * reset everything we do nothing to VRAM here, any driver that feels
+	 * the need to clear screen or something will have to do it on its own
+	 * Additional screens will start out in the background anyway so
+	 * cleaning or not only really affects the initial console screen
+	 */
+	for (i = 0; i < cnt; i++) {
+		scr->scr_attrs[i] = scr->scr_defattr;
+		scr->scr_chars[i] = 0x20;
+	}
+
+#ifdef VCONS_DRAW_INTR
+	size = ri->ri_cols * ri->ri_rows;
+	if (size > vd->cells) {
+		if (vd->chars != NULL) free(vd->chars, M_DEVBUF);
+		if (vd->attrs != NULL) free(vd->attrs, M_DEVBUF);
+		vd->cells = size;
+		vd->chars = malloc(size * sizeof(uint32_t), M_DEVBUF,
+		    M_WAITOK|M_ZERO);
+		vd->attrs = malloc(size * sizeof(long), M_DEVBUF,
+		    M_WAITOK|M_ZERO);
+		vcons_invalidate_cache(vd);
+	} else if (SCREEN_IS_VISIBLE(scr))
+		vcons_invalidate_cache(vd);
+#endif
+	return 0;
+}
+
+int
+vcons_init_screen(struct vcons_data *vd, struct vcons_screen *scr,
+    int existing, long *defattr)
+{
+	struct rasops_info *ri = &scr->scr_ri;
+	int i;
+
 	scr->scr_cookie = vd->cookie;
 	scr->scr_vd = scr->scr_origvd = vd;
 	scr->scr_busy = 0;
+	if (scr->scr_type == NULL)
+		scr->scr_type = vd->defaulttype;
 	
 	/*
 	 * call the driver-supplied init_screen function which is expected
@@ -246,7 +314,7 @@ vcons_init_screen(struct vcons_data *vd,
 	 */
 	vd->eraserows = ri->ri_ops.eraserows;
 	vd->erasecols = ri->ri_ops.erasecols;
-	vd->putchar   = ri->ri_ops.putchar;
+	scr->putchar   = ri->ri_ops.putchar;
 	vd->cursor    = ri->ri_ops.cursor;
 
 	if (scr->scr_flags & VCONS_NO_COPYCOLS) {
@@ -271,27 +339,6 @@ vcons_init_screen(struct vcons_data *vd,
 
 	ri->ri_hw = scr;
 
-	/* 
-	 * we allocate both chars and attributes in one chunk, attributes first 
-	 * because they have the (potentially) bigger alignment 
-	 */
-#ifdef WSDISPLAY_SCROLLSUPPORT
-	cnt = (ri->ri_rows + WSDISPLAY_SCROLLBACK_LINES) * ri->ri_cols;
-	scr->scr_lines_in_buffer = WSDISPLAY_SCROLLBACK_LINES;
-	scr->scr_current_line = 0;
-	scr->scr_line_wanted = 0;
-	scr->scr_offset_to_zero = ri->ri_cols * WSDISPLAY_SCROLLBACK_LINES;
-	scr->scr_current_offset = scr->scr_offset_to_zero;
-#else
-	cnt = ri->ri_rows * ri->ri_cols;
-#endif
-	scr->scr_attrs = malloc(cnt * (sizeof(long) + 
-	    sizeof(uint32_t)), M_DEVBUF, M_WAITOK);
-	if (scr->scr_attrs == NULL)
-		return ENOMEM;
-
-	scr->scr_chars = (uint32_t *)&scr->scr_attrs[cnt];
-
 	i = ri->ri_ops.allocattr(ri, WS_DEFAULT_FG, WS_DEFAULT_BG, 0, defattr);
 	if (i != 0) {
 #ifdef DIAGNOSTIC
@@ -301,32 +348,7 @@ vcons_init_screen(struct vcons_data *vd,
 	} else
 		scr->scr_defattr = *defattr;
 
-	/* 
-	 * fill the attribute buffer with *defattr, chars with 0x20 
-	 * since we don't know if the driver tries to mimic firmware output or
-	 * reset everything we do nothing to VRAM here, any driver that feels
-	 * the need to clear screen or something will have to do it on its own
-	 * Additional screens will start out in the background anyway so
-	 * cleaning or not only really affects the initial console screen
-	 */
-	for (i = 0; i < cnt; i++) {
-		scr->scr_attrs[i] = *defattr;
-		scr->scr_chars[i] = 0x20;
-	}
-
-#ifdef VCONS_DRAW_INTR
-	size = ri->ri_cols * ri->ri_rows;
-	if (size > vd->cells) {
-		if (vd->chars != NULL) free(vd->chars, M_DEVBUF);
-		if (vd->attrs != NULL) free(vd->attrs, M_DEVBUF);
-		vd->cells = size;
-		vd->chars = malloc(size * sizeof(uint32_t), M_DEVBUF,
-		    M_WAITOK|M_ZERO);
-		vd->attrs = malloc(size * sizeof(long), M_DEVBUF,
-		    M_WAITOK|M_ZERO);
-		vcons_invalidate_cache(vd);
-	}
-#endif
+	vcons_alloc_buffers(vd, scr);
 
 	if(vd->active == NULL) {
 		vd->active = scr;
@@ -344,6 +366,93 @@ vcons_init_screen(struct vcons_data *vd,
 	return 0;
 }
 
+static int
+vcons_load_font(void *v, void *cookie, struct wsdisplay_font *f)
+{
+	struct vcons_data *vd = v;
+	struct vcons_screen *scr = cookie;
+	struct rasops_info *ri;
+	struct wsdisplay_font *font;
+	int flags = WSFONT_FIND_BITMAP, fcookie;
+
+	/* see if we're asked to add a font or use it */
+	if (scr == NULL)
+		return 0;
+
+	ri = &scr->scr_ri;
+
+	/* see if the driver knows how to handle multiple fonts */
+	if ((scr->scr_flags & VCONS_LOADFONT) == 0) {
+		return EOPNOTSUPP;
+	}
+
+	/* now see what fonts we can use */
+	if (ri->ri_flg & RI_ENABLE_ALPHA) {
+		flags |= WSFONT_FIND_ALPHA;
+	}
+
+	fcookie = wsfont_find(f->name, 0, 0, 0, 0, 0, flags);
+	if (fcookie == -1)
+		return EINVAL;
+
+	wsfont_lock(fcookie, &font);
+	if (font == NULL)
+		return EINVAL;
+
+	/* ok, we got a font. Now clear the screen with the old parameters */
+	if (SCREEN_IS_VISIBLE(scr))
+		vd->eraserows(ri, 0, ri->ri_rows, scr->scr_defattr);
+
+	vcons_lock(vd->active);
+#ifdef VCONS_DRAW_INTR
+	callout_halt(&vd->intr, NULL);
+#endif
+	/* set the new font and re-initialize things */
+	ri->ri_font = font;
+	wsfont_unlock(ri->ri_wsfcookie);
+	ri->ri_wsfcookie = fcookie;
+
+	vd->init_screen(vd->cookie, scr, 1, &scr->scr_defattr);
+	DPRINTF("caps %x %x\n", scr->scr_type->capabilities, ri->ri_caps);
+	if (scr->scr_type->capabilities & WSSCREEN_RESIZE) {
+		scr->scr_type->nrows = ri->ri_rows;
+		scr->scr_type->ncols = ri->ri_cols;
+		DPRINTF("new size %d %d\n", ri->ri_rows, ri->ri_cols);
+	}
+
+
+	/* now, throw the old buffers away */
+	if (scr->scr_attrs)
+		free(scr->scr_attrs, M_DEVBUF);
+	/* allocate new buffers */
+	vcons_alloc_buffers(vd, scr);
+	
+	/* save the potentially changed putchar */ 
+	scr->putchar   = ri->ri_ops.putchar;
+
+	/* and put our wrappers back */
+	ri->ri_ops.eraserows = vcons_eraserows;	
+	ri->ri_ops.erasecols = vcons_erasecols;	
+	ri->ri_ops.putchar   = vcons_putchar;
+	ri->ri_ops.cursor    = vcons_cursor;
+	ri->ri_ops.copycols  = vcons_copycols;
+	ri->ri_ops.copyrows  = vcons_copyrows;
+	vcons_unlock(vd->active);
+#ifdef VCONS_DRAW_INTR
+	/*
+	 * XXX
+	 * Something(tm) craps all over VRAM somewhere up there if we're 
+	 * using VCONS_DRAW_INTR. Until I figure out what causes it, just
+	 * redraw the screen for now.
+	 */
+	vcons_redraw_screen(vd->active);
+	callout_schedule(&vd->intr, mstohz(33));
+#endif
+	/* no need to draw anything, wsdisplay should reset the terminal */
+
+	return 0;
+}	
+
 static void
 vcons_do_switch(void *arg)
 {
@@ -401,6 +510,10 @@ vcons_do_switch(void *arg)
 	vd->active = scr;
 	vd->wanted = NULL;
 
+#ifdef VCONS_DRAW_INTR
+	vcons_invalidate_cache(vd);
+#endif
+
 	if (vd->show_screen_cb != NULL)
 		vd->show_screen_cb(scr);
 
@@ -488,7 +601,7 @@ vcons_redraw_screen(struct vcons_screen 
 						start = -1;
 					}
 							
-					vd->putchar(ri, i, j, c, a);
+					scr->putchar(ri, i, j, c, a);
 				}
 next:
 #ifdef VCONS_DRAW_INTR
@@ -550,7 +663,7 @@ vcons_update_screen(struct vcons_screen 
 				 */
 				if ((vd->chars[boffset] != charptr[offset]) ||
 				    (vd->attrs[boffset] != attrptr[offset])) {
-					vd->putchar(ri, i, j, 
+					scr->putchar(ri, i, j, 
 				 	   charptr[offset], attrptr[offset]);
 					vd->chars[boffset] = charptr[offset];
 					vd->attrs[boffset] = attrptr[offset];
@@ -616,6 +729,7 @@ vcons_alloc_screen(void *v, const struct
 {
 	struct vcons_data *vd = v;
 	struct vcons_screen *scr;
+	struct wsscreen_descr *t = __UNCONST(type);
 	int ret;
 
 	scr = malloc(sizeof(struct vcons_screen), M_DEVBUF, M_WAITOK | M_ZERO);
@@ -625,13 +739,17 @@ vcons_alloc_screen(void *v, const struct
 	scr->scr_flags = 0;		
 	scr->scr_status = 0;
 	scr->scr_busy = 0;
-	scr->scr_type = type;
+	scr->scr_type = __UNCONST(type);
 
 	ret = vcons_init_screen(vd, scr, 0, defattrp);
 	if (ret != 0) {
 		free(scr, M_DEVBUF);
 		return ret;
 	}
+	if (t->capabilities & WSSCREEN_RESIZE) {
+		t->nrows = scr->scr_ri.ri_rows;
+		t->ncols = scr->scr_ri.ri_cols;
+	}
 
 	if (vd->active == NULL) {
 		SCREEN_VISIBLE(scr);
@@ -757,7 +875,9 @@ vcons_copycols_noread(void *cookie, int 
 {
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#ifdef VCONS_DRAW_INTR
 	struct vcons_data *vd = scr->scr_vd;
+#endif
 
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
@@ -774,13 +894,13 @@ vcons_copycols_noread(void *cookie, int 
 #ifdef VCONS_DRAW_INTR
 			if ((scr->scr_chars[pos] != vd->chars[ppos]) ||
 			    (scr->scr_attrs[pos] != vd->attrs[ppos])) {
-				vd->putchar(cookie, row, c, 
+				scr->putchar(cookie, row, c, 
 				   scr->scr_chars[pos], scr->scr_attrs[pos]);
 				vd->chars[ppos] = scr->scr_chars[pos];
 				vd->attrs[ppos] = scr->scr_attrs[pos];
 			}
 #else
-			vd->putchar(cookie, row, c, scr->scr_chars[pos],
+			scr->putchar(cookie, row, c, scr->scr_chars[pos],
 			    scr->scr_attrs[pos]);
 #endif
 			pos++;
@@ -929,8 +1049,9 @@ vcons_copyrows_noread(void *cookie, int 
 {
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#ifdef VCONS_DRAW_INTR
 	struct vcons_data *vd = scr->scr_vd;
-
+#endif
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 		int pos, l, c, offset, ppos;
@@ -947,13 +1068,13 @@ vcons_copyrows_noread(void *cookie, int 
 #ifdef VCONS_DRAW_INTR
 				if ((scr->scr_chars[pos] != vd->chars[ppos]) ||
 				    (scr->scr_attrs[pos] != vd->attrs[ppos])) {
-					vd->putchar(cookie, l, c, 
+					scr->putchar(cookie, l, c, 
 					   scr->scr_chars[pos], scr->scr_attrs[pos]);
 					vd->chars[ppos] = scr->scr_chars[pos];
 					vd->attrs[ppos] = scr->scr_attrs[pos];
 				}
 #else
-				vd->putchar(cookie, l, c, scr->scr_chars[pos],
+				scr->putchar(cookie, l, c, scr->scr_chars[pos],
 				    scr->scr_attrs[pos]);
 #endif
 				pos++;
@@ -1074,13 +1195,13 @@ vcons_putchar_cached(void *cookie, int r
 	int pos = row * ri->ri_cols + col;
 
 	if ((vd->chars == NULL) || (vd->attrs == NULL)) {
-		vd->putchar(cookie, row, col, c, attr);
+		scr->putchar(cookie, row, col, c, attr);
 		return;
 	}
 	if ((vd->chars[pos] != c) || (vd->attrs[pos] != attr)) {
 		vd->attrs[pos] = attr;
 		vd->chars[pos] = c;
-		vd->putchar(cookie, row, col, c, attr);
+		scr->putchar(cookie, row, col, c, attr);
 	}
 }
 #endif
@@ -1103,7 +1224,7 @@ vcons_putchar(void *cookie, int row, int
 #ifdef VCONS_DRAW_INTR
 		vcons_putchar_cached(cookie, row, col, c, attr);
 #else
-		scr->scr_vd->putchar(cookie, row, col, c, attr);
+		scr->putchar(cookie, row, col, c, attr);
 #endif
 	}
 	vcons_unlock(scr);
@@ -1277,7 +1398,7 @@ vcons_do_scroll(struct vcons_screen *scr
 			    scr->scr_chars[r_offset],
 			    scr->scr_attrs[r_offset]);
 #else
-			scr->scr_vd->putchar(scr, i + r_start, j,
+			scr->putchar(scr, i + r_start, j,
 			    scr->scr_chars[r_offset],
 			    scr->scr_attrs[r_offset]);
 #endif

Index: src/sys/dev/wscons/wsdisplay_vconsvar.h
diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.24 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.25
--- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.24	Thu Jun  2 21:17:14 2016
+++ src/sys/dev/wscons/wsdisplay_vconsvar.h	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vconsvar.h,v 1.24 2016/06/02 21:17:14 macallan Exp $ */
+/*	$NetBSD: wsdisplay_vconsvar.h,v 1.25 2017/05/19 19:22:33 macallan Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -42,9 +42,10 @@ struct vcons_screen {
 	void *scr_cookie;
 	struct vcons_data *scr_vd;
 	struct vcons_data *scr_origvd;
-	const struct wsscreen_descr *scr_type;
+	struct wsscreen_descr *scr_type;
 	uint32_t *scr_chars;
 	long *scr_attrs;
+	void (*putchar)(void *, int, int, u_int, long);
 	long scr_defattr;
 	/* static flags set by the driver */
 	uint32_t scr_flags;
@@ -63,6 +64,7 @@ struct vcons_screen {
 #define VCONS_NO_COPYCOLS	0x10	/* use putchar() based copycols() */
 #define VCONS_NO_COPYROWS	0x20	/* use putchar() based copyrows() */
 #define VCONS_DONT_READ		0x30	/* avoid framebuffer reads */
+#define VCONS_LOADFONT		0x40	/* driver can load_font() */
 	/* status flags used by vcons */
 	uint32_t scr_status;
 #define VCONS_IS_VISIBLE	1	/* this screen is currently visible */
@@ -112,7 +114,6 @@ struct vcons_data {
 	void (*erasecols)(void *, int, int, int, long);
 	void (*copyrows)(void *, int, int, int);
 	void (*eraserows)(void *, int, int, long);
-	void (*putchar)(void *, int, int, u_int, long);
 	void (*cursor)(void *, int, int, int);
 	/* called before vcons_redraw_screen */
 	void (*show_screen_cb)(struct vcons_screen *);
@@ -124,6 +125,7 @@ struct vcons_data {
 	LIST_HEAD(, vcons_screen) screens;
 	struct vcons_screen *active, *wanted;
 	const struct wsscreen_descr *currenttype;
+	struct wsscreen_descr *defaulttype;
 	int switch_poll_count;
 #ifdef VCONS_DRAW_INTR
 	int cells;

Index: src/sys/dev/wscons/wsdisplayvar.h
diff -u src/sys/dev/wscons/wsdisplayvar.h:1.51 src/sys/dev/wscons/wsdisplayvar.h:1.52
--- src/sys/dev/wscons/wsdisplayvar.h:1.51	Tue Jan 21 00:08:27 2014
+++ src/sys/dev/wscons/wsdisplayvar.h	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplayvar.h,v 1.51 2014/01/21 00:08:27 mlelstv Exp $ */
+/* $NetBSD: wsdisplayvar.h,v 1.52 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -98,6 +98,9 @@ struct wsscreen_descr {
 #define WSSCREEN_HILIT		4	/* can highlight (however) */
 #define WSSCREEN_BLINK		8	/* can blink */
 #define WSSCREEN_UNDERLINE	16	/* can underline */
+#define WSSCREEN_RESIZE		32	/* can resize */
+#define WSSCREEN_FREE		64	/* free() this struct when deleting
+					 * internal only, do not set */
 	void *modecookie;
 };
 

Index: src/sys/dev/wscons/wsemul_dumb.c
diff -u src/sys/dev/wscons/wsemul_dumb.c:1.15 src/sys/dev/wscons/wsemul_dumb.c:1.16
--- src/sys/dev/wscons/wsemul_dumb.c:1.15	Thu Jan 28 22:36:19 2010
+++ src/sys/dev/wscons/wsemul_dumb.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemul_dumb.c,v 1.15 2010/01/28 22:36:19 drochner Exp $ */
+/* $NetBSD: wsemul_dumb.c,v 1.16 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsemul_dumb.c,v 1.15 2010/01/28 22:36:19 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsemul_dumb.c,v 1.16 2017/05/19 19:22:33 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -64,6 +64,7 @@ const struct wsemul_ops wsemul_dumb_ops 
 	wsemul_dumb_resetop,
 	NULL,	/* getmsgattrs */
 	NULL,	/* setmsgattrs */
+	NULL	/* resize */
 };
 
 struct wsemul_dumb_emuldata {
Index: src/sys/dev/wscons/wsemulvar.h
diff -u src/sys/dev/wscons/wsemulvar.h:1.15 src/sys/dev/wscons/wsemulvar.h:1.16
--- src/sys/dev/wscons/wsemulvar.h:1.15	Tue Feb  2 16:18:29 2010
+++ src/sys/dev/wscons/wsemulvar.h	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemulvar.h,v 1.15 2010/02/02 16:18:29 drochner Exp $ */
+/* $NetBSD: wsemulvar.h,v 1.16 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -52,6 +52,7 @@ struct wsemul_ops {
 	void	(*getmsgattrs)(void *, struct wsdisplay_msgattrs *);
 	void	(*setmsgattrs)(void *, const struct wsscreen_descr *,
 		               const struct wsdisplay_msgattrs *);
+	void	(*resize)(void *, const struct wsscreen_descr *);
 };
 
 #if defined(_KERNEL_OPT)

Index: src/sys/dev/wscons/wsemul_sun.c
diff -u src/sys/dev/wscons/wsemul_sun.c:1.29 src/sys/dev/wscons/wsemul_sun.c:1.30
--- src/sys/dev/wscons/wsemul_sun.c:1.29	Sun Nov  8 16:49:41 2015
+++ src/sys/dev/wscons/wsemul_sun.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemul_sun.c,v 1.29 2015/11/08 16:49:41 christos Exp $ */
+/* $NetBSD: wsemul_sun.c,v 1.30 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -33,7 +33,7 @@
 /* XXX DESCRIPTION/SOURCE OF INFORMATION */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsemul_sun.c,v 1.29 2015/11/08 16:49:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsemul_sun.c,v 1.30 2017/05/19 19:22:33 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,6 +67,7 @@ const struct wsemul_ops wsemul_sun_ops =
 	wsemul_sun_resetop,
 	NULL,	/* getmsgattrs */
 	NULL,	/* setmsgattrs */
+	NULL	/* resize */
 };
 
 #define	SUN_EMUL_STATE_NORMAL	0	/* normal processing */

Index: src/sys/dev/wscons/wsemul_vt100.c
diff -u src/sys/dev/wscons/wsemul_vt100.c:1.37 src/sys/dev/wscons/wsemul_vt100.c:1.38
--- src/sys/dev/wscons/wsemul_vt100.c:1.37	Mon Aug 24 22:50:33 2015
+++ src/sys/dev/wscons/wsemul_vt100.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemul_vt100.c,v 1.37 2015/08/24 22:50:33 pooka Exp $ */
+/* $NetBSD: wsemul_vt100.c,v 1.38 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1998
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsemul_vt100.c,v 1.37 2015/08/24 22:50:33 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsemul_vt100.c,v 1.38 2017/05/19 19:22:33 macallan Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_wsmsgattrs.h"
@@ -57,6 +57,7 @@ static void wsemul_vt100_getmsgattrs(voi
 static void wsemul_vt100_setmsgattrs(void *, const struct wsscreen_descr *,
                                      const struct wsdisplay_msgattrs *);
 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
+static void wsemul_vt100_resize(void *, const struct wsscreen_descr *);
 
 const struct wsemul_ops wsemul_vt100_ops = {
 	"vt100",
@@ -73,6 +74,7 @@ const struct wsemul_ops wsemul_vt100_ops
 	NULL,
 	NULL,
 #endif
+	.resize = wsemul_vt100_resize
 };
 
 struct wsemul_vt100_emuldata wsemul_vt100_console_emuldata;
@@ -253,8 +255,8 @@ wsemul_vt100_attach(int console, const s
 	vd = &edp->bd;
 	vd->cbcookie = cbcookie;
 
-	vd->tabs = malloc(vd->ncols, M_DEVBUF, M_NOWAIT);
-	vd->dblwid = malloc(vd->nrows, M_DEVBUF, M_NOWAIT|M_ZERO);
+	vd->tabs = malloc(1024, M_DEVBUF, M_NOWAIT);
+	vd->dblwid = malloc(1024, M_DEVBUF, M_NOWAIT|M_ZERO);
 	vd->dw = 0;
 	vd->dcsarg = malloc(DCS_MAXLEN, M_DEVBUF, M_NOWAIT);
 	edp->isolatin1tab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
@@ -287,6 +289,17 @@ wsemul_vt100_detach(void *cookie, u_int 
 		free(edp, M_DEVBUF);
 }
 
+static void
+wsemul_vt100_resize(void * cookie, const struct wsscreen_descr *type)
+{
+	struct wsemul_vt100_emuldata *edp = cookie;
+
+	edp->bd.nrows = type->nrows;
+	edp->bd.ncols = type->ncols;
+	wsemul_vt100_reset(edp);
+	wsemul_vt100_resetop(cookie, WSEMUL_CLEARSCREEN);
+}
+
 void
 wsemul_vt100_resetop(void *cookie, enum wsemul_resetops op)
 {

Index: src/sys/dev/wscons/wsemul_vt100_subr.c
diff -u src/sys/dev/wscons/wsemul_vt100_subr.c:1.20 src/sys/dev/wscons/wsemul_vt100_subr.c:1.21
--- src/sys/dev/wscons/wsemul_vt100_subr.c:1.20	Wed Feb 10 19:39:39 2010
+++ src/sys/dev/wscons/wsemul_vt100_subr.c	Fri May 19 19:22:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: wsemul_vt100_subr.c,v 1.20 2010/02/10 19:39:39 drochner Exp $ */
+/* $NetBSD: wsemul_vt100_subr.c,v 1.21 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1998
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsemul_vt100_subr.c,v 1.20 2010/02/10 19:39:39 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsemul_vt100_subr.c,v 1.21 2017/05/19 19:22:33 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -543,6 +543,18 @@ wsemul_vt100_handle_csi(struct vt100base
 			edp->bgcol = bgcol;
 		}
 		break;
+	    case 't': /* terminal size and such */
+		switch (ARG(edp, 0)) {
+		    case 18: {	/* xterm size */
+			char buf[20];
+
+			n = snprintf(buf, sizeof(buf), "\033[8;%d;%dt",
+			    edp->nrows, edp->ncols);
+			wsdisplay_emulinput(edp->cbcookie, buf, n);
+			}
+			break;
+		}
+		break;	
 	    case 'n': /* reports */
 		switch (ARG(edp, 0)) {
 		    case 5: /* DSR operating status */

Reply via email to