Subject: New options to wsconscfg(8) and wsfontload(8) for uwscons
To: None <tech-userlevel@netbsd.org>
From: Bang Jun-Young <junyoung@netbsd.org>
List: netbsd-users
Date: 04/10/2003 01:01:43
--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

As part of merging long-long-delayed uwscons project into -current,
I'd like to add a couple of options to wsconscfg(8) and wsfontload(8).
(For those who don't know what uwscons is, it is multilingual
extention to wscons console driver framework.)

1. wsconscfg(8)

wsconscfg now has two new flags, -c and -C. First, -c is used to
create virtual screen. Most users won't need to use it themselves,
since virtual screens are usually created by /etc/rc.d/wscons script
at system startup.

-C option sets the character set encoding for the specified screen.
Encoding can be changed at any time while the system is running.

Example:

 # wsconfcfg -C euckr 2

sets character set encoding for screen 2 to EUC-KR.

2. wsfontload(8)

One option is added. -c sets the first character of the font to be
loaded. In most cases, this is only meaningful when Unicode-encoded
font is loaded.

 # wsfontload -N uhangul -h 16 -c 0xac00 -e uni \
 /usr/share/wscons/fonts/uhangul1616

3. /etc/wscons.conf

Syntax of `font' line is changed. Current systax is as follows:

#       name    width   height  enc     file
font    ibm     -       10      ibm     /usr/share/wscons/fonts/vt220l.810

New syntax with uwscons:

#	name	width	height	fstchar enc	file
font	ibm	-	8	-	ibm	/usr/share/wscons/fonts/vt220l.808
font uhangul	16	16	0xac00	uni	/usr/share/wscons/fonts/unihangul.1616

`screen' line is also changed (probably in backward compatible way,
though that's not important). Current syntax:

#	idx     screen  emul
screen  1       80x25	vt100

New with uwscons:

#	idx     screen  emul	charset
screen  1       -   	vt100	euckr

Patches for wsconscfg(8) and wsfontload(8) are attached in this
mail. Any comments will be appreciated.

Jun-Young

-- 
Bang Jun-Young <junyoung@netbsd.org>

--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wsconscfg.patch"

? .gdbinit
? wsconscfg
? wsconscfg.cat8
? wsconscfg.patch
Index: wsconscfg.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/wsconscfg/wsconscfg.8,v
retrieving revision 1.14
diff -c -r1.14 wsconscfg.8
*** wsconscfg.8	2003/02/25 10:36:22	1.14
--- wsconscfg.8	2003/04/09 15:12:41
***************
*** 24,30 ****
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .Dd January 12, 1999
  .Os
  .Dt WSCONSCFG 8
  .Sh NAME
--- 24,30 ----
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .Dd April 9, 2003
  .Os
  .Dt WSCONSCFG 8
  .Sh NAME
***************
*** 33,40 ****
--- 33,42 ----
  .Sh SYNOPSIS
  .Nm
  .Op Fl f Ar ctldev
+ .Fl c
  .Op Fl t Ar type
  .Op Fl e Ar emul
+ .Op Fl C Ar charset
  .Ar index
  .Nm
  .Op Fl f Ar ctldev
***************
*** 46,58 ****
  .Fl k | m
  .Op Fl d
  .Op Ar index
  .Sh DESCRIPTION
  The
  .Nm
  tool allows to create and delete virtual terminals on display devices
  controlled by the wscons terminal framework if the underlying display hardware
  driver supports multiple screens. Further it controls the assignment of
! keyboards to displays.
  The
  .Ar index
  argument specifies which virtual terminal is to be configured; the allowed
--- 48,66 ----
  .Fl k | m
  .Op Fl d
  .Op Ar index
+ .Nm
+ .Op Fl f Ar ctldev
+ .Fl C Ar charset
+ .Op Ar index
  .Sh DESCRIPTION
  The
  .Nm
  tool allows to create and delete virtual terminals on display devices
  controlled by the wscons terminal framework if the underlying display hardware
  driver supports multiple screens. Further it controls the assignment of
