diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2013-10-18 22:06:43 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2013-10-18 22:06:43 +0000 |
commit | da16c4a585db0f4d4c68c63f8e1ec68bad619792 (patch) | |
tree | 1dd99714301bad2a62381dbe13004d2239dffef4 /sys | |
parent | 0c0471767b4261526224c8ef1d331039f4c50a3a (diff) |
UTF-8 support for wsdisplay emulation modes. Both vt100 and sun emulation
will now recognize xterm-compatible escape sequences ESC % G and ESC % @ to
enter and leave UTF-8 mode, respectively.
Not enabled on SMALL_KERNEL.
Most of this written during c2k7, completed during b2k13.
Note that the value of several international keysyms change, to switch from
ISO Latin-[257] values to the real Unicode values. Be sure to update your
includes and rebuild and install wsconsctl.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/wscons/files.wscons | 3 | ||||
-rw-r--r-- | sys/dev/wscons/wscons_callbacks.h | 4 | ||||
-rw-r--r-- | sys/dev/wscons/wscons_features.h | 6 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 20 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_dumb.c | 7 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_subr.c | 706 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_sun.c | 198 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_vt100.c | 289 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_vt100_chars.c | 4 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_vt100_keys.c | 23 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_vt100_subr.c | 20 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_vt100var.h | 17 | ||||
-rw-r--r-- | sys/dev/wscons/wsemulvar.h | 26 | ||||
-rw-r--r-- | sys/dev/wscons/wskbd.c | 4 | ||||
-rw-r--r-- | sys/dev/wscons/wsksymdef.h | 404 |
15 files changed, 1358 insertions, 373 deletions
diff --git a/sys/dev/wscons/files.wscons b/sys/dev/wscons/files.wscons index 724347eba54..9893665ea92 100644 --- a/sys/dev/wscons/files.wscons +++ b/sys/dev/wscons/files.wscons @@ -1,4 +1,4 @@ -# $OpenBSD: files.wscons,v 1.15 2007/05/31 22:23:13 tedu Exp $ +# $OpenBSD: files.wscons,v 1.16 2013/10/18 22:06:40 miod Exp $ # $NetBSD: files.wscons,v 1.34 2005/05/04 01:52:16 augustss Exp $ # @@ -35,6 +35,7 @@ file dev/wscons/wsmux.c wsmux needs-flag # emulation code file dev/wscons/wsemulconf.c wsdisplay file dev/wscons/wsemul_dumb.c wsdisplay & wsemul_dumb +file dev/wscons/wsemul_subr.c wsdisplay file dev/wscons/wsemul_sun.c wsdisplay & wsemul_sun file dev/wscons/wsemul_vt100.c wsdisplay & !wsemul_no_vt100 file dev/wscons/wsemul_vt100_subr.c wsdisplay & !wsemul_no_vt100 diff --git a/sys/dev/wscons/wscons_callbacks.h b/sys/dev/wscons/wscons_callbacks.h index 48933af6332..ddfd08d36e9 100644 --- a/sys/dev/wscons/wscons_callbacks.h +++ b/sys/dev/wscons/wscons_callbacks.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wscons_callbacks.h,v 1.8 2010/11/20 20:52:10 miod Exp $ */ +/* $OpenBSD: wscons_callbacks.h,v 1.9 2013/10/18 22:06:40 miod Exp $ */ /* $NetBSD: wscons_callbacks.h,v 1.16 2001/11/10 17:14:51 augustss Exp $ */ /* @@ -41,7 +41,7 @@ void wsdisplay_set_console_kbd(struct wsevsrc *); /* * Calls to the display interface from the keyboard interface. */ -void wsdisplay_kbdinput(struct device *v, keysym_t *, int); +void wsdisplay_kbdinput(struct device *v, kbd_t, keysym_t *, int); void wsdisplay_rawkbdinput(struct device *v, u_char *, int); int wsdisplay_switch(struct device *, int, int); enum wsdisplay_resetops { diff --git a/sys/dev/wscons/wscons_features.h b/sys/dev/wscons/wscons_features.h index b18603fe4e8..58ffaeb2ca7 100644 --- a/sys/dev/wscons/wscons_features.h +++ b/sys/dev/wscons/wscons_features.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wscons_features.h,v 1.2 2013/10/18 14:17:23 miod Exp $ */ +/* $OpenBSD: wscons_features.h,v 1.3 2013/10/18 22:06:40 miod Exp $ */ /* public domain */ /* @@ -15,6 +15,9 @@ * wsdisplay supports this * HAVE_JUMP_SCROLL * defined to enable jump scroll in the textmode emulation code + * HAVE_UTF8_SUPPORT + * defined to enable UTF-8 mode and escape sequences in the textmode + * emulation code * HAVE_RESTARTABLE_EMULOPS * defined to disable most of the restartable emulops code (to be used * only if all wsdisplay drivers are compliant, i.e. no udl(4) in the @@ -28,6 +31,7 @@ #define HAVE_BURNER_SUPPORT #define HAVE_SCROLLBACK_SUPPORT #define HAVE_JUMP_SCROLL +#define HAVE_UTF8_SUPPORT #define HAVE_RESTARTABLE_EMULOPS #endif diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 867be152a9f..f32a2fbdfeb 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplay.c,v 1.113 2013/10/18 13:54:08 miod Exp $ */ +/* $OpenBSD: wsdisplay.c,v 1.114 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */ /* @@ -1602,11 +1602,11 @@ wsdisplay_emulinput(void *v, const u_char *data, u_int count) * Calls from the keyboard interface. */ void -wsdisplay_kbdinput(struct device *dev, keysym_t *ks, int num) +wsdisplay_kbdinput(struct device *dev, kbd_t layout, keysym_t *ks, int num) { struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev; struct wsscreen *scr; - const char *dp; + const u_char *dp; int count; struct tty *tp; @@ -1616,15 +1616,11 @@ wsdisplay_kbdinput(struct device *dev, keysym_t *ks, int num) tp = scr->scr_tty; - for (; num > 0; num--, ks++) { - if (KS_GROUP(*ks) == KS_GROUP_Ascii) - (*linesw[tp->t_line].l_rint)(KS_VALUE(*ks), tp); - else { - count = (*scr->scr_dconf->wsemul->translate) - (scr->scr_dconf->wsemulcookie, *ks, &dp); - while (count-- > 0) - (*linesw[tp->t_line].l_rint)(*dp++, tp); - } + for (; num > 0; num--) { + count = (*scr->scr_dconf->wsemul->translate) + (scr->scr_dconf->wsemulcookie, layout, *ks++, &dp); + while (count-- > 0) + (*linesw[tp->t_line].l_rint)(*dp++, tp); } } diff --git a/sys/dev/wscons/wsemul_dumb.c b/sys/dev/wscons/wsemul_dumb.c index 86010f0666a..1226cb2cd72 100644 --- a/sys/dev/wscons/wsemul_dumb.c +++ b/sys/dev/wscons/wsemul_dumb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_dumb.c,v 1.10 2010/08/28 12:48:14 miod Exp $ */ +/* $OpenBSD: wsemul_dumb.c,v 1.11 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_dumb.c,v 1.7 2000/01/05 11:19:36 drochner Exp $ */ /* @@ -47,7 +47,7 @@ void *wsemul_dumb_cnattach(const struct wsscreen_descr *, void *, void *wsemul_dumb_attach(int, const struct wsscreen_descr *, void *, int, int, void *, long); u_int wsemul_dumb_output(void *, const u_char *, u_int, int); -int wsemul_dumb_translate(void *, keysym_t, const char **); +int wsemul_dumb_translate(void *, kbd_t, keysym_t, const u_char **); void wsemul_dumb_detach(void *, u_int *, u_int *); void wsemul_dumb_resetop(void *, enum wsemul_resetops); @@ -285,7 +285,8 @@ wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int kernel) } int -wsemul_dumb_translate(void *cookie, keysym_t in, const char **out) +wsemul_dumb_translate(void *cookie, kbd_t layout, keysym_t in, + const u_char **out) { return (0); } diff --git a/sys/dev/wscons/wsemul_subr.c b/sys/dev/wscons/wsemul_subr.c new file mode 100644 index 00000000000..50d7b7a2436 --- /dev/null +++ b/sys/dev/wscons/wsemul_subr.c @@ -0,0 +1,706 @@ +/* $OpenBSD: wsemul_subr.c,v 1.1 2013/10/18 22:06:41 miod Exp $ */ + +/* + * Copyright (c) 2007, 2013 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/errno.h> + +#include <dev/wscons/wscons_features.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/wscons/wsemulvar.h> +#include <dev/wscons/wsksymdef.h> + +int wsemul_local_translate(u_int32_t, kbd_t, u_char *); + +/* + * Get characters from an input stream and update the input state. + * Processing stops when the stream is empty, or a complete character + * sequence has been recognized, in which case it returns zero. + */ +int +wsemul_getchar(const u_char **inbuf, u_int *inlen, + struct wsemul_inputstate *state, int allow_utf8) +{ +#ifndef HAVE_UTF8_SUPPORT + u_int len = *inlen; + const u_char *buf = *inbuf; + + if (len == 0) + return (EAGAIN); + + state->inchar = *buf++; + state->mbleft = 0; + len--; + *inlen = len; + *inbuf = buf; + return (0); +#else + u_int len = *inlen; + const u_char *buf = *inbuf; + int rc = EAGAIN; + u_int32_t tmpchar; + u_int mbleft; + + if (len == 0) + return (rc); + + /* + * If we do not allow multibyte sequences, process as quickly + * as possible. + */ + if (!allow_utf8) { + state->inchar = *buf++; + state->mbleft = 0; + len--; + *inlen = len; + *inbuf = buf; + return (0); + } + + tmpchar = state->inchar; + mbleft = state->mbleft; + + while (len != 0) { + u_int32_t frag = (u_int32_t)*buf++; + len--; + + /* + * If we are in the middle of a multibyte sequence, try + * to complete it. + */ + + if (mbleft != 0) { + if ((frag & 0xc0) != 0x80) { + /* Abort the sequence and continue */ + mbleft = 0; + tmpchar = 0; + rc = EILSEQ; + } else { + tmpchar = (tmpchar << 6) | (frag & 0x3f); + mbleft--; + if (mbleft == 0) { + rc = 0; + break; + } + } + } + + /* + * Otherwise let's decide if this is the start of a new + * multibyte sequence, or a 7-bit character. + */ + + if ((frag & 0x80) == 0) { + tmpchar = frag; + rc = 0; + break; + } + + if (frag == 0xfe || frag == 0xff || (frag & 0x40) == 0) { + /* Abort the sequence and continue */ + mbleft = 0; + tmpchar = 0; + rc = EILSEQ; + } else { + frag &= ~(0x80 | 0x40); + mbleft = 1; + + if (frag & 0x20) { + frag &= ~0x20; + mbleft++; + } + if (frag & 0x10) { + frag &= ~0x10; + mbleft++; + } + if (frag & 0x08) { + frag &= ~0x08; + mbleft++; + } + if (frag & 0x04) { + frag &= ~0x04; + mbleft++; + } + + tmpchar = frag; + } + } + + state->inchar = tmpchar; + state->mbleft = mbleft; + *inlen = len; + *inbuf = buf; + return (rc); +#endif +} + +/* + * Unicode Cyrillic to KOI8 translation table (starts at U+0400), + * from RFC 2319. + */ +const u_int8_t cyrillic_to_koi8[] = { + 0x00, /* IE grave */ /* 0400 */ + 0xb3, /* IO */ + 0x00, /* DJE */ + 0x00, /* GJE */ + 0xb4, /* UKR IE */ + 0x00, /* DZE */ + 0xb6, /* BYE/UKR I */ + 0xb7, /* YI */ + 0x00, /* JE */ + 0x00, /* LJE */ + 0x00, /* NJE */ + 0x00, /* TSHE */ + 0x00, /* KJE */ + 0x00, /* I grave */ + 0x00, /* short U */ + 0x00, /* DZHE */ + 0xe1, /* A */ /* 0410 */ + 0xe2, /* BE */ + 0xf7, /* VE */ + 0xe7, /* GHE */ + 0xe4, /* DE */ + 0xe5, /* IE */ + 0xf6, /* ZHE */ + 0xfa, /* ZE */ + 0xe9, /* I */ + 0xea, /* short I */ + 0xeb, /* KA */ + 0xec, /* EL */ + 0xed, /* EM */ + 0xee, /* EN */ + 0xef, /* O */ + 0xf0, /* PE */ + 0xf2, /* ER */ /* 0420 */ + 0xf3, /* ES */ + 0xf4, /* TE */ + 0xf5, /* U */ + 0xe6, /* EF */ + 0xe8, /* HA */ + 0xe3, /* TSE */ + 0xfe, /* CHE */ + 0xfb, /* SHA */ + 0xfd, /* SHCHA */ + 0xff, /* HARD SIGN */ + 0xf9, /* YERU */ + 0xf8, /* SOFT SIGN */ + 0xfc, /* E */ + 0xe0, /* YU */ + 0xf1, /* YA */ + 0xc1, /* a */ /* 0430 */ + 0xc2, /* be */ + 0xd7, /* ve */ + 0xc7, /* ghe */ + 0xc4, /* de */ + 0xc5, /* ie */ + 0xd6, /* zhe */ + 0xda, /* ze */ + 0xc9, /* i */ + 0xca, /* short i */ + 0xcb, /* ka */ + 0xcc, /* el */ + 0xcd, /* em */ + 0xce, /* en */ + 0xcf, /* o */ + 0xd0, /* pe */ + 0xd2, /* er */ /* 0440 */ + 0xd3, /* es */ + 0xd4, /* te */ + 0xd5, /* u */ + 0xc6, /* ef */ + 0xc8, /* ha */ + 0xc3, /* tse */ + 0xde, /* che */ + 0xdb, /* sha */ + 0xdd, /* shcha */ + 0xdf, /* hard sign */ + 0xd9, /* yeru */ + 0xd8, /* soft sign */ + 0xdc, /* e */ + 0xc0, /* yu */ + 0xd1, /* ya */ + 0x00, /* ie grave */ /* 0450 */ + 0xa3, /* io */ + 0x00, /* dje */ + 0x00, /* GJE */ + 0xa4, /* UKR ie */ + 0x00, /* DZE */ + 0xa6, /* BYE/UKR I */ + 0xa7, /* YI */ + 0x00, /* JE */ + 0x00, /* LJE */ + 0x00, /* NJE */ + 0x00, /* TSHE */ + 0x00, /* KJE */ + 0x00, /* I grave */ + 0x00, /* short U */ + 0x00 /* DZHE */ +}; + +/* + * Europe to Latin-2 translation table (starts at U+0100). + */ +const u_int8_t unicode_to_latin2[] = { + 0x00, /* A macron */ /* 0100 */ + 0x00, /* a macron */ + 0xc3, /* A breve */ + 0xe3, /* a breve */ + 0xa1, /* A ogonek */ + 0xb1, /* a ogonek */ + 0xc6, /* C acute */ + 0xe6, /* c acute */ + 0x00, /* C circumflex */ + 0x00, /* c circumflex */ + 0x00, /* C abovering */ + 0x00, /* c abovering */ + 0xc8, /* C caron */ + 0xe8, /* c caron */ + 0xcf, /* D caron */ + 0xef, /* d caron */ + 0xd0, /* D stroke */ /* 0110 */ + 0xf0, /* d stroke */ + 0x00, /* E macron */ + 0x00, /* e macron */ + 0x00, /* E breve */ + 0x00, /* e breve */ + 0x00, /* E abovering */ + 0x00, /* e abovering */ + 0xca, /* E ogonek */ + 0xea, /* e ogonek */ + 0xcc, /* E caron */ + 0xec, /* e caron */ + 0x00, /* G circumflex */ + 0x00, /* g circumflex */ + 0x00, /* G breve */ + 0x00, /* g breve */ + 0x00, /* G abovering */ /* 0120 */ + 0x00, /* g abovering */ + 0x00, /* G cedilla */ + 0x00, /* g cedilla */ + 0x00, /* H circumflex */ + 0x00, /* h circumflex */ + 0x00, /* H stroke */ + 0x00, /* h stroke */ + 0x00, /* I tilde */ + 0x00, /* i tilde */ + 0x00, /* I macron */ + 0x00, /* i macron */ + 0x00, /* I breve */ + 0x00, /* i breve */ + 0x00, /* I ogonek */ + 0x00, /* i ogonek */ + 0x00, /* dotted I */ /* 0130 */ + 0x00, /* non-dotted i */ + 0x00, /* ligature IJ */ + 0x00, /* ligature ij */ + 0x00, /* J circumflex */ + 0x00, /* j circumflex */ + 0x00, /* K cedilla */ + 0x00, /* k cedilla */ + 0x00, /* kra */ + 0xc5, /* L acute */ + 0xe5, /* l acute */ + 0x00, /* L cedilla */ + 0x00, /* l cedilla */ + 0xa5, /* L caron */ + 0xb5, /* l caron */ + 0x00, /* L middle dot */ + 0x00, /* l middle dot */ /* 0140 */ + 0xa3, /* L stroke */ + 0xb3, /* l stroke */ + 0xd1, /* N acute */ + 0xf1, /* n acute */ + 0x00, /* N cedilla */ + 0x00, /* n cedilla */ + 0xd2, /* N caron */ + 0xf2, /* n caron */ + 0x00, /* N preceded by apostrophe */ + 0x00, /* ENG */ + 0x00, /* eng */ + 0x00, /* O macron */ + 0x00, /* o macron */ + 0x00, /* O breve */ + 0x00, /* o breve */ + 0xd5, /* O double acute */ /* 0150 */ + 0xf5, /* o double acute */ + 0x00, /* ligature OE */ + 0x00, /* ligature oe */ + 0xc0, /* R acute */ + 0xe0, /* r acute */ + 0x00, /* R cedilla */ + 0x00, /* r cedilla */ + 0xd8, /* R caron */ + 0xf8, /* r caron */ + 0xa6, /* S acute */ + 0xb6, /* s acute */ + 0x00, /* S circumflex */ + 0x00, /* s circumflex */ + 0xaa, /* S cedilla */ + 0xba, /* s cedilla */ + 0xa9, /* S caron */ /* 0160 */ + 0xb9, /* s caron */ + 0xde, /* T cedilla */ + 0xfe, /* t cedilla */ + 0xab, /* T caron */ + 0xbb, /* t caron */ + 0x00, /* T stroke */ + 0x00, /* t stroke */ + 0x00, /* U tilde */ + 0x00, /* u tilde */ + 0x00, /* U macron */ + 0x00, /* u macron */ + 0x00, /* U breve */ + 0x00, /* u breve */ + 0xd9, /* U abovering */ + 0xf9, /* u abovering */ + 0xdb, /* U double acute */ /* 0170 */ + 0xfb, /* u double acute */ + 0x00, /* U ogonek */ + 0x00, /* u ogonek */ + 0x00, /* W circumflex */ + 0x00, /* w circumflex */ + 0x00, /* Y circumflex */ + 0x00, /* y circumflex */ + 0x00, /* Y diaeresis */ + 0xac, /* Z acute */ + 0xbc, /* z acute */ + 0xaf, /* Z abovering */ + 0xbf, /* z abovering */ + 0xae, /* Z caron */ + 0xbe, /* z caron */ + 0x00 /* long s */ +}; + +/* + * Baltic to Latin-7 translation table. + */ +const u_int8_t unicode_to_latin7[] = { + 0xc2, /* A macron */ /* 0100 */ + 0xe2, /* a macron */ + 0x00, /* A breve */ + 0x00, /* a breve */ + 0xc0, /* A ogonek */ + 0xe0, /* a ogonek */ + 0xc3, /* C acute */ + 0xe3, /* c acute */ + 0x00, /* C circumflex */ + 0x00, /* c circumflex */ + 0x00, /* C abovering */ + 0x00, /* c abovering */ + 0xc8, /* C caron */ + 0xe8, /* c caron */ + 0x00, /* D caron */ + 0x00, /* d caron */ + 0x00, /* D stroke */ /* 0110 */ + 0x00, /* d stroke */ + 0xc7, /* E macron */ + 0xe7, /* e macron */ + 0x00, /* E breve */ + 0x00, /* e breve */ + 0xcb, /* E abovering */ + 0xeb, /* e abovering */ + 0xc6, /* E ogonek */ + 0xe6, /* e ogonek */ + 0x00, /* E caron */ + 0x00, /* e caron */ + 0x00, /* G circumflex */ + 0x00, /* g circumflex */ + 0x00, /* G breve */ + 0x00, /* g breve */ + 0x00, /* G abovering */ /* 0120 */ + 0x00, /* g abovering */ + 0xcc, /* G cedilla */ + 0xec, /* g cedilla */ + 0x00, /* H circumflex */ + 0x00, /* h circumflex */ + 0x00, /* H stroke */ + 0x00, /* h stroke */ + 0x00, /* I tilde */ + 0x00, /* i tilde */ + 0xce, /* I macron */ + 0xee, /* i macron */ + 0x00, /* I breve */ + 0x00, /* i breve */ + 0xc1, /* I ogonek */ + 0xe1, /* i ogonek */ + 0x00, /* dotted I */ /* 0130 */ + 0x00, /* non-dotted I */ + 0x00, /* ligature IJ */ + 0x00, /* ligature ij */ + 0x00, /* J circumflex */ + 0x00, /* j circumflex */ + 0xcd, /* K cedilla */ + 0xed, /* k cedilla */ + 0x00, /* kra */ + 0x00, /* L acute */ + 0x00, /* l acute */ + 0xcf, /* L cedilla */ + 0xef, /* l cedilla */ + 0x00, /* L caron */ + 0x00, /* l caron */ + 0x00, /* L middle dot */ + 0x00, /* l middle dot */ /* 0140 */ + 0xd9, /* L stroke */ + 0xf9, /* l stroke */ + 0xd1, /* N acute */ + 0xf1, /* n acute */ + 0xd2, /* N cedilla */ + 0xf2, /* n cedilla */ + 0x00, /* N caron */ + 0x00, /* n caron */ + 0x00, /* N preceded by apostrophe */ + 0x00, /* ENG */ + 0x00, /* eng */ + 0xd4, /* O macron */ + 0xf4, /* o macron */ + 0x00, /* O breve */ + 0x00, /* o breve */ + 0x00, /* O double acute */ /* 0150 */ + 0x00, /* o double acute */ + 0x00, /* ligature OE */ + 0x00, /* ligature oe */ + 0x00, /* R acute */ + 0x00, /* r acute */ + 0xaa, /* R cedilla */ + 0xba, /* r cedilla */ + 0x00, /* R caron */ + 0x00, /* r caron */ + 0xda, /* S acute */ + 0xfa, /* s acute */ + 0x00, /* S circumflex */ + 0x00, /* s circumflex */ + 0x00, /* S cedilla */ + 0x00, /* s cedilla */ + 0xd0, /* S caron */ /* 0160 */ + 0xf0, /* s caron */ + 0x00, /* T cedilla */ + 0x00, /* t cedilla */ + 0x00, /* T caron */ + 0x00, /* t caron */ + 0x00, /* T stroke */ + 0x00, /* t stroke */ + 0x00, /* U tilde */ + 0x00, /* u tilde */ + 0xdb, /* U macron */ + 0xfb, /* u macron */ + 0x00, /* U breve */ + 0x00, /* u breve */ + 0x00, /* U abovering */ + 0x00, /* u abovering */ + 0x00, /* U double acute */ /* 0170 */ + 0x00, /* u double acute */ + 0xd8, /* U ogonek */ + 0xf8, /* u ogonek */ + 0x00, /* W circumflex */ + 0x00, /* w circumflex */ + 0x00, /* Y circumflex */ + 0x00, /* y circumflex */ + 0x00, /* Y diaeresis */ + 0xca, /* Z acute */ + 0xea, /* z acute */ + 0xdd, /* Z abovering */ + 0xfd, /* z abovering */ + 0xde, /* Z caron */ + 0xfe, /* z caron */ + 0x00 /* long s */ +}; + +/* + * Keysym to local 8-bit charset sequence translation function. + * The out buffer is at least one character long. + * The keyboard layout is used as a hint to decide which latin charset to + * assume. + */ +int +wsemul_local_translate(u_int32_t unisym, kbd_t layout, u_char *out) +{ + switch (unisym >> 7) { + case 0x0080 >> 7: + switch (KB_ENCODING(layout)) { + case KB_LT: + case KB_LV: + switch (unisym) { + case KS_L7_AE: + unisym = 0xaf; + break; + case KS_L7_Ostroke: + unisym = 0xa8; + break; + case KS_L7_ae: + unisym = 0xbf; + break; + case KS_L7_ostroke: + unisym = 0xb8; + break; + } + } + break; + + case 0x0100 >> 7: + switch (KB_ENCODING(layout)) { + case KB_LT: + case KB_LV: + if (unisym < 0x100 + nitems(unicode_to_latin7) && + unicode_to_latin7[unisym - 0x100] != 0) + unisym = unicode_to_latin7[unisym - 0x100]; + break; + case KB_TR: + switch (unisym) { + case KS_L5_Gbreve: + unisym = 0xd0; + break; + case KS_L5_gbreve: + unisym = 0xf0; + break; + case KS_L5_Idotabove: + unisym = 0xdd; + break; + case KS_L5_idotless: + unisym = 0xfd; + break; + case KS_L5_Scedilla: + unisym = 0xde; + break; + case KS_L5_scedilla: + unisym = 0xfe; + break; + } + break; + case KB_PL: + case KB_SI: + if (unisym < 0x100 + nitems(unicode_to_latin2) && + unicode_to_latin2[unisym - 0x100] != 0) + unisym = unicode_to_latin2[unisym - 0x100]; + break; + } + break; + + case 0x0280 >> 7: + switch (KB_ENCODING(layout)) { + case KB_PL: + case KB_SI: + switch (unisym) { + case KS_L2_caron: + unisym = 0xb7; + break; + case KS_L2_breve: + unisym = 0xa2; + break; + case KS_L2_dotabove: + unisym = 0xff; + break; + case KS_L2_ogonek: + unisym = 0xb2; + break; + case KS_L2_dblacute: + unisym = 0xbd; + break; + } + break; + } + break; + + case 0x0400 >> 7: + if (unisym < 0x400 + + sizeof(cyrillic_to_koi8) / sizeof(cyrillic_to_koi8[0]) && + cyrillic_to_koi8[unisym - 0x400] != 0) + unisym = cyrillic_to_koi8[unisym - 0x400]; + break; + case 0x0480 >> 7: + if (unisym == KS_Cyrillic_GHEUKR) + unisym = 0xbd; /* ukrainian GHE */ + else if (unisym == KS_Cyrillic_gheukr) + unisym = 0xad; /* ukrainian ghe */ + break; + + case 0x2000 >> 7: + switch (KB_ENCODING(layout)) { + case KB_LT: + case KB_LV: + switch (unisym) { + case KS_L7_rightsnglquot: + unisym = 0xff; + break; + case KS_L7_leftdblquot: + unisym = 0xb4; + break; + case KS_L7_rightdblquot: + unisym = 0xa1; + break; + case KS_L7_dbllow9quot: + unisym = 0xa5; + break; + } + } + break; + + } + + out[0] = unisym & 0xff; + return (1); +} + +/* + * Keysym to UTF-8 sequence translation function. + * The out buffer is at least 6 characters long. + */ +int +wsemul_utf8_translate(u_int32_t unisym, kbd_t layout, u_char *out, + int allow_utf8) +{ +#ifndef HAVE_UTF8_SUPPORT + return (wsemul_local_translate(unisym, layout, out)); +#else + u_int pos, length, headpat; + + if (!allow_utf8) + return (wsemul_local_translate(unisym, layout, out)); + + if (unisym >= 0x80000000) { + return (0); + } else if (unisym > 0x04000000) { + headpat = 0xfc; + length = 6; + } else if (unisym > 0x00200000) { + headpat = 0xf8; + length = 5; + } else if (unisym > 0x00010000) { + headpat = 0xf0; + length = 4; + } else if (unisym > 0x00000800) { + headpat = 0xe0; + length = 3; + } else if (unisym > 0x00000080) { + headpat = 0xc0; + length = 2; + } else { + headpat = 0x00; + length = 1; + } + + for (pos = length - 1; pos > 0; pos--) { + out[pos] = 0x80 | (unisym & 0x3f); + unisym >>= 6; + } + out[0] = headpat | unisym; + + return (length); +#endif +} diff --git a/sys/dev/wscons/wsemul_sun.c b/sys/dev/wscons/wsemul_sun.c index d490894077b..b698fd3c03f 100644 --- a/sys/dev/wscons/wsemul_sun.c +++ b/sys/dev/wscons/wsemul_sun.c @@ -1,7 +1,23 @@ -/* $OpenBSD: wsemul_sun.c,v 1.29 2013/10/18 13:54:09 miod Exp $ */ +/* $OpenBSD: wsemul_sun.c,v 1.30 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_sun.c,v 1.11 2000/01/05 11:19:36 drochner Exp $ */ /* + * Copyright (c) 2007, 2013 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,7 +72,7 @@ void *wsemul_sun_cnattach(const struct wsscreen_descr *, void *, void *wsemul_sun_attach(int, const struct wsscreen_descr *, void *, int, int, void *, long); u_int wsemul_sun_output(void *, const u_char *, u_int, int); -int wsemul_sun_translate(void *, keysym_t, const char **); +int wsemul_sun_translate(void *, kbd_t, keysym_t, const u_char **); void wsemul_sun_detach(void *, u_int *, u_int *); void wsemul_sun_resetop(void *, enum wsemul_resetops); @@ -72,7 +88,10 @@ const struct wsemul_ops wsemul_sun_ops = { #define SUN_EMUL_STATE_NORMAL 0 /* normal processing */ #define SUN_EMUL_STATE_HAVEESC 1 /* seen start of ctl seq */ -#define SUN_EMUL_STATE_CONTROL 2 /* processing ctl seq */ +#define SUN_EMUL_STATE_CONTROL 2 /* processing ESC [ ctl seq */ +#define SUN_EMUL_STATE_PERCENT 3 /* processing ESC % ctl seq */ + +#define SUN_EMUL_FLAGS_UTF8 0x01 /* UTF-8 character set */ #define SUN_EMUL_NARGS 2 /* max # of args to a command */ @@ -86,6 +105,7 @@ struct wsemul_sun_emuldata { long defattr; /* default attribute (rendition) */ u_int state; /* processing state */ + u_int flags; u_int args[SUN_EMUL_NARGS]; /* command args, if CONTROL */ int nargs; /* number of args */ @@ -94,6 +114,15 @@ struct wsemul_sun_emuldata { long kernattr; /* attribute for kernel output */ int attrflags, fgcol, bgcol; /* properties of curattr */ + struct wsemul_inputstate instate; /* userland input state */ + struct wsemul_inputstate kstate; /* kernel input state */ + +#ifdef HAVE_UTF8_SUPPORT + u_char translatebuf[6]; +#else + u_char translatebuf[1]; +#endif + #ifdef DIAGNOSTIC int console; #endif @@ -104,11 +133,18 @@ void wsemul_sun_init(struct wsemul_sun_emuldata *, int wsemul_sun_jump_scroll(struct wsemul_sun_emuldata *, const u_char *, u_int, int); void wsemul_sun_reset(struct wsemul_sun_emuldata *); -int wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *, u_char, int); -int wsemul_sun_output_normal(struct wsemul_sun_emuldata *, u_char, int); -void wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *, u_char); -int wsemul_sun_output_control(struct wsemul_sun_emuldata *, u_char); -int wsemul_sun_control(struct wsemul_sun_emuldata *, u_char); +int wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *, int); +int wsemul_sun_output_normal(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *, int); +int wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *); +int wsemul_sun_output_control(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *); +int wsemul_sun_output_percent(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *); +int wsemul_sun_control(struct wsemul_sun_emuldata *, + struct wsemul_inputstate *); int wsemul_sun_selectattribute(struct wsemul_sun_emuldata *, int, int, int, long *, long *); int wsemul_sun_scrollup(struct wsemul_sun_emuldata *, u_int); @@ -141,12 +177,17 @@ wsemul_sun_init(struct wsemul_sun_emuldata *edp, void wsemul_sun_reset(struct wsemul_sun_emuldata *edp) { + edp->flags = 0; edp->state = SUN_EMUL_STATE_NORMAL; edp->bkgdattr = edp->curattr = edp->defattr; edp->attrflags = 0; edp->fgcol = WSCOL_BLACK; edp->bgcol = WSCOL_WHITE; edp->scrolldist = 1; + edp->instate.inchar = 0; + edp->instate.mbleft = 0; + edp->kstate.inchar = 0; + edp->kstate.mbleft = 0; } void * @@ -222,13 +263,13 @@ wsemul_sun_attach(int console, const struct wsscreen_descr *type, void *cookie, } int -wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *edp, u_char c, - int kernel) +wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate, int kernel) { u_int n; int rc = 0; - switch (c) { + switch (instate->inchar) { case ASCII_NUL: default: /* ignore */ @@ -298,13 +339,16 @@ wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *edp, u_char c, } int -wsemul_sun_output_normal(struct wsemul_sun_emuldata *edp, u_char c, int kernel) +wsemul_sun_output_normal(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate, int kernel) { int rc; + u_int outchar; + (*edp->emulops->mapchar)(edp->emulcookie, instate->inchar, &outchar); WSEMULOP(rc, edp, &edp->abortstate, putchar, (edp->emulcookie, edp->crow, edp->ccol, - c, kernel ? edp->kernattr : edp->curattr)); + outchar, kernel ? edp->kernattr : edp->curattr)); if (rc != 0) return rc; @@ -327,34 +371,41 @@ wsemul_sun_output_normal(struct wsemul_sun_emuldata *edp, u_char c, int kernel) return 0; } -void -wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *edp, u_char c) +int +wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate) { - switch (c) { + switch (instate->inchar) { case '[': /* continuation of multi-char sequence */ edp->nargs = 0; bzero(edp->args, sizeof (edp->args)); edp->state = SUN_EMUL_STATE_CONTROL; break; - +#ifdef HAVE_UTF8_SUPPORT + case '%': + edp->state = SUN_EMUL_STATE_PERCENT; + break; +#endif default: #ifdef DEBUG - printf("ESC%c unknown\n", c); + printf("ESC %x unknown\n", instate->inchar); #endif edp->state = SUN_EMUL_STATE_NORMAL; /* XXX is this wise? */ break; } + return 0; } int -wsemul_sun_control(struct wsemul_sun_emuldata *edp, u_char c) +wsemul_sun_control(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate) { u_int n, src, dst; int flags, fgcol, bgcol; long attr, bkgdattr; int rc = 0; - switch (c) { + switch (instate->inchar) { case '@': /* "Insert Character (ICH)" */ n = min(NORMALIZE(ARG(0,1)), COLS_LEFT + 1); src = edp->ccol; @@ -541,12 +592,13 @@ setattr: } int -wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c) +wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate) { int oargs; int rc; - switch (c) { + switch (instate->inchar) { case '0': case '1': case '2': case '3': case '4': /* argument digit */ case '5': case '6': case '7': case '8': case '9': /* @@ -559,7 +611,7 @@ wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c) edp->args[edp->nargs = SUN_EMUL_NARGS - 1] = 0; } edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) + - (c - '0'); + (instate->inchar - '0'); break; case ';': /* argument terminator */ @@ -570,7 +622,7 @@ wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c) oargs = edp->nargs++; if (edp->nargs > SUN_EMUL_NARGS) edp->nargs = SUN_EMUL_NARGS; - rc = wsemul_sun_control(edp, c); + rc = wsemul_sun_control(edp, instate); if (rc != 0) { /* undo nargs progress */ edp->nargs = oargs; @@ -584,12 +636,31 @@ wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c) return 0; } +#ifdef HAVE_UTF8_SUPPORT +int +wsemul_sun_output_percent(struct wsemul_sun_emuldata *edp, + struct wsemul_inputstate *instate) +{ + switch (instate->inchar) { + case 'G': + edp->flags |= SUN_EMUL_FLAGS_UTF8; + edp->kstate.mbleft = edp->instate.mbleft = 0; + break; + case '@': + edp->flags &= ~SUN_EMUL_FLAGS_UTF8; + break; + } + edp->state = SUN_EMUL_STATE_NORMAL; + return 0; +} +#endif + u_int wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) { struct wsemul_sun_emuldata *edp = cookie; + struct wsemul_inputstate *instate; u_int processed = 0; - u_char c; #ifdef HAVE_JUMP_SCROLL int lines; #endif @@ -600,6 +671,8 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) panic("wsemul_sun_output: kernel output, not console"); #endif + instate = kernel ? &edp->kstate : &edp->instate; + switch (edp->abortstate.state) { case ABORT_FAILED_CURSOR: /* @@ -622,7 +695,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) break; } - for (; count > 0; data++, count--) { + for (;;) { #ifdef HAVE_JUMP_SCROLL switch (edp->abortstate.state) { case ABORT_FAILED_JUMP_SCROLL: @@ -671,9 +744,18 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) wsemul_resume_abort(&edp->abortstate); - c = *data; - if (c < ' ') { - rc = wsemul_sun_output_lowchars(edp, c, kernel); + if (wsemul_getchar(&data, &count, instate, +#ifdef HAVE_UTF8_SUPPORT + (edp->state == SUN_EMUL_STATE_NORMAL && !kernel) ? + edp->flags & SUN_EMUL_FLAGS_UTF8 : 0 +#else + 0 +#endif + ) != 0) + break; + + if (instate->inchar < ' ') { + rc = wsemul_sun_output_lowchars(edp, instate, kernel); if (rc != 0) break; processed++; @@ -681,7 +763,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) } if (kernel) { - rc = wsemul_sun_output_normal(edp, c, 1); + rc = wsemul_sun_output_normal(edp, instate, 1); if (rc != 0) break; processed++; @@ -690,21 +772,26 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) switch (edp->state) { case SUN_EMUL_STATE_NORMAL: - rc = wsemul_sun_output_normal(edp, c, 0); + rc = wsemul_sun_output_normal(edp, instate, 0); break; case SUN_EMUL_STATE_HAVEESC: - wsemul_sun_output_haveesc(edp, c); + rc = wsemul_sun_output_haveesc(edp, instate); break; case SUN_EMUL_STATE_CONTROL: - rc = wsemul_sun_output_control(edp, c); + rc = wsemul_sun_output_control(edp, instate); + break; +#ifdef HAVE_UTF8_SUPPORT + case SUN_EMUL_STATE_PERCENT: + rc = wsemul_sun_output_percent(edp, instate); break; +#endif default: #ifdef DIAGNOSTIC panic("wsemul_sun: invalid state %d", edp->state); #else /* try to recover, if things get screwed up... */ edp->state = SUN_EMUL_STATE_NORMAL; - rc = wsemul_sun_output_normal(edp, c, 0); + rc = wsemul_sun_output_normal(edp, instate, 0); #endif break; } @@ -740,18 +827,26 @@ int wsemul_sun_jump_scroll(struct wsemul_sun_emuldata *edp, const u_char *data, u_int count, int kernel) { - u_char curchar; u_int pos, lines; + struct wsemul_inputstate tmpstate; lines = 0; pos = edp->ccol; - for (; count != 0; data++, count--) { - curchar = *data; - if (curchar == ASCII_FF || - curchar == ASCII_VT || curchar == ASCII_ESC) + tmpstate = kernel ? edp->kstate : edp->instate; /* structure copy */ + + while (wsemul_getchar(&data, &count, &tmpstate, +#ifdef HAVE_UTF8_SUPPORT + kernel ? 0 : edp->flags & SUN_EMUL_FLAGS_UTF8 +#else + 0 +#endif + ) == 0) { + if (tmpstate.inchar == ASCII_FF || + tmpstate.inchar == ASCII_VT || + tmpstate.inchar == ASCII_ESC) break; - switch (curchar) { + switch (tmpstate.inchar) { case ASCII_BS: if (pos > 0) pos--; @@ -769,11 +864,11 @@ wsemul_sun_jump_scroll(struct wsemul_sun_emuldata *edp, const u_char *data, default: if (++pos >= edp->ncols) { pos = 0; - curchar = ASCII_LF; + tmpstate.inchar = ASCII_LF; } break; } - if (curchar == ASCII_LF) { + if (tmpstate.inchar == ASCII_LF) { if (++lines >= edp->nrows - 1) break; } @@ -849,7 +944,7 @@ wsemul_sun_selectattribute(struct wsemul_sun_emuldata *edp, int flags, return (0); } -static const char *sun_fkeys[] = { +static const u_char *sun_fkeys[] = { "\033[224z", /* F1 */ "\033[225z", "\033[226z", @@ -864,7 +959,7 @@ static const char *sun_fkeys[] = { "\033[235z", /* F12 */ }; -static const char *sun_lkeys[] = { +static const u_char *sun_lkeys[] = { "\033[207z", /* KS_Help */ NULL, /* KS_Execute */ "\033[200z", /* KS_Find */ @@ -880,13 +975,20 @@ static const char *sun_lkeys[] = { }; int -wsemul_sun_translate(void *cookie, keysym_t in, const char **out) +wsemul_sun_translate(void *cookie, kbd_t layout, keysym_t in, + const u_char **out) { - static char c; + struct wsemul_sun_emuldata *edp = cookie; + + if (KS_GROUP(in) == KS_GROUP_Ascii) { + *out = edp->translatebuf; + return (wsemul_utf8_translate(KS_VALUE(in), layout, + edp->translatebuf, edp->flags & SUN_EMUL_FLAGS_UTF8)); + } if (KS_GROUP(in) == KS_GROUP_Keypad && (in & 0x80) == 0) { - c = in & 0xff; /* turn into ASCII */ - *out = &c; + edp->translatebuf[0] = in & 0xff; /* turn into ASCII */ + *out = edp->translatebuf; return (1); } diff --git a/sys/dev/wscons/wsemul_vt100.c b/sys/dev/wscons/wsemul_vt100.c index ae6b918fc12..20ec8b12d57 100644 --- a/sys/dev/wscons/wsemul_vt100.c +++ b/sys/dev/wscons/wsemul_vt100.c @@ -1,7 +1,23 @@ -/* $OpenBSD: wsemul_vt100.c,v 1.30 2013/10/18 13:54:09 miod Exp $ */ +/* $OpenBSD: wsemul_vt100.c,v 1.31 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_vt100.c,v 1.13 2000/04/28 21:56:16 mycroft Exp $ */ /* + * Copyright (c) 2007, 2013 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* * Copyright (c) 1998 * Matthias Drochner. All rights reserved. * @@ -64,10 +80,14 @@ void wsemul_vt100_init(struct wsemul_vt100_emuldata *, const struct wsscreen_descr *, void *, int, int, long); int wsemul_vt100_jump_scroll(struct wsemul_vt100_emuldata *, const u_char *, u_int, int); -int wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *, u_char, int); -int wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *, u_char, int); +int wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *, + struct wsemul_inputstate *, int); +int wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *, + struct wsemul_inputstate *, int); int wsemul_vt100_nextline(struct wsemul_vt100_emuldata *); -typedef int vt100_handler(struct wsemul_vt100_emuldata *, u_char); + +typedef int vt100_handler(struct wsemul_vt100_emuldata *, struct + wsemul_inputstate *); vt100_handler wsemul_vt100_output_esc, wsemul_vt100_output_csi, @@ -80,7 +100,8 @@ vt100_handler wsemul_vt100_output_string, wsemul_vt100_output_string_esc, wsemul_vt100_output_dcs, - wsemul_vt100_output_dcs_dollar; + wsemul_vt100_output_dcs_dollar, + wsemul_vt100_output_esc_percent; #define VT100_EMUL_STATE_NORMAL 0 /* normal processing */ #define VT100_EMUL_STATE_ESC 1 /* got ESC */ @@ -95,6 +116,7 @@ vt100_handler #define VT100_EMUL_STATE_STRING_ESC 10 /* waiting for ST, got ESC */ #define VT100_EMUL_STATE_DCS 11 /* got DCS (ESC P) */ #define VT100_EMUL_STATE_DCS_DOLLAR 12 /* got DCS<p>$ */ +#define VT100_EMUL_STATE_ESC_PERCENT 13 /* got ESC% */ vt100_handler *vt100_output[] = { wsemul_vt100_output_esc, @@ -109,6 +131,7 @@ vt100_handler *vt100_output[] = { wsemul_vt100_output_string_esc, wsemul_vt100_output_dcs, wsemul_vt100_output_dcs_dollar, + wsemul_vt100_output_esc_percent, }; void @@ -313,10 +336,11 @@ wsemul_vt100_nextline(struct wsemul_vt100_emuldata *edp) */ int -wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *edp, u_char c, - int kernel) +wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate, int kernel) { u_int *ct, dc; + u_char c; int oldsschartab = edp->sschartab; int rc = 0; @@ -329,17 +353,25 @@ wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *edp, u_char c, edp->flags &= ~VTFL_LASTCHAR; } - if (c & 0x80) { - c &= 0x7f; - ct = edp->chartab_G[edp->chartab1]; - } else { - if (edp->sschartab) { - ct = edp->chartab_G[edp->sschartab]; - edp->sschartab = 0; - } else - ct = edp->chartab_G[edp->chartab0]; +#ifdef HAVE_UTF8_SUPPORT + if (edp->flags & VTFL_UTF8) { + (*edp->emulops->mapchar)(edp->emulcookie, instate->inchar, &dc); + } else +#endif + { + c = instate->inchar & 0xff; + if (c & 0x80) { + c &= 0x7f; + ct = edp->chartab_G[edp->chartab1]; + } else { + if (edp->sschartab) { + ct = edp->chartab_G[edp->sschartab]; + edp->sschartab = 0; + } else + ct = edp->chartab_G[edp->chartab0]; + } + dc = ct ? ct[c] : c; } - dc = (ct ? ct[c] : c); if ((edp->flags & VTFL_INSERTMODE) && COLS_LEFT) { WSEMULOP(rc, edp, &edp->abortstate, copycols, @@ -371,13 +403,13 @@ wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *edp, u_char c, } int -wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *edp, u_char c, - int kernel) +wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate, int kernel) { u_int n; int rc = 0; - switch (c) { + switch (instate->inchar) { case ASCII_NUL: default: /* ignore */ @@ -413,9 +445,11 @@ wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *edp, u_char c, edp->ccol = n; break; case ASCII_SO: /* LS1 */ + edp->flags &= ~VTFL_UTF8; edp->chartab0 = 1; break; case ASCII_SI: /* LS0 */ + edp->flags &= ~VTFL_UTF8; edp->chartab0 = 0; break; case ASCII_ESC: @@ -471,13 +505,14 @@ wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *edp, u_char c, } int -wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { u_int newstate = VT100_EMUL_STATE_NORMAL; int rc = 0; int i; - switch (c) { + switch (instate->inchar) { case '[': /* CSI */ edp->nargs = 0; memset(edp->args, 0, sizeof (edp->args)); @@ -530,24 +565,31 @@ wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c) edp->tabs[edp->ccol] = 1; break; case '~': /* LS1R */ + edp->flags &= ~VTFL_UTF8; edp->chartab1 = 1; break; case 'n': /* LS2 */ + edp->flags &= ~VTFL_UTF8; edp->chartab0 = 2; break; case '}': /* LS2R */ + edp->flags &= ~VTFL_UTF8; edp->chartab1 = 2; break; case 'o': /* LS3 */ + edp->flags &= ~VTFL_UTF8; edp->chartab0 = 3; break; case '|': /* LS3R */ + edp->flags &= ~VTFL_UTF8; edp->chartab1 = 3; break; case 'N': /* SS2 */ + edp->flags &= ~VTFL_UTF8; edp->sschartab = 2; break; case 'O': /* SS3 */ + edp->flags &= ~VTFL_UTF8; edp->sschartab = 3; break; case 'M': /* RI */ @@ -571,11 +613,11 @@ wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c) edp->ccol = edp->crow = 0; break; case '(': case ')': case '*': case '+': /* SCS */ - edp->designating = c - '('; + edp->designating = instate->inchar - '('; newstate = VT100_EMUL_STATE_SCS94; break; case '-': case '.': case '/': /* SCS */ - edp->designating = c - '-' + 1; + edp->designating = instate->inchar - '-' + 1; newstate = VT100_EMUL_STATE_SCS96; break; case '#': @@ -592,9 +634,12 @@ wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c) break; case '<': /* exit VT52 mode - ignored */ break; + case '%': /* UTF-8 encoding sequences */ + newstate = VT100_EMUL_STATE_ESC_PERCENT; + break; default: #ifdef VT100_PRINTUNKNOWN - printf("ESC%c unknown\n", c); + printf("ESC %x unknown\n", instate->inchar); #endif break; } @@ -610,33 +655,40 @@ wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_scs94(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_scs94(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { u_int newstate = VT100_EMUL_STATE_NORMAL; - switch (c) { + switch (instate->inchar) { case '%': /* probably DEC supplemental graphic */ newstate = VT100_EMUL_STATE_SCS94_PERCENT; break; case 'A': /* british / national */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->nrctab; break; case 'B': /* ASCII */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = 0; break; case '<': /* user preferred supplemental */ /* XXX not really "user" preferred */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->isolatin1tab; break; case '0': /* DEC special graphic */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->decgraphtab; break; case '>': /* DEC tech */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->dectechtab; break; default: #ifdef VT100_PRINTUNKNOWN - printf("ESC%c%c unknown\n", edp->designating + '(', c); + printf("ESC%c %x unknown\n", edp->designating + '(', + instate->inchar); #endif break; } @@ -646,16 +698,19 @@ wsemul_vt100_output_scs94(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_scs94_percent(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_scs94_percent(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - switch (c) { + switch (instate->inchar) { case '5': /* DEC supplemental graphic */ /* XXX there are differences */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->isolatin1tab; break; default: #ifdef VT100_PRINTUNKNOWN - printf("ESC%c%%%c unknown\n", edp->designating + '(', c); + printf("ESC%c%% %x unknown\n", edp->designating + '(', + instate->inchar); #endif break; } @@ -665,16 +720,18 @@ wsemul_vt100_output_scs94_percent(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_scs96(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_scs96(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { u_int newstate = VT100_EMUL_STATE_NORMAL; int nrc; - switch (c) { + switch (instate->inchar) { case '%': /* probably portuguese */ newstate = VT100_EMUL_STATE_SCS96_PERCENT; break; case 'A': /* ISO-latin-1 supplemental */ + edp->flags &= ~VTFL_UTF8; edp->chartab_G[edp->designating] = edp->isolatin1tab; break; case '4': /* dutch */ @@ -712,7 +769,8 @@ setnrc: /* else FALLTHROUGH */ default: #ifdef VT100_PRINTUNKNOWN - printf("ESC%c%c unknown\n", edp->designating + '-' - 1, c); + printf("ESC%c %x unknown\n", edp->designating + '-' - 1, + instate->inchar); #endif break; } @@ -722,16 +780,18 @@ setnrc: } int -wsemul_vt100_output_scs96_percent(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_scs96_percent(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - switch (c) { + switch (instate->inchar) { case '6': /* portuguese */ if (vt100_setnrc(edp, 8) == 0) break; /* else FALLTHROUGH */ default: #ifdef VT100_PRINTUNKNOWN - printf("ESC%c%%%c unknown\n", edp->designating + '-' - 1, c); + printf("ESC%c%% %x unknown\n", edp->designating + '-' - 1, + instate->inchar); #endif break; } @@ -741,18 +801,19 @@ wsemul_vt100_output_scs96_percent(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_esc_spc(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_esc_spc(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - switch (c) { + switch (instate->inchar) { case 'F': /* 7-bit controls */ case 'G': /* 8-bit controls */ #ifdef VT100_PRINTNOTIMPL - printf("ESC<SPC>%c ignored\n", c); + printf("ESC<SPC> %x ignored\n", instate->inchar); #endif break; default: #ifdef VT100_PRINTUNKNOWN - printf("ESC<SPC>%c unknown\n", c); + printf("ESC<SPC> %x unknown\n", instate->inchar); #endif break; } @@ -762,19 +823,27 @@ wsemul_vt100_output_esc_spc(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_string(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_string(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - if (edp->dcstype && edp->dcspos < DCS_MAXLEN) - edp->dcsarg[edp->dcspos++] = c; + if (edp->dcstype && edp->dcspos < DCS_MAXLEN) { + if (instate->inchar & ~0xff) { +#ifdef VT100_PRINTUNKNOWN + printf("unknown char %x in DCS\n", instate->inchar); +#endif + } else + edp->dcsarg[edp->dcspos++] = (char)instate->inchar; + } edp->state = VT100_EMUL_STATE_STRING; return 0; } int -wsemul_vt100_output_string_esc(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_string_esc(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - if (c == '\\') { /* ST complete */ + if (instate->inchar == '\\') { /* ST complete */ wsemul_vt100_handle_dcs(edp); edp->state = VT100_EMUL_STATE_NORMAL; } else @@ -784,18 +853,19 @@ wsemul_vt100_output_string_esc(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { u_int newstate = VT100_EMUL_STATE_DCS; - switch (c) { + switch (instate->inchar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* argument digit */ if (edp->nargs > VT100_EMUL_NARGS - 1) break; edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) + - (c - '0'); + (instate->inchar - '0'); break; case ';': /* argument terminator */ edp->nargs++; @@ -809,7 +879,7 @@ wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, u_char c) edp->nargs = VT100_EMUL_NARGS; } newstate = VT100_EMUL_STATE_STRING; - switch (c) { + switch (instate->inchar) { case '$': newstate = VT100_EMUL_STATE_DCS_DOLLAR; break; @@ -818,12 +888,13 @@ wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, u_char c) /* 'u' must follow - need another state */ case '|': /* DECUDK program F6..F20 */ #ifdef VT100_PRINTNOTIMPL - printf("DCS%c ignored\n", c); + printf("DCS%c ignored\n", (char)instate->inchar); #endif break; default: #ifdef VT100_PRINTUNKNOWN - printf("DCS%c (%d, %d) unknown\n", c, ARG(0), ARG(1)); + printf("DCS %x (%d, %d) unknown\n", instate->inchar, + ARG(0), ARG(1)); #endif break; } @@ -834,13 +905,14 @@ wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_dcs_dollar(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_dcs_dollar(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { - switch (c) { + switch (instate->inchar) { case 'p': /* DECRSTS terminal state restore */ case 'q': /* DECRQSS control function request */ #ifdef VT100_PRINTNOTIMPL - printf("DCS$%c ignored\n", c); + printf("DCS$%c ignored\n", (char)instate->inchar); #endif break; case 't': /* DECRSPS restore presentation state */ @@ -865,7 +937,8 @@ wsemul_vt100_output_dcs_dollar(struct wsemul_vt100_emuldata *edp, u_char c) break; default: #ifdef VT100_PRINTUNKNOWN - printf("DCS$%c (%d, %d) unknown\n", c, ARG(0), ARG(1)); + printf("DCS$ %x (%d, %d) unknown\n", + instate->inchar, ARG(0), ARG(1)); #endif break; } @@ -875,12 +948,37 @@ wsemul_vt100_output_dcs_dollar(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_esc_hash(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_esc_percent(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) +{ + switch (instate->inchar) { +#ifdef HAVE_UTF8_SUPPORT + case 'G': + edp->flags |= VTFL_UTF8; + edp->kstate.mbleft = edp->instate.mbleft = 0; + break; + case '@': + edp->flags &= ~VTFL_UTF8; + break; +#endif + default: +#ifdef VT100_PRINTUNKNOWN + printf("ESC% %x unknown\n", instate->inchar); +#endif + break; + } + edp->state = VT100_EMUL_STATE_NORMAL; + return 0; +} + +int +wsemul_vt100_output_esc_hash(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { int i; int rc = 0; - switch (c) { + switch (instate->inchar) { case '5': /* DECSWL single width, single height */ if (edp->dblwid != NULL && edp->dw != 0) { for (i = 0; i < edp->ncols / 2; i++) { @@ -936,7 +1034,7 @@ wsemul_vt100_output_esc_hash(struct wsemul_vt100_emuldata *edp, u_char c) break; default: #ifdef VT100_PRINTUNKNOWN - printf("ESC#%c unknown\n", c); + printf("ESC# %x unknown\n", instate->inchar); #endif break; } @@ -949,33 +1047,34 @@ wsemul_vt100_output_esc_hash(struct wsemul_vt100_emuldata *edp, u_char c) } int -wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { u_int newstate = VT100_EMUL_STATE_CSI; int oargs; int rc = 0; - switch (c) { + switch (instate->inchar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* argument digit */ if (edp->nargs > VT100_EMUL_NARGS - 1) break; edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) + - (c - '0'); + (instate->inchar - '0'); break; case ';': /* argument terminator */ edp->nargs++; break; case '?': /* DEC specific */ case '>': /* DA query */ - edp->modif1 = c; + edp->modif1 = (char)instate->inchar; break; case '!': case '"': case '$': case '&': - edp->modif2 = c; + edp->modif2 = (char)instate->inchar; break; default: /* end of escape sequence */ oargs = edp->nargs++; @@ -985,7 +1084,7 @@ wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp, u_char c) #endif edp->nargs = VT100_EMUL_NARGS; } - rc = wsemul_vt100_handle_csi(edp, c); + rc = wsemul_vt100_handle_csi(edp, instate); if (rc != 0) { edp->nargs = oargs; return rc; @@ -1005,8 +1104,8 @@ u_int wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel) { struct wsemul_vt100_emuldata *edp = cookie; + struct wsemul_inputstate *instate; u_int processed = 0; - u_char c; #ifdef HAVE_JUMP_SCROLL int lines; #endif @@ -1017,6 +1116,8 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel) panic("wsemul_vt100_output: kernel output, not console"); #endif + instate = kernel ? &edp->kstate : &edp->instate; + switch (edp->abortstate.state) { case ABORT_FAILED_CURSOR: /* @@ -1042,7 +1143,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel) break; } - for (; count > 0; data++, count--) { + for (;;) { #ifdef HAVE_JUMP_SCROLL switch (edp->abortstate.state) { case ABORT_FAILED_JUMP_SCROLL: @@ -1090,17 +1191,27 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel) wsemul_resume_abort(&edp->abortstate); - c = *data; - if ((c & 0x7f) < 0x20) { - rc = wsemul_vt100_output_c0c1(edp, c, kernel); + if (wsemul_getchar(&data, &count, instate, +#ifdef HAVE_UTF8_SUPPORT + (edp->state == VT100_EMUL_STATE_NORMAL && !kernel) ? + edp->flags & VTFL_UTF8 : 0 +#else + 0 +#endif + ) != 0) + break; + + if (!(instate->inchar & ~0xff) && + (instate->inchar & 0x7f) < 0x20) { + rc = wsemul_vt100_output_c0c1(edp, instate, kernel); if (rc != 0) break; processed++; - continue; - } - + continue; + } + if (edp->state == VT100_EMUL_STATE_NORMAL || kernel) { - rc = wsemul_vt100_output_normal(edp, c, kernel); + rc = wsemul_vt100_output_normal(edp, instate, kernel); if (rc != 0) break; processed++; @@ -1110,7 +1221,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel) if (edp->state > nitems(vt100_output)) panic("wsemul_vt100: invalid state %d", edp->state); #endif - rc = vt100_output[edp->state - 1](edp, c); + rc = vt100_output[edp->state - 1](edp, instate); if (rc != 0) break; processed++; @@ -1147,23 +1258,30 @@ int wsemul_vt100_jump_scroll(struct wsemul_vt100_emuldata *edp, const u_char *data, u_int count, int kernel) { - u_char curchar; + struct wsemul_inputstate tmpstate; u_int pos, lines; lines = 0; pos = edp->ccol; - for (; count != 0; data++, count--) { - curchar = *data; + tmpstate = kernel ? edp->kstate : edp->instate; /* structure copy */ + + while (wsemul_getchar(&data, &count, &tmpstate, +#ifdef HAVE_UTF8_SUPPORT + kernel ? 0 : edp->flags & VTFL_UTF8 +#else + 0 +#endif + ) == 0) { /* * Only char causing a transition from * VT100_EMUL_STATE_NORMAL to another state, for now. * Revisit this if this changes... */ - if (curchar == ASCII_ESC) + if (tmpstate.inchar == ASCII_ESC) break; if (ISSET(edp->flags, VTFL_DECAWM)) - switch (curchar) { + switch (tmpstate.inchar) { case ASCII_BS: if (pos > 0) pos--; @@ -1184,18 +1302,19 @@ wsemul_vt100_jump_scroll(struct wsemul_vt100_emuldata *edp, const u_char *data, } break; default: - if ((curchar & 0x7f) < 0x20) + if (!(tmpstate.inchar & ~0xff) && + (tmpstate.inchar & 0x7f) < 0x20) break; if (pos++ >= NCOLS) { pos = 0; - curchar = ASCII_LF; + tmpstate.inchar = ASCII_LF; } break; } - if (curchar == ASCII_LF || - curchar == ASCII_VT || - curchar == ASCII_FF) { + if (tmpstate.inchar == ASCII_LF || + tmpstate.inchar == ASCII_VT || + tmpstate.inchar == ASCII_FF) { if (++lines >= edp->scrreg_nrows - 1) break; } diff --git a/sys/dev/wscons/wsemul_vt100_chars.c b/sys/dev/wscons/wsemul_vt100_chars.c index 373a34ab4fd..521a91d9dcd 100644 --- a/sys/dev/wscons/wsemul_vt100_chars.c +++ b/sys/dev/wscons/wsemul_vt100_chars.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_vt100_chars.c,v 1.7 2009/12/10 16:35:28 oga Exp $ */ +/* $OpenBSD: wsemul_vt100_chars.c,v 1.8 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_vt100_chars.c,v 1.4 1999/02/20 18:20:02 drochner Exp $ */ /* @@ -29,6 +29,8 @@ #include <sys/param.h> #include <sys/systm.h> + +#include <dev/wscons/wscons_features.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsksymvar.h> diff --git a/sys/dev/wscons/wsemul_vt100_keys.c b/sys/dev/wscons/wsemul_vt100_keys.c index e90f918fc70..d94618b4bbf 100644 --- a/sys/dev/wscons/wsemul_vt100_keys.c +++ b/sys/dev/wscons/wsemul_vt100_keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_vt100_keys.c,v 1.6 2013/04/14 19:40:12 miod Exp $ */ +/* $OpenBSD: wsemul_vt100_keys.c,v 1.7 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_vt100_keys.c,v 1.3 1999/04/22 20:06:02 mycroft Exp $ */ /* @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <dev/wscons/wscons_features.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsksymvar.h> @@ -37,7 +38,7 @@ #include <dev/wscons/wsemulvar.h> #include <dev/wscons/wsemul_vt100var.h> -static const char *vt100_fkeys[] = { +static const u_char *vt100_fkeys[] = { "\033[11~", /* F1 */ "\033[12~", "\033[13~", /* F1-F5 normally don't send codes */ @@ -64,14 +65,14 @@ static const char *vt100_fkeys[] = { "\033[38~" }; -static const char *vt100_pfkeys[] = { +static const u_char *vt100_pfkeys[] = { "\033OP", /* PF1 */ "\033OQ", "\033OR", "\033OS", /* PF4 */ }; -static const char *vt100_numpad[] = { +static const u_char *vt100_numpad[] = { "\033Op", /* KP 0 */ "\033Oq", /* KP 1 */ "\033Or", /* KP 2 */ @@ -85,10 +86,16 @@ static const char *vt100_numpad[] = { }; int -wsemul_vt100_translate(void *cookie, keysym_t in, const char **out) +wsemul_vt100_translate(void *cookie, kbd_t layout, keysym_t in, + const u_char **out) { struct wsemul_vt100_emuldata *edp = cookie; - static char c; + + if (KS_GROUP(in) == KS_GROUP_Ascii) { + *out = edp->translatebuf; + return (wsemul_utf8_translate(KS_VALUE(in), layout, + edp->translatebuf, edp->flags & VTFL_UTF8)); + } if (in >= KS_f1 && in <= KS_f24) { *out = vt100_fkeys[in - KS_f1]; @@ -135,8 +142,8 @@ wsemul_vt100_translate(void *cookie, keysym_t in, const char **out) } } else { if (!(in & 0x80)) { - c = in & 0xff; /* turn into ASCII */ - *out = &c; + edp->translatebuf[0] = in & 0xff; /* turn into ASCII */ + *out = edp->translatebuf; return (1); } } diff --git a/sys/dev/wscons/wsemul_vt100_subr.c b/sys/dev/wscons/wsemul_vt100_subr.c index ecb03a0549d..5f463bb5998 100644 --- a/sys/dev/wscons/wsemul_vt100_subr.c +++ b/sys/dev/wscons/wsemul_vt100_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_vt100_subr.c,v 1.18 2013/06/11 18:15:55 deraadt Exp $ */ +/* $OpenBSD: wsemul_vt100_subr.c,v 1.19 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_vt100_subr.c,v 1.7 2000/04/28 21:56:16 mycroft Exp $ */ /* @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <dev/wscons/wscons_features.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsksymvar.h> #include <dev/wscons/wsdisplayvar.h> @@ -214,11 +215,18 @@ wsemul_vt100_el(struct wsemul_vt100_emuldata *edp, int arg) * handle commands after CSI (ESC[) */ int -wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *edp, u_char c) +wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *edp, + struct wsemul_inputstate *instate) { int n, help, flags, fgcol, bgcol; long attr, bkgdattr; + u_char c; int rc = 0; + + if (instate->inchar >= 0x100) + c = 0x00; /* cause the switch below to end in default: */ + else + c = (u_char)instate->inchar; #define A3(a, b, c) (((a) << 16) | ((b) << 8) | (c)) switch (A3(edp->modif1, edp->modif2, c)) { @@ -666,7 +674,8 @@ wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *edp, u_char c) break; default: #ifdef VT100_PRINTUNKNOWN - printf("CSI%c (%d, %d) unknown\n", c, ARG(0), ARG(1)); + printf("CSI %x (%d, %d) unknown\n", + instate->inchar, ARG(0), ARG(1)); #endif break; } @@ -793,7 +802,10 @@ wsemul_vt100_handle_dcs(struct wsemul_vt100_emuldata *edp) } break; default: - panic("wsemul_vt100_handle_dcs: bad type %d", edp->dcstype); +#ifdef VT100_PRINTUNKNOWN + printf("wsemul_vt100_handle_dcs: bad type %d\n", edp->dcstype); +#endif + break; } edp->dcstype = 0; } diff --git a/sys/dev/wscons/wsemul_vt100var.h b/sys/dev/wscons/wsemul_vt100var.h index 3926eb734fc..460913387c5 100644 --- a/sys/dev/wscons/wsemul_vt100var.h +++ b/sys/dev/wscons/wsemul_vt100var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_vt100var.h,v 1.9 2009/09/05 14:49:20 miod Exp $ */ +/* $OpenBSD: wsemul_vt100var.h,v 1.10 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemul_vt100var.h,v 1.5 2000/04/28 21:56:17 mycroft Exp $ */ /* @@ -54,6 +54,7 @@ struct wsemul_vt100_emuldata { #define VTFL_CURSORON 0x040 #define VTFL_NATCHARSET 0x080 /* national replacement charset mode */ #define VTFL_SAVEDCURS 0x100 /* we have a saved cursor state */ +#define VTFL_UTF8 0x200 /* utf-8 character set */ long curattr, bkgdattr; /* currently used attribute */ int attrflags, fgcol, bgcol; /* properties of curattr */ u_int scrreg_startrow; @@ -87,6 +88,15 @@ struct wsemul_vt100_emuldata { int savedattrflags, savedfgcol, savedbgcol; int savedchartab0, savedchartab1; u_int *savedchartab_G[4]; + + struct wsemul_inputstate instate; /* userland input state */ + struct wsemul_inputstate kstate; /* kernel input state */ + +#ifdef HAVE_UTF8_SUPPORT + u_char translatebuf[6]; +#else + u_char translatebuf[1]; +#endif }; /* some useful utility macros */ @@ -133,10 +143,11 @@ int wsemul_vt100_scrollup(struct wsemul_vt100_emuldata *, int); int wsemul_vt100_scrolldown(struct wsemul_vt100_emuldata *, int); int wsemul_vt100_ed(struct wsemul_vt100_emuldata *, int); int wsemul_vt100_el(struct wsemul_vt100_emuldata *, int); -int wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *, u_char); +int wsemul_vt100_handle_csi(struct wsemul_vt100_emuldata *, + struct wsemul_inputstate *); void wsemul_vt100_handle_dcs(struct wsemul_vt100_emuldata *); -int wsemul_vt100_translate(void *cookie, keysym_t, const char **); +int wsemul_vt100_translate(void *cookie, kbd_t, keysym_t, const u_char **); void vt100_initchartables(struct wsemul_vt100_emuldata *); int vt100_setnrc(struct wsemul_vt100_emuldata *, int); diff --git a/sys/dev/wscons/wsemulvar.h b/sys/dev/wscons/wsemulvar.h index 77a9fd38fed..5d70a02ff9c 100644 --- a/sys/dev/wscons/wsemulvar.h +++ b/sys/dev/wscons/wsemulvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemulvar.h,v 1.14 2013/10/18 14:17:23 miod Exp $ */ +/* $OpenBSD: wsemulvar.h,v 1.15 2013/10/18 22:06:41 miod Exp $ */ /* $NetBSD: wsemulvar.h,v 1.6 1999/01/17 15:46:15 drochner Exp $ */ /* @@ -68,11 +68,20 @@ struct wsemul_ops { void *(*attach)(int, const struct wsscreen_descr *, void *, int, int, void *, long); u_int (*output)(void *, const u_char *, u_int, int); - int (*translate)(void *, keysym_t, const char **); + int (*translate)(void *, kbd_t, keysym_t, const u_char **); void (*detach)(void *, u_int *, u_int *); void (*reset)(void *, enum wsemul_resetops); }; +/* + * Structure carrying the state of multi-byte character sequences + * decoding. + */ +struct wsemul_inputstate { + u_int32_t inchar; /* character being reconstructed */ + u_int mbleft; /* multibyte bytes left until char complete */ +}; + extern const struct wsemul_ops wsemul_dumb_ops; extern const struct wsemul_ops wsemul_sun_ops; extern const struct wsemul_ops wsemul_vt100_ops; @@ -87,6 +96,19 @@ void wsdisplay_emulbell(void *v); void wsdisplay_emulinput(void *v, const u_char *, u_int); /* + * Get characters from an input stream and update the input state. + * Processing stops when the stream is empty, or a complete character + * sequence has been recognized, in which case it returns zero. + */ +int wsemul_getchar(const u_char **, u_int *, struct wsemul_inputstate *, + int); + +/* + * Keysym to UTF-8 sequence translation function. + */ +int wsemul_utf8_translate(u_int32_t, kbd_t, u_char *, int); + +/* * emulops failure abort/recovery state * * The tty layer needs a character output to be atomic. Since this may diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c index 0fafe4d48c8..0cc9e91d46d 100644 --- a/sys/dev/wscons/wskbd.c +++ b/sys/dev/wscons/wskbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wskbd.c,v 1.73 2013/10/18 13:54:09 miod Exp $ */ +/* $OpenBSD: wskbd.c,v 1.74 2013/10/18 22:06:42 miod Exp $ */ /* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */ /* @@ -511,6 +511,7 @@ wskbd_repeat(void *v) /* deliver keys */ if (sc->sc_displaydv != NULL) wsdisplay_kbdinput(sc->sc_displaydv, + sc->id->t_keymap->layout, sc->id->t_symbols, sc->sc_repeating); } else { /* queue event */ @@ -629,6 +630,7 @@ wskbd_input(struct device *dev, u_int type, int value) } #endif wsdisplay_kbdinput(sc->sc_displaydv, + sc->id->t_keymap->layout, sc->id->t_symbols, num); } diff --git a/sys/dev/wscons/wsksymdef.h b/sys/dev/wscons/wsksymdef.h index 5c8d58978e4..b1abb46f393 100644 --- a/sys/dev/wscons/wsksymdef.h +++ b/sys/dev/wscons/wsksymdef.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsksymdef.h,v 1.34 2011/04/05 19:12:13 miod Exp $ */ +/* $OpenBSD: wsksymdef.h,v 1.35 2013/10/18 22:06:42 miod Exp $ */ /* $NetBSD: wsksymdef.h,v 1.34.4.1 2000/07/07 09:49:54 hannken Exp $ */ /*- @@ -36,7 +36,6 @@ /* * Keysymbols encoded as 16-bit Unicode. Special symbols * are encoded in the private area (0xe000 - 0xf8ff). - * Currently only ISO Latin-1 subset is supported. * * This file is parsed from userland. Encode keysyms as: * @@ -251,10 +250,10 @@ #define KS_thorn 0xfe #define KS_ydiaeresis 0xff -#define KS_Odoubleacute 0x150 -#define KS_odoubleacute 0x151 -#define KS_Udoubleacute 0x170 -#define KS_udoubleacute 0x171 +#define KS_Odoubleacute 0x0150 +#define KS_odoubleacute 0x0151 +#define KS_Udoubleacute 0x0170 +#define KS_udoubleacute 0x0171 /* * Group Dead (dead accents) @@ -269,216 +268,217 @@ #define KS_dead_cedilla 0x0327 /* - * Group Cyrillic (koi8-r) + * Group Cyrillic */ -#define KS_Cyrillic_A 0xe1 -#define KS_Cyrillic_BE 0xe2 -#define KS_Cyrillic_VE 0xf7 -#define KS_Cyrillic_GE 0xe7 -#define KS_Cyrillic_DE 0xe4 -#define KS_Cyrillic_IE 0xe5 -#define KS_Cyrillic_YO 0xb3 -#define KS_Cyrillic_ZHE 0xf6 -#define KS_Cyrillic_ZE 0xfa -#define KS_Cyrillic_I 0xe9 -#define KS_Cyrillic_ISHORT 0xea -#define KS_Cyrillic_IUKR 0xb6 -#define KS_Cyrillic_YI 0xb7 -#define KS_Cyrillic_KA 0xeb -#define KS_Cyrillic_EL 0xec -#define KS_Cyrillic_EM 0xed -#define KS_Cyrillic_EN 0xee -#define KS_Cyrillic_O 0xef -#define KS_Cyrillic_PE 0xf0 -#define KS_Cyrillic_ER 0xf2 -#define KS_Cyrillic_ES 0xf3 -#define KS_Cyrillic_TE 0xf4 -#define KS_Cyrillic_U 0xf5 -#define KS_Cyrillic_EF 0xe6 -#define KS_Cyrillic_HA 0xe8 -#define KS_Cyrillic_TSE 0xe3 -#define KS_Cyrillic_CHE 0xfe -#define KS_Cyrillic_SHA 0xfb -#define KS_Cyrillic_SCHA 0xfd -#define KS_Cyrillic_HSIGHN 0xff -#define KS_Cyrillic_YERU 0xf9 -#define KS_Cyrillic_SSIGHN 0xf8 -#define KS_Cyrillic_E 0xfc -#define KS_Cyrillic_YU 0xe0 -#define KS_Cyrillic_YA 0xf1 -#define KS_Cyrillic_a 0xc1 -#define KS_Cyrillic_be 0xc2 -#define KS_Cyrillic_ve 0xd7 -#define KS_Cyrillic_ge 0xc7 -#define KS_Cyrillic_de 0xc4 -#define KS_Cyrillic_ie 0xc5 -#define KS_Cyrillic_yo 0xa3 -#define KS_Cyrillic_zhe 0xd6 -#define KS_Cyrillic_ze 0xda -#define KS_Cyrillic_i 0xc9 -#define KS_Cyrillic_ishort 0xca -#define KS_Cyrillic_iukr 0xa6 -#define KS_Cyrillic_yi 0xa7 -#define KS_Cyrillic_ka 0xcb -#define KS_Cyrillic_el 0xcc -#define KS_Cyrillic_em 0xcd -#define KS_Cyrillic_en 0xce -#define KS_Cyrillic_o 0xcf -#define KS_Cyrillic_pe 0xd0 -#define KS_Cyrillic_er 0xd2 -#define KS_Cyrillic_es 0xd3 -#define KS_Cyrillic_te 0xd4 -#define KS_Cyrillic_u 0xd5 -#define KS_Cyrillic_ef 0xc6 -#define KS_Cyrillic_ha 0xc8 -#define KS_Cyrillic_tse 0xc3 -#define KS_Cyrillic_che 0xde -#define KS_Cyrillic_sha 0xdb -#define KS_Cyrillic_scha 0xdd -#define KS_Cyrillic_hsighn 0xdf -#define KS_Cyrillic_yeru 0xd9 -#define KS_Cyrillic_ssighn 0xd8 -#define KS_Cyrillic_e 0xdc -#define KS_Cyrillic_yu 0xc0 -#define KS_Cyrillic_ya 0xd1 -#define KS_Cyrillic_gheukr 0xad -#define KS_Cyrillic_GHEUKR 0xbd -#define KS_Cyrillic_yeukr 0xa4 -#define KS_Cyrillic_YEUKR 0xb4 +#define KS_Cyrillic_YO 0x0401 +#define KS_Cyrillic_YEUKR 0x0404 +#define KS_Cyrillic_IUKR 0x0406 +#define KS_Cyrillic_YI 0x0407 +#define KS_Cyrillic_A 0x0410 +#define KS_Cyrillic_BE 0x0411 +#define KS_Cyrillic_VE 0x0412 +#define KS_Cyrillic_GE 0x0413 +#define KS_Cyrillic_DE 0x0414 +#define KS_Cyrillic_IE 0x0415 +#define KS_Cyrillic_ZHE 0x0416 +#define KS_Cyrillic_ZE 0x0417 +#define KS_Cyrillic_I 0x0418 +#define KS_Cyrillic_ISHORT 0x0419 +#define KS_Cyrillic_KA 0x041a +#define KS_Cyrillic_EL 0x041b +#define KS_Cyrillic_EM 0x041c +#define KS_Cyrillic_EN 0x041d +#define KS_Cyrillic_O 0x041e +#define KS_Cyrillic_PE 0x041f +#define KS_Cyrillic_ER 0x0420 +#define KS_Cyrillic_ES 0x0421 +#define KS_Cyrillic_TE 0x0422 +#define KS_Cyrillic_U 0x0423 +#define KS_Cyrillic_EF 0x0424 +#define KS_Cyrillic_HA 0x0425 +#define KS_Cyrillic_TSE 0x0426 +#define KS_Cyrillic_CHE 0x0427 +#define KS_Cyrillic_SHA 0x0428 +#define KS_Cyrillic_SCHA 0x0429 +#define KS_Cyrillic_HSIGHN 0x042a +#define KS_Cyrillic_YERU 0x042b +#define KS_Cyrillic_SSIGHN 0x042c +#define KS_Cyrillic_E 0x042d +#define KS_Cyrillic_YU 0x042e +#define KS_Cyrillic_YA 0x042f +#define KS_Cyrillic_a 0x0430 +#define KS_Cyrillic_be 0x0431 +#define KS_Cyrillic_ve 0x0432 +#define KS_Cyrillic_ge 0x0433 +#define KS_Cyrillic_de 0x0434 +#define KS_Cyrillic_ie 0x0435 +#define KS_Cyrillic_zhe 0x0436 +#define KS_Cyrillic_ze 0x0437 +#define KS_Cyrillic_i 0x0438 +#define KS_Cyrillic_ishort 0x0439 +#define KS_Cyrillic_ka 0x043a +#define KS_Cyrillic_el 0x043b +#define KS_Cyrillic_em 0x043c +#define KS_Cyrillic_en 0x043d +#define KS_Cyrillic_o 0x043e +#define KS_Cyrillic_pe 0x043f +#define KS_Cyrillic_er 0x0440 +#define KS_Cyrillic_es 0x0441 +#define KS_Cyrillic_te 0x0442 +#define KS_Cyrillic_u 0x0443 +#define KS_Cyrillic_ef 0x0444 +#define KS_Cyrillic_ha 0x0445 +#define KS_Cyrillic_tse 0x0446 +#define KS_Cyrillic_che 0x0447 +#define KS_Cyrillic_sha 0x0448 +#define KS_Cyrillic_scha 0x0449 +#define KS_Cyrillic_hsighn 0x044a +#define KS_Cyrillic_yeru 0x044b +#define KS_Cyrillic_ssighn 0x044c +#define KS_Cyrillic_e 0x044d +#define KS_Cyrillic_yu 0x044e +#define KS_Cyrillic_ya 0x044f +#define KS_Cyrillic_yo 0x0451 +#define KS_Cyrillic_yeukr 0x0454 +#define KS_Cyrillic_iukr 0x0456 +#define KS_Cyrillic_yi 0x0457 +#define KS_Cyrillic_GHEUKR 0x0490 +#define KS_Cyrillic_gheukr 0x0491 /* - * Group Latin-2 (iso8859-2) + * Group Latin-2 */ -#define KS_L2_Aogonek 0xa1 -#define KS_L2_breve 0xa2 -#define KS_L2_Lstroke 0xa3 -#define KS_L2_Lcaron 0xa5 -#define KS_L2_Sacute 0xa6 -#define KS_L2_Scaron 0xa9 -#define KS_L2_Scedilla 0xaa -#define KS_L2_Tcaron 0xab -#define KS_L2_Zacute 0xac -#define KS_L2_Zcaron 0xae -#define KS_L2_Zdotabove 0xaf -#define KS_L2_aogonek 0xb1 -#define KS_L2_ogonek 0xb2 -#define KS_L2_lstroke 0xb3 -#define KS_L2_lcaron 0xb5 -#define KS_L2_sacute 0xb6 -#define KS_L2_caron 0xb7 -#define KS_L2_scaron 0xb9 -#define KS_L2_scedilla 0xba -#define KS_L2_tcaron 0xbb -#define KS_L2_zacute 0xbc -#define KS_L2_dblacute 0xbd -#define KS_L2_zcaron 0xbe -#define KS_L2_zdotabove 0xbf -#define KS_L2_Racute 0xc0 -#define KS_L2_Abreve 0xc3 -#define KS_L2_Lacute 0xc5 -#define KS_L2_Cacute 0xc6 -#define KS_L2_Ccaron 0xc8 -#define KS_L2_Eogonek 0xca -#define KS_L2_Ecaron 0xcc -#define KS_L2_Dcaron 0xcf -#define KS_L2_Dstroke 0xd0 -#define KS_L2_Nacute 0xd1 -#define KS_L2_Ncaron 0xd2 -#define KS_L2_Odoubleacute 0xd5 -#define KS_L2_Rcaron 0xd8 -#define KS_L2_Uring 0xd9 -#define KS_L2_Udoubleacute 0xdb -#define KS_L2_Tcedilla 0xde -#define KS_L2_racute 0xe0 -#define KS_L2_abreve 0xe3 -#define KS_L2_lacute 0xe5 -#define KS_L2_cacute 0xe6 -#define KS_L2_ccaron 0xe8 -#define KS_L2_eogonek 0xea -#define KS_L2_ecaron 0xec -#define KS_L2_dcaron 0xef -#define KS_L2_dstroke 0xf0 -#define KS_L2_nacute 0xf1 -#define KS_L2_odoubleacute 0xf5 -#define KS_L2_rcaron 0xf8 -#define KS_L2_uring 0xf9 -#define KS_L2_udoubleacute 0xfb -#define KS_L2_tcedilla 0xfe -#define KS_L2_dotabove 0xff +#define KS_L2_Abreve 0x0102 +#define KS_L2_abreve 0x0103 +#define KS_L2_Aogonek 0x0104 +#define KS_L2_aogonek 0x0105 +#define KS_L2_Cacute 0x0106 +#define KS_L2_cacute 0x0107 +#define KS_L2_Ccaron 0x010c +#define KS_L2_ccaron 0x010d +#define KS_L2_Dcaron 0x010e +#define KS_L2_dcaron 0x010f +#define KS_L2_Dstroke 0x0110 +#define KS_L2_dstroke 0x0111 +#define KS_L2_Eogonek 0x0118 +#define KS_L2_eogonek 0x0119 +#define KS_L2_Ecaron 0x011a +#define KS_L2_ecaron 0x011b +#define KS_L2_Lacute 0x0139 +#define KS_L2_lacute 0x013a +#define KS_L2_Lcaron 0x013d +#define KS_L2_lcaron 0x013e +#define KS_L2_Lstroke 0x0141 +#define KS_L2_lstroke 0x0142 +#define KS_L2_Nacute 0x0143 +#define KS_L2_nacute 0x0144 +#define KS_L2_Ncaron 0x0147 +#define KS_L2_Odoubleacute 0x0150 +#define KS_L2_odoubleacute 0x0151 +#define KS_L2_Racute 0x0154 +#define KS_L2_racute 0x0155 +#define KS_L2_Rcaron 0x0158 +#define KS_L2_rcaron 0x0159 +#define KS_L2_Sacute 0x015a +#define KS_L2_sacute 0x015b +#define KS_L2_Scedilla 0x015e +#define KS_L2_scedilla 0x015f +#define KS_L2_Scaron 0x0160 +#define KS_L2_scaron 0x0161 +#define KS_L2_Tcedilla 0x0162 +#define KS_L2_tcedilla 0x0163 +#define KS_L2_Tcaron 0x0164 +#define KS_L2_tcaron 0x0165 +#define KS_L2_Uring 0x016e +#define KS_L2_uring 0x016f +#define KS_L2_Udoubleacute 0x0170 +#define KS_L2_udoubleacute 0x0171 +#define KS_L2_Zacute 0x0179 +#define KS_L2_zacute 0x017a +#define KS_L2_Zdotabove 0x017b +#define KS_L2_zdotabove 0x017c +#define KS_L2_Zcaron 0x017d +#define KS_L2_zcaron 0x017e + +#define KS_L2_caron 0x02c7 +#define KS_L2_breve 0x02d8 +#define KS_L2_dotabove 0x02d9 +#define KS_L2_ogonek 0x02db +#define KS_L2_dblacute 0x02dd /* - * Group Latin-5 (iso8859-9) + * Group Latin-5 */ -#define KS_L5_Gbreve 0xd0 -#define KS_L5_Idotabove 0xdd -#define KS_L5_Scedilla 0xde -#define KS_L5_gbreve 0xf0 -#define KS_L5_idotless 0xfd -#define KS_L5_scedilla 0xfe +#define KS_L5_Gbreve 0x011e +#define KS_L5_gbreve 0x011f +#define KS_L5_Idotabove 0x0130 +#define KS_L5_idotless 0x0131 +#define KS_L5_Scedilla 0x015e +#define KS_L5_scedilla 0x015f /* - * Group Latin-7 (iso8859-13) + * Group Latin-7 */ -#define KS_L7_rightdblquot 0xa1 -#define KS_L7_dbllow9quot 0xa5 -#define KS_L7_Ostroke 0xa8 -#define KS_L7_Rcedilla 0xaa -#define KS_L7_AE 0xaf -#define KS_L7_leftdblquot 0xb4 -#define KS_L7_ostroke 0xb8 -#define KS_L7_rcedilla 0xba -#define KS_L7_ae 0xbf -#define KS_L7_Aogonek 0xc0 -#define KS_L7_Iogonek 0xc1 -#define KS_L7_Amacron 0xc2 -#define KS_L7_Cacute 0xc3 -#define KS_L7_Eogonek 0xc6 -#define KS_L7_Emacron 0xc7 -#define KS_L7_Ccaron 0xc8 -#define KS_L7_Zacute 0xca -#define KS_L7_Edot 0xcb -#define KS_L7_Gcedilla 0xcc -#define KS_L7_Kcedilla 0xcd -#define KS_L7_Imacron 0xce -#define KS_L7_Lcedilla 0xcf -#define KS_L7_Scaron 0xd0 -#define KS_L7_Nacute 0xd1 -#define KS_L7_Ncedilla 0xd2 -#define KS_L7_Omacron 0xd4 -#define KS_L7_Uogonek 0xd8 -#define KS_L7_Lstroke 0xd9 -#define KS_L7_Sacute 0xda -#define KS_L7_Umacron 0xdb -#define KS_L7_Zdot 0xdd -#define KS_L7_Zcaron 0xde -#define KS_L7_aogonek 0xe0 -#define KS_L7_iogonek 0xe1 -#define KS_L7_amacron 0xe2 -#define KS_L7_cacute 0xe3 -#define KS_L7_eogonek 0xe6 -#define KS_L7_emacron 0xe7 -#define KS_L7_ccaron 0xe8 -#define KS_L7_zacute 0xea -#define KS_L7_edot 0xeb -#define KS_L7_gcedilla 0xec -#define KS_L7_kcedilla 0xed -#define KS_L7_imacron 0xee -#define KS_L7_lcedilla 0xef -#define KS_L7_scaron 0xf0 -#define KS_L7_nacute 0xf1 -#define KS_L7_ncedilla 0xf2 -#define KS_L7_omacron 0xf4 -#define KS_L7_uogonek 0xf8 -#define KS_L7_lstroke 0xf9 -#define KS_L7_sacute 0xfa -#define KS_L7_umacron 0xfb -#define KS_L7_zdot 0xfd -#define KS_L7_zcaron 0xfe -#define KS_L7_rightsnglquot 0xff +#define KS_L7_rightdblquot 0x201d +#define KS_L7_dbllow9quot 0x201e +#define KS_L7_Ostroke 0x00d8 +#define KS_L7_Rcedilla 0x0156 +#define KS_L7_AE 0x00c0 +#define KS_L7_leftdblquot 0x201c +#define KS_L7_ostroke 0x00f8 +#define KS_L7_rcedilla 0x0157 +#define KS_L7_ae 0x00e6 +#define KS_L7_Aogonek 0x0104 +#define KS_L7_Iogonek 0x012e +#define KS_L7_Amacron 0x0100 +#define KS_L7_Cacute 0x0106 +#define KS_L7_Eogonek 0x0118 +#define KS_L7_Emacron 0x0112 +#define KS_L7_Ccaron 0x010c +#define KS_L7_Zacute 0x0179 +#define KS_L7_Edot 0x0116 +#define KS_L7_Gcedilla 0x0122 +#define KS_L7_Kcedilla 0x0136 +#define KS_L7_Imacron 0x012a +#define KS_L7_Lcedilla 0x013b +#define KS_L7_Scaron 0x0160 +#define KS_L7_Nacute 0x0143 +#define KS_L7_Ncedilla 0x0145 +#define KS_L7_Omacron 0x014c +#define KS_L7_Uogonek 0x0172 +#define KS_L7_Lstroke 0x0141 +#define KS_L7_Sacute 0x015a +#define KS_L7_Umacron 0x016a +#define KS_L7_Zdot 0x017b +#define KS_L7_Zcaron 0x017d +#define KS_L7_aogonek 0x0105 +#define KS_L7_iogonek 0x012f +#define KS_L7_amacron 0x0101 +#define KS_L7_cacute 0x0107 +#define KS_L7_eogonek 0x0119 +#define KS_L7_emacron 0x0113 +#define KS_L7_ccaron 0x010d +#define KS_L7_zacute 0x017a +#define KS_L7_edot 0x0117 +#define KS_L7_gcedilla 0x0123 +#define KS_L7_kcedilla 0x0137 +#define KS_L7_imacron 0x012b +#define KS_L7_lcedilla 0x013c +#define KS_L7_scaron 0x0161 +#define KS_L7_nacute 0x0144 +#define KS_L7_ncedilla 0x0146 +#define KS_L7_omacron 0x014d +#define KS_L7_uogonek 0x0173 +#define KS_L7_lstroke 0x0142 +#define KS_L7_sacute 0x015b +#define KS_L7_umacron 0x016b +#define KS_L7_zdot 0x017c +#define KS_L7_zcaron 0x017e +#define KS_L7_rightsnglquot 0x2019 /* * Group 1 (modifiers) |