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