charsets.c revision 04b94745
104b94745Smrg/* $XTermId: charsets.c,v 1.126 2024/05/22 00:27:53 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: 11304b94745Smrg case nrc_Norwegian_Danish2: 11404b94745Smrg case nrc_Norwegian_Danish3: 11504b94745Smrg case nrc_Norwegian_Danish: 11604b94745Smrg case nrc_Portugese: 11704b94745Smrg case nrc_Russian: 11804b94745Smrg case nrc_SCS_NRCS: 11904b94745Smrg case nrc_Spanish: 12004b94745Smrg case nrc_Swedish2: 12104b94745Smrg case nrc_Swedish: 12204b94745Smrg case nrc_Swiss: 12304b94745Smrg case nrc_Turkish: 12404b94745Smrg /* other DEC character sets */ 12504b94745Smrg case nrc_DEC_Cyrillic: 12604b94745Smrg case nrc_DEC_Greek_Supp: 12704b94745Smrg case nrc_DEC_Hebrew_Supp: 12804b94745Smrg case nrc_DEC_Turkish_Supp: 12904b94745Smrg result = True; 13004b94745Smrg break; 13104b94745Smrg case nrc_Unknown: 13204b94745Smrg break; 13304b94745Smrg } 13404b94745Smrg return result; 13504b94745Smrg} 136e0a2b6dfSmrg 137e0a2b6dfSmrg/* 138e0a2b6dfSmrg * Translate an input keysym to the corresponding NRC keysym. 139e0a2b6dfSmrg */ 140e0a2b6dfSmrgunsigned 141f2e35a3aSmrgxtermCharSetIn(XtermWidget xw, unsigned code, DECNRCM_codes charset) 142e0a2b6dfSmrg{ 143f2e35a3aSmrg TScreen *screen = TScreenOf(xw); 14404b94745Smrg#define MAP(to, from) case from: code = to; break; 145e0a2b6dfSmrg 146e0a2b6dfSmrg#if OPT_WIDE_CHARS 14704b94745Smrg#define UNI(to, from) case from: if (screen->utf8_nrc_mode) code = to; break; 148e0a2b6dfSmrg#else 14904b94745Smrg#define UNI(to, from) case from: break; 150e0a2b6dfSmrg#endif 151e0a2b6dfSmrg 152e0a2b6dfSmrg#define XXX(to, from) /* no defined mapping to 0..255 */ 153e0a2b6dfSmrg 154e0a2b6dfSmrg TRACE(("CHARSET-IN GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 155e0a2b6dfSmrg visibleScsCode(screen->gsets[screen->curgl]), screen->curgl, 156e0a2b6dfSmrg visibleScsCode(screen->gsets[screen->curgr]), screen->curgr, 157e0a2b6dfSmrg screen->curss, 158e0a2b6dfSmrg visibleUChar(code))); 159e0a2b6dfSmrg 16004b94745Smrg HandleUPSS(charset); 16104b94745Smrg 162e0a2b6dfSmrg switch (charset) { 163e0a2b6dfSmrg case nrc_British: /* United Kingdom set (or Latin 1) */ 164e0a2b6dfSmrg if (code == XK_sterling) 165e0a2b6dfSmrg code = 0x23; 166e0a2b6dfSmrg code &= 0x7f; 167e0a2b6dfSmrg break; 168e0a2b6dfSmrg 169e0a2b6dfSmrg case nrc_DEC_Alt_Chars: 170e0a2b6dfSmrg case nrc_DEC_Alt_Graphics: 171e0a2b6dfSmrg case nrc_ASCII: 172e0a2b6dfSmrg break; 173e0a2b6dfSmrg 174e0a2b6dfSmrg case nrc_DEC_Spec_Graphic: 175e0a2b6dfSmrg break; 176e0a2b6dfSmrg 177e0a2b6dfSmrg case nrc_DEC_Supp: 178f2e35a3aSmrg map_DEC_Supp_Graphic(code, code &= 0x7f); 179e0a2b6dfSmrg break; 180e0a2b6dfSmrg 181e0a2b6dfSmrg case nrc_DEC_Supp_Graphic: 182f2e35a3aSmrg map_DEC_Supp_Graphic(code, code |= 0x80); 183e0a2b6dfSmrg break; 184e0a2b6dfSmrg 185e0a2b6dfSmrg case nrc_DEC_Technical: 186f2e35a3aSmrg map_DEC_Technical(code); 187e0a2b6dfSmrg break; 188e0a2b6dfSmrg 189e0a2b6dfSmrg case nrc_Dutch: 190e0a2b6dfSmrg map_NRCS_Dutch(code); 191e0a2b6dfSmrg break; 192e0a2b6dfSmrg 193e0a2b6dfSmrg case nrc_Finnish: 194e0a2b6dfSmrg case nrc_Finnish2: 195e0a2b6dfSmrg map_NRCS_Finnish(code); 196e0a2b6dfSmrg break; 197e0a2b6dfSmrg 198e0a2b6dfSmrg case nrc_French: 199e0a2b6dfSmrg case nrc_French2: 200e0a2b6dfSmrg map_NRCS_French(code); 201e0a2b6dfSmrg break; 202e0a2b6dfSmrg 203e0a2b6dfSmrg case nrc_French_Canadian: 204e0a2b6dfSmrg map_NRCS_French_Canadian(code); 205e0a2b6dfSmrg break; 206e0a2b6dfSmrg 207e0a2b6dfSmrg case nrc_German: 208e0a2b6dfSmrg map_NRCS_German(code); 209e0a2b6dfSmrg break; 210e0a2b6dfSmrg 211f2e35a3aSmrg case nrc_Greek: 212f2e35a3aSmrg map_NRCS_Greek(code); /* FIXME - ELOT? */ 213f2e35a3aSmrg break; 214f2e35a3aSmrg 215f2e35a3aSmrg case nrc_DEC_Greek_Supp: 216f2e35a3aSmrg map_DEC_Greek_Supp(code); 217f2e35a3aSmrg break; 218f2e35a3aSmrg 219f2e35a3aSmrg case nrc_ISO_Greek_Supp: 220f2e35a3aSmrg map_ISO_Greek_Supp(code); 221f2e35a3aSmrg break; 222f2e35a3aSmrg 223f2e35a3aSmrg case nrc_DEC_Hebrew_Supp: 224f2e35a3aSmrg map_DEC_Hebrew_Supp(code); 225f2e35a3aSmrg break; 226f2e35a3aSmrg 227e0a2b6dfSmrg case nrc_Hebrew: 228f2e35a3aSmrg map_NRCS_Hebrew(code); 229f2e35a3aSmrg break; 230f2e35a3aSmrg 231f2e35a3aSmrg case nrc_ISO_Hebrew_Supp: 232f2e35a3aSmrg map_ISO_Hebrew(code); 233e0a2b6dfSmrg break; 234e0a2b6dfSmrg 235e0a2b6dfSmrg case nrc_Italian: 236e0a2b6dfSmrg map_NRCS_Italian(code); 237e0a2b6dfSmrg break; 238e0a2b6dfSmrg 239f2e35a3aSmrg case nrc_ISO_Latin_2_Supp: 240f2e35a3aSmrg map_ISO_Latin_2(code); 241f2e35a3aSmrg break; 242f2e35a3aSmrg 243f2e35a3aSmrg case nrc_ISO_Latin_5_Supp: 244f2e35a3aSmrg map_ISO_Latin_5(code); 245f2e35a3aSmrg break; 246f2e35a3aSmrg 247f2e35a3aSmrg case nrc_ISO_Latin_Cyrillic: 248f2e35a3aSmrg map_ISO_Latin_Cyrillic(code); 249f2e35a3aSmrg break; 250f2e35a3aSmrg 251e0a2b6dfSmrg case nrc_Norwegian_Danish: 252e0a2b6dfSmrg case nrc_Norwegian_Danish2: 253e0a2b6dfSmrg case nrc_Norwegian_Danish3: 254e0a2b6dfSmrg map_NRCS_Norwegian_Danish(code); 255e0a2b6dfSmrg break; 256e0a2b6dfSmrg 257e0a2b6dfSmrg case nrc_Portugese: 258e0a2b6dfSmrg map_NRCS_Portuguese(code); 259e0a2b6dfSmrg break; 260e0a2b6dfSmrg 26104b94745Smrg case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 262e0a2b6dfSmrg /* FIXME */ 263e0a2b6dfSmrg break; 264e0a2b6dfSmrg 265e0a2b6dfSmrg case nrc_Spanish: 266e0a2b6dfSmrg map_NRCS_Spanish(code); 267e0a2b6dfSmrg break; 268e0a2b6dfSmrg 269e0a2b6dfSmrg case nrc_Swedish2: 270e0a2b6dfSmrg case nrc_Swedish: 271e0a2b6dfSmrg map_NRCS_Swedish(code); 272e0a2b6dfSmrg break; 273e0a2b6dfSmrg 274e0a2b6dfSmrg case nrc_Swiss: 275e0a2b6dfSmrg map_NRCS_Swiss(code); 276e0a2b6dfSmrg break; 277e0a2b6dfSmrg 278e0a2b6dfSmrg case nrc_Turkish: 279f2e35a3aSmrg map_NRCS_Turkish(code); 280f2e35a3aSmrg break; 281f2e35a3aSmrg 282f2e35a3aSmrg case nrc_DEC_Turkish_Supp: 283f2e35a3aSmrg map_DEC_Turkish_Supp(code); 284e0a2b6dfSmrg break; 285e0a2b6dfSmrg 286f2e35a3aSmrg case nrc_DEC_Cyrillic: 287f2e35a3aSmrg map_DEC_Cyrillic(code); 288f2e35a3aSmrg break; 289f2e35a3aSmrg 290f2e35a3aSmrg case nrc_ISO_Latin_1_Supp: 291f2e35a3aSmrg case nrc_British_Latin_1: 292f2e35a3aSmrg case nrc_Russian: 293f2e35a3aSmrg case nrc_French_Canadian2: 294f2e35a3aSmrg case nrc_Unknown: 29504b94745Smrg case nrc_DEC_UPSS: 296e0a2b6dfSmrg default: /* any character sets we don't recognize */ 297e0a2b6dfSmrg break; 2982eaa94a1Schristos } 299e0a2b6dfSmrg code &= 0x7f; /* NRC in any case is 7-bit */ 300e0a2b6dfSmrg TRACE(("->\t%s\n", 301e0a2b6dfSmrg visibleUChar(code))); 3022eaa94a1Schristos return code; 3032eaa94a1Schristos#undef MAP 304e0a2b6dfSmrg#undef UNI 305e0a2b6dfSmrg#undef XXX 306d522f475Smrg} 307d522f475Smrg 308d522f475Smrg/* 309d522f475Smrg * Translate a string to the display form. This assumes the font has the 310d522f475Smrg * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1. 311d522f475Smrg */ 31204b94745SmrgCardinal 31304b94745SmrgxtermCharSetOut(XtermWidget xw, Cardinal length, DECNRCM_codes leftset) 314d522f475Smrg{ 31504b94745Smrg IChar *buf = xw->work.write_text; 31604b94745Smrg IChar *ptr = buf + length; 3172eaa94a1Schristos IChar *s; 3182eaa94a1Schristos TScreen *screen = TScreenOf(xw); 31904b94745Smrg Cardinal count = 0; 320f2e35a3aSmrg DECNRCM_codes rightset = screen->gsets[(int) (screen->curgr)]; 32104b94745Smrg#if OPT_DEC_RECTOPS 32204b94745Smrg int sums = 0; 32304b94745Smrg#endif 3242eaa94a1Schristos 32504b94745Smrg#define MAP(from, to) case from: chr = to; break; 3262eaa94a1Schristos 327e0a2b6dfSmrg#if OPT_WIDE_CHARS 32804b94745Smrg#define UNI(from, to) case from: if (screen->utf8_nrc_mode) chr = to; break; 329e0a2b6dfSmrg#define XXX(from, to) UNI(from, to) 330e0a2b6dfSmrg#else 33104b94745Smrg#define UNI(old, new) case new: chr = old; break; 332e0a2b6dfSmrg#define XXX(from, to) /* nothing */ 333e0a2b6dfSmrg#endif 334e0a2b6dfSmrg 335e0a2b6dfSmrg TRACE(("CHARSET-OUT GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 336e0a2b6dfSmrg visibleScsCode(leftset), screen->curgl, 337e0a2b6dfSmrg visibleScsCode(rightset), screen->curgr, 3382eaa94a1Schristos screen->curss, 33904b94745Smrg visibleIChars(buf, (size_t) length))); 34004b94745Smrg 34104b94745Smrg assert(length != 0); 34204b94745Smrg#if OPT_DEC_RECTOPS 34304b94745Smrg if (length != 0 && length > xw->work.sizeof_sums) { 34404b94745Smrg xw->work.sizeof_sums += length + 80; 34504b94745Smrg xw->work.buffer_sums = realloc(xw->work.buffer_sums, 34604b94745Smrg xw->work.sizeof_sums); 34704b94745Smrg xw->work.buffer_sets = realloc(xw->work.buffer_sets, 34804b94745Smrg xw->work.sizeof_sums); 34904b94745Smrg } 35004b94745Smrg xw->work.write_sums = xw->work.buffer_sums; 35104b94745Smrg#endif 3522eaa94a1Schristos 3532eaa94a1Schristos for (s = buf; s < ptr; ++s) { 3542eaa94a1Schristos int eight = CharOf(E2A(*s)); 3552eaa94a1Schristos int seven = eight & 0x7f; 356f2e35a3aSmrg DECNRCM_codes cs = (eight >= 128) ? rightset : leftset; 3572eaa94a1Schristos int chr = eight; 3582eaa94a1Schristos 35904b94745Smrg HandleUPSS(cs); 36004b94745Smrg 36104b94745Smrg#if OPT_DEC_RECTOPS 36204b94745Smrg if (xw->work.buffer_sums != NULL && xw->work.buffer_sets != NULL) { 36304b94745Smrg xw->work.buffer_sums[sums] = (Char) ((eight < 32 || eight > 255) 36404b94745Smrg ? ANSI_ESC 36504b94745Smrg : eight); 36604b94745Smrg xw->work.buffer_sets[sums] = cs; 36704b94745Smrg ++sums; 36804b94745Smrg } 36904b94745Smrg#endif 3702eaa94a1Schristos count++; 3712eaa94a1Schristos#if OPT_WIDE_CHARS 3722eaa94a1Schristos /* 373f2e35a3aSmrg * This is only partly right - prevent inadvertent remapping of 3742eaa94a1Schristos * the replacement character and other non-8bit codes into bogus 3752eaa94a1Schristos * 8bit codes. 3762eaa94a1Schristos */ 377e0a2b6dfSmrg if (screen->utf8_mode || screen->utf8_nrc_mode) { 3782eaa94a1Schristos if (*s > 255) 3792eaa94a1Schristos continue; 3802eaa94a1Schristos } 3812eaa94a1Schristos#endif 382e0a2b6dfSmrg if (*s < 32) 383e0a2b6dfSmrg continue; 384e0a2b6dfSmrg 3852eaa94a1Schristos switch (cs) { 38604b94745Smrg case nrc_DEC_UPSS: 38704b94745Smrg break; 38804b94745Smrg 389f2e35a3aSmrg case nrc_ISO_Latin_1_Supp: 390e0a2b6dfSmrg case nrc_British_Latin_1: 391e0a2b6dfSmrg case nrc_British: /* United Kingdom set (or Latin 1) */ 3922eaa94a1Schristos if ((xw->flags & NATIONAL) 3932eaa94a1Schristos || (screen->vtXX_level <= 1)) { 394e0a2b6dfSmrg if ((xw->flags & NATIONAL)) { 395e0a2b6dfSmrg chr = seven; 396e0a2b6dfSmrg } 3972eaa94a1Schristos if (chr == 0x23) { 3982eaa94a1Schristos chr = XTERM_POUND; 399e0a2b6dfSmrg#if OPT_WIDE_CHARS 400e0a2b6dfSmrg if (screen->utf8_nrc_mode) { 401e0a2b6dfSmrg chr = 0xa3; 402e0a2b6dfSmrg } 4032eaa94a1Schristos#endif 4042eaa94a1Schristos } 4052eaa94a1Schristos } 4062eaa94a1Schristos break; 407d522f475Smrg 408e0a2b6dfSmrg case nrc_DEC_Alt_Chars: 409e0a2b6dfSmrg case nrc_DEC_Alt_Graphics: 410e0a2b6dfSmrg case nrc_ASCII: 4112eaa94a1Schristos break; 412d522f475Smrg 413e0a2b6dfSmrg case nrc_DEC_Spec_Graphic: 4142eaa94a1Schristos if (seven > 0x5f && seven <= 0x7e) { 415d522f475Smrg#if OPT_WIDE_CHARS 416e0a2b6dfSmrg if (screen->utf8_mode || screen->utf8_nrc_mode) 417f2e35a3aSmrg chr = (int) dec2ucs(screen, (unsigned) (seven - 0x5f)); 4182eaa94a1Schristos else 419d522f475Smrg#endif 4202eaa94a1Schristos chr = seven - 0x5f; 421f2e35a3aSmrg } else if (chr == 0x5f) { 422f2e35a3aSmrg chr = 0; 4232eaa94a1Schristos } else { 4242eaa94a1Schristos chr = seven; 4252eaa94a1Schristos } 4262eaa94a1Schristos break; 4272eaa94a1Schristos 428e0a2b6dfSmrg case nrc_DEC_Supp: 429e0a2b6dfSmrg case nrc_DEC_Supp_Graphic: 43004b94745Smrg map_DEC_Supp_Graphic(chr = seven, chr = eight); 4312eaa94a1Schristos break; 4322eaa94a1Schristos 433e0a2b6dfSmrg case nrc_DEC_Technical: 434f2e35a3aSmrg map_DEC_Technical(chr = seven); 4352eaa94a1Schristos break; 4362eaa94a1Schristos 437e0a2b6dfSmrg case nrc_Dutch: 438e0a2b6dfSmrg map_NRCS_Dutch(chr = seven); 4392eaa94a1Schristos break; 4402eaa94a1Schristos 441e0a2b6dfSmrg case nrc_Finnish: 442e0a2b6dfSmrg case nrc_Finnish2: 443e0a2b6dfSmrg map_NRCS_Finnish(chr = seven); 4442eaa94a1Schristos break; 4452eaa94a1Schristos 446e0a2b6dfSmrg case nrc_French: 447e0a2b6dfSmrg case nrc_French2: 448e0a2b6dfSmrg map_NRCS_French(chr = seven); 4492eaa94a1Schristos break; 4502eaa94a1Schristos 451e0a2b6dfSmrg case nrc_French_Canadian: 452e0a2b6dfSmrg case nrc_French_Canadian2: 453e0a2b6dfSmrg map_NRCS_French_Canadian(chr = seven); 4542eaa94a1Schristos break; 4552eaa94a1Schristos 456e0a2b6dfSmrg case nrc_German: 457e0a2b6dfSmrg map_NRCS_German(chr = seven); 4582eaa94a1Schristos break; 4592eaa94a1Schristos 460f2e35a3aSmrg case nrc_Greek: 461f2e35a3aSmrg map_NRCS_Greek(chr = seven); /* FIXME - ELOT? */ 462f2e35a3aSmrg break; 463f2e35a3aSmrg 464f2e35a3aSmrg case nrc_DEC_Greek_Supp: 465f2e35a3aSmrg map_DEC_Greek_Supp(chr = seven); 466f2e35a3aSmrg break; 467f2e35a3aSmrg 468f2e35a3aSmrg case nrc_ISO_Greek_Supp: 469f2e35a3aSmrg map_ISO_Greek_Supp(chr = seven); 470f2e35a3aSmrg break; 471f2e35a3aSmrg 472f2e35a3aSmrg case nrc_DEC_Hebrew_Supp: 473f2e35a3aSmrg map_DEC_Hebrew_Supp(chr = seven); 474f2e35a3aSmrg break; 475f2e35a3aSmrg 476e0a2b6dfSmrg case nrc_Hebrew: 477f2e35a3aSmrg map_NRCS_Hebrew(chr = seven); 478f2e35a3aSmrg break; 479f2e35a3aSmrg 480f2e35a3aSmrg case nrc_ISO_Hebrew_Supp: 481f2e35a3aSmrg map_ISO_Hebrew(chr = seven); 4822eaa94a1Schristos break; 4832eaa94a1Schristos 484e0a2b6dfSmrg case nrc_Italian: 485e0a2b6dfSmrg map_NRCS_Italian(chr = seven); 486e0a2b6dfSmrg break; 487e0a2b6dfSmrg 488f2e35a3aSmrg case nrc_ISO_Latin_2_Supp: 489f2e35a3aSmrg map_ISO_Latin_2(chr = seven); 490f2e35a3aSmrg break; 491f2e35a3aSmrg 492f2e35a3aSmrg case nrc_ISO_Latin_5_Supp: 493f2e35a3aSmrg map_ISO_Latin_5(chr = seven); 494f2e35a3aSmrg break; 495f2e35a3aSmrg 496f2e35a3aSmrg case nrc_ISO_Latin_Cyrillic: 497f2e35a3aSmrg map_ISO_Latin_Cyrillic(chr = seven); 498f2e35a3aSmrg break; 499f2e35a3aSmrg 500e0a2b6dfSmrg case nrc_Norwegian_Danish: 501e0a2b6dfSmrg case nrc_Norwegian_Danish2: 502e0a2b6dfSmrg case nrc_Norwegian_Danish3: 503e0a2b6dfSmrg map_NRCS_Norwegian_Danish(chr = seven); 504e0a2b6dfSmrg break; 505e0a2b6dfSmrg 506e0a2b6dfSmrg case nrc_Portugese: 507e0a2b6dfSmrg map_NRCS_Portuguese(chr = seven); 508e0a2b6dfSmrg break; 509e0a2b6dfSmrg 51004b94745Smrg case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 511e0a2b6dfSmrg /* FIXME */ 512e0a2b6dfSmrg break; 513e0a2b6dfSmrg 514e0a2b6dfSmrg case nrc_Spanish: 515e0a2b6dfSmrg map_NRCS_Spanish(chr = seven); 516e0a2b6dfSmrg break; 517e0a2b6dfSmrg 518e0a2b6dfSmrg case nrc_Swedish2: 519e0a2b6dfSmrg case nrc_Swedish: 520e0a2b6dfSmrg map_NRCS_Swedish(chr = seven); 521e0a2b6dfSmrg break; 522e0a2b6dfSmrg 523e0a2b6dfSmrg case nrc_Swiss: 524e0a2b6dfSmrg map_NRCS_Swiss(chr = seven); 525e0a2b6dfSmrg break; 526e0a2b6dfSmrg 527e0a2b6dfSmrg case nrc_Turkish: 528f2e35a3aSmrg map_NRCS_Turkish(chr = seven); 5292eaa94a1Schristos break; 5302eaa94a1Schristos 531f2e35a3aSmrg case nrc_DEC_Turkish_Supp: 532f2e35a3aSmrg map_DEC_Turkish_Supp(chr = seven); 533f2e35a3aSmrg break; 534f2e35a3aSmrg 535f2e35a3aSmrg case nrc_DEC_Cyrillic: 536f2e35a3aSmrg map_DEC_Cyrillic(chr = seven); 537f2e35a3aSmrg break; 538f2e35a3aSmrg 539f2e35a3aSmrg case nrc_Russian: 540f2e35a3aSmrg case nrc_Unknown: 5412eaa94a1Schristos default: /* any character sets we don't recognize */ 5422eaa94a1Schristos break; 543d522f475Smrg } 5442eaa94a1Schristos /* 5452eaa94a1Schristos * The state machine already treated DEL as a nonprinting and 546f2e35a3aSmrg * nonspacing character. If we have DEL now, remove it. 5472eaa94a1Schristos */ 54804b94745Smrg if (chr == ANSI_DEL && isSevenBit(cs)) { 549f2e35a3aSmrg IChar *s1; 550f2e35a3aSmrg --ptr; 551f2e35a3aSmrg for (s1 = s; s1 < ptr; ++s1) { 552f2e35a3aSmrg s1[0] = s1[1]; 553f2e35a3aSmrg } 55404b94745Smrg --count; 55504b94745Smrg#if OPT_DEC_RECTOPS 55604b94745Smrg --sums; 55704b94745Smrg#endif 558f2e35a3aSmrg } else { 55904b94745Smrg if (eight >= 128 && chr < 128 && chr > 32) 56004b94745Smrg chr |= 128; 561f2e35a3aSmrg *s = (IChar) A2E(chr); 562f2e35a3aSmrg } 5632eaa94a1Schristos } 5642eaa94a1Schristos TRACE(("%d\t%s\n", 5652eaa94a1Schristos count, 56604b94745Smrg visibleIChars(buf, (size_t) length))); 5672eaa94a1Schristos return count; 5682eaa94a1Schristos#undef MAP 569e0a2b6dfSmrg#undef UNI 570e0a2b6dfSmrg#undef XXX 571d522f475Smrg} 57204b94745Smrg 57304b94745Smrg#if OPT_DEC_RECTOPS 57404b94745Smrg/* 57504b94745Smrg * Given a mapped character, e.g., a Unicode value returned by xtermCharSetIn, 57604b94745Smrg * match it against the current GL/GR selection and return the corresponding 57704b94745Smrg * DEC internal character-set code for DECRQCRA. 57804b94745Smrg * 57904b94745Smrg * A hardware terminal presumably stores the original and mapped characters, 58004b94745Smrg * as well as the character set which was selected at that time Doing that 58104b94745Smrg * in xterm adds a couple of bytes to every cell. 58204b94745Smrg */ 58304b94745Smrgint 58404b94745SmrgxtermCharSetDec(XtermWidget xw, IChar chr, DECNRCM_codes cs) 58504b94745Smrg{ 58604b94745Smrg#define MAP(from, to) case from: result = to; break; 58704b94745Smrg 58804b94745Smrg#define DFTMAP() result = (actual | 0x80) 58904b94745Smrg#define DFT_94(chr) result = ((actual) & 0x7f) 59004b94745Smrg#define DFT_96(chr) result = ((actual) | 0x80) 59104b94745Smrg 59204b94745Smrg#if OPT_WIDE_CHARS 59304b94745Smrg#define UNI(from, to) case from: if (screen->utf8_nrc_mode) result = to; break; 59404b94745Smrg#define XXX(from, to) UNI(from, to) 59504b94745Smrg#else 59604b94745Smrg#define UNI(old, new) case new: result = old; break; 59704b94745Smrg#define XXX(from, to) /* nothing */ 59804b94745Smrg#endif 59904b94745Smrg 60004b94745Smrg int result; 60104b94745Smrg 60204b94745Smrg if (chr < 0x20 60304b94745Smrg#if OPT_WIDE_CHARS 60404b94745Smrg || chr > 0xff 60504b94745Smrg#endif 60604b94745Smrg ) { 60704b94745Smrg result = ANSI_ESC; 60804b94745Smrg } else { 60904b94745Smrg Boolean isSeven = isSevenBit(cs); 61004b94745Smrg TScreen *screen = TScreenOf(xw); 61104b94745Smrg 61204b94745Smrg result = -1; 61304b94745Smrg 61404b94745Smrg HandleUPSS(cs); 61504b94745Smrg 61604b94745Smrg if (chr == 0xa0 && isSeven) { 61704b94745Smrg result = ANSI_ESC; 61804b94745Smrg } else if (chr == ANSI_SPA && isSeven) { 61904b94745Smrg result = ANSI_SPA; 62004b94745Smrg } else if ((chr == ANSI_DEL || chr == 0xff) && isSeven) { 62104b94745Smrg result = 0; 62204b94745Smrg } else { 62304b94745Smrg int actual = (int) chr; 62404b94745Smrg chr &= 0x7f; 62504b94745Smrg 62604b94745Smrg switch (cs) { 62704b94745Smrg case nrc_DEC_Alt_Chars: 62804b94745Smrg case nrc_DEC_Alt_Graphics: 62904b94745Smrg case nrc_ASCII: 63004b94745Smrg result = (int) chr; 63104b94745Smrg break; 63204b94745Smrg 63304b94745Smrg case nrc_British: 63404b94745Smrg if (chr >= 0xa0 && chr < 0xff) { 63504b94745Smrg if (chr == 0x23) 63604b94745Smrg chr = 0xA3; 63704b94745Smrg result = (int) chr; 63804b94745Smrg } 63904b94745Smrg break; 64004b94745Smrg 64104b94745Smrg case nrc_DEC_Cyrillic: 64204b94745Smrg unmap_DEC_Cyrillic(chr, DFT_94(chr)); 64304b94745Smrg break; 64404b94745Smrg 64504b94745Smrg case nrc_DEC_Spec_Graphic: 64604b94745Smrg unmap_DEC_Spec_Graphic(chr, DFT_94(chr)); 64704b94745Smrg break; 64804b94745Smrg 64904b94745Smrg case nrc_DEC_Supp: 65004b94745Smrg /* FALLTHRU */ 65104b94745Smrg case nrc_DEC_Supp_Graphic: 65204b94745Smrg unmap_DEC_Supp_Graphic(chr, DFTMAP()); 65304b94745Smrg break; 65404b94745Smrg 65504b94745Smrg case nrc_DEC_Technical: 65604b94745Smrg unmap_DEC_Technical(chr, DFTMAP()); 65704b94745Smrg break; 65804b94745Smrg 65904b94745Smrg case nrc_Dutch: 66004b94745Smrg unmap_NRCS_Dutch(chr, DFT_94(chr)); 66104b94745Smrg break; 66204b94745Smrg 66304b94745Smrg case nrc_Finnish: 66404b94745Smrg case nrc_Finnish2: 66504b94745Smrg unmap_NRCS_Finnish(chr, DFT_94(chr)); 66604b94745Smrg break; 66704b94745Smrg 66804b94745Smrg case nrc_French: 66904b94745Smrg case nrc_French2: 67004b94745Smrg unmap_NRCS_French(chr, DFT_94(chr)); 67104b94745Smrg break; 67204b94745Smrg 67304b94745Smrg case nrc_French_Canadian: 67404b94745Smrg case nrc_French_Canadian2: 67504b94745Smrg unmap_NRCS_French_Canadian(chr, DFT_94(chr)); 67604b94745Smrg break; 67704b94745Smrg 67804b94745Smrg case nrc_German: 67904b94745Smrg unmap_NRCS_German(chr, DFT_94(chr)); 68004b94745Smrg break; 68104b94745Smrg 68204b94745Smrg case nrc_Greek: 68304b94745Smrg unmap_NRCS_Greek(chr, DFT_94(chr)); 68404b94745Smrg break; 68504b94745Smrg 68604b94745Smrg case nrc_DEC_Greek_Supp: 68704b94745Smrg unmap_DEC_Greek_Supp(chr, DFTMAP()); 68804b94745Smrg break; 68904b94745Smrg 69004b94745Smrg case nrc_ISO_Greek_Supp: 69104b94745Smrg unmap_ISO_Greek_Supp(chr, DFTMAP()); 69204b94745Smrg break; 69304b94745Smrg 69404b94745Smrg case nrc_DEC_Hebrew_Supp: 69504b94745Smrg unmap_DEC_Hebrew_Supp(chr, DFTMAP()); 69604b94745Smrg break; 69704b94745Smrg 69804b94745Smrg case nrc_Hebrew: 69904b94745Smrg unmap_NRCS_Hebrew(chr, DFT_94(chr)); 70004b94745Smrg break; 70104b94745Smrg 70204b94745Smrg case nrc_ISO_Hebrew_Supp: 70304b94745Smrg unmap_ISO_Hebrew(chr, DFTMAP()); 70404b94745Smrg break; 70504b94745Smrg 70604b94745Smrg case nrc_Italian: 70704b94745Smrg unmap_NRCS_Italian(chr, DFT_94(chr)); 70804b94745Smrg break; 70904b94745Smrg 71004b94745Smrg case nrc_ISO_Latin_1_Supp: 71104b94745Smrg unmap_ISO_Latin_1(chr, DFTMAP()); 71204b94745Smrg break; 71304b94745Smrg 71404b94745Smrg case nrc_ISO_Latin_2_Supp: 71504b94745Smrg unmap_ISO_Latin_2(chr, DFTMAP()); 71604b94745Smrg break; 71704b94745Smrg 71804b94745Smrg case nrc_ISO_Latin_5_Supp: 71904b94745Smrg unmap_ISO_Latin_5(chr, DFTMAP()); 72004b94745Smrg break; 72104b94745Smrg 72204b94745Smrg case nrc_ISO_Latin_Cyrillic: 72304b94745Smrg unmap_ISO_Latin_Cyrillic(chr, DFTMAP()); 72404b94745Smrg break; 72504b94745Smrg 72604b94745Smrg case nrc_Norwegian_Danish: 72704b94745Smrg case nrc_Norwegian_Danish2: 72804b94745Smrg case nrc_Norwegian_Danish3: 72904b94745Smrg unmap_NRCS_Norwegian_Danish(chr, DFT_94(chr)); 73004b94745Smrg break; 73104b94745Smrg 73204b94745Smrg case nrc_Portugese: 73304b94745Smrg unmap_NRCS_Portuguese(chr, DFT_94(chr)); 73404b94745Smrg break; 73504b94745Smrg 73604b94745Smrg case nrc_Spanish: 73704b94745Smrg unmap_NRCS_Spanish(chr, DFT_94(chr)); 73804b94745Smrg break; 73904b94745Smrg 74004b94745Smrg case nrc_Swedish: 74104b94745Smrg case nrc_Swedish2: 74204b94745Smrg unmap_NRCS_Swedish(chr, DFT_94(chr)); 74304b94745Smrg break; 74404b94745Smrg 74504b94745Smrg case nrc_Swiss: 74604b94745Smrg unmap_NRCS_Swiss(chr, DFT_94(chr)); 74704b94745Smrg break; 74804b94745Smrg 74904b94745Smrg case nrc_DEC_Turkish_Supp: 75004b94745Smrg unmap_DEC_Turkish_Supp(chr, DFTMAP()); 75104b94745Smrg break; 75204b94745Smrg 75304b94745Smrg case nrc_Turkish: 75404b94745Smrg unmap_NRCS_Turkish(chr, DFT_94(chr)); 75504b94745Smrg break; 75604b94745Smrg 75704b94745Smrg case nrc_British_Latin_1: 75804b94745Smrg case nrc_SCS_NRCS: 75904b94745Smrg case nrc_Russian: 76004b94745Smrg case nrc_Unknown: 76104b94745Smrg case nrc_DEC_UPSS: 76204b94745Smrg default: /* anything we cannot unmap */ 76304b94745Smrg break; 76404b94745Smrg } 76504b94745Smrg if (result < 0) { 76604b94745Smrg if (isSeven) { 76704b94745Smrg DFT_94(chr); 76804b94745Smrg } else { 76904b94745Smrg DFT_96(chr); 77004b94745Smrg } 77104b94745Smrg } 77204b94745Smrg } 77304b94745Smrg } 77404b94745Smrg return result; 77504b94745Smrg#undef MAP 77604b94745Smrg#undef UNI 77704b94745Smrg#undef XXX 77804b94745Smrg} 77904b94745Smrg#endif /* OPT_DEC_RECTOPS */ 780