More comment cleanup.
[u/mdw/putty] / unicode.c
CommitLineData
f7f27309 1#ifdef WINDOWS
4eeb7d09 2#include <windows.h>
f7f27309 3#endif
4eeb7d09 4
5#include <stdio.h>
6#include <stdlib.h>
7#include <ctype.h>
4eeb7d09 8#include <time.h>
5def7522 9#include <assert.h>
10
4eeb7d09 11#include "putty.h"
887035a5 12#include "terminal.h"
875b193f 13#include "misc.h"
4eeb7d09 14
4eeb7d09 15/* Character conversion arrays; they are usually taken from windows,
16 * the xterm one has the four scanlines that have no unicode 2.0
dc3c8261 17 * equivalents mapped to their unicode 3.0 locations.
4eeb7d09 18 */
19static char **uni_tbl;
20
c4399982 21static const WCHAR unitab_xterm_std[32] = {
4eeb7d09 22 0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
23 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
24 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
25 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
26};
27
875b193f 28/*
29 * If the codepage is non-zero it's a window codepage, zero means use a
30 * local codepage. The name is always converted to the first of any
31 * duplicate definitions.
32 */
33
d6dcf6c6 34/*
35 * Tables for ISO-8859-{1-9,13-16} derived from those downloaded
36 * 2001-10-02 from <http://www.unicode.org/Public/MAPPINGS/> -- jtn
bc9f5888 37 * Table for ISO-8859-11 derived from same on 2002-11-18. -- bjh21
d6dcf6c6 38 */
39
40/* XXX: This could be done algorithmically, but I'm not sure it's
41 * worth the hassle -- jtn */
42/* ISO/IEC 8859-1:1998 (Latin-1, "Western", "West European") */
c4399982 43static const wchar_t iso_8859_1[] = {
d6dcf6c6 44 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
45 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
46 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
47 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
48 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
49 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
50 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
51 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
52 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
53 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
54 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
55 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
56};
57
bc9f5888 58/* ISO/IEC 8859-2:1999 (Latin-2, "Central European", "East European") */
c4399982 59static const wchar_t iso_8859_2[] = {
d6dcf6c6 60 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
61 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
62 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
63 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
64 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
65 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
66 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
67 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
68 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
69 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
70 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
71 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
72};
73
74/* ISO/IEC 8859-3:1999 (Latin-3, "South European", "Maltese & Esperanto") */
c4399982 75static const wchar_t iso_8859_3[] = {
d6dcf6c6 76 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7,
77 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B,
78 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
79 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C,
80 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7,
81 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
82 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
83 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
84 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7,
85 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
86 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
87 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9
88};
89
90/* ISO/IEC 8859-4:1998 (Latin-4, "North European") */
c4399982 91static const wchar_t iso_8859_4[] = {
d6dcf6c6 92 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
93 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
94 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
95 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
96 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
97 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
98 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
99 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
100 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
101 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
102 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
103 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9
104};
105
bc9f5888 106/* ISO/IEC 8859-5:1999 (Latin/Cyrillic) */
c4399982 107static const wchar_t iso_8859_5[] = {
d6dcf6c6 108 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
109 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
110 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
111 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
112 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
113 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
114 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
115 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
116 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
117 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
118 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
119 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F
120};
121
bc9f5888 122/* ISO/IEC 8859-6:1999 (Latin/Arabic) */
c4399982 123static const wchar_t iso_8859_6[] = {
d6dcf6c6 124 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD,
125 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD,
126 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
127 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F,
128 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
129 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
130 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
131 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
132 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
133 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
134 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
135 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
136};
137
138/* ISO 8859-7:1987 (Latin/Greek) */
c4399982 139static const wchar_t iso_8859_7[] = {
d6dcf6c6 140 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
141 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
142 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
143 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
144 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
145 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
146 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
147 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
148 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
149 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
150 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
151 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD
152};
153
154/* ISO/IEC 8859-8:1999 (Latin/Hebrew) */
c4399982 155static const wchar_t iso_8859_8[] = {
d6dcf6c6 156 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
157 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
158 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
159 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
160 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
161 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
162 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
163 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
164 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
165 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
166 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
167 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD
168};
169
170/* ISO/IEC 8859-9:1999 (Latin-5, "Turkish") */
c4399982 171static const wchar_t iso_8859_9[] = {
d6dcf6c6 172 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
173 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
174 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
175 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
176 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
177 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
178 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
179 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
180 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
181 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
182 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
183 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
184};
185
186/* ISO 8859-10:1993? (Latin-6, "Nordic" [Sami, Inuit, Icelandic]) */
187/* Translation table from RDB. unicode.org (ISO/IEC 8859-10:1998) has
188 * U+2015 (HORIZONTAL BAR) at codepoint 0xBD instead
189 * (U+2014 is EM DASH). -- jtn */
c4399982 190static const wchar_t iso_8859_10[] = {
875b193f 191 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
192 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
193 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
194 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B,
195 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
196 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
197 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
198 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
199 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
200 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
201 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
202 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138
203};
204
6a3d95c7 205/* ISO/IEC 8859-11:2001 ("Thai", "TIS620") */
c4399982 206static const wchar_t iso_8859_11[] = {
875b193f 207 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
208 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
209 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
210 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
211 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
212 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
213 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
214 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
215 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
216 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
217 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
218 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
219};
220
d6dcf6c6 221/* ISO/IEC 8859-13:1998 (Latin-7, "Baltic Rim") */
c4399982 222static const wchar_t iso_8859_13[] = {
875b193f 223 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7,
224 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
225 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7,
226 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
227 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
228 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
229 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
230 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
231 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
232 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
233 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
234 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019
235};
236
d6dcf6c6 237/* ISO/IEC 8859-14:1998 (Latin-8, "Celtic", "Gaelic/Welsh") */
c4399982 238static const wchar_t iso_8859_14[] = {
875b193f 239 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7,
240 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
241 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56,
242 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
243 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
244 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
245 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A,
246 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
247 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
248 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
249 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
250 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF
251};
252
d6dcf6c6 253/* ISO/IEC 8859-15:1999 (Latin-9 aka -0, "euro") */
c4399982 254static const wchar_t iso_8859_15[] = {
d6dcf6c6 255 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
256 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
257 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
258 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
259 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
260 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
261 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
262 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
263 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
264 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
265 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
266 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
875b193f 267};
268
d6dcf6c6 269/* ISO/IEC 8859-16:2001 (Latin-10, "Balkan") */
c4399982 270static const wchar_t iso_8859_16[] = {
a0c1ddf1 271 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7,
272 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B,
273 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7,
274 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C,
275 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7,
276 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
277 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A,
278 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF,
279 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7,
280 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
281 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B,
282 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF
283};
284
c4399982 285static const wchar_t roman8[] = {
875b193f 286 0x00A0, 0x00C0, 0x00C2, 0x00C8, 0x00CA, 0x00CB, 0x00CE, 0x00CF,
287 0x00B4, 0x02CB, 0x02C6, 0x00A8, 0x02DC, 0x00D9, 0x00DB, 0x20A4,
288 0x00AF, 0x00DD, 0x00FD, 0x00B0, 0x00C7, 0x00E7, 0x00D1, 0x00F1,
289 0x00A1, 0x00BF, 0x00A4, 0x00A3, 0x00A5, 0x00A7, 0x0192, 0x00A2,
290 0x00E2, 0x00EA, 0x00F4, 0x00FB, 0x00E1, 0x00E9, 0x00F3, 0x00FA,
291 0x00E0, 0x00E8, 0x00F2, 0x00F9, 0x00E4, 0x00EB, 0x00F6, 0x00FC,
292 0x00C5, 0x00EE, 0x00D8, 0x00C6, 0x00E5, 0x00ED, 0x00F8, 0x00E6,
293 0x00C4, 0x00EC, 0x00D6, 0x00DC, 0x00C9, 0x00EF, 0x00DF, 0x00D4,
294 0x00C1, 0x00C3, 0x00E3, 0x00D0, 0x00F0, 0x00CD, 0x00CC, 0x00D3,
295 0x00D2, 0x00D5, 0x00F5, 0x0160, 0x0161, 0x00DA, 0x0178, 0x00FF,
296 0x00DE, 0x00FE, 0x00B7, 0x00B5, 0x00B6, 0x00BE, 0x2014, 0x00BC,
297 0x00BD, 0x00AA, 0x00BA, 0x00AB, 0x25A0, 0x00BB, 0x00B1, 0xFFFD
298};
299
c4399982 300static const wchar_t koi8_u[] = {
875b193f 301 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
302 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
303 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248,
304 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
305 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
306 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
307 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
308 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
309 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
310 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
311 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
312 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
313 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
314 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
315 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
316 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
317};
318
c4399982 319static const wchar_t vscii[] = {
875b193f 320 0x0000, 0x0001, 0x1EB2, 0x0003, 0x0004, 0x1EB4, 0x1EAA, 0x0007,
321 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
322 0x0010, 0x0011, 0x0012, 0x0013, 0x1EF6, 0x0015, 0x0016, 0x0017,
323 0x0018, 0x1EF8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1EF4, 0x001f,
324 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
325 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
326 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
327 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
328 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
329 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
330 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
331 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
332 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
333 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
334 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
335 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007f,
336 0x1EA0, 0x1EAE, 0x1EB0, 0x1EB6, 0x1EA4, 0x1EA6, 0x1EA8, 0x1EAC,
337 0x1EBC, 0x1EB8, 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, 0x1EC6, 0x1ED0,
338 0x1ED2, 0x1ED4, 0x1ED6, 0x1ED8, 0x1EE2, 0x1EDA, 0x1EDC, 0x1EDE,
339 0x1ECA, 0x1ECE, 0x1ECC, 0x1EC8, 0x1EE6, 0x0168, 0x1EE4, 0x1EF2,
340 0x00D5, 0x1EAF, 0x1EB1, 0x1EB7, 0x1EA5, 0x1EA7, 0x1EA8, 0x1EAD,
341 0x1EBD, 0x1EB9, 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, 0x1EC7, 0x1ED1,
342 0x1ED3, 0x1ED5, 0x1ED7, 0x1EE0, 0x01A0, 0x1ED9, 0x1EDD, 0x1EDF,
343 0x1ECB, 0x1EF0, 0x1EE8, 0x1EEA, 0x1EEC, 0x01A1, 0x1EDB, 0x01AF,
344 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x1EA2, 0x0102, 0x1EB3, 0x1EB5,
345 0x00C8, 0x00C9, 0x00CA, 0x1EBA, 0x00CC, 0x00CD, 0x0128, 0x1EF3,
346 0x0110, 0x1EE9, 0x00D2, 0x00D3, 0x00D4, 0x1EA1, 0x1EF7, 0x1EEB,
347 0x1EED, 0x00D9, 0x00DA, 0x1EF9, 0x1EF5, 0x00DD, 0x1EE1, 0x01B0,
348 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x1EA3, 0x0103, 0x1EEF, 0x1EAB,
349 0x00E8, 0x00E9, 0x00EA, 0x1EBB, 0x00EC, 0x00ED, 0x0129, 0x1EC9,
350 0x0111, 0x1EF1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x1ECF, 0x1ECD,
351 0x1EE5, 0x00F9, 0x00FA, 0x0169, 0x1EE7, 0x00FD, 0x1EE3, 0x1EEE
352};
353
c4399982 354static const wchar_t dec_mcs[] = {
875b193f 355 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0xFFFD, 0x00A5, 0xFFFD, 0x00A7,
356 0x00A4, 0x00A9, 0x00AA, 0x00AB, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
357 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0xFFFD, 0x00B5, 0x00B6, 0x00B7,
358 0xFFFD, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0xFFFD, 0x00BF,
359 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
360 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
361 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0152,
362 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0178, 0xFFFD, 0x00DF,
363 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
364 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
365 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0153,
366 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FF, 0xFFFD, 0xFFFD
367};
368
369struct cp_list_item {
4eeb7d09 370 char *name;
371 int codepage;
372 int cp_size;
c4399982 373 const wchar_t *cp_table;
875b193f 374};
375
c4399982 376static const struct cp_list_item cp_list[] = {
d6dcf6c6 377 {"ISO-8859-1:1998 (Latin-1, West Europe)", 0, 96, iso_8859_1},
378 {"ISO-8859-2:1999 (Latin-2, East Europe)", 0, 96, iso_8859_2},
379 {"ISO-8859-3:1999 (Latin-3, South Europe)", 0, 96, iso_8859_3},
380 {"ISO-8859-4:1998 (Latin-4, North Europe)", 0, 96, iso_8859_4},
381 {"ISO-8859-5:1999 (Latin/Cyrillic)", 0, 96, iso_8859_5},
382 {"ISO-8859-6:1999 (Latin/Arabic)", 0, 96, iso_8859_6},
383 {"ISO-8859-7:1987 (Latin/Greek)", 0, 96, iso_8859_7},
384 {"ISO-8859-8:1999 (Latin/Hebrew)", 0, 96, iso_8859_8},
385 {"ISO-8859-9:1999 (Latin-5, Turkish)", 0, 96, iso_8859_9},
386 {"ISO-8859-10:1993 (Latin-6, Nordic)", 0, 96, iso_8859_10},
eec8f73c 387 {"ISO-8859-11:2001 (Latin/Thai)", 0, 96, iso_8859_11},
d6dcf6c6 388 {"ISO-8859-13:1998 (Latin-7, Baltic)", 0, 96, iso_8859_13},
389 {"ISO-8859-14:1998 (Latin-8, Celtic)", 0, 96, iso_8859_14},
390 {"ISO-8859-15:1999 (Latin-9, \"euro\")", 0, 96, iso_8859_15},
391 {"ISO-8859-16:2001 (Latin-10, Balkan)", 0, 96, iso_8859_16},
875b193f 392
393 {"UTF-8", CP_UTF8},
394
395 {"KOI8-U", 0, 128, koi8_u},
396 {"KOI8-R", 20866},
397 {"HP-ROMAN8", 0, 96, roman8},
398 {"VSCII", 0, 256, vscii},
399 {"DEC-MCS", 0, 96, dec_mcs},
400
401 {"Win1250 (Central European)", 1250},
402 {"Win1251 (Cyrillic)", 1251},
403 {"Win1252 (Western)", 1252},
404 {"Win1253 (Greek)", 1253},
405 {"Win1254 (Turkish)", 1254},
406 {"Win1255 (Hebrew)", 1255},
407 {"Win1256 (Arabic)", 1256},
408 {"Win1257 (Baltic)", 1257},
409 {"Win1258 (Vietnamese)", 1258},
410
b8ae1f0f 411 {"CP437", 437},
875b193f 412 {"CP819", 28591},
413 {"CP878", 20866},
b8ae1f0f 414
415 {"Use font encoding", -1},
416
875b193f 417 {0, 0}
418};
4eeb7d09 419
420static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr);
421
5def7522 422void init_ucs(void)
4eeb7d09 423{
424 int i, j;
425 int used_dtf = 0;
426 char tbuf[256];
dc3c8261 427
4eeb7d09 428 for (i = 0; i < 256; i++)
429 tbuf[i] = i;
430
431 /* Decide on the Line and Font codepages */
432 line_codepage = decode_codepage(cfg.line_codepage);
433
8f22582c 434 if (font_codepage <= 0) {
435 font_codepage=0;
436 dbcs_screenfont=0;
437 }
438
4eeb7d09 439 if (cfg.vtmode == VT_OEMONLY) {
440 font_codepage = 437;
441 dbcs_screenfont = 0;
442 if (line_codepage <= 0)
443 line_codepage = GetACP();
444 } else if (line_codepage <= 0)
445 line_codepage = font_codepage;
4eeb7d09 446
447 /* Collect screen font ucs table */
8f22582c 448 if (dbcs_screenfont || font_codepage == 0) {
4eeb7d09 449 get_unitab(font_codepage, unitab_font, 2);
450 for (i = 128; i < 256; i++)
451 unitab_font[i] = (WCHAR) (ATTR_ACP + i);
452 } else {
453 get_unitab(font_codepage, unitab_font, 1);
454
455 /* CP437 fonts are often broken ... */
456 if (font_codepage == 437)
457 unitab_font[0] = unitab_font[255] = 0xFFFF;
458 }
459 if (cfg.vtmode == VT_XWINDOWS)
460 memcpy(unitab_font + 1, unitab_xterm_std,
461 sizeof(unitab_xterm_std));
462
463 /* Collect OEMCP ucs table */
464 get_unitab(CP_OEMCP, unitab_oemcp, 1);
465
d3cb5465 466 /* Collect CP437 ucs table for SCO acs */
467 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
468 memcpy(unitab_scoacs, unitab_oemcp, sizeof(unitab_scoacs));
469 else
470 get_unitab(437, unitab_scoacs, 1);
471
4eeb7d09 472 /* Collect line set ucs table */
473 if (line_codepage == font_codepage &&
8f22582c 474 (dbcs_screenfont || cfg.vtmode == VT_POORMAN || font_codepage==0)) {
4eeb7d09 475
476 /* For DBCS and POOR fonts force direct to font */
477 used_dtf = 1;
478 for (i = 0; i < 32; i++)
479 unitab_line[i] = (WCHAR) i;
480 for (i = 32; i < 256; i++)
481 unitab_line[i] = (WCHAR) (ATTR_ACP + i);
482 unitab_line[127] = (WCHAR) 127;
483 } else {
484 get_unitab(line_codepage, unitab_line, 0);
485 }
486
487#if 0
488 debug(
489 ("Line cp%d, Font cp%d%s\n", line_codepage, font_codepage,
490 dbcs_screenfont ? " DBCS" : ""));
491
492 for (i = 0; i < 256; i += 16) {
493 for (j = 0; j < 16; j++) {
494 debug(("%04x%s", unitab_line[i + j], j == 15 ? "" : ","));
495 }
496 debug(("\n"));
497 }
498#endif
499
500 /* VT100 graphics - NB: Broken for non-ascii CP's */
501 memcpy(unitab_xterm, unitab_line, sizeof(unitab_xterm));
502 memcpy(unitab_xterm + '`', unitab_xterm_std, sizeof(unitab_xterm_std));
503 unitab_xterm['_'] = ' ';
504
505 /* Generate UCS ->line page table. */
506 if (uni_tbl) {
507 for (i = 0; i < 256; i++)
508 if (uni_tbl[i])
509 sfree(uni_tbl[i]);
510 sfree(uni_tbl);
511 uni_tbl = 0;
512 }
513 if (!used_dtf) {
514 for (i = 0; i < 256; i++) {
515 if (DIRECT_CHAR(unitab_line[i]))
516 continue;
517 if (DIRECT_FONT(unitab_line[i]))
518 continue;
519 if (!uni_tbl) {
520 uni_tbl = smalloc(256 * sizeof(char *));
521 memset(uni_tbl, 0, 256 * sizeof(char *));
522 }
523 j = ((unitab_line[i] >> 8) & 0xFF);
524 if (!uni_tbl[j]) {
525 uni_tbl[j] = smalloc(256 * sizeof(char));
526 memset(uni_tbl[j], 0, 256 * sizeof(char));
527 }
528 uni_tbl[j][unitab_line[i] & 0xFF] = i;
529 }
530 }
531
532 /* Find the line control characters. */
533 for (i = 0; i < 256; i++)
534 if (unitab_line[i] < ' '
535 || (unitab_line[i] >= 0x7F && unitab_line[i] < 0xA0))
536 unitab_ctrl[i] = i;
537 else
538 unitab_ctrl[i] = 0xFF;
539
540 /* Generate line->screen direct conversion links. */
d3cb5465 541 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
542 link_font(unitab_scoacs, unitab_oemcp, ATTR_OEMCP);
543
4eeb7d09 544 link_font(unitab_line, unitab_font, ATTR_ACP);
d3cb5465 545 link_font(unitab_scoacs, unitab_font, ATTR_ACP);
4eeb7d09 546 link_font(unitab_xterm, unitab_font, ATTR_ACP);
547
548 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS) {
549 link_font(unitab_line, unitab_oemcp, ATTR_OEMCP);
550 link_font(unitab_xterm, unitab_oemcp, ATTR_OEMCP);
551 }
552
5a73255e 553 if (dbcs_screenfont && font_codepage != line_codepage) {
554 /* F***ing Microsoft fonts, Japanese and Korean codepage fonts
555 * have a currency symbol at 0x5C but their unicode value is
556 * still given as U+005C not the correct U+00A5. */
557 unitab_line['\\'] = ATTR_OEMCP + '\\';
558 }
559
4eeb7d09 560 /* Last chance, if !unicode then try poorman links. */
561 if (cfg.vtmode != VT_UNICODE) {
d3cb5465 562 static char poorman_scoacs[] =
563 "CueaaaaceeeiiiAAE**ooouuyOUc$YPsaiounNao?++**!<>###||||++||++++++--|-+||++--|-+----++++++++##||#aBTPEsyt******EN=+><++-=... n2* ";
4eeb7d09 564 static char poorman_latin1[] =
565 " !cL.Y|S\"Ca<--R~o+23'u|.,1o>///?AAAAAAACEEEEIIIIDNOOOOOxOUUUUYPBaaaaaaaceeeeiiiionooooo/ouuuuypy";
566 static char poorman_vt100[] = "*#****o~**+++++-----++++|****L.";
567
568 for (i = 160; i < 256; i++)
569 if (!DIRECT_FONT(unitab_line[i]) &&
570 unitab_line[i] >= 160 && unitab_line[i] < 256)
571 unitab_line[i] = (WCHAR) (ATTR_ACP
572 + poorman_latin1[unitab_line[i] -
573 160]);
574 for (i = 96; i < 127; i++)
575 if (!DIRECT_FONT(unitab_xterm[i]))
576 unitab_xterm[i] =
577 (WCHAR) (ATTR_ACP + poorman_vt100[i - 96]);
d3cb5465 578 for(i=128;i<256;i++)
579 if (!DIRECT_FONT(unitab_scoacs[i]))
580 unitab_scoacs[i] =
581 (WCHAR) (ATTR_ACP + poorman_scoacs[i - 128]);
4eeb7d09 582 }
583}
584
585static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr)
586{
614e8f54 587 int font_index, line_index, i;
588 for (line_index = 0; line_index < 256; line_index++) {
589 if (DIRECT_FONT(line_tbl[line_index]))
4eeb7d09 590 continue;
614e8f54 591 for(i = 0; i < 256; i++) {
592 font_index = ((32 + i) & 0xFF);
593 if (line_tbl[line_index] == font_tbl[font_index]) {
594 line_tbl[line_index] = (WCHAR) (attr + font_index);
4eeb7d09 595 break;
596 }
597 }
598 }
599}
600
a9c02454 601wchar_t xlat_uskbd2cyrllic(int ch)
602{
603 static wchar_t cyrtab[] = {
604 0, 1, 2, 3, 4, 5, 6, 7,
605 8, 9, 10, 11, 12, 13, 14, 15,
606 16, 17, 18, 19, 20, 21, 22, 23,
607 24, 25, 26, 27, 28, 29, 30, 31,
608 32, 33, 0x042d, 35, 36, 37, 38, 0x044d,
609 40, 41, 42, 0x0406, 0x0431, 0x0454, 0x044e, 0x002e,
610 48, 49, 50, 51, 52, 53, 54, 55,
611 56, 57, 0x0416, 0x0436, 0x0411, 0x0456, 0x042e, 0x002c,
612 64, 0x0424, 0x0418, 0x0421, 0x0412, 0x0423, 0x0410, 0x041f,
613 0x0420, 0x0428, 0x041e, 0x041b, 0x0414, 0x042c, 0x0422, 0x0429,
614 0x0417, 0x0419, 0x041a, 0x042b, 0x0415, 0x0413, 0x041c, 0x0426,
615 0x0427, 0x041d, 0x042f, 0x0445, 0x0457, 0x044a, 94, 0x0404,
616 96, 0x0444, 0x0438, 0x0441, 0x0432, 0x0443, 0x0430, 0x043f,
617 0x0440, 0x0448, 0x043e, 0x043b, 0x0434, 0x044c, 0x0442, 0x0449,
618 0x0437, 0x0439, 0x043a, 0x044b, 0x0435, 0x0433, 0x043c, 0x0446,
619 0x0447, 0x043d, 0x044f, 0x0425, 0x0407, 0x042a, 126, 127
620 };
621 return cyrtab[ch&0x7F];
622}
623
4eeb7d09 624int check_compose(int first, int second)
625{
626
627 static struct {
628 char first, second;
629 wchar_t composed;
630 } composetbl[] = {
631 {
632 0x2b, 0x2b, 0x0023}, {
633 0x41, 0x41, 0x0040}, {
634 0x28, 0x28, 0x005b}, {
635 0x2f, 0x2f, 0x005c}, {
636 0x29, 0x29, 0x005d}, {
637 0x28, 0x2d, 0x007b}, {
638 0x2d, 0x29, 0x007d}, {
639 0x2f, 0x5e, 0x007c}, {
640 0x21, 0x21, 0x00a1}, {
641 0x43, 0x2f, 0x00a2}, {
642 0x43, 0x7c, 0x00a2}, {
643 0x4c, 0x2d, 0x00a3}, {
5a73255e 644 0x4c, 0x3d, 0x20a4}, {
4eeb7d09 645 0x58, 0x4f, 0x00a4}, {
646 0x58, 0x30, 0x00a4}, {
647 0x59, 0x2d, 0x00a5}, {
648 0x59, 0x3d, 0x00a5}, {
649 0x7c, 0x7c, 0x00a6}, {
650 0x53, 0x4f, 0x00a7}, {
651 0x53, 0x21, 0x00a7}, {
652 0x53, 0x30, 0x00a7}, {
653 0x22, 0x22, 0x00a8}, {
654 0x43, 0x4f, 0x00a9}, {
655 0x43, 0x30, 0x00a9}, {
656 0x41, 0x5f, 0x00aa}, {
657 0x3c, 0x3c, 0x00ab}, {
658 0x2c, 0x2d, 0x00ac}, {
659 0x2d, 0x2d, 0x00ad}, {
660 0x52, 0x4f, 0x00ae}, {
661 0x2d, 0x5e, 0x00af}, {
662 0x30, 0x5e, 0x00b0}, {
663 0x2b, 0x2d, 0x00b1}, {
664 0x32, 0x5e, 0x00b2}, {
665 0x33, 0x5e, 0x00b3}, {
666 0x27, 0x27, 0x00b4}, {
667 0x2f, 0x55, 0x00b5}, {
668 0x50, 0x21, 0x00b6}, {
669 0x2e, 0x5e, 0x00b7}, {
670 0x2c, 0x2c, 0x00b8}, {
671 0x31, 0x5e, 0x00b9}, {
672 0x4f, 0x5f, 0x00ba}, {
673 0x3e, 0x3e, 0x00bb}, {
674 0x31, 0x34, 0x00bc}, {
675 0x31, 0x32, 0x00bd}, {
676 0x33, 0x34, 0x00be}, {
677 0x3f, 0x3f, 0x00bf}, {
678 0x60, 0x41, 0x00c0}, {
679 0x27, 0x41, 0x00c1}, {
680 0x5e, 0x41, 0x00c2}, {
681 0x7e, 0x41, 0x00c3}, {
682 0x22, 0x41, 0x00c4}, {
683 0x2a, 0x41, 0x00c5}, {
684 0x41, 0x45, 0x00c6}, {
685 0x2c, 0x43, 0x00c7}, {
686 0x60, 0x45, 0x00c8}, {
687 0x27, 0x45, 0x00c9}, {
688 0x5e, 0x45, 0x00ca}, {
689 0x22, 0x45, 0x00cb}, {
690 0x60, 0x49, 0x00cc}, {
691 0x27, 0x49, 0x00cd}, {
692 0x5e, 0x49, 0x00ce}, {
693 0x22, 0x49, 0x00cf}, {
694 0x2d, 0x44, 0x00d0}, {
695 0x7e, 0x4e, 0x00d1}, {
696 0x60, 0x4f, 0x00d2}, {
697 0x27, 0x4f, 0x00d3}, {
698 0x5e, 0x4f, 0x00d4}, {
699 0x7e, 0x4f, 0x00d5}, {
700 0x22, 0x4f, 0x00d6}, {
701 0x58, 0x58, 0x00d7}, {
702 0x2f, 0x4f, 0x00d8}, {
703 0x60, 0x55, 0x00d9}, {
704 0x27, 0x55, 0x00da}, {
705 0x5e, 0x55, 0x00db}, {
706 0x22, 0x55, 0x00dc}, {
707 0x27, 0x59, 0x00dd}, {
708 0x48, 0x54, 0x00de}, {
709 0x73, 0x73, 0x00df}, {
710 0x60, 0x61, 0x00e0}, {
711 0x27, 0x61, 0x00e1}, {
712 0x5e, 0x61, 0x00e2}, {
713 0x7e, 0x61, 0x00e3}, {
714 0x22, 0x61, 0x00e4}, {
715 0x2a, 0x61, 0x00e5}, {
716 0x61, 0x65, 0x00e6}, {
717 0x2c, 0x63, 0x00e7}, {
718 0x60, 0x65, 0x00e8}, {
719 0x27, 0x65, 0x00e9}, {
720 0x5e, 0x65, 0x00ea}, {
721 0x22, 0x65, 0x00eb}, {
722 0x60, 0x69, 0x00ec}, {
723 0x27, 0x69, 0x00ed}, {
724 0x5e, 0x69, 0x00ee}, {
725 0x22, 0x69, 0x00ef}, {
726 0x2d, 0x64, 0x00f0}, {
727 0x7e, 0x6e, 0x00f1}, {
728 0x60, 0x6f, 0x00f2}, {
729 0x27, 0x6f, 0x00f3}, {
730 0x5e, 0x6f, 0x00f4}, {
731 0x7e, 0x6f, 0x00f5}, {
732 0x22, 0x6f, 0x00f6}, {
733 0x3a, 0x2d, 0x00f7}, {
734 0x6f, 0x2f, 0x00f8}, {
735 0x60, 0x75, 0x00f9}, {
736 0x27, 0x75, 0x00fa}, {
737 0x5e, 0x75, 0x00fb}, {
738 0x22, 0x75, 0x00fc}, {
739 0x27, 0x79, 0x00fd}, {
740 0x68, 0x74, 0x00fe}, {
741 0x22, 0x79, 0x00ff},
742 /* Unicode extras. */
743 {
744 0x6f, 0x65, 0x0153}, {
745 0x4f, 0x45, 0x0152},
746 /* Compose pairs from UCS */
747 {
748 0x41, 0x2D, 0x0100}, {
749 0x61, 0x2D, 0x0101}, {
750 0x43, 0x27, 0x0106}, {
751 0x63, 0x27, 0x0107}, {
752 0x43, 0x5E, 0x0108}, {
753 0x63, 0x5E, 0x0109}, {
754 0x45, 0x2D, 0x0112}, {
755 0x65, 0x2D, 0x0113}, {
756 0x47, 0x5E, 0x011C}, {
757 0x67, 0x5E, 0x011D}, {
758 0x47, 0x2C, 0x0122}, {
759 0x67, 0x2C, 0x0123}, {
760 0x48, 0x5E, 0x0124}, {
761 0x68, 0x5E, 0x0125}, {
762 0x49, 0x7E, 0x0128}, {
763 0x69, 0x7E, 0x0129}, {
764 0x49, 0x2D, 0x012A}, {
765 0x69, 0x2D, 0x012B}, {
766 0x4A, 0x5E, 0x0134}, {
767 0x6A, 0x5E, 0x0135}, {
768 0x4B, 0x2C, 0x0136}, {
769 0x6B, 0x2C, 0x0137}, {
770 0x4C, 0x27, 0x0139}, {
771 0x6C, 0x27, 0x013A}, {
772 0x4C, 0x2C, 0x013B}, {
773 0x6C, 0x2C, 0x013C}, {
774 0x4E, 0x27, 0x0143}, {
775 0x6E, 0x27, 0x0144}, {
776 0x4E, 0x2C, 0x0145}, {
777 0x6E, 0x2C, 0x0146}, {
778 0x4F, 0x2D, 0x014C}, {
779 0x6F, 0x2D, 0x014D}, {
780 0x52, 0x27, 0x0154}, {
781 0x72, 0x27, 0x0155}, {
782 0x52, 0x2C, 0x0156}, {
783 0x72, 0x2C, 0x0157}, {
784 0x53, 0x27, 0x015A}, {
785 0x73, 0x27, 0x015B}, {
786 0x53, 0x5E, 0x015C}, {
787 0x73, 0x5E, 0x015D}, {
788 0x53, 0x2C, 0x015E}, {
789 0x73, 0x2C, 0x015F}, {
790 0x54, 0x2C, 0x0162}, {
791 0x74, 0x2C, 0x0163}, {
792 0x55, 0x7E, 0x0168}, {
793 0x75, 0x7E, 0x0169}, {
794 0x55, 0x2D, 0x016A}, {
795 0x75, 0x2D, 0x016B}, {
796 0x55, 0x2A, 0x016E}, {
797 0x75, 0x2A, 0x016F}, {
798 0x57, 0x5E, 0x0174}, {
799 0x77, 0x5E, 0x0175}, {
800 0x59, 0x5E, 0x0176}, {
801 0x79, 0x5E, 0x0177}, {
802 0x59, 0x22, 0x0178}, {
803 0x5A, 0x27, 0x0179}, {
804 0x7A, 0x27, 0x017A}, {
805 0x47, 0x27, 0x01F4}, {
806 0x67, 0x27, 0x01F5}, {
807 0x4E, 0x60, 0x01F8}, {
808 0x6E, 0x60, 0x01F9}, {
809 0x45, 0x2C, 0x0228}, {
810 0x65, 0x2C, 0x0229}, {
811 0x59, 0x2D, 0x0232}, {
812 0x79, 0x2D, 0x0233}, {
813 0x44, 0x2C, 0x1E10}, {
814 0x64, 0x2C, 0x1E11}, {
815 0x47, 0x2D, 0x1E20}, {
816 0x67, 0x2D, 0x1E21}, {
817 0x48, 0x22, 0x1E26}, {
818 0x68, 0x22, 0x1E27}, {
819 0x48, 0x2C, 0x1E28}, {
820 0x68, 0x2C, 0x1E29}, {
821 0x4B, 0x27, 0x1E30}, {
822 0x6B, 0x27, 0x1E31}, {
823 0x4D, 0x27, 0x1E3E}, {
824 0x6D, 0x27, 0x1E3F}, {
825 0x50, 0x27, 0x1E54}, {
826 0x70, 0x27, 0x1E55}, {
827 0x56, 0x7E, 0x1E7C}, {
828 0x76, 0x7E, 0x1E7D}, {
829 0x57, 0x60, 0x1E80}, {
830 0x77, 0x60, 0x1E81}, {
831 0x57, 0x27, 0x1E82}, {
832 0x77, 0x27, 0x1E83}, {
833 0x57, 0x22, 0x1E84}, {
834 0x77, 0x22, 0x1E85}, {
835 0x58, 0x22, 0x1E8C}, {
836 0x78, 0x22, 0x1E8D}, {
837 0x5A, 0x5E, 0x1E90}, {
838 0x7A, 0x5E, 0x1E91}, {
839 0x74, 0x22, 0x1E97}, {
840 0x77, 0x2A, 0x1E98}, {
841 0x79, 0x2A, 0x1E99}, {
842 0x45, 0x7E, 0x1EBC}, {
843 0x65, 0x7E, 0x1EBD}, {
844 0x59, 0x60, 0x1EF2}, {
845 0x79, 0x60, 0x1EF3}, {
846 0x59, 0x7E, 0x1EF8}, {
847 0x79, 0x7E, 0x1EF9},
848 /* Compatible/possibles from UCS */
849 {
850 0x49, 0x4A, 0x0132}, {
851 0x69, 0x6A, 0x0133}, {
852 0x4C, 0x4A, 0x01C7}, {
853 0x4C, 0x6A, 0x01C8}, {
854 0x6C, 0x6A, 0x01C9}, {
855 0x4E, 0x4A, 0x01CA}, {
856 0x4E, 0x6A, 0x01CB}, {
857 0x6E, 0x6A, 0x01CC}, {
858 0x44, 0x5A, 0x01F1}, {
859 0x44, 0x7A, 0x01F2}, {
860 0x64, 0x7A, 0x01F3}, {
861 0x2E, 0x2E, 0x2025}, {
862 0x21, 0x21, 0x203C}, {
863 0x3F, 0x21, 0x2048}, {
864 0x21, 0x3F, 0x2049}, {
865 0x52, 0x73, 0x20A8}, {
866 0x4E, 0x6F, 0x2116}, {
867 0x53, 0x4D, 0x2120}, {
868 0x54, 0x4D, 0x2122}, {
869 0x49, 0x49, 0x2161}, {
870 0x49, 0x56, 0x2163}, {
871 0x56, 0x49, 0x2165}, {
872 0x49, 0x58, 0x2168}, {
873 0x58, 0x49, 0x216A}, {
874 0x69, 0x69, 0x2171}, {
875 0x69, 0x76, 0x2173}, {
876 0x76, 0x69, 0x2175}, {
877 0x69, 0x78, 0x2178}, {
878 0x78, 0x69, 0x217A}, {
879 0x31, 0x30, 0x2469}, {
880 0x31, 0x31, 0x246A}, {
881 0x31, 0x32, 0x246B}, {
882 0x31, 0x33, 0x246C}, {
883 0x31, 0x34, 0x246D}, {
884 0x31, 0x35, 0x246E}, {
885 0x31, 0x36, 0x246F}, {
886 0x31, 0x37, 0x2470}, {
887 0x31, 0x38, 0x2471}, {
888 0x31, 0x39, 0x2472}, {
889 0x32, 0x30, 0x2473}, {
890 0x31, 0x2E, 0x2488}, {
891 0x32, 0x2E, 0x2489}, {
892 0x33, 0x2E, 0x248A}, {
893 0x34, 0x2E, 0x248B}, {
894 0x35, 0x2E, 0x248C}, {
895 0x36, 0x2E, 0x248D}, {
896 0x37, 0x2E, 0x248E}, {
897 0x38, 0x2E, 0x248F}, {
898 0x39, 0x2E, 0x2490}, {
899 0x64, 0x61, 0x3372}, {
900 0x41, 0x55, 0x3373}, {
901 0x6F, 0x56, 0x3375}, {
902 0x70, 0x63, 0x3376}, {
903 0x70, 0x41, 0x3380}, {
904 0x6E, 0x41, 0x3381}, {
905 0x6D, 0x41, 0x3383}, {
906 0x6B, 0x41, 0x3384}, {
907 0x4B, 0x42, 0x3385}, {
908 0x4D, 0x42, 0x3386}, {
909 0x47, 0x42, 0x3387}, {
910 0x70, 0x46, 0x338A}, {
911 0x6E, 0x46, 0x338B}, {
912 0x6D, 0x67, 0x338E}, {
913 0x6B, 0x67, 0x338F}, {
914 0x48, 0x7A, 0x3390}, {
915 0x66, 0x6D, 0x3399}, {
916 0x6E, 0x6D, 0x339A}, {
917 0x6D, 0x6D, 0x339C}, {
918 0x63, 0x6D, 0x339D}, {
919 0x6B, 0x6D, 0x339E}, {
920 0x50, 0x61, 0x33A9}, {
921 0x70, 0x73, 0x33B0}, {
922 0x6E, 0x73, 0x33B1}, {
923 0x6D, 0x73, 0x33B3}, {
924 0x70, 0x56, 0x33B4}, {
925 0x6E, 0x56, 0x33B5}, {
926 0x6D, 0x56, 0x33B7}, {
927 0x6B, 0x56, 0x33B8}, {
928 0x4D, 0x56, 0x33B9}, {
929 0x70, 0x57, 0x33BA}, {
930 0x6E, 0x57, 0x33BB}, {
931 0x6D, 0x57, 0x33BD}, {
932 0x6B, 0x57, 0x33BE}, {
933 0x4D, 0x57, 0x33BF}, {
934 0x42, 0x71, 0x33C3}, {
935 0x63, 0x63, 0x33C4}, {
936 0x63, 0x64, 0x33C5}, {
937 0x64, 0x42, 0x33C8}, {
938 0x47, 0x79, 0x33C9}, {
939 0x68, 0x61, 0x33CA}, {
940 0x48, 0x50, 0x33CB}, {
941 0x69, 0x6E, 0x33CC}, {
942 0x4B, 0x4B, 0x33CD}, {
943 0x4B, 0x4D, 0x33CE}, {
944 0x6B, 0x74, 0x33CF}, {
945 0x6C, 0x6D, 0x33D0}, {
946 0x6C, 0x6E, 0x33D1}, {
947 0x6C, 0x78, 0x33D3}, {
948 0x6D, 0x62, 0x33D4}, {
949 0x50, 0x48, 0x33D7}, {
950 0x50, 0x52, 0x33DA}, {
951 0x73, 0x72, 0x33DB}, {
952 0x53, 0x76, 0x33DC}, {
953 0x57, 0x62, 0x33DD}, {
954 0x66, 0x66, 0xFB00}, {
955 0x66, 0x69, 0xFB01}, {
956 0x66, 0x6C, 0xFB02}, {
957 0x73, 0x74, 0xFB06}, {
958 0, 0, 0}
959 }, *c;
960
961 static int recurse = 0;
962 int nc = -1;
963
964 for (c = composetbl; c->first; c++) {
965 if (c->first == first && c->second == second)
966 return c->composed;
967 }
968
969 if (recurse == 0) {
970 recurse = 1;
971 nc = check_compose(second, first);
972 if (nc == -1)
973 nc = check_compose(toupper(first), toupper(second));
974 if (nc == -1)
975 nc = check_compose(toupper(second), toupper(first));
976 recurse = 0;
977 }
978 return nc;
979}
980
981int decode_codepage(char *cp_name)
982{
983 char *s, *d;
c4399982 984 const struct cp_list_item *cpi;
4eeb7d09 985 int codepage = -1;
4eeb7d09 986 CPINFO cpinfo;
987
b8ae1f0f 988 if (!*cp_name) {
989 /*
990 * Here we select a plausible default code page based on
991 * the locale the user is in. We wish to select an ISO code
992 * page or appropriate local default _rather_ than go with
993 * the Win125* series, because it's more important to have
994 * CSI and friends enabled by default than the ghastly
995 * Windows extra quote characters, and because it's more
996 * likely the user is connecting to a remote server that
997 * does something Unixy or VMSy and hence standards-
998 * compliant than that they're connecting back to a Windows
999 * box using horrible nonstandard charsets.
1000 *
1001 * Accordingly, Robert de Bath suggests a method for
1002 * picking a default character set that runs as follows:
1003 * first call GetACP to get the system's ANSI code page
1004 * identifier, and translate as follows:
1005 *
1006 * 1250 -> ISO 8859-2
1007 * 1251 -> KOI8-U
1008 * 1252 -> ISO 8859-1
1009 * 1253 -> ISO 8859-7
1010 * 1254 -> ISO 8859-9
1011 * 1255 -> ISO 8859-8
1012 * 1256 -> ISO 8859-6
1013 * 1257 -> ISO 8859-4
1014 *
1015 * and for anything else, choose direct-to-font.
1016 */
1017 int cp = GetACP();
1018 switch (cp) {
1019 case 1250: cp_name = "ISO-8859-2"; break;
1020 case 1251: cp_name = "KOI8-U"; break;
1021 case 1252: cp_name = "ISO-8859-1"; break;
1022 case 1253: cp_name = "ISO-8859-7"; break;
1023 case 1254: cp_name = "ISO-8859-9"; break;
1024 case 1255: cp_name = "ISO-8859-8"; break;
1025 case 1256: cp_name = "ISO-8859-6"; break;
1026 case 1257: cp_name = "ISO-8859-4"; break;
1027 /* default: leave it blank, which will select -1, direct->font */
1028 }
1029 }
1030
4eeb7d09 1031 if (cp_name && *cp_name)
1032 for (cpi = cp_list; cpi->name; cpi++) {
1033 s = cp_name;
1034 d = cpi->name;
1035 for (;;) {
1036 while (*s && !isalnum(*s) && *s != ':')
1037 s++;
1038 while (*d && !isalnum(*d) && *d != ':')
1039 d++;
1040 if (*s == 0) {
1041 codepage = cpi->codepage;
1042 if (codepage == CP_UTF8)
1043 goto break_break;
792de8f6 1044 if (codepage == -1)
1045 return codepage;
4eeb7d09 1046 if (codepage == 0) {
1047 codepage = 65536 + (cpi - cp_list);
1048 goto break_break;
1049 }
1050
1051 if (GetCPInfo(codepage, &cpinfo) != 0)
1052 goto break_break;
1053 }
274a5b41 1054 if (tolower(*s++) != tolower(*d++))
4eeb7d09 1055 break;
1056 }
1057 }
1058
1059 if (cp_name && *cp_name) {
1060 d = cp_name;
2d466ffd 1061 if (tolower(d[0]) == 'c' && tolower(d[1]) == 'p')
4eeb7d09 1062 d += 2;
2d466ffd 1063 if (tolower(d[0]) == 'i' && tolower(d[1]) == 'b'
1064 && tolower(d[1]) == 'm')
4eeb7d09 1065 d += 3;
1066 for (s = d; *s >= '0' && *s <= '9'; s++);
1067 if (*s == 0 && s != d)
1068 codepage = atoi(d); /* CP999 or IBM999 */
1069
1070 if (codepage == CP_ACP)
1071 codepage = GetACP();
1072 if (codepage == CP_OEMCP)
1073 codepage = GetOEMCP();
1074 if (codepage > 65535)
1075 codepage = -2;
1076 }
1077
1078 break_break:;
1079 if (codepage != -1) {
1080 if (codepage != CP_UTF8 && codepage < 65536) {
1081 if (GetCPInfo(codepage, &cpinfo) == 0) {
1082 codepage = -2;
1083 } else if (cpinfo.MaxCharSize > 1)
1084 codepage = -3;
1085 }
1086 }
1087 if (codepage == -1 && *cp_name)
1088 codepage = -2;
1089 return codepage;
1090}
1091
1092char *cp_name(int codepage)
1093{
c4399982 1094 const struct cp_list_item *cpi, *cpno;
4eeb7d09 1095 static char buf[32];
b8ae1f0f 1096
1097 if (codepage == -1) {
1098 sprintf(buf, "Use font encoding");
1099 return buf;
1100 }
1101
4eeb7d09 1102 if (codepage > 0 && codepage < 65536)
1103 sprintf(buf, "CP%03d", codepage);
1104 else
1105 *buf = 0;
1106
1107 if (codepage >= 65536) {
1108 cpno = 0;
1109 for (cpi = cp_list; cpi->name; cpi++)
1110 if (cpi == cp_list + (codepage - 65536)) {
1111 cpno = cpi;
1112 break;
1113 }
1114 if (cpno)
1115 for (cpi = cp_list; cpi->name; cpi++) {
1116 if (cpno->cp_table == cpi->cp_table)
1117 return cpi->name;
1118 }
1119 } else {
1120 for (cpi = cp_list; cpi->name; cpi++) {
1121 if (codepage == cpi->codepage)
1122 return cpi->name;
1123 }
1124 }
1125 return buf;
1126}
1127
875b193f 1128/*
1129 * Return the nth code page in the list, for use in the GUI
1130 * configurer.
1131 */
1132char *cp_enumerate(int index)
1133{
1134 if (index < 0 || index >= lenof(cp_list))
1135 return NULL;
1136 return cp_list[index].name;
1137}
1138
a7419ea4 1139void get_unitab(int codepage, wchar_t * unitab, int ftype)
4eeb7d09 1140{
1141 char tbuf[4];
1142 int i, max = 256, flg = MB_ERR_INVALID_CHARS;
1143
1144 if (ftype)
1145 flg |= MB_USEGLYPHCHARS;
1146 if (ftype == 2)
1147 max = 128;
1148
d6dcf6c6 1149 if (codepage == CP_UTF8) {
1150 for (i = 0; i < max; i++)
1151 unitab[i] = i;
1152 return;
1153 }
1154
1155 if (codepage == CP_ACP)
4eeb7d09 1156 codepage = GetACP();
1157 else if (codepage == CP_OEMCP)
1158 codepage = GetOEMCP();
1159
1160 if (codepage > 0 && codepage < 65536) {
1161 for (i = 0; i < max; i++) {
1162 tbuf[0] = i;
1163
1709795f 1164 if (mb_to_wc(codepage, flg, tbuf, 1, unitab + i, 1)
4eeb7d09 1165 != 1)
1166 unitab[i] = 0xFFFD;
1167 }
1168 } else {
1169 int j = 256 - cp_list[codepage & 0xFFFF].cp_size;
1170 for (i = 0; i < max; i++)
1171 unitab[i] = i;
1172 for (i = j; i < max; i++)
1173 unitab[i] = cp_list[codepage & 0xFFFF].cp_table[i - j];
1174 }
1175}
5def7522 1176
1177int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
1178 char *mbstr, int mblen, char *defchr, int *defused)
1179{
1180 char *p;
1181 int i;
1182 if (codepage == line_codepage && uni_tbl) {
1183 /* Do this by array lookup if we can. */
1184 if (wclen < 0) {
1185 for (wclen = 0; wcstr[wclen++] ;); /* will include the NUL */
1186 }
1187 for (p = mbstr, i = 0; i < wclen; i++) {
1188 wchar_t ch = wcstr[i];
1189 int by;
1190 char *p1;
1191 if (uni_tbl && (p1 = uni_tbl[(ch >> 8) & 0xFF])
1192 && (by = p1[ch & 0xFF]))
1193 *p++ = by;
1194 else if (ch < 0x80)
1195 *p++ = (char) ch;
1196 else if (defchr) {
1197 int j;
1198 for (j = 0; defchr[j]; j++)
1199 *p++ = defchr[j];
1200 if (defused) *defused = 1;
1201 }
1202#if 1
1203 else
1204 *p++ = '.';
1205#endif
1206 assert(p - mbstr < mblen);
1207 }
1208 return p - mbstr;
1209 } else
1210 return WideCharToMultiByte(codepage, flags, wcstr, wclen,
1211 mbstr, mblen, defchr, defused);
1212}
1213
1214int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
1215 wchar_t *wcstr, int wclen)
1216{
1217 return MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
1218}
1219
1220int is_dbcs_leadbyte(int codepage, char byte)
1221{
1222 return IsDBCSLeadByteEx(codepage, byte);
1223}