charsets.c revision d522f475
1d522f475Smrg/* $XTermId: charsets.c,v 1.36 2007/03/19 23:47:00 tom Exp $ */
2d522f475Smrg
3d522f475Smrg/*
4d522f475Smrg * $XFree86: xc/programs/xterm/charsets.c,v 1.12 2005/01/14 01:50:02 dickey Exp $
5d522f475Smrg */
6d522f475Smrg
7d522f475Smrg/************************************************************
8d522f475Smrg
9d522f475SmrgCopyright 1998-2006,2007 by Thomas E. Dickey
10d522f475Smrg
11d522f475Smrg                        All Rights Reserved
12d522f475Smrg
13d522f475SmrgPermission is hereby granted, free of charge, to any person obtaining a
14d522f475Smrgcopy of this software and associated documentation files (the
15d522f475Smrg"Software"), to deal in the Software without restriction, including
16d522f475Smrgwithout limitation the rights to use, copy, modify, merge, publish,
17d522f475Smrgdistribute, sublicense, and/or sell copies of the Software, and to
18d522f475Smrgpermit persons to whom the Software is furnished to do so, subject to
19d522f475Smrgthe following conditions:
20d522f475Smrg
21d522f475SmrgThe above copyright notice and this permission notice shall be included
22d522f475Smrgin all copies or substantial portions of the Software.
23d522f475Smrg
24d522f475SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25d522f475SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26d522f475SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27d522f475SmrgIN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
28d522f475SmrgCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29d522f475SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30d522f475SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31d522f475Smrg
32d522f475SmrgExcept as contained in this notice, the name(s) of the above copyright
33d522f475Smrgholders shall not be used in advertising or otherwise to promote the
34d522f475Smrgsale, use or other dealings in this Software without prior written
35d522f475Smrgauthorization.
36d522f475Smrg
37d522f475Smrg********************************************************/
38d522f475Smrg
39d522f475Smrg#include <xterm.h>
40d522f475Smrg#include <data.h>
41d522f475Smrg#include <fontutils.h>
42d522f475Smrg
43d522f475Smrg#include <X11/keysym.h>
44d522f475Smrg
45d522f475Smrg/*
46d522f475Smrg * This module performs translation as needed to support the DEC VT220 national
47d522f475Smrg * replacement character sets.  We assume that xterm's font is based on the ISO
48d522f475Smrg * 8859-1 (Latin 1) character set, which is almost the same as the DEC
49d522f475Smrg * multinational character set.  Glyph positions 0-31 have to be the DEC
50d522f475Smrg * graphic characters, though.
51d522f475Smrg *
52d522f475Smrg * References:
53d522f475Smrg *	"VT220 Programmer Pocket Guide" EK-VT220-HR-002 (2nd ed., 1984), which
54d522f475Smrg *		contains character charts for the national character sets.
55d522f475Smrg *	"VT330/VT340 Programmer Reference Manual Volume 1: Text Programming"
56d522f475Smrg *		EK-VT3XX-TP-001 (1st ed, 1987), which contains a table (2-1)
57d522f475Smrg *		listing the glyphs which are mapped from the multinational
58d522f475Smrg *		character set to the national character set.
59d522f475Smrg *
60d522f475Smrg * The latter reference, though easier to read, has a few errors and omissions.
61d522f475Smrg */
62d522f475Smrg
63d522f475Smrg/*
64d522f475Smrg * Translate an input keysym to the corresponding NRC keysym.
65d522f475Smrg */
66d522f475Smrgunsigned xtermCharSetIn(unsigned code, int charset)
67d522f475Smrg{
68d522f475Smrg	if (code >= 128 && code < 256) {
69d522f475Smrg		switch (charset) {
70d522f475Smrg		case 'A':	/* United Kingdom set (or Latin 1)	*/
71d522f475Smrg			if (code == XK_sterling)
72d522f475Smrg				code = 0x23;
73d522f475Smrg			code &= 0x7f;
74d522f475Smrg			break;
75d522f475Smrg
76d522f475Smrg#if OPT_XMC_GLITCH
77d522f475Smrg		case '?':
78d522f475Smrg#endif
79d522f475Smrg		case '1':	/* Alternate Character ROM standard characters */
80d522f475Smrg		case '2':	/* Alternate Character ROM special graphics */
81d522f475Smrg		case 'B':	/* ASCII set				*/
82d522f475Smrg			break;
83d522f475Smrg
84d522f475Smrg		case '0':	/* special graphics (line drawing)	*/
85d522f475Smrg			break;
86d522f475Smrg
87d522f475Smrg		case '4':	/* Dutch */
88d522f475Smrg			switch (code) {
89d522f475Smrg			case XK_sterling:	code = 0x23;	break;
90d522f475Smrg			case XK_threequarters:	code = 0x40;	break;
91d522f475Smrg			case XK_ydiaeresis:	code = 0x5b;	break;
92d522f475Smrg			case XK_onehalf:	code = 0x5c;	break;
93d522f475Smrg	/* N/A		case XK_bar:		code = 0x5d;	break; */
94d522f475Smrg			case XK_diaeresis:	code = 0x7b;	break;
95d522f475Smrg	/* N/A		case XK_f:		code = 0x7c;	break; */
96d522f475Smrg			case XK_onequarter:	code = 0x7d;	break;
97d522f475Smrg			case XK_acute:		code = 0x7e;	break;
98d522f475Smrg			}
99d522f475Smrg			break;
100d522f475Smrg
101d522f475Smrg		case 'C':
102d522f475Smrg		case '5':	/* Finnish */
103d522f475Smrg			switch (code) {
104d522f475Smrg			case XK_Adiaeresis:	code = 0x5b;	break;
105d522f475Smrg			case XK_Odiaeresis:	code = 0x5c;	break;
106d522f475Smrg			case XK_Aring:		code = 0x5d;	break;
107d522f475Smrg			case XK_Udiaeresis:	code = 0x5e;	break;
108d522f475Smrg			case XK_eacute:		code = 0x60;	break;
109d522f475Smrg			case XK_adiaeresis:	code = 0x7b;	break;
110d522f475Smrg			case XK_odiaeresis:	code = 0x7c;	break;
111d522f475Smrg			case XK_aring:		code = 0x7d;	break;
112d522f475Smrg			case XK_udiaeresis:	code = 0x7e;	break;
113d522f475Smrg			}
114d522f475Smrg			break;
115d522f475Smrg
116d522f475Smrg		case 'R':	/* French */
117d522f475Smrg			switch (code) {
118d522f475Smrg			case XK_sterling:	code = 0x23;	break;
119d522f475Smrg			case XK_agrave:		code = 0x40;	break;
120d522f475Smrg			case XK_degree:		code = 0x5b;	break;
121d522f475Smrg			case XK_ccedilla:	code = 0x5c;	break;
122d522f475Smrg			case XK_section:	code = 0x5d;	break;
123d522f475Smrg			case XK_eacute:		code = 0x7b;	break;
124d522f475Smrg			case XK_ugrave:		code = 0x7c;	break;
125d522f475Smrg			case XK_egrave:		code = 0x7d;	break;
126d522f475Smrg			case XK_diaeresis:	code = 0x7e;	break;
127d522f475Smrg			}
128d522f475Smrg			break;
129d522f475Smrg
130d522f475Smrg		case 'Q':	/* French Canadian */
131d522f475Smrg			switch (code) {
132d522f475Smrg			case XK_agrave:		code = 0x40;	break;
133d522f475Smrg			case XK_acircumflex:	code = 0x5b;	break;
134d522f475Smrg			case XK_ccedilla:	code = 0x5c;	break;
135d522f475Smrg			case XK_ecircumflex:	code = 0x5d;	break;
136d522f475Smrg			case XK_icircumflex:	code = 0x5e;	break;
137d522f475Smrg			case XK_ocircumflex:	code = 0x60;	break;
138d522f475Smrg			case XK_eacute:		code = 0x7b;	break;
139d522f475Smrg			case XK_ugrave:		code = 0x7c;	break;
140d522f475Smrg			case XK_egrave:		code = 0x7d;	break;
141d522f475Smrg			case XK_ucircumflex:	code = 0x7e;	break;
142d522f475Smrg			}
143d522f475Smrg			break;
144d522f475Smrg
145d522f475Smrg		case 'K':	/* German */
146d522f475Smrg			switch (code) {
147d522f475Smrg			case XK_section:	code = 0x40;	break;
148d522f475Smrg			case XK_Adiaeresis:	code = 0x5b;	break;
149d522f475Smrg			case XK_Odiaeresis:	code = 0x5c;	break;
150d522f475Smrg			case XK_Udiaeresis:	code = 0x5d;	break;
151d522f475Smrg			case XK_adiaeresis:	code = 0x7b;	break;
152d522f475Smrg			case XK_odiaeresis:	code = 0x7c;	break;
153d522f475Smrg			case XK_udiaeresis:	code = 0x7d;	break;
154d522f475Smrg			case XK_ssharp:		code = 0x7e;	break;
155d522f475Smrg			}
156d522f475Smrg			break;
157d522f475Smrg
158d522f475Smrg		case 'Y':	/* Italian */
159d522f475Smrg			switch (code) {
160d522f475Smrg			case XK_sterling:	code = 0x23;	break;
161d522f475Smrg			case XK_section:	code = 0x40;	break;
162d522f475Smrg			case XK_degree:		code = 0x5b;	break;
163d522f475Smrg			case XK_ccedilla:	code = 0x5c;	break;
164d522f475Smrg			case XK_eacute:		code = 0x5d;	break;
165d522f475Smrg			case XK_ugrave:		code = 0x60;	break;
166d522f475Smrg			case XK_agrave:		code = 0x7b;	break;
167d522f475Smrg			case XK_ograve:		code = 0x7c;	break;
168d522f475Smrg			case XK_egrave:		code = 0x7d;	break;
169d522f475Smrg			case XK_igrave:		code = 0x7e;	break;
170d522f475Smrg			}
171d522f475Smrg			break;
172d522f475Smrg
173d522f475Smrg		case 'E':
174d522f475Smrg		case '6':	/* Norwegian/Danish */
175d522f475Smrg			switch (code) {
176d522f475Smrg			case XK_Adiaeresis:	code = 0x40;	break;
177d522f475Smrg			case XK_AE:		code = 0x5b;	break;
178d522f475Smrg			case XK_Ooblique:	code = 0x5c;	break;
179d522f475Smrg			case XK_Aring:		code = 0x5d;	break;
180d522f475Smrg			case XK_Udiaeresis:	code = 0x5e;	break;
181d522f475Smrg			case XK_adiaeresis:	code = 0x60;	break;
182d522f475Smrg			case XK_ae:		code = 0x7b;	break;
183d522f475Smrg			case XK_oslash:		code = 0x7c;	break;
184d522f475Smrg			case XK_aring:		code = 0x7d;	break;
185d522f475Smrg			case XK_udiaeresis:	code = 0x7e;	break;
186d522f475Smrg			}
187d522f475Smrg			break;
188d522f475Smrg
189d522f475Smrg		case 'Z':	/* Spanish */
190d522f475Smrg			switch (code) {
191d522f475Smrg			case XK_sterling:	code = 0x23;	break;
192d522f475Smrg			case XK_section:	code = 0x40;	break;
193d522f475Smrg			case XK_exclamdown:	code = 0x5b;	break;
194d522f475Smrg			case XK_Ntilde:		code = 0x5c;	break;
195d522f475Smrg			case XK_questiondown:	code = 0x5d;	break;
196d522f475Smrg			case XK_degree:		code = 0x7b;	break;
197d522f475Smrg			case XK_ntilde:		code = 0x7c;	break;
198d522f475Smrg			case XK_ccedilla:	code = 0x7d;	break;
199d522f475Smrg			}
200d522f475Smrg			break;
201d522f475Smrg
202d522f475Smrg		case 'H':
203d522f475Smrg		case '7':	/* Swedish */
204d522f475Smrg			switch (code) {
205d522f475Smrg			case XK_Eacute:		code = 0x40;	break;
206d522f475Smrg			case XK_Adiaeresis:	code = 0x5b;	break;
207d522f475Smrg			case XK_Odiaeresis:	code = 0x5c;	break;
208d522f475Smrg			case XK_Aring:		code = 0x5d;	break;
209d522f475Smrg			case XK_Udiaeresis:	code = 0x5e;	break;
210d522f475Smrg			case XK_eacute:		code = 0x60;	break;
211d522f475Smrg			case XK_adiaeresis:	code = 0x7b;	break;
212d522f475Smrg			case XK_odiaeresis:	code = 0x7c;	break;
213d522f475Smrg			case XK_aring:		code = 0x7d;	break;
214d522f475Smrg			case XK_udiaeresis:	code = 0x7e;	break;
215d522f475Smrg			}
216d522f475Smrg			break;
217d522f475Smrg
218d522f475Smrg		case '=':	/* Swiss */
219d522f475Smrg			switch (code) {
220d522f475Smrg			case XK_ugrave:		code = 0x23;	break;
221d522f475Smrg			case XK_agrave:		code = 0x40;	break;
222d522f475Smrg			case XK_eacute:		code = 0x5b;	break;
223d522f475Smrg			case XK_ccedilla:	code = 0x5c;	break;
224d522f475Smrg			case XK_ecircumflex:	code = 0x5d;	break;
225d522f475Smrg			case XK_icircumflex:	code = 0x5e;	break;
226d522f475Smrg			case XK_egrave:		code = 0x5f;	break;
227d522f475Smrg			case XK_ocircumflex:	code = 0x60;	break;
228d522f475Smrg			case XK_adiaeresis:	code = 0x7b;	break;
229d522f475Smrg			case XK_odiaeresis:	code = 0x7c;	break;
230d522f475Smrg			case XK_udiaeresis:	code = 0x7d;	break;
231d522f475Smrg			case XK_ucircumflex:	code = 0x7e;	break;
232d522f475Smrg			}
233d522f475Smrg			break;
234d522f475Smrg
235d522f475Smrg		default:	/* any character sets we don't recognize*/
236d522f475Smrg			break;
237d522f475Smrg		}
238d522f475Smrg		code &= 0x7f;	/* NRC in any case is 7-bit */
239d522f475Smrg	}
240d522f475Smrg	return code;
241d522f475Smrg}
242d522f475Smrg
243d522f475Smrg/*
244d522f475Smrg * Translate a string to the display form.  This assumes the font has the
245d522f475Smrg * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1.
246d522f475Smrg */
247d522f475Smrgint xtermCharSetOut(IChar *buf, IChar *ptr, int leftset)
248d522f475Smrg{
249d522f475Smrg	IChar *s;
250d522f475Smrg	register TScreen *screen = TScreenOf(term);
251d522f475Smrg	int count = 0;
252d522f475Smrg	int rightset = screen->gsets[(int)(screen->curgr)];
253d522f475Smrg
254d522f475Smrg	TRACE(("CHARSET GL=%c(G%d) GR=%c(G%d) SS%d:%s\n",
255d522f475Smrg		leftset,  screen->curgl,
256d522f475Smrg		rightset, screen->curgr,
257d522f475Smrg		screen->curss,
258d522f475Smrg		visibleIChar(buf, (unsigned)(ptr - buf))));
259d522f475Smrg
260d522f475Smrg	for (s = buf; s < ptr; ++s) {
261d522f475Smrg		int eight = CharOf(E2A(*s));
262d522f475Smrg		int seven = eight & 0x7f;
263d522f475Smrg		int cs = (eight >= 128) ? rightset : leftset;
264d522f475Smrg		int chr = eight;
265d522f475Smrg
266d522f475Smrg		count++;
267d522f475Smrg		switch (cs) {
268d522f475Smrg		case 'A':	/* United Kingdom set (or Latin 1)	*/
269d522f475Smrg			if ((term->flags & NATIONAL)
270d522f475Smrg			 || (screen->vtXX_level <= 1)) {
271d522f475Smrg				if (chr == 0x23) {
272d522f475Smrg					chr = XTERM_POUND;	/* UK pound sign*/
273d522f475Smrg				}
274d522f475Smrg			} else {
275d522f475Smrg				chr = (seven | 0x80);
276d522f475Smrg			}
277d522f475Smrg			break;
278d522f475Smrg
279d522f475Smrg#if OPT_XMC_GLITCH
280d522f475Smrg		case '?':
281d522f475Smrg#endif
282d522f475Smrg		case '1':	/* Alternate Character ROM standard characters */
283d522f475Smrg		case '2':	/* Alternate Character ROM special graphics */
284d522f475Smrg		case 'B':	/* ASCII set				*/
285d522f475Smrg			break;
286d522f475Smrg
287d522f475Smrg		case '0':	/* special graphics (line drawing)	*/
288d522f475Smrg			if (seven > 0x5f && seven <= 0x7e) {
289d522f475Smrg#if OPT_WIDE_CHARS
290d522f475Smrg			    if (screen->utf8_mode)
291d522f475Smrg				chr = dec2ucs((unsigned)(seven - 0x5f));
292d522f475Smrg			    else
293d522f475Smrg#endif
294d522f475Smrg				chr = seven - 0x5f;
295d522f475Smrg			} else {
296d522f475Smrg			    chr = seven;
297d522f475Smrg			}
298d522f475Smrg			break;
299d522f475Smrg
300d522f475Smrg		case '4':	/* Dutch */
301d522f475Smrg			switch (chr = seven) {
302d522f475Smrg			case 0x23:	chr = XK_sterling;	break;
303d522f475Smrg			case 0x40:	chr = XK_threequarters;	break;
304d522f475Smrg			case 0x5b:	chr = XK_ydiaeresis;	break;
305d522f475Smrg			case 0x5c:	chr = XK_onehalf;	break;
306d522f475Smrg			case 0x5d:	chr = XK_bar;		break;
307d522f475Smrg			case 0x7b:	chr = XK_diaeresis;	break;
308d522f475Smrg			case 0x7c:	chr = XK_f;		break;
309d522f475Smrg			case 0x7d:	chr = XK_onequarter;	break;
310d522f475Smrg			case 0x7e:	chr = XK_acute;		break;
311d522f475Smrg			}
312d522f475Smrg			break;
313d522f475Smrg
314d522f475Smrg		case 'C':
315d522f475Smrg		case '5':	/* Finnish */
316d522f475Smrg			switch (chr = seven) {
317d522f475Smrg			case 0x5b:	chr = XK_Adiaeresis;	break;
318d522f475Smrg			case 0x5c:	chr = XK_Odiaeresis;	break;
319d522f475Smrg			case 0x5d:	chr = XK_Aring;		break;
320d522f475Smrg			case 0x5e:	chr = XK_Udiaeresis;	break;
321d522f475Smrg			case 0x60:	chr = XK_eacute;	break;
322d522f475Smrg			case 0x7b:	chr = XK_adiaeresis;	break;
323d522f475Smrg			case 0x7c:	chr = XK_odiaeresis;	break;
324d522f475Smrg			case 0x7d:	chr = XK_aring;		break;
325d522f475Smrg			case 0x7e:	chr = XK_udiaeresis;	break;
326d522f475Smrg			}
327d522f475Smrg			break;
328d522f475Smrg
329d522f475Smrg		case 'R':	/* French */
330d522f475Smrg			switch (chr = seven) {
331d522f475Smrg			case 0x23:	chr = XK_sterling;	break;
332d522f475Smrg			case 0x40:	chr = XK_agrave;	break;
333d522f475Smrg			case 0x5b:	chr = XK_degree;	break;
334d522f475Smrg			case 0x5c:	chr = XK_ccedilla;	break;
335d522f475Smrg			case 0x5d:	chr = XK_section;	break;
336d522f475Smrg			case 0x7b:	chr = XK_eacute;	break;
337d522f475Smrg			case 0x7c:	chr = XK_ugrave;	break;
338d522f475Smrg			case 0x7d:	chr = XK_egrave;	break;
339d522f475Smrg			case 0x7e:	chr = XK_diaeresis;	break;
340d522f475Smrg			}
341d522f475Smrg			break;
342d522f475Smrg
343d522f475Smrg		case 'Q':	/* French Canadian */
344d522f475Smrg			switch (chr = seven) {
345d522f475Smrg			case 0x40:	chr = XK_agrave;	break;
346d522f475Smrg			case 0x5b:	chr = XK_acircumflex;	break;
347d522f475Smrg			case 0x5c:	chr = XK_ccedilla;	break;
348d522f475Smrg			case 0x5d:	chr = XK_ecircumflex;	break;
349d522f475Smrg			case 0x5e:	chr = XK_icircumflex;	break;
350d522f475Smrg			case 0x60:	chr = XK_ocircumflex;	break;
351d522f475Smrg			case 0x7b:	chr = XK_eacute;	break;
352d522f475Smrg			case 0x7c:	chr = XK_ugrave;	break;
353d522f475Smrg			case 0x7d:	chr = XK_egrave;	break;
354d522f475Smrg			case 0x7e:	chr = XK_ucircumflex;	break;
355d522f475Smrg			}
356d522f475Smrg			break;
357d522f475Smrg
358d522f475Smrg		case 'K':	/* German */
359d522f475Smrg			switch (chr = seven) {
360d522f475Smrg			case 0x40:	chr = XK_section;	break;
361d522f475Smrg			case 0x5b:	chr = XK_Adiaeresis;	break;
362d522f475Smrg			case 0x5c:	chr = XK_Odiaeresis;	break;
363d522f475Smrg			case 0x5d:	chr = XK_Udiaeresis;	break;
364d522f475Smrg			case 0x7b:	chr = XK_adiaeresis;	break;
365d522f475Smrg			case 0x7c:	chr = XK_odiaeresis;	break;
366d522f475Smrg			case 0x7d:	chr = XK_udiaeresis;	break;
367d522f475Smrg			case 0x7e:	chr = XK_ssharp;	break;
368d522f475Smrg			}
369d522f475Smrg			break;
370d522f475Smrg
371d522f475Smrg		case 'Y':	/* Italian */
372d522f475Smrg			switch (chr = seven) {
373d522f475Smrg			case 0x23:	chr = XK_sterling;	break;
374d522f475Smrg			case 0x40:	chr = XK_section;	break;
375d522f475Smrg			case 0x5b:	chr = XK_degree;	break;
376d522f475Smrg			case 0x5c:	chr = XK_ccedilla;	break;
377d522f475Smrg			case 0x5d:	chr = XK_eacute;	break;
378d522f475Smrg			case 0x60:	chr = XK_ugrave;	break;
379d522f475Smrg			case 0x7b:	chr = XK_agrave;	break;
380d522f475Smrg			case 0x7c:	chr = XK_ograve;	break;
381d522f475Smrg			case 0x7d:	chr = XK_egrave;	break;
382d522f475Smrg			case 0x7e:	chr = XK_igrave;	break;
383d522f475Smrg			}
384d522f475Smrg			break;
385d522f475Smrg
386d522f475Smrg		case 'E':
387d522f475Smrg		case '6':	/* Norwegian/Danish */
388d522f475Smrg			switch (chr = seven) {
389d522f475Smrg			case 0x40:	chr = XK_Adiaeresis;	break;
390d522f475Smrg			case 0x5b:	chr = XK_AE;		break;
391d522f475Smrg			case 0x5c:	chr = XK_Ooblique;	break;
392d522f475Smrg			case 0x5d:	chr = XK_Aring;		break;
393d522f475Smrg			case 0x5e:	chr = XK_Udiaeresis;	break;
394d522f475Smrg			case 0x60:	chr = XK_adiaeresis;	break;
395d522f475Smrg			case 0x7b:	chr = XK_ae;		break;
396d522f475Smrg			case 0x7c:	chr = XK_oslash;	break;
397d522f475Smrg			case 0x7d:	chr = XK_aring;		break;
398d522f475Smrg			case 0x7e:	chr = XK_udiaeresis;	break;
399d522f475Smrg			}
400d522f475Smrg			break;
401d522f475Smrg
402d522f475Smrg		case 'Z':	/* Spanish */
403d522f475Smrg			switch (chr = seven) {
404d522f475Smrg			case 0x23:	chr = XK_sterling;	break;
405d522f475Smrg			case 0x40:	chr = XK_section;	break;
406d522f475Smrg			case 0x5b:	chr = XK_exclamdown;	break;
407d522f475Smrg			case 0x5c:	chr = XK_Ntilde;	break;
408d522f475Smrg			case 0x5d:	chr = XK_questiondown;	break;
409d522f475Smrg			case 0x7b:	chr = XK_degree;	break;
410d522f475Smrg			case 0x7c:	chr = XK_ntilde;	break;
411d522f475Smrg			case 0x7d:	chr = XK_ccedilla;	break;
412d522f475Smrg			}
413d522f475Smrg			break;
414d522f475Smrg
415d522f475Smrg		case 'H':
416d522f475Smrg		case '7':	/* Swedish */
417d522f475Smrg			switch (chr = seven) {
418d522f475Smrg			case 0x40:	chr = XK_Eacute;	break;
419d522f475Smrg			case 0x5b:	chr = XK_Adiaeresis;	break;
420d522f475Smrg			case 0x5c:	chr = XK_Odiaeresis;	break;
421d522f475Smrg			case 0x5d:	chr = XK_Aring;		break;
422d522f475Smrg			case 0x5e:	chr = XK_Udiaeresis;	break;
423d522f475Smrg			case 0x60:	chr = XK_eacute;	break;
424d522f475Smrg			case 0x7b:	chr = XK_adiaeresis;	break;
425d522f475Smrg			case 0x7c:	chr = XK_odiaeresis;	break;
426d522f475Smrg			case 0x7d:	chr = XK_aring;		break;
427d522f475Smrg			case 0x7e:	chr = XK_udiaeresis;	break;
428d522f475Smrg			}
429d522f475Smrg			break;
430d522f475Smrg
431d522f475Smrg		case '=':	/* Swiss */
432d522f475Smrg			switch (chr = seven) {
433d522f475Smrg			case 0x23:	chr = XK_ugrave;	break;
434d522f475Smrg			case 0x40:	chr = XK_agrave;	break;
435d522f475Smrg			case 0x5b:	chr = XK_eacute;	break;
436d522f475Smrg			case 0x5c:	chr = XK_ccedilla;	break;
437d522f475Smrg			case 0x5d:	chr = XK_ecircumflex;	break;
438d522f475Smrg			case 0x5e:	chr = XK_icircumflex;	break;
439d522f475Smrg			case 0x5f:	chr = XK_egrave;	break;
440d522f475Smrg			case 0x60:	chr = XK_ocircumflex;	break;
441d522f475Smrg			case 0x7b:	chr = XK_adiaeresis;	break;
442d522f475Smrg			case 0x7c:	chr = XK_odiaeresis;	break;
443d522f475Smrg			case 0x7d:	chr = XK_udiaeresis;	break;
444d522f475Smrg			case 0x7e:	chr = XK_ucircumflex;	break;
445d522f475Smrg			}
446d522f475Smrg			break;
447d522f475Smrg
448d522f475Smrg		default:	/* any character sets we don't recognize*/
449d522f475Smrg			count --;
450d522f475Smrg			break;
451d522f475Smrg		}
452d522f475Smrg		/*
453d522f475Smrg		 * The state machine already treated DEL as a nonprinting and
454d522f475Smrg		 * nonspacing character.  If we have DEL now, simply render
455d522f475Smrg		 * it as a blank.
456d522f475Smrg		 */
457d522f475Smrg		if (chr == ANSI_DEL)
458d522f475Smrg		    chr = ' ';
459d522f475Smrg		*s = A2E(chr);
460d522f475Smrg	}
461d522f475Smrg	return count;
462d522f475Smrg}
463