/* * BRLTTY - A background process providing access to the console screen (when in * text mode) for a blind person using a refreshable braille display. * * Copyright (C) 1995-2021 by The BRLTTY Developers. * * BRLTTY comes with ABSOLUTELY NO WARRANTY. * * This is free software, placed under the terms of the * GNU Lesser General Public License, as published by the Free Software * Foundation; either version 2.1 of the License, or (at your option) any * later version. Please see the file LICENSE-LGPL for details. * * Web Page: http://brltty.app/ * * This software is maintained by Dave Mielke . */ #include "prologue.h" #include #include #include "charset_internal.h" #include "unicode.h" #include "system_msdos.h" #define CHARACTER_SET_SIZE 0X100 static const uint16_t toUnicode_Latin1[CHARACTER_SET_SIZE] = { /* 00 */ 0X0000, 0X0001, 0X0002, 0X0003, 0X0004, 0X0005, 0X0006, 0X0007, /* 08 */ 0X0008, 0X0009, 0X000A, 0X000B, 0X000C, 0X000D, 0X000E, 0X000F, /* 10 */ 0X0010, 0X0011, 0X0012, 0X0013, 0X0014, 0X0015, 0X0016, 0X0017, /* 18 */ 0X0018, 0X0019, 0X001A, 0X001B, 0X001C, 0X001D, 0X001E, 0X001F, /* 20 */ 0X0020, 0X0021, 0X0022, 0X0023, 0X0024, 0X0025, 0X0026, 0X0027, /* 28 */ 0X0028, 0X0029, 0X002A, 0X002B, 0X002C, 0X002D, 0X002E, 0X002F, /* 30 */ 0X0030, 0X0031, 0X0032, 0X0033, 0X0034, 0X0035, 0X0036, 0X0037, /* 38 */ 0X0038, 0X0039, 0X003A, 0X003B, 0X003C, 0X003D, 0X003E, 0X003F, /* 40 */ 0X0040, 0X0041, 0X0042, 0X0043, 0X0044, 0X0045, 0X0046, 0X0047, /* 48 */ 0X0048, 0X0049, 0X004A, 0X004B, 0X004C, 0X004D, 0X004E, 0X004F, /* 50 */ 0X0050, 0X0051, 0X0052, 0X0053, 0X0054, 0X0055, 0X0056, 0X0057, /* 58 */ 0X0058, 0X0059, 0X005A, 0X005B, 0X005C, 0X005D, 0X005E, 0X005F, /* 60 */ 0X0060, 0X0061, 0X0062, 0X0063, 0X0064, 0X0065, 0X0066, 0X0067, /* 68 */ 0X0068, 0X0069, 0X006A, 0X006B, 0X006C, 0X006D, 0X006E, 0X006F, /* 70 */ 0X0070, 0X0071, 0X0072, 0X0073, 0X0074, 0X0075, 0X0076, 0X0077, /* 78 */ 0X0078, 0X0079, 0X007A, 0X007B, 0X007C, 0X007D, 0X007E, 0X007F, /* 80 */ 0X0080, 0X0081, 0X0082, 0X0083, 0X0084, 0X0085, 0X0086, 0X0087, /* 88 */ 0X0088, 0X0089, 0X008A, 0X008B, 0X008C, 0X008D, 0X008E, 0X008F, /* 90 */ 0X0090, 0X0091, 0X0092, 0X0093, 0X0094, 0X0095, 0X0096, 0X0097, /* 98 */ 0X0098, 0X0099, 0X009A, 0X009B, 0X009C, 0X009D, 0X009E, 0X009F, /* A0 */ 0X00A0, 0X00A1, 0X00A2, 0X00A3, 0X00A4, 0X00A5, 0X00A6, 0X00A7, /* A8 */ 0X00A8, 0X00A9, 0X00AA, 0X00AB, 0X00AC, 0X00AD, 0X00AE, 0X00AF, /* B0 */ 0X00B0, 0X00B1, 0X00B2, 0X00B3, 0X00B4, 0X00B5, 0X00B6, 0X00B7, /* B8 */ 0X00B8, 0X00B9, 0X00BA, 0X00BB, 0X00BC, 0X00BD, 0X00BE, 0X00BF, /* C0 */ 0X00C0, 0X00C1, 0X00C2, 0X00C3, 0X00C4, 0X00C5, 0X00C6, 0X00C7, /* C8 */ 0X00C8, 0X00C9, 0X00CA, 0X00CB, 0X00CC, 0X00CD, 0X00CE, 0X00CF, /* D0 */ 0X00D0, 0X00D1, 0X00D2, 0X00D3, 0X00D4, 0X00D5, 0X00D6, 0X00D7, /* D8 */ 0X00D8, 0X00D9, 0X00DA, 0X00DB, 0X00DC, 0X00DD, 0X00DE, 0X00DF, /* E0 */ 0X00E0, 0X00E1, 0X00E2, 0X00E3, 0X00E4, 0X00E5, 0X00E6, 0X00E7, /* E8 */ 0X00E8, 0X00E9, 0X00EA, 0X00EB, 0X00EC, 0X00ED, 0X00EE, 0X00EF, /* F0 */ 0X00F0, 0X00F1, 0X00F2, 0X00F3, 0X00F4, 0X00F5, 0X00F6, 0X00F7, /* F8 */ 0X00F8, 0X00F9, 0X00FA, 0X00FB, 0X00FC, 0X00FD, 0X00FE, 0X00FF, }; static const uint16_t toUnicode_CP437[CHARACTER_SET_SIZE] = { /* 00 */ 0X0000, 0X0001, 0X0002, 0X0003, 0X0004, 0X0005, 0X0006, 0X0007, /* 08 */ 0X0008, 0X0009, 0X000A, 0X000B, 0X000C, 0X000D, 0X000E, 0X000F, /* 10 */ 0X0010, 0X0011, 0X0012, 0X0013, 0X0014, 0X0015, 0X0016, 0X0017, /* 18 */ 0X0018, 0X0019, 0X001A, 0X001B, 0X001C, 0X001D, 0X001E, 0X001F, /* 20 */ 0X0020, 0X0021, 0X0022, 0X0023, 0X0024, 0X0025, 0X0026, 0X0027, /* 28 */ 0X0028, 0X0029, 0X002A, 0X002B, 0X002C, 0X002D, 0X002E, 0X002F, /* 30 */ 0X0030, 0X0031, 0X0032, 0X0033, 0X0034, 0X0035, 0X0036, 0X0037, /* 38 */ 0X0038, 0X0039, 0X003A, 0X003B, 0X003C, 0X003D, 0X003E, 0X003F, /* 40 */ 0X0040, 0X0041, 0X0042, 0X0043, 0X0044, 0X0045, 0X0046, 0X0047, /* 48 */ 0X0048, 0X0049, 0X004A, 0X004B, 0X004C, 0X004D, 0X004E, 0X004F, /* 50 */ 0X0050, 0X0051, 0X0052, 0X0053, 0X0054, 0X0055, 0X0056, 0X0057, /* 58 */ 0X0058, 0X0059, 0X005A, 0X005B, 0X005C, 0X005D, 0X005E, 0X005F, /* 60 */ 0X0060, 0X0061, 0X0062, 0X0063, 0X0064, 0X0065, 0X0066, 0X0067, /* 68 */ 0X0068, 0X0069, 0X006A, 0X006B, 0X006C, 0X006D, 0X006E, 0X006F, /* 70 */ 0X0070, 0X0071, 0X0072, 0X0073, 0X0074, 0X0075, 0X0076, 0X0077, /* 78 */ 0X0078, 0X0079, 0X007A, 0X007B, 0X007C, 0X007D, 0X007E, 0X007F, /* 80 */ 0X00C7, 0X00FC, 0X00E9, 0X00E2, 0X00E4, 0X00E0, 0X00E5, 0X00E7, /* 88 */ 0X00EA, 0X00EB, 0X00E8, 0X00EF, 0X00EE, 0X00EC, 0X00C4, 0X00C5, /* 90 */ 0X00C9, 0X00E6, 0X00C6, 0X00F4, 0X00F6, 0X00F2, 0X00FB, 0X00F9, /* 98 */ 0X00FF, 0X00D6, 0X00DC, 0X00A2, 0X00A3, 0X00A5, 0X20A7, 0X0192, /* A0 */ 0X00E1, 0X00ED, 0X00F3, 0X00FA, 0X00F1, 0X00D1, 0X00AA, 0X00BA, /* A8 */ 0X00BF, 0X2310, 0X00AC, 0X00BD, 0X00BC, 0X00A1, 0X00AB, 0X00BB, /* B0 */ 0X2591, 0X2592, 0X2593, 0X2502, 0X2524, 0X2561, 0X2562, 0X2556, /* B8 */ 0X2555, 0X2563, 0X2551, 0X2557, 0X255D, 0X255C, 0X255B, 0X2510, /* C0 */ 0X2514, 0X2534, 0X252C, 0X251C, 0X2500, 0X253C, 0X255E, 0X255F, /* C8 */ 0X255A, 0X2554, 0X2569, 0X2566, 0X2560, 0X2550, 0X256C, 0X2567, /* D0 */ 0X2568, 0X2564, 0X2565, 0X2559, 0X2558, 0X2552, 0X2553, 0X256B, /* D8 */ 0X256A, 0X2518, 0X250C, 0X2588, 0X2584, 0X258C, 0X2590, 0X2580, /* E0 */ 0X03B1, 0X00DF, 0X0393, 0X03C0, 0X03A3, 0X03C3, 0X00B5, 0X03C4, /* E8 */ 0X03A6, 0X0398, 0X03A9, 0X03B4, 0X221E, 0X03C6, 0X03B5, 0X2229, /* F0 */ 0X2261, 0X00B1, 0X2265, 0X2264, 0X2320, 0X2321, 0X00F7, 0X2248, /* F8 */ 0X00B0, 0X2219, 0X00B7, 0X221A, 0X207F, 0X00B2, 0X25A0, 0X00A0 }; static const uint16_t toUnicode_CP850[CHARACTER_SET_SIZE] = { /* 00 */ 0X0000, 0X0001, 0X0002, 0X0003, 0X0004, 0X0005, 0X0006, 0X0007, /* 08 */ 0X0008, 0X0009, 0X000A, 0X000B, 0X000C, 0X000D, 0X000E, 0X000F, /* 10 */ 0X0010, 0X0011, 0X0012, 0X0013, 0X0014, 0X0015, 0X0016, 0X0017, /* 18 */ 0X0018, 0X0019, 0X001A, 0X001B, 0X001C, 0X001D, 0X001E, 0X001F, /* 20 */ 0X0020, 0X0021, 0X0022, 0X0023, 0X0024, 0X0025, 0X0026, 0X0027, /* 28 */ 0X0028, 0X0029, 0X002A, 0X002B, 0X002C, 0X002D, 0X002E, 0X002F, /* 30 */ 0X0030, 0X0031, 0X0032, 0X0033, 0X0034, 0X0035, 0X0036, 0X0037, /* 38 */ 0X0038, 0X0039, 0X003A, 0X003B, 0X003C, 0X003D, 0X003E, 0X003F, /* 40 */ 0X0040, 0X0041, 0X0042, 0X0043, 0X0044, 0X0045, 0X0046, 0X0047, /* 48 */ 0X0048, 0X0049, 0X004A, 0X004B, 0X004C, 0X004D, 0X004E, 0X004F, /* 50 */ 0X0050, 0X0051, 0X0052, 0X0053, 0X0054, 0X0055, 0X0056, 0X0057, /* 58 */ 0X0058, 0X0059, 0X005A, 0X005B, 0X005C, 0X005D, 0X005E, 0X005F, /* 60 */ 0X0060, 0X0061, 0X0062, 0X0063, 0X0064, 0X0065, 0X0066, 0X0067, /* 68 */ 0X0068, 0X0069, 0X006A, 0X006B, 0X006C, 0X006D, 0X006E, 0X006F, /* 70 */ 0X0070, 0X0071, 0X0072, 0X0073, 0X0074, 0X0075, 0X0076, 0X0077, /* 78 */ 0X0078, 0X0079, 0X007A, 0X007B, 0X007C, 0X007D, 0X007E, 0X007F, /* 80 */ 0X00C7, 0X00FC, 0X00E9, 0X00E2, 0X00E4, 0X00E0, 0X00E5, 0X00E7, /* 88 */ 0X00EA, 0X00EB, 0X00E8, 0X00EF, 0X00EE, 0X00EC, 0X00C4, 0X00C5, /* 90 */ 0X00C9, 0X00E6, 0X00C6, 0X00F4, 0X00F6, 0X00F2, 0X00FB, 0X00F9, /* 98 */ 0X00FF, 0X00D6, 0X00DC, 0X00F8, 0X00A3, 0X00D8, 0X00D7, 0X0192, /* A0 */ 0X00E1, 0X00ED, 0X00F3, 0X00FA, 0X00F1, 0X00D1, 0X00AA, 0X00BA, /* A8 */ 0X00BF, 0X00AE, 0X00AC, 0X00BD, 0X00BC, 0X00A1, 0X00AB, 0X00BB, /* B0 */ 0X2591, 0X2592, 0X2593, 0X2502, 0X2524, 0X00C1, 0X00C2, 0X00C0, /* B8 */ 0X00A9, 0X2563, 0X2551, 0X2557, 0X255D, 0X00A2, 0X00A5, 0X2510, /* C0 */ 0X2514, 0X2534, 0X252C, 0X251C, 0X2500, 0X253C, 0X00E3, 0X00C3, /* C8 */ 0X255A, 0X2554, 0X2569, 0X2566, 0X2560, 0X2550, 0X256C, 0X00A4, /* D0 */ 0X00F0, 0X00D0, 0X00CA, 0X00CB, 0X00C8, 0X0131, 0X00CD, 0X00CE, /* D8 */ 0X00CF, 0X2518, 0X250C, 0X2588, 0X2584, 0X00A6, 0X00CC, 0X2580, /* E0 */ 0X00D3, 0X00DF, 0X00D4, 0X00D2, 0X00F5, 0X00D5, 0X00B5, 0X00FE, /* E8 */ 0X00DE, 0X00DA, 0X00DB, 0X00D9, 0X00FD, 0X00DD, 0X00AF, 0X00B4, /* F0 */ 0X00AD, 0X00B1, 0X2017, 0X00BE, 0X00B6, 0X00A7, 0X00F7, 0X00B8, /* F8 */ 0X00B0, 0X00A8, 0X00B7, 0X00B9, 0X00B3, 0X00B2, 0X25A0, 0X00A0 }; typedef struct { const char *name; const uint16_t *toUnicode; } CharacterSet; static const CharacterSet characterSets[] = { {.name="iso-8859-1", .toUnicode=toUnicode_Latin1}, {.name="cp437", .toUnicode=toUnicode_CP437}, {.name="cp850", .toUnicode=toUnicode_CP850}, {} }; static const CharacterSet *characterSet; static char *unicodeRows[UNICODE_ROWS_PER_PLANE]; static void clearUnicodeRow (char *row) { memset(row, 0, UNICODE_CELLS_PER_ROW); } static void clearUnicodeRows (void) { int rowNumber; for (rowNumber=0; rowNumber> 8; char **rowAddress = &unicodeRows[rowNumber]; if (!*rowAddress) { if (!allocate) return NULL; { char *row = malloc(UNICODE_CELLS_PER_ROW); if (!row) return NULL; clearUnicodeRow(row); *rowAddress = row; } } return &(*rowAddress)[cellNumber]; } static int setCharacterSet (const char *name) { const CharacterSet *set = characterSets; while (set->name) { if (strcasecmp(name, set->name) == 0) { clearUnicodeRows(); characterSet = NULL; { int character; for (character=CHARACTER_SET_SIZE-1; character>=0; --character) { char *cell = getUnicodeCell(set->toUnicode[character], 1); if (!cell) return 0; *cell = character; } } characterSet = set; return 1; } ++set; } return 0; } wint_t convertCharToWchar (char c) { if (getCharset()) { uint16_t wc = characterSet->toUnicode[(unsigned char)c & 0XFF]; if (wc || !c) if ((sizeof(wchar_t) > 1) || iswLatin1(wc)) return wc; } return WEOF; } int convertWcharToChar (wchar_t wc) { if (getCharset()) { char *cell = getUnicodeCell(wc, 0); if (cell) if (*cell || !wc) return *cell & 0XFF; } return EOF; } const char * getLocaleCharset (void) { static char codepage[8]; snprintf(codepage, sizeof(codepage), "CP%03u", msdosGetCodePage()); return codepage; } int registerCharacterSet (const char *charset) { return setCharacterSet(charset); }