root/foundation-apps/mxterm-maxx/charsets.c

Revision 8, 13.8 KB (checked in by emasson, 3 years ago)

initial import for the community edition

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