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