charsets.c revision e0a2b6df
1/* $XTermId: charsets.c,v 1.67 2013/12/01 16:38:13 tom Exp $ */ 2 3/* 4 * Copyright 1998-2011,2013 by Thomas E. Dickey 5 * 6 * All Rights Reserved 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name(s) of the above copyright 28 * holders shall not be used in advertising or otherwise to promote the 29 * sale, use or other dealings in this Software without prior written 30 * authorization. 31 * 32 */ 33 34#include <xterm.h> 35#include <data.h> 36#include <fontutils.h> 37 38#include <X11/keysym.h> 39 40/* 41 * This module performs translation as needed to support the DEC VT220 national 42 * replacement character sets. We assume that xterm's font is based on the ISO 43 * 8859-1 (Latin 1) character set, which is almost the same as the DEC 44 * multinational character set. Glyph positions 0-31 have to be the DEC 45 * graphic characters, though. 46 * 47 * References: 48 * "VT220 Programmer Pocket Guide" EK-VT220-HR-002 (2nd ed., 1984), which 49 * contains character charts for the national character sets. 50 * "VT330/VT340 Programmer Reference Manual Volume 1: Text Programming" 51 * EK-VT3XX-TP-001 (1st ed, 1987), which contains a table (2-1) 52 * listing the glyphs which are mapped from the multinational 53 * character set to the national character set. 54 * 55 * The latter reference, though easier to read, has a few errors and omissions. 56 */ 57 58#define map_NRCS_Dutch(code) \ 59 switch (code) { \ 60 MAP(0x23, XK_sterling); \ 61 MAP(0x40, XK_threequarters); \ 62 UNI(0x5b, 0x0133); /* ij ligature */ \ 63 MAP(0x5c, XK_onehalf); \ 64 MAP(0x5d, XK_bar); \ 65 MAP(0x7b, XK_diaeresis); \ 66 UNI(0x7c, 0x0192); /* florin */ \ 67 MAP(0x7d, XK_onequarter); \ 68 MAP(0x7e, XK_acute); \ 69 } 70 71#define map_NRCS_Finnish(code) \ 72 switch (code) { \ 73 MAP(0x5b, XK_Adiaeresis); \ 74 MAP(0x5c, XK_Odiaeresis); \ 75 MAP(0x5d, XK_Aring); \ 76 MAP(0x5e, XK_Udiaeresis); \ 77 MAP(0x60, XK_eacute); \ 78 MAP(0x7b, XK_adiaeresis); \ 79 MAP(0x7c, XK_odiaeresis); \ 80 MAP(0x7d, XK_aring); \ 81 MAP(0x7e, XK_udiaeresis); \ 82 } 83 84#define map_NRCS_French(code) \ 85 switch (code) { \ 86 MAP(0x23, XK_sterling); \ 87 MAP(0x40, XK_agrave); \ 88 MAP(0x5b, XK_degree); \ 89 MAP(0x5c, XK_ccedilla); \ 90 MAP(0x5d, XK_section); \ 91 MAP(0x7b, XK_eacute); \ 92 MAP(0x7c, XK_ugrave); \ 93 MAP(0x7d, XK_egrave); \ 94 MAP(0x7e, XK_diaeresis); \ 95 } 96 97#define map_NRCS_French_Canadian(code) \ 98 switch (code) { \ 99 MAP(0x40, XK_agrave); \ 100 MAP(0x5b, XK_acircumflex); \ 101 MAP(0x5c, XK_ccedilla); \ 102 MAP(0x5d, XK_ecircumflex); \ 103 MAP(0x5e, XK_icircumflex); \ 104 MAP(0x60, XK_ocircumflex); \ 105 MAP(0x7b, XK_eacute); \ 106 MAP(0x7c, XK_ugrave); \ 107 MAP(0x7d, XK_egrave); \ 108 MAP(0x7e, XK_ucircumflex); \ 109 } 110 111#define map_NRCS_German(code) \ 112 switch (code) { \ 113 MAP(0x40, XK_section); \ 114 MAP(0x5b, XK_Adiaeresis); \ 115 MAP(0x5c, XK_Odiaeresis); \ 116 MAP(0x5d, XK_Udiaeresis); \ 117 MAP(0x7b, XK_adiaeresis); \ 118 MAP(0x7c, XK_odiaeresis); \ 119 MAP(0x7d, XK_udiaeresis); \ 120 MAP(0x7e, XK_ssharp); \ 121 } 122 123#define map_NRCS_Italian(code) \ 124 switch (code) { \ 125 MAP(0x23, XK_sterling); \ 126 MAP(0x40, XK_section); \ 127 MAP(0x5b, XK_degree); \ 128 MAP(0x5c, XK_ccedilla); \ 129 MAP(0x5d, XK_eacute); \ 130 MAP(0x60, XK_ugrave); \ 131 MAP(0x7b, XK_agrave); \ 132 MAP(0x7c, XK_ograve); \ 133 MAP(0x7d, XK_egrave); \ 134 MAP(0x7e, XK_igrave); \ 135 } 136 137#define map_NRCS_Norwegian_Danish(code) \ 138 switch (code) { \ 139 MAP(0x40, XK_Adiaeresis); \ 140 MAP(0x5b, XK_AE); \ 141 MAP(0x5c, XK_Ooblique); \ 142 MAP(0x5d, XK_Aring); \ 143 MAP(0x5e, XK_Udiaeresis); \ 144 MAP(0x60, XK_adiaeresis); \ 145 MAP(0x7b, XK_ae); \ 146 MAP(0x7c, XK_oslash); \ 147 MAP(0x7d, XK_aring); \ 148 MAP(0x7e, XK_udiaeresis); \ 149 } 150 151#define map_NRCS_Portuguese(code) \ 152 switch (code) { \ 153 MAP(0x5b, XK_Atilde); \ 154 MAP(0x5c, XK_Ccedilla); \ 155 MAP(0x5d, XK_Otilde); \ 156 MAP(0x7b, XK_atilde); \ 157 MAP(0x7c, XK_ccedilla); \ 158 MAP(0x7d, XK_otilde); \ 159 } 160 161#define map_NRCS_Spanish(code) \ 162 switch (code) { \ 163 MAP(0x23, XK_sterling); \ 164 MAP(0x40, XK_section); \ 165 MAP(0x5b, XK_exclamdown); \ 166 MAP(0x5c, XK_Ntilde); \ 167 MAP(0x5d, XK_questiondown); \ 168 MAP(0x7b, XK_degree); \ 169 MAP(0x7c, XK_ntilde); \ 170 MAP(0x7d, XK_ccedilla); \ 171 } 172 173#define map_NRCS_Swedish(code) \ 174 switch (code) { \ 175 MAP(0x40, XK_Eacute); \ 176 MAP(0x5b, XK_Adiaeresis); \ 177 MAP(0x5c, XK_Odiaeresis); \ 178 MAP(0x5d, XK_Aring); \ 179 MAP(0x5e, XK_Udiaeresis); \ 180 MAP(0x60, XK_eacute); \ 181 MAP(0x7b, XK_adiaeresis); \ 182 MAP(0x7c, XK_odiaeresis); \ 183 MAP(0x7d, XK_aring); \ 184 MAP(0x7e, XK_udiaeresis); \ 185 } 186 187#define map_NRCS_Swiss(code) \ 188 switch (code) { \ 189 MAP(0x23, XK_ugrave); \ 190 MAP(0x40, XK_agrave); \ 191 MAP(0x5b, XK_eacute); \ 192 MAP(0x5c, XK_ccedilla); \ 193 MAP(0x5d, XK_ecircumflex); \ 194 MAP(0x5e, XK_icircumflex); \ 195 MAP(0x5f, XK_egrave); \ 196 MAP(0x60, XK_ocircumflex); \ 197 MAP(0x7b, XK_adiaeresis); \ 198 MAP(0x7c, XK_odiaeresis); \ 199 MAP(0x7d, XK_udiaeresis); \ 200 MAP(0x7e, XK_ucircumflex); \ 201 } 202 203/* 204 * Unlike NRCS, which splices a few characters onto ASCII, the supplementary 205 * character sets are complete, normally mapped to GR. Most of these mappings 206 * rely upon glyphs not found in ISO-8859-1. We can display most of those 207 * using Unicode, thereby supporting specialized applications that use SCS 208 * with luit, subject to the limitation that select/paste will give meaningless 209 * results in terms of the application which uses these mappings. 210 * 211 * Since the VT320, etc, use only 8-bit encodings, there is no plausible 212 * argument to be made that these mappings "use" UTF-8, even though there is 213 * a hidden step in the terminal emulator which relies upon UTF-8. 214 */ 215#define map_SCS_DEC_Supp(code,dft) \ 216 switch (code) { \ 217 XXX(0x24, 0x2e2e); \ 218 XXX(0x26, 0x2e2e); \ 219 XXX(0x2c, 0x2e2e); \ 220 XXX(0x2d, 0x2e2e); \ 221 XXX(0x2e, 0x2e2e); \ 222 XXX(0x2f, 0x2e2e); \ 223 XXX(0x34, 0x2e2e); \ 224 XXX(0x38, 0x2e2e); \ 225 XXX(0x3e, 0x2e2e); \ 226 UNI(0x47, 0x2426); \ 227 MAP(0x48, 0xc7); \ 228 MAP(0x49, 0xc8); \ 229 MAP(0x4a, 0xc9); \ 230 MAP(0x4b, 0xca); \ 231 MAP(0x4c, 0xcb); \ 232 MAP(0x4d, 0xcc); \ 233 MAP(0x4e, 0xcd); \ 234 MAP(0x4f, 0xce); \ 235 XXX(0x50, 0x2e2e); \ 236 UNI(0x57, 0x0152); \ 237 XXX(0x5e, 0x2e2e); \ 238 XXX(0x70, 0x2e2e); \ 239 UNI(0x77, 0x0153); \ 240 MAP(0x7d, 0xff); \ 241 XXX(0x7e, 0x2e2e); \ 242 default: dft; break; \ 243 } 244 245#define map_SCS_DEC_Supp_Graphic(code,dft) \ 246 switch (code) { \ 247 XXX(0x24, 0x2e2e); \ 248 XXX(0x26, 0x2e2e); \ 249 XXX(0x2c, 0x2e2e); \ 250 XXX(0x2d, 0x2e2e); \ 251 XXX(0x2e, 0x2e2e); \ 252 XXX(0x2f, 0x2e2e); \ 253 XXX(0x34, 0x2e2e); \ 254 XXX(0x38, 0x2e2e); \ 255 XXX(0x3e, 0x2e2e); \ 256 XXX(0x50, 0x2e2e); \ 257 UNI(0x57, 0x0152); \ 258 XXX(0x5e, 0x2e2e); \ 259 XXX(0x70, 0x2e2e); \ 260 UNI(0x77, 0x0153); \ 261 MAP(0x7d, 0xff); \ 262 XXX(0x7e, 0x2e2e); \ 263 XXX(0x7f, 0x2e2e); \ 264 default: dft; break; \ 265 } 266 267 /* derived from http://www.vt100.net/charsets/technical.html */ 268#if OPT_WIDE_CHARS 269#define map_SCS_DEC_Technical(code) \ 270 switch (code) { \ 271 UNI(0x21, 0x23b7); /* RADICAL SYMBOL BOTTOM Centred left to right, so that it joins up with 02/02 */ \ 272 UNI(0x22, 0x250c); /* BOX DRAWINGS LIGHT DOWN AND RIGHT */ \ 273 UNI(0x23, 0x2500); /* BOX DRAWINGS LIGHT HORIZONTAL */ \ 274 UNI(0x24, 0x2320); /* TOP HALF INTEGRAL with the proviso that the stem is vertical, to join with 02/06 */ \ 275 UNI(0x25, 0x2321); /* BOTTOM HALF INTEGRAL with the proviso above. */ \ 276 UNI(0x26, 0x2502); /* BOX DRAWINGS LIGHT VERTICAL */ \ 277 UNI(0x27, 0x23a1); /* LEFT SQUARE BRACKET UPPER CORNER Joins vertically to 02/06, 02/08. Doesn't join to its right. */ \ 278 UNI(0x28, 0x23a3); /* LEFT SQUARE BRACKET LOWER CORNER Joins vertically to 02/06, 02/07. Doesn't join to its right. */ \ 279 UNI(0x29, 0x23a4); /* RIGHT SQUARE BRACKET UPPER CORNER Joins vertically to 026, 02a. Doesn't join to its left. */ \ 280 UNI(0x2a, 0x23a6); /* RIGHT SQUARE BRACKET LOWER CORNER Joins vertically to 026, 029. Doesn't join to its left. */ \ 281 UNI(0x2b, 0x239b); /* LEFT PARENTHESIS UPPER HOOK Joins vertically to 026, 02c, 02/15. Doesn't join to its right. */ \ 282 UNI(0x2c, 0x239d); /* LEFT PARENTHESIS LOWER HOOK Joins vertically to 026, 02b, 02/15. Doesn't join to its right. */ \ 283 UNI(0x2d, 0x239e); /* RIGHT PARENTHESIS UPPER HOOK Joins vertically to 026, 02e, 03/00. Doesn't join to its left. */ \ 284 UNI(0x2e, 0x23a0); /* RIGHT PARENTHESIS LOWER HOOK Joins vertically to 026, 02d, 03/00. Doesn't join to its left. */ \ 285 UNI(0x2f, 0x23a8); /* LEFT CURLY BRACKET MIDDLE PIECE Joins vertically to 026, 02b, 02c. */ \ 286 UNI(0x30, 0x23ac); /* RIGHT CURLY BRACKET MIDDLE PIECE Joins vertically to 02/06, 02d, 02e. */ \ 287 XXX(0x31, 0x2426); /* Top Left Sigma. Joins to right with 02/03, 03/05. Joins diagonally below right with 03/03, 03/07. */ \ 288 XXX(0x32, 0x2426); /* Bottom Left Sigma. Joins to right with 02/03, 03/06. Joins diagonally above right with 03/04, 03/07. */ \ 289 XXX(0x33, 0x2426); /* Top Diagonal Sigma. Line for joining 03/01 to 03/04 or 03/07. */ \ 290 XXX(0x34, 0x2426); /* Bottom Diagonal Sigma. Line for joining 03/02 to 03/03 or 03/07. */ \ 291 XXX(0x35, 0x2426); /* Top Right Sigma. Joins to left with 02/03, 03/01. */ \ 292 XXX(0x36, 0x2426); /* Bottom Right Sigma. Joins to left with 02/03, 03/02. */ \ 293 XXX(0x37, 0x2426); /* Middle Sigma. Joins diagonally with 03/01, 03/02, 03/03, 03/04. */ \ 294 XXX(0x38, 0x2426); /* undefined */ \ 295 XXX(0x39, 0x2426); /* undefined */ \ 296 XXX(0x3a, 0x2426); /* undefined */ \ 297 XXX(0x3b, 0x2426); /* undefined */ \ 298 UNI(0x3c, 0x2264); /* LESS-THAN OR EQUAL TO */ \ 299 UNI(0x3d, 0x2260); /* NOT EQUAL TO */ \ 300 UNI(0x3e, 0x2265); /* GREATER-THAN OR EQUAL TO */ \ 301 UNI(0x3f, 0x222B); /* INTEGRAL */ \ 302 UNI(0x40, 0x2234); /* THEREFORE */ \ 303 UNI(0x41, 0x221d); /* PROPORTIONAL TO */ \ 304 UNI(0x42, 0x221e); /* INFINITY */ \ 305 UNI(0x43, 0x00f7); /* DIVISION SIGN */ \ 306 UNI(0x44, 0x039a); /* GREEK CAPITAL DELTA */ \ 307 UNI(0x45, 0x2207); /* NABLA */ \ 308 UNI(0x46, 0x03a6); /* GREEK CAPITAL LETTER PHI */ \ 309 UNI(0x47, 0x0393); /* GREEK CAPITAL LETTER GAMMA */ \ 310 UNI(0x48, 0x223c); /* TILDE OPERATOR */ \ 311 UNI(0x49, 0x2243); /* ASYMPTOTICALLY EQUAL TO */ \ 312 UNI(0x4a, 0x0398); /* GREEK CAPITAL LETTER THETA */ \ 313 UNI(0x4b, 0x00d7); /* MULTIPLICATION SIGN */ \ 314 UNI(0x4c, 0x039b); /* GREEK CAPITAL LETTER LAMDA */ \ 315 UNI(0x4d, 0x21d4); /* LEFT RIGHT DOUBLE ARROW */ \ 316 UNI(0x4e, 0x21d2); /* RIGHTWARDS DOUBLE ARROW */ \ 317 UNI(0x4f, 0x2261); /* IDENTICAL TO */ \ 318 UNI(0x50, 0x03a0); /* GREEK CAPITAL LETTER PI */ \ 319 UNI(0x51, 0x03a8); /* GREEK CAPITAL LETTER PSI */ \ 320 UNI(0x52, 0x2426); /* undefined */ \ 321 UNI(0x53, 0x03a3); /* GREEK CAPITAL LETTER SIGMA */ \ 322 XXX(0x54, 0x2426); /* undefined */ \ 323 XXX(0x55, 0x2426); /* undefined */ \ 324 UNI(0x56, 0x221a); /* SQUARE ROOT */ \ 325 UNI(0x57, 0x03a9); /* GREEK CAPITAL LETTER OMEGA */ \ 326 UNI(0x58, 0x039e); /* GREEK CAPITAL LETTER XI */ \ 327 UNI(0x59, 0x03a5); /* GREEK CAPITAL LETTER UPSILON */ \ 328 UNI(0x5a, 0x2282); /* SUBSET OF */ \ 329 UNI(0x5b, 0x2283); /* SUPERSET OF */ \ 330 UNI(0x5c, 0x2229); /* INTERSECTION */ \ 331 UNI(0x5d, 0x222a); /* UNION */ \ 332 UNI(0x5e, 0x2227); /* LOGICAL AND */ \ 333 UNI(0x5f, 0x2228); /* LOGICAL OR */ \ 334 UNI(0x60, 0x00ac); /* NOT SIGN */ \ 335 UNI(0x61, 0x03b1); /* GREEK SMALL LETTER ALPHA */ \ 336 UNI(0x62, 0x03b2); /* GREEK SMALL LETTER BETA */ \ 337 UNI(0x63, 0x03c7); /* GREEK SMALL LETTER CHI */ \ 338 UNI(0x64, 0x03b4); /* GREEK SMALL LETTER DELTA */ \ 339 UNI(0x65, 0x03b5); /* GREEK SMALL LETTER EPSILON */ \ 340 UNI(0x66, 0x03c6); /* GREEK SMALL LETTER PHI */ \ 341 UNI(0x67, 0x03b3); /* GREEK SMALL LETTER GAMMA */ \ 342 UNI(0x68, 0x03b7); /* GREEK SMALL LETTER ETA */ \ 343 UNI(0x69, 0x03b9); /* GREEK SMALL LETTER IOTA */ \ 344 UNI(0x6a, 0x03b8); /* GREEK SMALL LETTER THETA */ \ 345 UNI(0x6b, 0x03ba); /* GREEK SMALL LETTER KAPPA */ \ 346 UNI(0x6c, 0x03bb); /* GREEK SMALL LETTER LAMDA */ \ 347 XXX(0x6d, 0x2426); /* undefined */ \ 348 UNI(0x6e, 0x03bd); /* GREEK SMALL LETTER NU */ \ 349 UNI(0x6f, 0x2202); /* PARTIAL DIFFERENTIAL */ \ 350 UNI(0x70, 0x03c0); /* GREEK SMALL LETTER PI */ \ 351 UNI(0x71, 0x03c8); /* GREEK SMALL LETTER PSI */ \ 352 UNI(0x72, 0x03c1); /* GREEK SMALL LETTER RHO */ \ 353 UNI(0x73, 0x03c3); /* GREEK SMALL LETTER SIGMA */ \ 354 UNI(0x74, 0x03c4); /* GREEK SMALL LETTER TAU */ \ 355 XXX(0x75, 0x2426); /* undefined */ \ 356 UNI(0x76, 0x0192); /* LATIN SMALL LETTER F WITH HOOK Probably chosen for its meaning of "function" */ \ 357 UNI(0x77, 0x03c9); /* GREEK SMALL LETTER OMEGA */ \ 358 UNI(0x78, 0x03bE); /* GREEK SMALL LETTER XI */ \ 359 UNI(0x79, 0x03c5); /* GREEK SMALL LETTER UPSILON */ \ 360 UNI(0x7a, 0x03b6); /* GREEK SMALL LETTER ZETA */ \ 361 UNI(0x7b, 0x2190); /* LEFTWARDS ARROW */ \ 362 UNI(0x7c, 0x2191); /* UPWARDS ARROW */ \ 363 UNI(0x7d, 0x2192); /* RIGHTWARDS ARROW */ \ 364 UNI(0x7e, 0x2193); /* DOWNWARDS ARROW */ \ 365 } 366#else 367#define map_SCS_DEC_Technical(code) /* nothing */ 368#endif /* OPT_WIDE_CHARS */ 369 370/* 371 * Translate an input keysym to the corresponding NRC keysym. 372 */ 373unsigned 374xtermCharSetIn(TScreen *screen, unsigned code, int charset) 375{ 376#define MAP(to, from) case from: code = to; break 377 378#if OPT_WIDE_CHARS 379#define UNI(to, from) case from: if (screen->utf8_nrc_mode) code = to; break 380#else 381#define UNI(to, from) case from: break 382#endif 383 384#define XXX(to, from) /* no defined mapping to 0..255 */ 385 386 TRACE(("CHARSET-IN GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 387 visibleScsCode(screen->gsets[screen->curgl]), screen->curgl, 388 visibleScsCode(screen->gsets[screen->curgr]), screen->curgr, 389 screen->curss, 390 visibleUChar(code))); 391 392 switch (charset) { 393 case nrc_British: /* United Kingdom set (or Latin 1) */ 394 if (code == XK_sterling) 395 code = 0x23; 396 code &= 0x7f; 397 break; 398 399#if OPT_XMC_GLITCH 400 case nrc_Unknown: 401#endif 402 case nrc_DEC_Alt_Chars: 403 case nrc_DEC_Alt_Graphics: 404 case nrc_ASCII: 405 break; 406 407 case nrc_DEC_Spec_Graphic: 408 break; 409 410 case nrc_DEC_Supp: 411 map_SCS_DEC_Supp(code, code &= 0x7f); 412 break; 413 414 case nrc_DEC_Supp_Graphic: 415 map_SCS_DEC_Supp_Graphic(code, code |= 0x80); 416 break; 417 418 case nrc_DEC_Technical: 419 map_SCS_DEC_Technical(code); 420 break; 421 422 case nrc_Dutch: 423 map_NRCS_Dutch(code); 424 break; 425 426 case nrc_Finnish: 427 case nrc_Finnish2: 428 map_NRCS_Finnish(code); 429 break; 430 431 case nrc_French: 432 case nrc_French2: 433 map_NRCS_French(code); 434 break; 435 436 case nrc_French_Canadian: 437 map_NRCS_French_Canadian(code); 438 break; 439 440 case nrc_German: 441 map_NRCS_German(code); 442 break; 443 444 case nrc_Hebrew: 445 case nrc_Hebrew2: 446 /* FIXME */ 447 break; 448 449 case nrc_Italian: 450 map_NRCS_Italian(code); 451 break; 452 453 case nrc_Norwegian_Danish: 454 case nrc_Norwegian_Danish2: 455 case nrc_Norwegian_Danish3: 456 map_NRCS_Norwegian_Danish(code); 457 break; 458 459 case nrc_Portugese: 460 map_NRCS_Portuguese(code); 461 break; 462 463 case nrc_SCS_NRCS: /* vt5xx - probably Serbo/Croatian */ 464 /* FIXME */ 465 break; 466 467 case nrc_Spanish: 468 map_NRCS_Spanish(code); 469 break; 470 471 case nrc_Swedish2: 472 case nrc_Swedish: 473 map_NRCS_Swedish(code); 474 break; 475 476 case nrc_Swiss: 477 map_NRCS_Swiss(code); 478 break; 479 480 case nrc_Turkish: 481 case nrc_Turkish2: 482 /* FIXME */ 483 break; 484 485 default: /* any character sets we don't recognize */ 486 break; 487 } 488 code &= 0x7f; /* NRC in any case is 7-bit */ 489 TRACE(("->\t%s\n", 490 visibleUChar(code))); 491 return code; 492#undef MAP 493#undef UNI 494#undef XXX 495} 496 497/* 498 * Translate a string to the display form. This assumes the font has the 499 * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1. 500 */ 501int 502xtermCharSetOut(XtermWidget xw, IChar *buf, IChar *ptr, int leftset) 503{ 504 IChar *s; 505 TScreen *screen = TScreenOf(xw); 506 int count = 0; 507 int rightset = screen->gsets[(int) (screen->curgr)]; 508 509#define MAP(from, to) case from: chr = to; break 510 511#if OPT_WIDE_CHARS 512#define UNI(from, to) case from: if (screen->utf8_nrc_mode) chr = to; break 513#define XXX(from, to) UNI(from, to) 514#else 515#define UNI(old, new) chr = old; break 516#define XXX(from, to) /* nothing */ 517#endif 518 519 TRACE(("CHARSET-OUT GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 520 visibleScsCode(leftset), screen->curgl, 521 visibleScsCode(rightset), screen->curgr, 522 screen->curss, 523 visibleIChars(buf, (unsigned) (ptr - buf)))); 524 525 for (s = buf; s < ptr; ++s) { 526 int eight = CharOf(E2A(*s)); 527 int seven = eight & 0x7f; 528 int cs = (eight >= 128) ? rightset : leftset; 529 int chr = eight; 530 531 count++; 532#if OPT_WIDE_CHARS 533 /* 534 * This is only partly right - prevent inadvertant remapping of 535 * the replacement character and other non-8bit codes into bogus 536 * 8bit codes. 537 */ 538 if (screen->utf8_mode || screen->utf8_nrc_mode) { 539 if (*s > 255) 540 continue; 541 } 542#endif 543 if (*s < 32) 544 continue; 545 546 switch (cs) { 547 case nrc_British_Latin_1: 548 /* FALLTHRU */ 549 case nrc_British: /* United Kingdom set (or Latin 1) */ 550 if ((xw->flags & NATIONAL) 551 || (screen->vtXX_level <= 1)) { 552 if ((xw->flags & NATIONAL)) { 553 chr = seven; 554 } 555 if (chr == 0x23) { 556 chr = XTERM_POUND; 557#if OPT_WIDE_CHARS 558 if (screen->utf8_nrc_mode) { 559 chr = 0xa3; 560 } 561#endif 562 } 563 } else { 564 chr = (seven | 0x80); 565 } 566 break; 567 568#if OPT_XMC_GLITCH 569 case nrc_Unknown: 570#endif 571 case nrc_DEC_Alt_Chars: 572 case nrc_DEC_Alt_Graphics: 573 case nrc_ASCII: 574 break; 575 576 case nrc_DEC_Spec_Graphic: 577 if (seven > 0x5f && seven <= 0x7e) { 578#if OPT_WIDE_CHARS 579 if (screen->utf8_mode || screen->utf8_nrc_mode) 580 chr = (int) dec2ucs((unsigned) (seven - 0x5f)); 581 else 582#endif 583 chr = seven - 0x5f; 584 } else { 585 chr = seven; 586 } 587 break; 588 589 case nrc_DEC_Supp: 590 map_SCS_DEC_Supp(chr = seven, chr |= 0x80); 591 break; 592 593 case nrc_DEC_Supp_Graphic: 594 map_SCS_DEC_Supp_Graphic(chr = seven, chr |= 0x80); 595 break; 596 597 case nrc_DEC_Technical: 598 map_SCS_DEC_Technical(chr = seven); 599 break; 600 601 case nrc_Dutch: 602 map_NRCS_Dutch(chr = seven); 603 break; 604 605 case nrc_Finnish: 606 case nrc_Finnish2: 607 map_NRCS_Finnish(chr = seven); 608 break; 609 610 case nrc_French: 611 case nrc_French2: 612 map_NRCS_French(chr = seven); 613 break; 614 615 case nrc_French_Canadian: 616 case nrc_French_Canadian2: 617 map_NRCS_French_Canadian(chr = seven); 618 break; 619 620 case nrc_German: 621 map_NRCS_German(chr = seven); 622 break; 623 624 case nrc_Hebrew: 625 case nrc_Hebrew2: 626 /* FIXME */ 627 break; 628 629 case nrc_Italian: 630 map_NRCS_Italian(chr = seven); 631 break; 632 633 case nrc_Norwegian_Danish: 634 case nrc_Norwegian_Danish2: 635 case nrc_Norwegian_Danish3: 636 map_NRCS_Norwegian_Danish(chr = seven); 637 break; 638 639 case nrc_Portugese: 640 map_NRCS_Portuguese(chr = seven); 641 break; 642 643 case nrc_SCS_NRCS: /* vt5xx - probably Serbo/Croatian */ 644 /* FIXME */ 645 break; 646 647 case nrc_Spanish: 648 map_NRCS_Spanish(chr = seven); 649 break; 650 651 case nrc_Swedish2: 652 case nrc_Swedish: 653 map_NRCS_Swedish(chr = seven); 654 break; 655 656 case nrc_Swiss: 657 map_NRCS_Swiss(chr = seven); 658 break; 659 660 case nrc_Turkish: 661 case nrc_Turkish2: 662 /* FIXME */ 663 break; 664 665 default: /* any character sets we don't recognize */ 666 count--; 667 break; 668 } 669 /* 670 * The state machine already treated DEL as a nonprinting and 671 * nonspacing character. If we have DEL now, simply render 672 * it as a blank. 673 */ 674 if (chr == ANSI_DEL) 675 chr = ' '; 676 *s = (IChar) A2E(chr); 677 } 678 TRACE(("%d\t%s\n", 679 count, 680 visibleIChars(buf, (unsigned) (ptr - buf)))); 681 return count; 682#undef MAP 683#undef UNI 684#undef XXX 685} 686