! keyboards to displays. It also sets character set encoding used to display
! characters on the screen if the underlying display hardware driver has
! capability of displaying multilingual text.
  The
  .Ar index
  argument specifies which virtual terminal is to be configured; the allowed
***************
*** 71,76 ****
--- 79,86 ----
  Specify the control device of the wscons display to operate on.
  Default is
  .Pa /dev/ttyEcfg .
+ .It Fl c
+ Create the specified terminal.
  .It Fl d
  Delete the specified terminal. A terminal opened by a program will not be
  deleted unless the
***************
*** 101,111 ****
  depth and other low-level display properties. Valid
  .Ar type
  arguments are defined by the underlying display device driver.
  .It Fl e Ar emul
  Specify the terminal emulation to use for the virtual terminal. The set of
! available terminal emulations is determined at kernel compile time. See
  .Xr wscons 4
  for details.
  .El
  .Pp
  Typically, the
--- 111,129 ----
  depth and other low-level display properties. Valid
  .Ar type
  arguments are defined by the underlying display device driver.
+ Note that it can only be used together with
+ .Fl c .
  .It Fl e Ar emul
  Specify the terminal emulation to use for the virtual terminal. The set of
! available terminal emulations is determined at kernel compile time.
! Note that it can only be used together with
! .Fl c .
! See
  .Xr wscons 4
  for details.
+ .It Fl C Ar charset
+ Set character set encoding of the specified screen.
+ If no screen index is given, screen 0 (i.e. the first) is assumed.
  .El
  .Pp
  Typically, the
***************
*** 118,124 ****
  .Sh FILES
  .Pa /etc/wscons.conf
  .Sh EXAMPLES
! .Dl wsconscfg -t 80x50 -e vt100 1
  .Pp
  Configure screen 1 (i.e. the second), it will get the type
  .Ql 80x50
--- 136,142 ----
  .Sh FILES
  .Pa /etc/wscons.conf
  .Sh EXAMPLES
! .Dl wsconscfg -c -t 80x50 -e vt100 1
  .Pp
  Configure screen 1 (i.e. the second), it will get the type
  .Ql 80x50
***************
*** 133,138 ****
--- 151,160 ----
  .Dl wsconscfg -k
  .Pp
  Connect the first unconnected keyboard to the display.
+ .Pp
+ .Dl wsconscfg -C euckr 2
+ .Pp
+ Set the character set encoding for screen 2 to EUC-KR.
  .Sh SEE ALSO
  .Xr wscons 4 ,
  .Xr wskbd 4 ,
Index: wsconscfg.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/wsconscfg/wsconscfg.c,v
retrieving revision 1.9
diff -c -r1.9 wsconscfg.c
*** wsconscfg.c	2001/06/25 08:47:29	1.9
--- wsconscfg.c	2003/04/09 15:12:41
***************
*** 45,51 ****
--- 45,78 ----
  
  #define DEFDEV "/dev/ttyEcfg"
  
+ static struct {
+ 	char *name;
+ 	int val;
+ } encodings[] = {
+ 	{"ibm", WSDISPLAY_CHARENC_IBM},
+ 	{"ascii", WSDISPLAY_CHARENC_IBM},
+ 	{"iso", WSDISPLAY_CHARENC_ISO},
+ 	{"iso2", WSDISPLAY_CHARENC_ISO2},
+ 	{"iso3", WSDISPLAY_CHARENC_ISO3},
+ 	{"iso4", WSDISPLAY_CHARENC_ISO4},
+ 	{"iso5", WSDISPLAY_CHARENC_ISO5},
+ 	{"iso6", WSDISPLAY_CHARENC_ISO6},
+ 	{"iso7", WSDISPLAY_CHARENC_ISO7},
+ 	{"iso8", WSDISPLAY_CHARENC_ISO8},
+ 	{"iso9", WSDISPLAY_CHARENC_ISO9},
+ 	{"iso10", WSDISPLAY_CHARENC_ISO10},
+ 	{"iso15", WSDISPLAY_CHARENC_ISO15},
+ 	{"utf8", WSDISPLAY_CHARENC_UTF8},
+ 	{"euccn", WSDISPLAY_CHARENC_EUCCN},
+ 	{"eucjp", WSDISPLAY_CHARENC_EUCJP},
+ 	{"euckr", WSDISPLAY_CHARENC_EUCKR},
+ 	{"koi8", WSDISPLAY_CHARENC_KOI8},
+ 	{"latin", WSDISPLAY_CHARENC_ISO},
+ 	{"latin2", WSDISPLAY_CHARENC_ISO2},
+ };
+ 
  static void usage __P((void));
