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