15104ee6eSmrg/* $XTermId: charsets.c,v 1.129 2024/10/03 22:21:32 tom Exp $ */ 2d522f475Smrg 30bd37d32Smrg/* 404b94745Smrg * Copyright 1998-2023,2024 by Thomas E. Dickey 50bd37d32Smrg * 60bd37d32Smrg * All Rights Reserved 70bd37d32Smrg * 80bd37d32Smrg * Permission is hereby granted, free of charge, to any person obtaining a 90bd37d32Smrg * copy of this software and associated documentation files (the 100bd37d32Smrg * "Software"), to deal in the Software without restriction, including 110bd37d32Smrg * without limitation the rights to use, copy, modify, merge, publish, 120bd37d32Smrg * distribute, sublicense, and/or sell copies of the Software, and to 130bd37d32Smrg * permit persons to whom the Software is furnished to do so, subject to 140bd37d32Smrg * the following conditions: 150bd37d32Smrg * 160bd37d32Smrg * The above copyright notice and this permission notice shall be included 170bd37d32Smrg * in all copies or substantial portions of the Software. 180bd37d32Smrg * 190bd37d32Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 200bd37d32Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 210bd37d32Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 220bd37d32Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 230bd37d32Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 240bd37d32Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 250bd37d32Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 260bd37d32Smrg * 270bd37d32Smrg * Except as contained in this notice, the name(s) of the above copyright 280bd37d32Smrg * holders shall not be used in advertising or otherwise to promote the 290bd37d32Smrg * sale, use or other dealings in this Software without prior written 300bd37d32Smrg * authorization. 310bd37d32Smrg * 320bd37d32Smrg */ 33d522f475Smrg 3404b94745Smrg#include <assert.h> 3504b94745Smrg#include <X11/keysym.h> 3604b94745Smrg 37d522f475Smrg#include <xterm.h> 38d522f475Smrg#include <data.h> 3904b94745Smrg#include <charsets.h> 40d522f475Smrg#include <fontutils.h> 41d522f475Smrg 42d522f475Smrg/* 43d522f475Smrg * This module performs translation as needed to support the DEC VT220 national 44f2e35a3aSmrg * replacement character sets as well as supplementary character sets (aka 45f2e35a3aSmrg * code-pages) introduced in VT320, etc. 46f2e35a3aSmrg * 47f2e35a3aSmrg * We assume that xterm's font is based on the ISO 8859-1 (Latin 1) character 48f2e35a3aSmrg * set, which is almost the same as the DEC multinational character set. Glyph 49f2e35a3aSmrg * positions 0-31 have to be the DEC graphic characters, though. 50d522f475Smrg * 51d522f475Smrg * References: 52d522f475Smrg * "VT220 Programmer Pocket Guide" EK-VT220-HR-002 (2nd ed., 1984), which 53d522f475Smrg * contains character charts for the national character sets. 54d522f475Smrg * "VT330/VT340 Programmer Reference Manual Volume 1: Text Programming" 55d522f475Smrg * EK-VT3XX-TP-001 (1st ed, 1987), which contains a table (2-1) 56d522f475Smrg * listing the glyphs which are mapped from the multinational 57d522f475Smrg * character set to the national character set. 58d522f475Smrg * 59d522f475Smrg * The latter reference, though easier to read, has a few errors and omissions. 60f2e35a3aSmrg */ 612eaa94a1Schristos 6204b94745Smrg#define HandleUPSS(charset) \ 6304b94745Smrg if (charset == nrc_DEC_UPSS) { \ 6404b94745Smrg charset = screen->gsets_upss; \ 6504b94745Smrg if (screen->vtXX_level >= 5) { \ 6604b94745Smrg /* EMPTY */ ; \ 6704b94745Smrg } else if (screen->vtXX_level >= 3) { \ 6804b94745Smrg if (charset != nrc_DEC_Supp) \ 6904b94745Smrg charset = nrc_ISO_Latin_1_Supp; \ 7004b94745Smrg } else if (screen->vtXX_level < 2) { \ 7104b94745Smrg charset = nrc_ASCII; \ 72f2e35a3aSmrg } \ 7304b94745Smrg } 742eaa94a1Schristos 7504b94745Smrgstatic Boolean 7604b94745SmrgisSevenBit(DECNRCM_codes cs) 7704b94745Smrg{ 7804b94745Smrg Boolean result = False; 7904b94745Smrg 8004b94745Smrg switch (cs) { 8104b94745Smrg case nrc_ISO_Greek_Supp: 8204b94745Smrg case nrc_ISO_Hebrew_Supp: 8304b94745Smrg case nrc_ISO_Latin_1_Supp: 8404b94745Smrg case nrc_ISO_Latin_2_Supp: 8504b94745Smrg case nrc_ISO_Latin_5_Supp: 8604b94745Smrg case nrc_ISO_Latin_Cyrillic: 8704b94745Smrg case nrc_DEC_UPSS: 8804b94745Smrg break; 8904b94745Smrg /* VT100 character sets */ 9004b94745Smrg case nrc_ASCII: 9104b94745Smrg case nrc_British: 9204b94745Smrg case nrc_DEC_Alt_Chars: 9304b94745Smrg case nrc_DEC_Spec_Graphic: 9404b94745Smrg /* VT220 character sets */ 9504b94745Smrg case nrc_DEC_Alt_Graphics: 9604b94745Smrg case nrc_DEC_Supp: 9704b94745Smrg /* VT320 character sets */ 9804b94745Smrg case nrc_DEC_Supp_Graphic: 9904b94745Smrg case nrc_DEC_Technical: 10004b94745Smrg /* NRCS character sets (VT320 to VT520) */ 10104b94745Smrg case nrc_British_Latin_1: 10204b94745Smrg case nrc_Dutch: 10304b94745Smrg case nrc_Finnish2: 10404b94745Smrg case nrc_Finnish: 10504b94745Smrg case nrc_French2: 10604b94745Smrg case nrc_French: 10704b94745Smrg case nrc_French_Canadian2: 10804b94745Smrg case nrc_French_Canadian: 10904b94745Smrg case nrc_German: 11004b94745Smrg case nrc_Greek: 11104b94745Smrg case nrc_Hebrew: 11204b94745Smrg case nrc_Italian: 1135104ee6eSmrg case nrc_JIS_Katakana: 1145104ee6eSmrg case nrc_JIS_Roman: 11504b94745Smrg case nrc_Norwegian_Danish2: 11604b94745Smrg case nrc_Norwegian_Danish3: 11704b94745Smrg case nrc_Norwegian_Danish: 11804b94745Smrg case nrc_Portugese: 11904b94745Smrg case nrc_Russian: 12004b94745Smrg case nrc_SCS_NRCS: 12104b94745Smrg case nrc_Spanish: 12204b94745Smrg case nrc_Swedish2: 12304b94745Smrg case nrc_Swedish: 12404b94745Smrg case nrc_Swiss: 12504b94745Smrg case nrc_Turkish: 12604b94745Smrg /* other DEC character sets */ 12704b94745Smrg case nrc_DEC_Cyrillic: 12804b94745Smrg case nrc_DEC_Greek_Supp: 12904b94745Smrg case nrc_DEC_Hebrew_Supp: 13004b94745Smrg case nrc_DEC_Turkish_Supp: 13104b94745Smrg result = True; 13204b94745Smrg break; 13304b94745Smrg case nrc_Unknown: 13404b94745Smrg break; 13504b94745Smrg } 13604b94745Smrg return result; 13704b94745Smrg} 138e0a2b6dfSmrg 139e0a2b6dfSmrg/* 140e0a2b6dfSmrg * Translate an input keysym to the corresponding NRC keysym. 141e0a2b6dfSmrg */ 142e0a2b6dfSmrgunsigned 143f2e35a3aSmrgxtermCharSetIn(XtermWidget xw, unsigned code, DECNRCM_codes charset) 144e0a2b6dfSmrg{ 145f2e35a3aSmrg TScreen *screen = TScreenOf(xw); 14604b94745Smrg#define MAP(to, from) case from: code = to; break; 147e0a2b6dfSmrg 148e0a2b6dfSmrg#if OPT_WIDE_CHARS 14904b94745Smrg#define UNI(to, from) case from: if (screen->utf8_nrc_mode) code = to; break; 150e0a2b6dfSmrg#else 15104b94745Smrg#define UNI(to, from) case from: break; 152e0a2b6dfSmrg#endif 153e0a2b6dfSmrg 154e0a2b6dfSmrg#define XXX(to, from) /* no defined mapping to 0..255 */ 155e0a2b6dfSmrg 156e0a2b6dfSmrg TRACE(("CHARSET-IN GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 157e0a2b6dfSmrg visibleScsCode(screen->gsets[screen->curgl]), screen->curgl, 158e0a2b6dfSmrg visibleScsCode(screen->gsets[screen->curgr]), screen->curgr, 159e0a2b6dfSmrg screen->curss, 160e0a2b6dfSmrg visibleUChar(code))); 161e0a2b6dfSmrg 16204b94745Smrg HandleUPSS(charset); 16304b94745Smrg 164e0a2b6dfSmrg switch (charset) { 165e0a2b6dfSmrg case nrc_British: /* United Kingdom set (or Latin 1) */ 166e0a2b6dfSmrg if (code == XK_sterling) 167e0a2b6dfSmrg code = 0x23; 168e0a2b6dfSmrg code &= 0x7f; 169e0a2b6dfSmrg break; 170e0a2b6dfSmrg 171e0a2b6dfSmrg case nrc_DEC_Alt_Chars: 172e0a2b6dfSmrg case nrc_DEC_Alt_Graphics: 173e0a2b6dfSmrg case nrc_ASCII: 174e0a2b6dfSmrg break; 175e0a2b6dfSmrg 176e0a2b6dfSmrg case nrc_DEC_Spec_Graphic: 177e0a2b6dfSmrg break; 178e0a2b6dfSmrg 179e0a2b6dfSmrg case nrc_DEC_Supp: 180f2e35a3aSmrg map_DEC_Supp_Graphic(code, code &= 0x7f); 181e0a2b6dfSmrg break; 182e0a2b6dfSmrg 183e0a2b6dfSmrg case nrc_DEC_Supp_Graphic: 184f2e35a3aSmrg map_DEC_Supp_Graphic(code, code |= 0x80); 185e0a2b6dfSmrg break; 186e0a2b6dfSmrg 187e0a2b6dfSmrg case nrc_DEC_Technical: 188f2e35a3aSmrg map_DEC_Technical(code); 189e0a2b6dfSmrg break; 190e0a2b6dfSmrg 191e0a2b6dfSmrg case nrc_Dutch: 192e0a2b6dfSmrg map_NRCS_Dutch(code); 193e0a2b6dfSmrg break; 194e0a2b6dfSmrg 195e0a2b6dfSmrg case nrc_Finnish: 196e0a2b6dfSmrg case nrc_Finnish2: 197e0a2b6dfSmrg map_NRCS_Finnish(code); 198e0a2b6dfSmrg break; 199e0a2b6dfSmrg 200e0a2b6dfSmrg case nrc_French: 201e0a2b6dfSmrg case nrc_French2: 202e0a2b6dfSmrg map_NRCS_French(code); 203e0a2b6dfSmrg break; 204e0a2b6dfSmrg 205e0a2b6dfSmrg case nrc_French_Canadian: 206e0a2b6dfSmrg map_NRCS_French_Canadian(code); 207e0a2b6dfSmrg break; 208e0a2b6dfSmrg 209e0a2b6dfSmrg case nrc_German: 210e0a2b6dfSmrg map_NRCS_German(code); 211e0a2b6dfSmrg break; 212e0a2b6dfSmrg 213f2e35a3aSmrg case nrc_Greek: 214f2e35a3aSmrg map_NRCS_Greek(code); /* FIXME - ELOT? */ 215f2e35a3aSmrg break; 216f2e35a3aSmrg 217f2e35a3aSmrg case nrc_DEC_Greek_Supp: 218f2e35a3aSmrg map_DEC_Greek_Supp(code); 219f2e35a3aSmrg break; 220f2e35a3aSmrg 221f2e35a3aSmrg case nrc_ISO_Greek_Supp: 222f2e35a3aSmrg map_ISO_Greek_Supp(code); 223f2e35a3aSmrg break; 224f2e35a3aSmrg 225f2e35a3aSmrg case nrc_DEC_Hebrew_Supp: 226f2e35a3aSmrg map_DEC_Hebrew_Supp(code); 227f2e35a3aSmrg break; 228f2e35a3aSmrg 229e0a2b6dfSmrg case nrc_Hebrew: 230f2e35a3aSmrg map_NRCS_Hebrew(code); 231f2e35a3aSmrg break; 232f2e35a3aSmrg 233f2e35a3aSmrg case nrc_ISO_Hebrew_Supp: 234f2e35a3aSmrg map_ISO_Hebrew(code); 235e0a2b6dfSmrg break; 236e0a2b6dfSmrg 237e0a2b6dfSmrg case nrc_Italian: 238e0a2b6dfSmrg map_NRCS_Italian(code); 239e0a2b6dfSmrg break; 240e0a2b6dfSmrg 241f2e35a3aSmrg case nrc_ISO_Latin_2_Supp: 242f2e35a3aSmrg map_ISO_Latin_2(code); 243f2e35a3aSmrg break; 244f2e35a3aSmrg 245f2e35a3aSmrg case nrc_ISO_Latin_5_Supp: 246f2e35a3aSmrg map_ISO_Latin_5(code); 247f2e35a3aSmrg break; 248f2e35a3aSmrg 249f2e35a3aSmrg case nrc_ISO_Latin_Cyrillic: 250f2e35a3aSmrg map_ISO_Latin_Cyrillic(code); 251f2e35a3aSmrg break; 252f2e35a3aSmrg 2535104ee6eSmrg case nrc_JIS_Katakana: 2545104ee6eSmrg map_JIS_Katakana(code); 2555104ee6eSmrg break; 2565104ee6eSmrg 2575104ee6eSmrg case nrc_JIS_Roman: 2585104ee6eSmrg map_JIS_Roman(code); 2595104ee6eSmrg break; 2605104ee6eSmrg 261e0a2b6dfSmrg case nrc_Norwegian_Danish: 262e0a2b6dfSmrg case nrc_Norwegian_Danish2: 263e0a2b6dfSmrg case nrc_Norwegian_Danish3: 264e0a2b6dfSmrg map_NRCS_Norwegian_Danish(code); 265e0a2b6dfSmrg break; 266e0a2b6dfSmrg 267e0a2b6dfSmrg case nrc_Portugese: 268e0a2b6dfSmrg map_NRCS_Portuguese(code); 269e0a2b6dfSmrg break; 270e0a2b6dfSmrg 2715104ee6eSmrg case nrc_Russian: 2725104ee6eSmrg map_NRCS_Russian(code); 2735104ee6eSmrg break; 2745104ee6eSmrg 27504b94745Smrg case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 2765104ee6eSmrg map_NRCS_Serbo_Croatian(code); 277e0a2b6dfSmrg break; 278e0a2b6dfSmrg 279e0a2b6dfSmrg case nrc_Spanish: 280e0a2b6dfSmrg map_NRCS_Spanish(code); 281e0a2b6dfSmrg break; 282e0a2b6dfSmrg 283e0a2b6dfSmrg case nrc_Swedish2: 284e0a2b6dfSmrg case nrc_Swedish: 285e0a2b6dfSmrg map_NRCS_Swedish(code); 286e0a2b6dfSmrg break; 287e0a2b6dfSmrg 288e0a2b6dfSmrg case nrc_Swiss: 289e0a2b6dfSmrg map_NRCS_Swiss(code); 290e0a2b6dfSmrg break; 291e0a2b6dfSmrg 292e0a2b6dfSmrg case nrc_Turkish: 293f2e35a3aSmrg map_NRCS_Turkish(code); 294f2e35a3aSmrg break; 295f2e35a3aSmrg 296f2e35a3aSmrg case nrc_DEC_Turkish_Supp: 297f2e35a3aSmrg map_DEC_Turkish_Supp(code); 298e0a2b6dfSmrg break; 299e0a2b6dfSmrg 300f2e35a3aSmrg case nrc_DEC_Cyrillic: 301f2e35a3aSmrg map_DEC_Cyrillic(code); 302f2e35a3aSmrg break; 303f2e35a3aSmrg 304f2e35a3aSmrg case nrc_ISO_Latin_1_Supp: 305f2e35a3aSmrg case nrc_British_Latin_1: 306f2e35a3aSmrg case nrc_French_Canadian2: 307f2e35a3aSmrg case nrc_Unknown: 30804b94745Smrg case nrc_DEC_UPSS: 309e0a2b6dfSmrg default: /* any character sets we don't recognize */ 310e0a2b6dfSmrg break; 3112eaa94a1Schristos } 312e0a2b6dfSmrg code &= 0x7f; /* NRC in any case is 7-bit */ 313e0a2b6dfSmrg TRACE(("->\t%s\n", 314e0a2b6dfSmrg visibleUChar(code))); 3152eaa94a1Schristos return code; 3162eaa94a1Schristos#undef MAP 317e0a2b6dfSmrg#undef UNI 318e0a2b6dfSmrg#undef XXX 319d522f475Smrg} 320d522f475Smrg 321d522f475Smrg/* 322d522f475Smrg * Translate a string to the display form. This assumes the font has the 323d522f475Smrg * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1. 324d522f475Smrg */ 32504b94745SmrgCardinal 32604b94745SmrgxtermCharSetOut(XtermWidget xw, Cardinal length, DECNRCM_codes leftset) 327d522f475Smrg{ 32804b94745Smrg IChar *buf = xw->work.write_text; 32904b94745Smrg IChar *ptr = buf + length; 3302eaa94a1Schristos IChar *s; 3312eaa94a1Schristos TScreen *screen = TScreenOf(xw); 33204b94745Smrg Cardinal count = 0; 333f2e35a3aSmrg DECNRCM_codes rightset = screen->gsets[(int) (screen->curgr)]; 33404b94745Smrg#if OPT_DEC_RECTOPS 33504b94745Smrg int sums = 0; 33604b94745Smrg#endif 3372eaa94a1Schristos 33804b94745Smrg#define MAP(from, to) case from: chr = to; break; 3392eaa94a1Schristos 340e0a2b6dfSmrg#if OPT_WIDE_CHARS 34104b94745Smrg#define UNI(from, to) case from: if (screen->utf8_nrc_mode) chr = to; break; 342e0a2b6dfSmrg#define XXX(from, to) UNI(from, to) 343e0a2b6dfSmrg#else 34404b94745Smrg#define UNI(old, new) case new: chr = old; break; 345e0a2b6dfSmrg#define XXX(from, to) /* nothing */ 346e0a2b6dfSmrg#endif 347e0a2b6dfSmrg 348e0a2b6dfSmrg TRACE(("CHARSET-OUT GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 349e0a2b6dfSmrg visibleScsCode(leftset), screen->curgl, 350e0a2b6dfSmrg visibleScsCode(rightset), screen->curgr, 3512eaa94a1Schristos screen->curss, 35204b94745Smrg visibleIChars(buf, (size_t) length))); 35304b94745Smrg 35404b94745Smrg assert(length != 0); 35504b94745Smrg#if OPT_DEC_RECTOPS 35604b94745Smrg if (length != 0 && length > xw->work.sizeof_sums) { 35704b94745Smrg xw->work.sizeof_sums += length + 80; 35804b94745Smrg xw->work.buffer_sums = realloc(xw->work.buffer_sums, 35904b94745Smrg xw->work.sizeof_sums); 36004b94745Smrg xw->work.buffer_sets = realloc(xw->work.buffer_sets, 36104b94745Smrg xw->work.sizeof_sums); 36204b94745Smrg } 36304b94745Smrg xw->work.write_sums = xw->work.buffer_sums; 36404b94745Smrg#endif 3652eaa94a1Schristos 3662eaa94a1Schristos for (s = buf; s < ptr; ++s) { 3675104ee6eSmrg int eight = CharOf(*s); 3682eaa94a1Schristos int seven = eight & 0x7f; 369f2e35a3aSmrg DECNRCM_codes cs = (eight >= 128) ? rightset : leftset; 3702eaa94a1Schristos int chr = eight; 3712eaa94a1Schristos 37204b94745Smrg HandleUPSS(cs); 37304b94745Smrg 37404b94745Smrg#if OPT_DEC_RECTOPS 37504b94745Smrg if (xw->work.buffer_sums != NULL && xw->work.buffer_sets != NULL) { 37604b94745Smrg xw->work.buffer_sums[sums] = (Char) ((eight < 32 || eight > 255) 37704b94745Smrg ? ANSI_ESC 37804b94745Smrg : eight); 37904b94745Smrg xw->work.buffer_sets[sums] = cs; 38004b94745Smrg ++sums; 38104b94745Smrg } 38204b94745Smrg#endif 3832eaa94a1Schristos count++; 3842eaa94a1Schristos#if OPT_WIDE_CHARS 3852eaa94a1Schristos /* 386f2e35a3aSmrg * This is only partly right - prevent inadvertent remapping of 3872eaa94a1Schristos * the replacement character and other non-8bit codes into bogus 3882eaa94a1Schristos * 8bit codes. 3892eaa94a1Schristos */ 390e0a2b6dfSmrg if (screen->utf8_mode || screen->utf8_nrc_mode) { 3912eaa94a1Schristos if (*s > 255) 3922eaa94a1Schristos continue; 3932eaa94a1Schristos } 3942eaa94a1Schristos#endif 395e0a2b6dfSmrg if (*s < 32) 396e0a2b6dfSmrg continue; 397e0a2b6dfSmrg 3982eaa94a1Schristos switch (cs) { 39904b94745Smrg case nrc_DEC_UPSS: 40004b94745Smrg break; 40104b94745Smrg 402f2e35a3aSmrg case nrc_ISO_Latin_1_Supp: 403e0a2b6dfSmrg case nrc_British_Latin_1: 404e0a2b6dfSmrg case nrc_British: /* United Kingdom set (or Latin 1) */ 4052eaa94a1Schristos if ((xw->flags & NATIONAL) 4062eaa94a1Schristos || (screen->vtXX_level <= 1)) { 407e0a2b6dfSmrg if ((xw->flags & NATIONAL)) { 408e0a2b6dfSmrg chr = seven; 409e0a2b6dfSmrg } 4102eaa94a1Schristos if (chr == 0x23) { 4112eaa94a1Schristos chr = XTERM_POUND; 412e0a2b6dfSmrg#if OPT_WIDE_CHARS 413e0a2b6dfSmrg if (screen->utf8_nrc_mode) { 414e0a2b6dfSmrg chr = 0xa3; 415e0a2b6dfSmrg } 4162eaa94a1Schristos#endif 4172eaa94a1Schristos } 4182eaa94a1Schristos } 4192eaa94a1Schristos break; 420d522f475Smrg 421e0a2b6dfSmrg case nrc_DEC_Alt_Chars: 422e0a2b6dfSmrg case nrc_DEC_Alt_Graphics: 423e0a2b6dfSmrg case nrc_ASCII: 4242eaa94a1Schristos break; 425d522f475Smrg 426e0a2b6dfSmrg case nrc_DEC_Spec_Graphic: 4272eaa94a1Schristos if (seven > 0x5f && seven <= 0x7e) { 428d522f475Smrg#if OPT_WIDE_CHARS 429e0a2b6dfSmrg if (screen->utf8_mode || screen->utf8_nrc_mode) 430f2e35a3aSmrg chr = (int) dec2ucs(screen, (unsigned) (seven - 0x5f)); 4312eaa94a1Schristos else 432d522f475Smrg#endif 4332eaa94a1Schristos chr = seven - 0x5f; 434f2e35a3aSmrg } else if (chr == 0x5f) { 435f2e35a3aSmrg chr = 0; 4362eaa94a1Schristos } else { 4372eaa94a1Schristos chr = seven; 4382eaa94a1Schristos } 4392eaa94a1Schristos break; 4402eaa94a1Schristos 441e0a2b6dfSmrg case nrc_DEC_Supp: 442e0a2b6dfSmrg case nrc_DEC_Supp_Graphic: 44304b94745Smrg map_DEC_Supp_Graphic(chr = seven, chr = eight); 4442eaa94a1Schristos break; 4452eaa94a1Schristos 446e0a2b6dfSmrg case nrc_DEC_Technical: 447f2e35a3aSmrg map_DEC_Technical(chr = seven); 4482eaa94a1Schristos break; 4492eaa94a1Schristos 450e0a2b6dfSmrg case nrc_Dutch: 451e0a2b6dfSmrg map_NRCS_Dutch(chr = seven); 4522eaa94a1Schristos break; 4532eaa94a1Schristos 454e0a2b6dfSmrg case nrc_Finnish: 455e0a2b6dfSmrg case nrc_Finnish2: 456e0a2b6dfSmrg map_NRCS_Finnish(chr = seven); 4572eaa94a1Schristos break; 4582eaa94a1Schristos 459e0a2b6dfSmrg case nrc_French: 460e0a2b6dfSmrg case nrc_French2: 461e0a2b6dfSmrg map_NRCS_French(chr = seven); 4622eaa94a1Schristos break; 4632eaa94a1Schristos 464e0a2b6dfSmrg case nrc_French_Canadian: 465e0a2b6dfSmrg case nrc_French_Canadian2: 466e0a2b6dfSmrg map_NRCS_French_Canadian(chr = seven); 4672eaa94a1Schristos break; 4682eaa94a1Schristos 469e0a2b6dfSmrg case nrc_German: 470e0a2b6dfSmrg map_NRCS_German(chr = seven); 4712eaa94a1Schristos break; 4722eaa94a1Schristos 473f2e35a3aSmrg case nrc_Greek: 474f2e35a3aSmrg map_NRCS_Greek(chr = seven); /* FIXME - ELOT? */ 475f2e35a3aSmrg break; 476f2e35a3aSmrg 477f2e35a3aSmrg case nrc_DEC_Greek_Supp: 478f2e35a3aSmrg map_DEC_Greek_Supp(chr = seven); 479f2e35a3aSmrg break; 480f2e35a3aSmrg 481f2e35a3aSmrg case nrc_ISO_Greek_Supp: 482f2e35a3aSmrg map_ISO_Greek_Supp(chr = seven); 483f2e35a3aSmrg break; 484f2e35a3aSmrg 485f2e35a3aSmrg case nrc_DEC_Hebrew_Supp: 486f2e35a3aSmrg map_DEC_Hebrew_Supp(chr = seven); 487f2e35a3aSmrg break; 488f2e35a3aSmrg 489e0a2b6dfSmrg case nrc_Hebrew: 490f2e35a3aSmrg map_NRCS_Hebrew(chr = seven); 491f2e35a3aSmrg break; 492f2e35a3aSmrg 493f2e35a3aSmrg case nrc_ISO_Hebrew_Supp: 494f2e35a3aSmrg map_ISO_Hebrew(chr = seven); 4952eaa94a1Schristos break; 4962eaa94a1Schristos 497e0a2b6dfSmrg case nrc_Italian: 498e0a2b6dfSmrg map_NRCS_Italian(chr = seven); 499e0a2b6dfSmrg break; 500e0a2b6dfSmrg 501f2e35a3aSmrg case nrc_ISO_Latin_2_Supp: 502f2e35a3aSmrg map_ISO_Latin_2(chr = seven); 503f2e35a3aSmrg break; 504f2e35a3aSmrg 505f2e35a3aSmrg case nrc_ISO_Latin_5_Supp: 506f2e35a3aSmrg map_ISO_Latin_5(chr = seven); 507f2e35a3aSmrg break; 508f2e35a3aSmrg 509f2e35a3aSmrg case nrc_ISO_Latin_Cyrillic: 510f2e35a3aSmrg map_ISO_Latin_Cyrillic(chr = seven); 511f2e35a3aSmrg break; 512f2e35a3aSmrg 5135104ee6eSmrg case nrc_JIS_Katakana: 5145104ee6eSmrg map_JIS_Katakana(chr = seven); 5155104ee6eSmrg break; 5165104ee6eSmrg 5175104ee6eSmrg case nrc_JIS_Roman: 5185104ee6eSmrg map_JIS_Roman(chr = seven); 5195104ee6eSmrg break; 5205104ee6eSmrg 521e0a2b6dfSmrg case nrc_Norwegian_Danish: 522e0a2b6dfSmrg case nrc_Norwegian_Danish2: 523e0a2b6dfSmrg case nrc_Norwegian_Danish3: 524e0a2b6dfSmrg map_NRCS_Norwegian_Danish(chr = seven); 525e0a2b6dfSmrg break; 526e0a2b6dfSmrg 527e0a2b6dfSmrg case nrc_Portugese: 528e0a2b6dfSmrg map_NRCS_Portuguese(chr = seven); 529e0a2b6dfSmrg break; 530e0a2b6dfSmrg 5315104ee6eSmrg case nrc_Russian: 5325104ee6eSmrg map_NRCS_Russian(chr = seven); 5335104ee6eSmrg break; 5345104ee6eSmrg 53504b94745Smrg case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 5365104ee6eSmrg map_NRCS_Serbo_Croatian(chr = seven); 537e0a2b6dfSmrg break; 538e0a2b6dfSmrg 539e0a2b6dfSmrg case nrc_Spanish: 540e0a2b6dfSmrg map_NRCS_Spanish(chr = seven); 541e0a2b6dfSmrg break; 542e0a2b6dfSmrg 543e0a2b6dfSmrg case nrc_Swedish2: 544e0a2b6dfSmrg case nrc_Swedish: 545e0a2b6dfSmrg map_NRCS_Swedish(chr = seven); 546e0a2b6dfSmrg break; 547e0a2b6dfSmrg 548e0a2b6dfSmrg case nrc_Swiss: 549e0a2b6dfSmrg map_NRCS_Swiss(chr = seven); 550e0a2b6dfSmrg break; 551e0a2b6dfSmrg 552e0a2b6dfSmrg case nrc_Turkish: 553f2e35a3aSmrg map_NRCS_Turkish(chr = seven); 5542eaa94a1Schristos break; 5552eaa94a1Schristos 556f2e35a3aSmrg case nrc_DEC_Turkish_Supp: 557f2e35a3aSmrg map_DEC_Turkish_Supp(chr = seven); 558f2e35a3aSmrg break; 559f2e35a3aSmrg 560f2e35a3aSmrg case nrc_DEC_Cyrillic: 561f2e35a3aSmrg map_DEC_Cyrillic(chr = seven); 562f2e35a3aSmrg break; 563f2e35a3aSmrg 564f2e35a3aSmrg case nrc_Unknown: 5652eaa94a1Schristos default: /* any character sets we don't recognize */ 5662eaa94a1Schristos break; 567d522f475Smrg } 5682eaa94a1Schristos /* 5692eaa94a1Schristos * The state machine already treated DEL as a nonprinting and 570f2e35a3aSmrg * nonspacing character. If we have DEL now, remove it. 5712eaa94a1Schristos */ 57204b94745Smrg if (chr == ANSI_DEL && isSevenBit(cs)) { 573f2e35a3aSmrg IChar *s1; 574f2e35a3aSmrg --ptr; 575f2e35a3aSmrg for (s1 = s; s1 < ptr; ++s1) { 576f2e35a3aSmrg s1[0] = s1[1]; 577f2e35a3aSmrg } 57804b94745Smrg --count; 57904b94745Smrg#if OPT_DEC_RECTOPS 58004b94745Smrg --sums; 58104b94745Smrg#endif 582f2e35a3aSmrg } else { 58304b94745Smrg if (eight >= 128 && chr < 128 && chr > 32) 58404b94745Smrg chr |= 128; 5855104ee6eSmrg *s = (IChar) chr; 586f2e35a3aSmrg } 5872eaa94a1Schristos } 5882eaa94a1Schristos TRACE(("%d\t%s\n", 5892eaa94a1Schristos count, 59004b94745Smrg visibleIChars(buf, (size_t) length))); 5912eaa94a1Schristos return count; 5922eaa94a1Schristos#undef MAP 593e0a2b6dfSmrg#undef UNI 594e0a2b6dfSmrg#undef XXX 595d522f475Smrg} 59604b94745Smrg 59704b94745Smrg#if OPT_DEC_RECTOPS 59804b94745Smrg/* 59904b94745Smrg * Given a mapped character, e.g., a Unicode value returned by xtermCharSetIn, 60004b94745Smrg * match it against the current GL/GR selection and return the corresponding 60104b94745Smrg * DEC internal character-set code for DECRQCRA. 60204b94745Smrg * 60304b94745Smrg * A hardware terminal presumably stores the original and mapped characters, 60404b94745Smrg * as well as the character set which was selected at that time Doing that 60504b94745Smrg * in xterm adds a couple of bytes to every cell. 60604b94745Smrg */ 60704b94745Smrgint 60804b94745SmrgxtermCharSetDec(XtermWidget xw, IChar chr, DECNRCM_codes cs) 60904b94745Smrg{ 61004b94745Smrg#define MAP(from, to) case from: result = to; break; 61104b94745Smrg 61204b94745Smrg#define DFTMAP() result = (actual | 0x80) 61304b94745Smrg#define DFT_94(chr) result = ((actual) & 0x7f) 61404b94745Smrg#define DFT_96(chr) result = ((actual) | 0x80) 61504b94745Smrg 61604b94745Smrg#if OPT_WIDE_CHARS 61704b94745Smrg#define UNI(from, to) case from: if (screen->utf8_nrc_mode) result = to; break; 61804b94745Smrg#define XXX(from, to) UNI(from, to) 61904b94745Smrg#else 62004b94745Smrg#define UNI(old, new) case new: result = old; break; 62104b94745Smrg#define XXX(from, to) /* nothing */ 62204b94745Smrg#endif 62304b94745Smrg 62404b94745Smrg int result; 62504b94745Smrg 62604b94745Smrg if (chr < 0x20 62704b94745Smrg#if OPT_WIDE_CHARS 62804b94745Smrg || chr > 0xff 62904b94745Smrg#endif 63004b94745Smrg ) { 63104b94745Smrg result = ANSI_ESC; 63204b94745Smrg } else { 63304b94745Smrg Boolean isSeven = isSevenBit(cs); 63404b94745Smrg TScreen *screen = TScreenOf(xw); 63504b94745Smrg 63604b94745Smrg result = -1; 63704b94745Smrg 63804b94745Smrg HandleUPSS(cs); 63904b94745Smrg 64004b94745Smrg if (chr == 0xa0 && isSeven) { 64104b94745Smrg result = ANSI_ESC; 64204b94745Smrg } else if (chr == ANSI_SPA && isSeven) { 64304b94745Smrg result = ANSI_SPA; 64404b94745Smrg } else if ((chr == ANSI_DEL || chr == 0xff) && isSeven) { 64504b94745Smrg result = 0; 64604b94745Smrg } else { 64704b94745Smrg int actual = (int) chr; 64804b94745Smrg chr &= 0x7f; 64904b94745Smrg 65004b94745Smrg switch (cs) { 65104b94745Smrg case nrc_DEC_Alt_Chars: 65204b94745Smrg case nrc_DEC_Alt_Graphics: 65304b94745Smrg case nrc_ASCII: 65404b94745Smrg result = (int) chr; 65504b94745Smrg break; 65604b94745Smrg 65704b94745Smrg case nrc_British: 65804b94745Smrg if (chr >= 0xa0 && chr < 0xff) { 65904b94745Smrg if (chr == 0x23) 66004b94745Smrg chr = 0xA3; 66104b94745Smrg result = (int) chr; 66204b94745Smrg } 66304b94745Smrg break; 66404b94745Smrg 66504b94745Smrg case nrc_DEC_Cyrillic: 66604b94745Smrg unmap_DEC_Cyrillic(chr, DFT_94(chr)); 66704b94745Smrg break; 66804b94745Smrg 66904b94745Smrg case nrc_DEC_Spec_Graphic: 67004b94745Smrg unmap_DEC_Spec_Graphic(chr, DFT_94(chr)); 67104b94745Smrg break; 67204b94745Smrg 67304b94745Smrg case nrc_DEC_Supp: 67404b94745Smrg /* FALLTHRU */ 67504b94745Smrg case nrc_DEC_Supp_Graphic: 67604b94745Smrg unmap_DEC_Supp_Graphic(chr, DFTMAP()); 67704b94745Smrg break; 67804b94745Smrg 67904b94745Smrg case nrc_DEC_Technical: 68004b94745Smrg unmap_DEC_Technical(chr, DFTMAP()); 68104b94745Smrg break; 68204b94745Smrg 68304b94745Smrg case nrc_Dutch: 68404b94745Smrg unmap_NRCS_Dutch(chr, DFT_94(chr)); 68504b94745Smrg break; 68604b94745Smrg 68704b94745Smrg case nrc_Finnish: 68804b94745Smrg case nrc_Finnish2: 68904b94745Smrg unmap_NRCS_Finnish(chr, DFT_94(chr)); 69004b94745Smrg break; 69104b94745Smrg 69204b94745Smrg case nrc_French: 69304b94745Smrg case nrc_French2: 69404b94745Smrg unmap_NRCS_French(chr, DFT_94(chr)); 69504b94745Smrg break; 69604b94745Smrg 69704b94745Smrg case nrc_French_Canadian: 69804b94745Smrg case nrc_French_Canadian2: 69904b94745Smrg unmap_NRCS_French_Canadian(chr, DFT_94(chr)); 70004b94745Smrg break; 70104b94745Smrg 70204b94745Smrg case nrc_German: 70304b94745Smrg unmap_NRCS_German(chr, DFT_94(chr)); 70404b94745Smrg break; 70504b94745Smrg 70604b94745Smrg case nrc_Greek: 70704b94745Smrg unmap_NRCS_Greek(chr, DFT_94(chr)); 70804b94745Smrg break; 70904b94745Smrg 71004b94745Smrg case nrc_DEC_Greek_Supp: 71104b94745Smrg unmap_DEC_Greek_Supp(chr, DFTMAP()); 71204b94745Smrg break; 71304b94745Smrg 71404b94745Smrg case nrc_ISO_Greek_Supp: 71504b94745Smrg unmap_ISO_Greek_Supp(chr, DFTMAP()); 71604b94745Smrg break; 71704b94745Smrg 71804b94745Smrg case nrc_DEC_Hebrew_Supp: 71904b94745Smrg unmap_DEC_Hebrew_Supp(chr, DFTMAP()); 72004b94745Smrg break; 72104b94745Smrg 72204b94745Smrg case nrc_Hebrew: 72304b94745Smrg unmap_NRCS_Hebrew(chr, DFT_94(chr)); 72404b94745Smrg break; 72504b94745Smrg 72604b94745Smrg case nrc_ISO_Hebrew_Supp: 72704b94745Smrg unmap_ISO_Hebrew(chr, DFTMAP()); 72804b94745Smrg break; 72904b94745Smrg 73004b94745Smrg case nrc_Italian: 73104b94745Smrg unmap_NRCS_Italian(chr, DFT_94(chr)); 73204b94745Smrg break; 73304b94745Smrg 7345104ee6eSmrg case nrc_JIS_Katakana: 7355104ee6eSmrg unmap_JIS_Katakana(chr, DFT_94(chr)); 7365104ee6eSmrg break; 7375104ee6eSmrg 7385104ee6eSmrg case nrc_JIS_Roman: 7395104ee6eSmrg unmap_JIS_Roman(chr, DFT_94(chr)); 7405104ee6eSmrg break; 7415104ee6eSmrg 74204b94745Smrg case nrc_ISO_Latin_1_Supp: 74304b94745Smrg unmap_ISO_Latin_1(chr, DFTMAP()); 74404b94745Smrg break; 74504b94745Smrg 74604b94745Smrg case nrc_ISO_Latin_2_Supp: 74704b94745Smrg unmap_ISO_Latin_2(chr, DFTMAP()); 74804b94745Smrg break; 74904b94745Smrg 75004b94745Smrg case nrc_ISO_Latin_5_Supp: 75104b94745Smrg unmap_ISO_Latin_5(chr, DFTMAP()); 75204b94745Smrg break; 75304b94745Smrg 75404b94745Smrg case nrc_ISO_Latin_Cyrillic: 75504b94745Smrg unmap_ISO_Latin_Cyrillic(chr, DFTMAP()); 75604b94745Smrg break; 75704b94745Smrg 75804b94745Smrg case nrc_Norwegian_Danish: 75904b94745Smrg case nrc_Norwegian_Danish2: 76004b94745Smrg case nrc_Norwegian_Danish3: 76104b94745Smrg unmap_NRCS_Norwegian_Danish(chr, DFT_94(chr)); 76204b94745Smrg break; 76304b94745Smrg 76404b94745Smrg case nrc_Portugese: 76504b94745Smrg unmap_NRCS_Portuguese(chr, DFT_94(chr)); 76604b94745Smrg break; 76704b94745Smrg 7685104ee6eSmrg case nrc_Russian: 7695104ee6eSmrg unmap_NRCS_Russian(chr, DFT_94(chr)); 7705104ee6eSmrg break; 7715104ee6eSmrg 7725104ee6eSmrg case nrc_SCS_NRCS: 7735104ee6eSmrg unmap_NRCS_Serbo_Croatian(chr, DFT_94(chr)); 7745104ee6eSmrg break; 7755104ee6eSmrg 77604b94745Smrg case nrc_Spanish: 77704b94745Smrg unmap_NRCS_Spanish(chr, DFT_94(chr)); 77804b94745Smrg break; 77904b94745Smrg 78004b94745Smrg case nrc_Swedish: 78104b94745Smrg case nrc_Swedish2: 78204b94745Smrg unmap_NRCS_Swedish(chr, DFT_94(chr)); 78304b94745Smrg break; 78404b94745Smrg 78504b94745Smrg case nrc_Swiss: 78604b94745Smrg unmap_NRCS_Swiss(chr, DFT_94(chr)); 78704b94745Smrg break; 78804b94745Smrg 78904b94745Smrg case nrc_DEC_Turkish_Supp: 79004b94745Smrg unmap_DEC_Turkish_Supp(chr, DFTMAP()); 79104b94745Smrg break; 79204b94745Smrg 79304b94745Smrg case nrc_Turkish: 79404b94745Smrg unmap_NRCS_Turkish(chr, DFT_94(chr)); 79504b94745Smrg break; 79604b94745Smrg 79704b94745Smrg case nrc_British_Latin_1: 79804b94745Smrg case nrc_Unknown: 79904b94745Smrg case nrc_DEC_UPSS: 80004b94745Smrg default: /* anything we cannot unmap */ 80104b94745Smrg break; 80204b94745Smrg } 80304b94745Smrg if (result < 0) { 80404b94745Smrg if (isSeven) { 80504b94745Smrg DFT_94(chr); 80604b94745Smrg } else { 80704b94745Smrg DFT_96(chr); 80804b94745Smrg } 80904b94745Smrg } 81004b94745Smrg } 81104b94745Smrg } 81204b94745Smrg return result; 81304b94745Smrg#undef MAP 81404b94745Smrg#undef UNI 81504b94745Smrg#undef XXX 81604b94745Smrg} 81704b94745Smrg#endif /* OPT_DEC_RECTOPS */ 818