+ static int getencoding __P((char *));
  int main __P((int, char**));
  
  static void
***************
*** 58,87 ****
  	exit(1);
  }
  
  int
  main(argc, argv)
  	int argc;
  	char **argv;
  {
  	char *wsdev;
! 	int c, delete, kbd, idx, wsfd, res, mux;
  	struct wsdisplay_addscreendata asd;
  	struct wsdisplay_delscreendata dsd;
  	struct wsmux_device wmd;
  
  	wsdev = DEFDEV;
  	delete = 0;
  	kbd = 0;
  	mux = 0;
  	asd.screentype = 0;
  	asd.emul = 0;
  	dsd.flags = 0;
  
! 	while ((c = getopt(argc, argv, "f:dkmt:e:F")) != -1) {
  		switch (c) {
  		case 'f':
  			wsdev = optarg;
  			break;
  		case 'd':
  			delete++;
  			break;
--- 85,138 ----
  	exit(1);
  }
  
+ /*
+  * map given encoding string to integer value
+  */
+ static int
+ getencoding(name)
+ 	char *name;
+ {
+ 	int i;
+ 
+ 	for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
+ 		if (!strcmp(name, encodings[i].name))
+ 			return (encodings[i].val);
+ 
+ 	errx(1, "invalid encoding %s", name);
+ }
+ 
  int
  main(argc, argv)
  	int argc;
  	char **argv;
  {
  	char *wsdev;
! 	char *charset;
! 	int c, create, delete, kbd, idx, wsfd, res, mux;
  	struct wsdisplay_addscreendata asd;
  	struct wsdisplay_delscreendata dsd;
  	struct wsmux_device wmd;
+ 	struct wsdisplay_encodingdata e;
  
  	wsdev = DEFDEV;
+ 	charset = NULL;
+ 	create = 0;
  	delete = 0;
  	kbd = 0;
  	mux = 0;
  	asd.screentype = 0;
  	asd.emul = 0;
  	dsd.flags = 0;
+ 	e.idx = 0;
  
! 	while ((c = getopt(argc, argv, "f:cdkmt:e:FC:")) != -1) {
  		switch (c) {
  		case 'f':
  			wsdev = optarg;
  			break;
+ 		case 'c':
+ 			create++;
+ 			break;
  		case 'd':
  			delete++;
  			break;
***************
*** 101,106 ****
--- 152,160 ----
  		case 'F':
  			dsd.flags |= WSDISPLAY_DELSCR_FORCE;
  			break;
+ 		case 'C':
+ 			charset = optarg;
+ 			break;
  		case '?':
  		default:
  			usage();
***************
*** 141,147 ****
  		res = ioctl(wsfd, WSDISPLAYIO_DELSCREEN, &dsd);
  		if (res < 0)
  			err(3, "WSDISPLAYIO_DELSCREEN");
! 	} else {
  		asd.idx = idx;
  		res = ioctl(wsfd, WSDISPLAYIO_ADDSCREEN, &asd);
  		if (res < 0) {
--- 195,201 ----
  		res = ioctl(wsfd, WSDISPLAYIO_DELSCREEN, &dsd);
  		if (res < 0)
  			err(3, "WSDISPLAYIO_DELSCREEN");
! 	} else if (create) {
  		asd.idx = idx;
  		res = ioctl(wsfd, WSDISPLAYIO_ADDSCREEN, &asd);
  		if (res < 0) {
***************
*** 150,155 ****
--- 204,217 ----
  			else
  				err(3, "WSDISPLAYIO_ADDSCREEN");
  		}
+ 	}
+ 
+ 	if (charset != NULL && kbd == 0 && delete == 0) {
+ 		e.idx = idx;
+ 		e.encoding = getencoding(charset);
+ 		res = ioctl(wsfd, WSDISPLAYIO_SENCODING, &e);
+ 		if (res < 0)
+ 			err(3, "WSDISPLAYIO_SENCODING");
  	}
  
  	return (0);

--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wsfontload.patch"

? .gdbinit
? wsfontload
? wsfontload.cat8
? wsfontload.patch
Index: wsfontload.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/wsfontload/wsfontload.8,v
retrieving revision 1.20
diff -c -r1.20 wsfontload.8
*** wsfontload.8	2003/02/25 10:36:23	1.20
--- wsfontload.8	2003/04/09 15:22:39
***************
*** 24,30 ****
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .Dd November 8, 2000
  .Os
  .Dt WSFONTLOAD 8
  .Sh NAME
--- 24,30 ----
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .Dd April 9, 2003
  .Os
  .Dt WSFONTLOAD 8
  .Sh NAME
***************
*** 42,47 ****
--- 42,50 ----
  .Op Fl h Ar height
  .Ek
  .Bk -words
+ .Op Fl c Ar fstchar
+ .Ek
+ .Bk -words
  .Op Fl e Ar encoding
  .Ek
  .Bk -words
***************
*** 80,85 ****
--- 83,91 ----
  Sets the width of a font character in pixels. Default is 8.
  .It Fl h Ar height
  Sets the height of a font character in pixels. Default is 16.
+ .It Fl c Ar fstchar
+ Sets the first character of the font in decimal or hexadecimal.
+ Default is 0.
  .It Fl e Ar encoding
  Sets the encoding of the font. This can be either a symbolic abbreviation
  or a numeric value. Currently recognized abbreviations are
***************
*** 129,134 ****
--- 135,146 ----
  50-line screen type on
  .Xr vga 4
  displays.
+ .Pp
+ .Dl wsfontload -N uhangul -h 16 -c 0xac00 -e uni 
+ /usr/share/wscons/fonts/uhangul1616
+ .Pp
+ Load the Unicode-encoded Hangul (Korean) font of which the first character
+ begins at 0xac00.
  .Sh SEE ALSO
  .Xr wscons 4 ,
  .Xr wsconscfg 8 ,
Index: wsfontload.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/wsfontload/wsfontload.c,v
retrieving revision 1.8
diff -c -r1.8 wsfontload.c
*** wsfontload.c	2001/10/29 17:58:19	1.8
--- wsfontload.c	2003/04/09 15:22:39
***************
*** 39,44 ****
--- 39,45 ----
  #include <unistd.h>
  #include <sys/types.h>
  #include <sys/ioctl.h>
+ #include <sys/stat.h>
  #include <err.h>
  #include <malloc.h>
  
***************
*** 47,52 ****
--- 48,55 ----
  #define DEFDEV		"/dev/wsfont"
  #define DEFWIDTH	8
  #define DEFHEIGHT	16
+ #define DEFFIRSTCHAR	0
+ #define DEFNUMCHARS	256
  #define DEFENC		WSDISPLAY_FONTENC_ISO
  #define DEFBITORDER	WSDISPLAY_FONTORDER_L2R
  #define DEFBYTEORDER	WSDISPLAY_FONTORDER_L2R
***************
*** 56,61 ****
--- 59,65 ----
  static int getencoding __P((char *));
  static char *rgetencoding __P((int));
  static char *rgetfontorder __P((int));
+ static char *readfont __P((char *, struct wsdisplay_font *));
  
  static struct {
  	char *name;
***************
*** 63,80 ****
  } fontorders[] = {
  	{ "known", WSDISPLAY_FONTORDER_KNOWN}, 
  	{ "l2r", WSDISPLAY_FONTORDER_L2R}, 
! 	{ "r2l", WSDISPLAY_FONTORDER_R2L}, 
  };
  
  static struct {
  	char *name;
  	int val;
  } encodings[] = {
- 	{"iso", WSDISPLAY_FONTENC_ISO},
  	{"ibm", WSDISPLAY_FONTENC_IBM},
  	{"pcvt", WSDISPLAY_FONTENC_PCVT},
! 	{"iso7", WSDISPLAY_FONTENC_ISO7},
  	{"iso2", WSDISPLAY_FONTENC_ISO2},
  };
  
  static void
--- 67,93 ----
  } fontorders[] = {
  	{ "known", WSDISPLAY_FONTORDER_KNOWN}, 
  	{ "l2r", WSDISPLAY_FONTORDER_L2R}, 
! 	{ "r2l", WSDISPLAY_FONTORDER_R2L},
  };
  
  static struct {
  	char *name;
  	int val;
  } encodings[] = {
  	{"ibm", WSDISPLAY_FONTENC_IBM},
  	{"pcvt", WSDISPLAY_FONTENC_PCVT},
! 	{"iso", WSDISPLAY_FONTENC_ISO},
  	{"iso2", WSDISPLAY_FONTENC_ISO2},
+ 	{"iso4", WSDISPLAY_FONTENC_ISO4},
+ 	{"iso7", WSDISPLAY_FONTENC_ISO7},
+ 	{"iso8", WSDISPLAY_FONTENC_ISO8},
+ 	{"iso9", WSDISPLAY_FONTENC_ISO9},
+ 	{"iso15", WSDISPLAY_FONTENC_ISO15},
+ 	{"uni", WSDISPLAY_FONTENC_UNI},
+ 	{"gb", WSDISPLAY_FONTENC_GB},
+ 	{"jis", WSDISPLAY_FONTENC_JIS},
+ 	{"ks", WSDISPLAY_FONTENC_KS},
+ 	{"koi8", WSDISPLAY_FONTENC_KOI8},
  };
  
  static void
***************
*** 82,89 ****
  {
  
  	(void)fprintf(stderr,
! 		"Usage: %s [-f wsdev] [-w width] [-h height] [-e encoding]"
! 		" [-N name] [-b] [-B] [fontfile]\n",
  		      getprogname());
  	exit(1);
  }
--- 95,102 ----
  {
  
  	(void)fprintf(stderr,
! 		"Usage: %s [-f wsdev] [-w width] [-h height] [-c firstchar]"
! 		"[-e encoding] [-N name] [-b] [-B] [fontfile]\n",
  		      getprogname());
  	exit(1);
  }
***************
*** 138,143 ****
--- 151,200 ----
  	return (i);
  }
  
+ static char *
+ readfont(name, f)
+ 	char *name;
+ 	struct wsdisplay_font *f;
+ {
+ 	size_t len;
+ 	int ffd, res;
+ 	void *buf;
+ 
+ 	ffd = open(name, O_RDONLY, 0);
+ 	if (ffd < 0)
+ 		err(4, "open font %s", name);
+ 
+ 	if (f->name == NULL)
+ 		f->name = name;
+ 	if (f->stride == 0)
+ 		f->stride = (f->fontwidth + 7) / 8;
+ 	if (f->encoding == WSDISPLAY_FONTENC_UNI ||
+ 	    f->encoding == WSDISPLAY_FONTENC_JIS ||
+ 	    f->encoding == WSDISPLAY_FONTENC_KS) {
+ 		struct stat sb;
+ 
+ 		stat(name, &sb);
+ 		f->numchars = sb.st_size / (f->fontheight * f->stride);
+ 		len = sb.st_size;
+ 	} else
+ 		len = f->fontheight * f->stride * f->numchars;
+ 	if (!len)
+ 		errx(1, "invalid font size");
+ 
+ 	buf = malloc(len);
+ 	if (!buf)
+ 		errx(1, "malloc");
+ 
+ 	res = read(ffd, buf, len);
+ 	if (res < 0)
+ 		err(4, "read font");
+ 	if (res != len)
+ 		errx(4, "short read");
+ 
+ 	close(ffd);
+ 	return buf;
+ }
+ 
  int
  main(argc, argv)
  	int argc;
***************
*** 145,166 ****
  {
  	char *wsdev;
  	struct wsdisplay_font f;
! 	int c, res, wsfd, ffd, verbose = 0;
! 	size_t len;
! 	void *buf;
! 
  	wsdev = DEFDEV;
  	f.fontwidth = DEFWIDTH;
  	f.fontheight = DEFHEIGHT;
! 	f.firstchar = 0;
! 	f.numchars = 256;
  	f.stride = 0;
  	f.encoding = DEFENC;
  	f.name = 0;
  	f.bitorder = DEFBITORDER;
  	f.byteorder = DEFBYTEORDER;
  
! 	while ((c = getopt(argc, argv, "f:w:h:e:N:bB:v")) != -1) {
  		switch (c) {
  		case 'f':
  			wsdev = optarg;
--- 202,222 ----
  {
  	char *wsdev;
  	struct wsdisplay_font f;
! 	int c, res, wsfd, verbose;
! 	 
! 	verbose = 0;
  	wsdev = DEFDEV;
  	f.fontwidth = DEFWIDTH;
  	f.fontheight = DEFHEIGHT;
! 	f.firstchar = DEFFIRSTCHAR;
! 	f.numchars = DEFNUMCHARS;
  	f.stride = 0;
  	f.encoding = DEFENC;
  	f.name = 0;
  	f.bitorder = DEFBITORDER;
  	f.byteorder = DEFBYTEORDER;
  
! 	while ((c = getopt(argc, argv, "f:w:h:c:e:N:bB:v")) != -1) {
  		switch (c) {
  		case 'f':
  			wsdev = optarg;
***************
*** 173,178 ****
--- 229,239 ----
  			if (sscanf(optarg, "%d", &f.fontheight) != 1)
  				errx(1, "invalid font height");
  			break;
+ 		case 'c':
+ 			if (sscanf(optarg, "%d", &f.firstchar) != 1 &&
+ 			    sscanf(optarg, "%x", &f.firstchar) != 1)
+ 				errx(1, "invalid first character");
+ 			break;
  		case 'e':
  			f.encoding = getencoding(optarg);
  			break;
***************
*** 203,234 ****
  	wsfd = open(wsdev, O_RDWR, 0);
  	if (wsfd < 0)
  		err(2, "open ws-device %s", wsdev);
- 
- 	if (argc > 0) {
- 		ffd = open(argv[0], O_RDONLY, 0);
- 		if (ffd < 0)
- 			err(4, "open font %s", argv[0]);
- 		if (!f.name)
- 			f.name = argv[0];
- 	} else
- 		ffd = 0;
- 
- 	if (!f.stride)
- 		f.stride = (f.fontwidth + 7) / 8;
- 	len = f.fontheight * f.numchars * f.stride;
- 	if (!len)
- 		errx(1, "invalid font size");
- 
- 	buf = malloc(len);
- 	if (!buf)
- 		errx(1, "malloc");
- 	res = read(ffd, buf, len);
- 	if (res < 0)
- 		err(4, "read font");
- 	if (res != len)
- 		errx(4, "short read");
  
! 	f.data = buf;
  
  	if (verbose) {
  		printf("name:       %s\n", f.name);
--- 264,271 ----
  	wsfd = open(wsdev, O_RDWR, 0);
  	if (wsfd < 0)
  		err(2, "open ws-device %s", wsdev);
  
! 	f.data = readfont(argv[0], &f);
  
  	if (verbose) {
  		printf("name:       %s\n", f.name);

--tThc/1wpZn/ma/RB--