Oops. Dirsep in Makefile.cyg should be / not \.
[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>
8
9#include <time.h>
10#include "putty.h"
875b193f 11#include "misc.h"
4eeb7d09 12
4eeb7d09 13/* Character conversion arrays; they are usually taken from windows,
14 * the xterm one has the four scanlines that have no unicode 2.0
dc3c8261 15 * equivalents mapped to their unicode 3.0 locations.
4eeb7d09 16 */
17static char **uni_tbl;
18
19static WCHAR unitab_xterm_std[32] = {
20 0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
21 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
22 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
23 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
24};
25
875b193f 26/*
27 * If the codepage is non-zero it's a window codepage, zero means use a
28 * local codepage. The name is always converted to the first of any
29 * duplicate definitions.
30 */
31
d6dcf6c6 32/*
33 * Tables for ISO-8859-{1-9,13-16} derived from those downloaded
34 * 2001-10-02 from <http://www.unicode.org/Public/MAPPINGS/> -- jtn
35 */
36
37/* XXX: This could be done algorithmically, but I'm not sure it's
38 * worth the hassle -- jtn */
39/* ISO/IEC 8859-1:1998 (Latin-1, "Western", "West European") */
40static wchar_t iso_8859_1[] = {
41 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
42 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
43 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
44 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
45 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
46 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
47 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
48 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
49 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
50 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
51 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
52 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
53};
54
55/* ISO 8859-2:1999 (Latin-2, "Central European", "East European") */
56static wchar_t iso_8859_2[] = {
57 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
58 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
59 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
60 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
61 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
62 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
63 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
64 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
65 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
66 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
67 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
68 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
69};
70
71/* ISO/IEC 8859-3:1999 (Latin-3, "South European", "Maltese & Esperanto") */
72static wchar_t iso_8859_3[] = {
73 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7,
74 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B,
75 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
76 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C,
77 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7,
78 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
79 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
80 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
81 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7,
82 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
83 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
84 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9
85};
86
87/* ISO/IEC 8859-4:1998 (Latin-4, "North European") */
88static wchar_t iso_8859_4[] = {
89 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
90 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
91 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
92 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
93 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
94 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
95 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
96 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
97 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
98 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
99 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
100 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9
101};
102
103/* ISO 8859-5:1999 (Latin/Cyrillic) */
104static wchar_t iso_8859_5[] = {
105 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
106 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
107 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
108 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
109 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
110 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
111 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
112 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
113 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
114 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
115 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
116 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F
117};
118
119/* ISO 8859-6:1999 (Latin/Arabic) */
120static wchar_t iso_8859_6[] = {
121 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD,
122 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD,
123 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
124 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F,
125 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
126 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
127 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
128 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
129 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
130 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
131 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
132 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
133};
134
135/* ISO 8859-7:1987 (Latin/Greek) */
136static wchar_t iso_8859_7[] = {
137 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
138 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
139 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
140 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
141 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
142 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
143 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
144 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
145 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
146 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
147 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
148 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD
149};
150
151/* ISO/IEC 8859-8:1999 (Latin/Hebrew) */
152static wchar_t iso_8859_8[] = {
153 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
154 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
155 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
156 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
157 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
158 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
159 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
160 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
161 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
162 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
163 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
164 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD
165};
166
167/* ISO/IEC 8859-9:1999 (Latin-5, "Turkish") */
168static wchar_t iso_8859_9[] = {
169 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
170 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
171 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
172 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
173 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
174 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
175 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
176 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
177 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
178 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
179 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
180 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
181};
182
183/* ISO 8859-10:1993? (Latin-6, "Nordic" [Sami, Inuit, Icelandic]) */
184/* Translation table from RDB. unicode.org (ISO/IEC 8859-10:1998) has
185 * U+2015 (HORIZONTAL BAR) at codepoint 0xBD instead
186 * (U+2014 is EM DASH). -- jtn */
875b193f 187static wchar_t iso_8859_10[] = {
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,
191 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B,
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
d6dcf6c6 202/* "ISO 8859-11:1997" ("Thai", "TIS620") */
203/* From RDB -- ISO and unicode.org disclaim all knowledge of this one.
204 * Maybe still in draft. --jtn */
875b193f 205static wchar_t iso_8859_11[] = {
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") */
a0c1ddf1 221static 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") */
875b193f 237static wchar_t iso_8859_14[] = {
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") */
875b193f 253static 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") */
a0c1ddf1 269static wchar_t iso_8859_16[] = {
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
875b193f 284static wchar_t roman8[] = {
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
299static wchar_t koi8_u[] = {
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
318static wchar_t vscii[] = {
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
353static wchar_t dec_mcs[] = {
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;
372 wchar_t *cp_table;
875b193f 373};
374
375static 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},
386 {"ISO-8859-11:1997 (Latin/Thai)", 0, 96, iso_8859_11},
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
421void init_ucs_tables(void)
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
760e88b2 600void lpage_send(int codepage, char *buf, int len, int interactive)
4eeb7d09 601{
602 static wchar_t *widebuffer = 0;
603 static int widesize = 0;
604 int wclen;
605
606 if (codepage < 0) {
760e88b2 607 ldisc_send(buf, len, interactive);
4eeb7d09 608 return;
609 }
610
611 if (len > widesize) {
612 sfree(widebuffer);
613 widebuffer = smalloc(len * 2 * sizeof(wchar_t));
614 widesize = len * 2;
615 }
616
617 wclen =
618 MultiByteToWideChar(codepage, 0, buf, len, widebuffer, widesize);
760e88b2 619 luni_send(widebuffer, wclen, interactive);
4eeb7d09 620}
621
760e88b2 622void luni_send(wchar_t * widebuf, int len, int interactive)
4eeb7d09 623{
624 static char *linebuffer = 0;
625 static int linesize = 0;
8f22582c 626 int ratio = (in_utf)?3:1;
4eeb7d09 627 int i;
628 char *p;
629
630 if (len * ratio > linesize) {
631 sfree(linebuffer);
632 linebuffer = smalloc(len * ratio * 2 * sizeof(wchar_t));
633 linesize = len * ratio * 2;
634 }
635
8f22582c 636 if (in_utf) {
4eeb7d09 637 /* UTF is a simple algorithm */
638 for (p = linebuffer, i = 0; i < len; i++) {
639 wchar_t ch = widebuf[i];
05054a30 640 /* Windows wchar_t is UTF-16 */
641 if ((ch&0xF800) == 0xD800) ch = '.';
642
4eeb7d09 643 if (ch < 0x80) {
644 *p++ = (char) (ch);
645 } else if (ch < 0x800) {
646 *p++ = (0xC0 | (ch >> 6));
647 *p++ = (0x80 | (ch & 0x3F));
648 } else {
649 *p++ = (0xE0 | (ch >> 12));
650 *p++ = (0x80 | ((ch >> 6) & 0x3F));
651 *p++ = (0x80 | (ch & 0x3F));
652 }
653 }
654 } else if (!uni_tbl) {
655 int rv;
656 rv = WideCharToMultiByte(line_codepage, 0, widebuf, len,
657 linebuffer, linesize, NULL, NULL);
658 if (rv >= 0)
659 p = linebuffer + rv;
660 else
661 p = linebuffer;
662 } else {
663 /* Others are a lookup in an array */
664 for (p = linebuffer, i = 0; i < len; i++) {
665 wchar_t ch = widebuf[i];
666 int by;
667 char *p1;
668 if (uni_tbl && (p1 = uni_tbl[(ch >> 8) & 0xFF])
669 && (by = p1[ch & 0xFF]))
670 *p++ = by;
671 else if (ch < 0x80)
672 *p++ = (char) ch;
673#if 1
674 else
675 *p++ = '.';
676#endif
677 }
678 }
679 if (p > linebuffer)
760e88b2 680 ldisc_send(linebuffer, p - linebuffer, interactive);
4eeb7d09 681}
682
a9c02454 683wchar_t xlat_uskbd2cyrllic(int ch)
684{
685 static wchar_t cyrtab[] = {
686 0, 1, 2, 3, 4, 5, 6, 7,
687 8, 9, 10, 11, 12, 13, 14, 15,
688 16, 17, 18, 19, 20, 21, 22, 23,
689 24, 25, 26, 27, 28, 29, 30, 31,
690 32, 33, 0x042d, 35, 36, 37, 38, 0x044d,
691 40, 41, 42, 0x0406, 0x0431, 0x0454, 0x044e, 0x002e,
692 48, 49, 50, 51, 52, 53, 54, 55,
693 56, 57, 0x0416, 0x0436, 0x0411, 0x0456, 0x042e, 0x002c,
694 64, 0x0424, 0x0418, 0x0421, 0x0412, 0x0423, 0x0410, 0x041f,
695 0x0420, 0x0428, 0x041e, 0x041b, 0x0414, 0x042c, 0x0422, 0x0429,
696 0x0417, 0x0419, 0x041a, 0x042b, 0x0415, 0x0413, 0x041c, 0x0426,
697 0x0427, 0x041d, 0x042f, 0x0445, 0x0457, 0x044a, 94, 0x0404,
698 96, 0x0444, 0x0438, 0x0441, 0x0432, 0x0443, 0x0430, 0x043f,
699 0x0440, 0x0448, 0x043e, 0x043b, 0x0434, 0x044c, 0x0442, 0x0449,
700 0x0437, 0x0439, 0x043a, 0x044b, 0x0435, 0x0433, 0x043c, 0x0446,
701 0x0447, 0x043d, 0x044f, 0x0425, 0x0407, 0x042a, 126, 127
702 };
703 return cyrtab[ch&0x7F];
704}
705
4eeb7d09 706int check_compose(int first, int second)
707{
708
709 static struct {
710 char first, second;
711 wchar_t composed;
712 } composetbl[] = {
713 {
714 0x2b, 0x2b, 0x0023}, {
715 0x41, 0x41, 0x0040}, {
716 0x28, 0x28, 0x005b}, {
717 0x2f, 0x2f, 0x005c}, {
718 0x29, 0x29, 0x005d}, {
719 0x28, 0x2d, 0x007b}, {
720 0x2d, 0x29, 0x007d}, {
721 0x2f, 0x5e, 0x007c}, {
722 0x21, 0x21, 0x00a1}, {
723 0x43, 0x2f, 0x00a2}, {
724 0x43, 0x7c, 0x00a2}, {
725 0x4c, 0x2d, 0x00a3}, {
5a73255e 726 0x4c, 0x3d, 0x20a4}, {
4eeb7d09 727 0x58, 0x4f, 0x00a4}, {
728 0x58, 0x30, 0x00a4}, {
729 0x59, 0x2d, 0x00a5}, {
730 0x59, 0x3d, 0x00a5}, {
731 0x7c, 0x7c, 0x00a6}, {
732 0x53, 0x4f, 0x00a7}, {
733 0x53, 0x21, 0x00a7}, {
734 0x53, 0x30, 0x00a7}, {
735 0x22, 0x22, 0x00a8}, {
736 0x43, 0x4f, 0x00a9}, {
737 0x43, 0x30, 0x00a9}, {
738 0x41, 0x5f, 0x00aa}, {
739 0x3c, 0x3c, 0x00ab}, {
740 0x2c, 0x2d, 0x00ac}, {
741 0x2d, 0x2d, 0x00ad}, {
742 0x52, 0x4f, 0x00ae}, {
743 0x2d, 0x5e, 0x00af}, {
744 0x30, 0x5e, 0x00b0}, {
745 0x2b, 0x2d, 0x00b1}, {
746 0x32, 0x5e, 0x00b2}, {
747 0x33, 0x5e, 0x00b3}, {
748 0x27, 0x27, 0x00b4}, {
749 0x2f, 0x55, 0x00b5}, {
750 0x50, 0x21, 0x00b6}, {
751 0x2e, 0x5e, 0x00b7}, {
752 0x2c, 0x2c, 0x00b8}, {
753 0x31, 0x5e, 0x00b9}, {
754 0x4f, 0x5f, 0x00ba}, {
755 0x3e, 0x3e, 0x00bb}, {
756 0x31, 0x34, 0x00bc}, {
757 0x31, 0x32, 0x00bd}, {
758 0x33, 0x34, 0x00be}, {
759 0x3f, 0x3f, 0x00bf}, {
760 0x60, 0x41, 0x00c0}, {
761 0x27, 0x41, 0x00c1}, {
762 0x5e, 0x41, 0x00c2}, {
763 0x7e, 0x41, 0x00c3}, {
764 0x22, 0x41, 0x00c4}, {
765 0x2a, 0x41, 0x00c5}, {
766 0x41, 0x45, 0x00c6}, {
767 0x2c, 0x43, 0x00c7}, {
768 0x60, 0x45, 0x00c8}, {
769 0x27, 0x45, 0x00c9}, {
770 0x5e, 0x45, 0x00ca}, {
771 0x22, 0x45, 0x00cb}, {
772 0x60, 0x49, 0x00cc}, {
773 0x27, 0x49, 0x00cd}, {
774 0x5e, 0x49, 0x00ce}, {
775 0x22, 0x49, 0x00cf}, {
776 0x2d, 0x44, 0x00d0}, {
777 0x7e, 0x4e, 0x00d1}, {
778 0x60, 0x4f, 0x00d2}, {
779 0x27, 0x4f, 0x00d3}, {
780 0x5e, 0x4f, 0x00d4}, {
781 0x7e, 0x4f, 0x00d5}, {
782 0x22, 0x4f, 0x00d6}, {
783 0x58, 0x58, 0x00d7}, {
784 0x2f, 0x4f, 0x00d8}, {
785 0x60, 0x55, 0x00d9}, {
786 0x27, 0x55, 0x00da}, {
787 0x5e, 0x55, 0x00db}, {
788 0x22, 0x55, 0x00dc}, {
789 0x27, 0x59, 0x00dd}, {
790 0x48, 0x54, 0x00de}, {
791 0x73, 0x73, 0x00df}, {
792 0x60, 0x61, 0x00e0}, {
793 0x27, 0x61, 0x00e1}, {
794 0x5e, 0x61, 0x00e2}, {
795 0x7e, 0x61, 0x00e3}, {
796 0x22, 0x61, 0x00e4}, {
797 0x2a, 0x61, 0x00e5}, {
798 0x61, 0x65, 0x00e6}, {
799 0x2c, 0x63, 0x00e7}, {
800 0x60, 0x65, 0x00e8}, {
801 0x27, 0x65, 0x00e9}, {
802 0x5e, 0x65, 0x00ea}, {
803 0x22, 0x65, 0x00eb}, {
804 0x60, 0x69, 0x00ec}, {
805 0x27, 0x69, 0x00ed}, {
806 0x5e, 0x69, 0x00ee}, {
807 0x22, 0x69, 0x00ef}, {
808 0x2d, 0x64, 0x00f0}, {
809 0x7e, 0x6e, 0x00f1}, {
810 0x60, 0x6f, 0x00f2}, {
811 0x27, 0x6f, 0x00f3}, {
812 0x5e, 0x6f, 0x00f4}, {
813 0x7e, 0x6f, 0x00f5}, {
814 0x22, 0x6f, 0x00f6}, {
815 0x3a, 0x2d, 0x00f7}, {
816 0x6f, 0x2f, 0x00f8}, {
817 0x60, 0x75, 0x00f9}, {
818 0x27, 0x75, 0x00fa}, {
819 0x5e, 0x75, 0x00fb}, {
820 0x22, 0x75, 0x00fc}, {
821 0x27, 0x79, 0x00fd}, {
822 0x68, 0x74, 0x00fe}, {
823 0x22, 0x79, 0x00ff},
824 /* Unicode extras. */
825 {
826 0x6f, 0x65, 0x0153}, {
827 0x4f, 0x45, 0x0152},
828 /* Compose pairs from UCS */
829 {
830 0x41, 0x2D, 0x0100}, {
831 0x61, 0x2D, 0x0101}, {
832 0x43, 0x27, 0x0106}, {
833 0x63, 0x27, 0x0107}, {
834 0x43, 0x5E, 0x0108}, {
835 0x63, 0x5E, 0x0109}, {
836 0x45, 0x2D, 0x0112}, {
837 0x65, 0x2D, 0x0113}, {
838 0x47, 0x5E, 0x011C}, {
839 0x67, 0x5E, 0x011D}, {
840 0x47, 0x2C, 0x0122}, {
841 0x67, 0x2C, 0x0123}, {
842 0x48, 0x5E, 0x0124}, {
843 0x68, 0x5E, 0x0125}, {
844 0x49, 0x7E, 0x0128}, {
845 0x69, 0x7E, 0x0129}, {
846 0x49, 0x2D, 0x012A}, {
847 0x69, 0x2D, 0x012B}, {
848 0x4A, 0x5E, 0x0134}, {
849 0x6A, 0x5E, 0x0135}, {
850 0x4B, 0x2C, 0x0136}, {
851 0x6B, 0x2C, 0x0137}, {
852 0x4C, 0x27, 0x0139}, {
853 0x6C, 0x27, 0x013A}, {
854 0x4C, 0x2C, 0x013B}, {
855 0x6C, 0x2C, 0x013C}, {
856 0x4E, 0x27, 0x0143}, {
857 0x6E, 0x27, 0x0144}, {
858 0x4E, 0x2C, 0x0145}, {
859 0x6E, 0x2C, 0x0146}, {
860 0x4F, 0x2D, 0x014C}, {
861 0x6F, 0x2D, 0x014D}, {
862 0x52, 0x27, 0x0154}, {
863 0x72, 0x27, 0x0155}, {
864 0x52, 0x2C, 0x0156}, {
865 0x72, 0x2C, 0x0157}, {
866 0x53, 0x27, 0x015A}, {
867 0x73, 0x27, 0x015B}, {
868 0x53, 0x5E, 0x015C}, {
869 0x73, 0x5E, 0x015D}, {
870 0x53, 0x2C, 0x015E}, {
871 0x73, 0x2C, 0x015F}, {
872 0x54, 0x2C, 0x0162}, {
873 0x74, 0x2C, 0x0163}, {
874 0x55, 0x7E, 0x0168}, {
875 0x75, 0x7E, 0x0169}, {
876 0x55, 0x2D, 0x016A}, {
877 0x75, 0x2D, 0x016B}, {
878 0x55, 0x2A, 0x016E}, {
879 0x75, 0x2A, 0x016F}, {
880 0x57, 0x5E, 0x0174}, {
881 0x77, 0x5E, 0x0175}, {
882 0x59, 0x5E, 0x0176}, {
883 0x79, 0x5E, 0x0177}, {
884 0x59, 0x22, 0x0178}, {
885 0x5A, 0x27, 0x0179}, {
886 0x7A, 0x27, 0x017A}, {
887 0x47, 0x27, 0x01F4}, {
888 0x67, 0x27, 0x01F5}, {
889 0x4E, 0x60, 0x01F8}, {
890 0x6E, 0x60, 0x01F9}, {
891 0x45, 0x2C, 0x0228}, {
892 0x65, 0x2C, 0x0229}, {
893 0x59, 0x2D, 0x0232}, {
894 0x79, 0x2D, 0x0233}, {
895 0x44, 0x2C, 0x1E10}, {
896 0x64, 0x2C, 0x1E11}, {
897 0x47, 0x2D, 0x1E20}, {
898 0x67, 0x2D, 0x1E21}, {
899 0x48, 0x22, 0x1E26}, {
900 0x68, 0x22, 0x1E27}, {
901 0x48, 0x2C, 0x1E28}, {
902 0x68, 0x2C, 0x1E29}, {
903 0x4B, 0x27, 0x1E30}, {
904 0x6B, 0x27, 0x1E31}, {
905 0x4D, 0x27, 0x1E3E}, {
906 0x6D, 0x27, 0x1E3F}, {
907 0x50, 0x27, 0x1E54}, {
908 0x70, 0x27, 0x1E55}, {
909 0x56, 0x7E, 0x1E7C}, {
910 0x76, 0x7E, 0x1E7D}, {
911 0x57, 0x60, 0x1E80}, {
912 0x77, 0x60, 0x1E81}, {
913 0x57, 0x27, 0x1E82}, {
914 0x77, 0x27, 0x1E83}, {
915 0x57, 0x22, 0x1E84}, {
916 0x77, 0x22, 0x1E85}, {
917 0x58, 0x22, 0x1E8C}, {
918 0x78, 0x22, 0x1E8D}, {
919 0x5A, 0x5E, 0x1E90}, {
920 0x7A, 0x5E, 0x1E91}, {
921 0x74, 0x22, 0x1E97}, {
922 0x77, 0x2A, 0x1E98}, {
923 0x79, 0x2A, 0x1E99}, {
924 0x45, 0x7E, 0x1EBC}, {
925 0x65, 0x7E, 0x1EBD}, {
926 0x59, 0x60, 0x1EF2}, {
927 0x79, 0x60, 0x1EF3}, {
928 0x59, 0x7E, 0x1EF8}, {
929 0x79, 0x7E, 0x1EF9},
930 /* Compatible/possibles from UCS */
931 {
932 0x49, 0x4A, 0x0132}, {
933 0x69, 0x6A, 0x0133}, {
934 0x4C, 0x4A, 0x01C7}, {
935 0x4C, 0x6A, 0x01C8}, {
936 0x6C, 0x6A, 0x01C9}, {
937 0x4E, 0x4A, 0x01CA}, {
938 0x4E, 0x6A, 0x01CB}, {
939 0x6E, 0x6A, 0x01CC}, {
940 0x44, 0x5A, 0x01F1}, {
941 0x44, 0x7A, 0x01F2}, {
942 0x64, 0x7A, 0x01F3}, {
943 0x2E, 0x2E, 0x2025}, {
944 0x21, 0x21, 0x203C}, {
945 0x3F, 0x21, 0x2048}, {
946 0x21, 0x3F, 0x2049}, {
947 0x52, 0x73, 0x20A8}, {
948 0x4E, 0x6F, 0x2116}, {
949 0x53, 0x4D, 0x2120}, {
950 0x54, 0x4D, 0x2122}, {
951 0x49, 0x49, 0x2161}, {
952 0x49, 0x56, 0x2163}, {
953 0x56, 0x49, 0x2165}, {
954 0x49, 0x58, 0x2168}, {
955 0x58, 0x49, 0x216A}, {
956 0x69, 0x69, 0x2171}, {
957 0x69, 0x76, 0x2173}, {
958 0x76, 0x69, 0x2175}, {
959 0x69, 0x78, 0x2178}, {
960 0x78, 0x69, 0x217A}, {
961 0x31, 0x30, 0x2469}, {
962 0x31, 0x31, 0x246A}, {
963 0x31, 0x32, 0x246B}, {
964 0x31, 0x33, 0x246C}, {
965 0x31, 0x34, 0x246D}, {
966 0x31, 0x35, 0x246E}, {
967 0x31, 0x36, 0x246F}, {
968 0x31, 0x37, 0x2470}, {
969 0x31, 0x38, 0x2471}, {
970 0x31, 0x39, 0x2472}, {
971 0x32, 0x30, 0x2473}, {
972 0x31, 0x2E, 0x2488}, {
973 0x32, 0x2E, 0x2489}, {
974 0x33, 0x2E, 0x248A}, {
975 0x34, 0x2E, 0x248B}, {
976 0x35, 0x2E, 0x248C}, {
977 0x36, 0x2E, 0x248D}, {
978 0x37, 0x2E, 0x248E}, {
979 0x38, 0x2E, 0x248F}, {
980 0x39, 0x2E, 0x2490}, {
981 0x64, 0x61, 0x3372}, {
982 0x41, 0x55, 0x3373}, {
983 0x6F, 0x56, 0x3375}, {
984 0x70, 0x63, 0x3376}, {
985 0x70, 0x41, 0x3380}, {
986 0x6E, 0x41, 0x3381}, {
987 0x6D, 0x41, 0x3383}, {
988 0x6B, 0x41, 0x3384}, {
989 0x4B, 0x42, 0x3385}, {
990 0x4D, 0x42, 0x3386}, {
991 0x47, 0x42, 0x3387}, {
992 0x70, 0x46, 0x338A}, {
993 0x6E, 0x46, 0x338B}, {
994 0x6D, 0x67, 0x338E}, {
995 0x6B, 0x67, 0x338F}, {
996 0x48, 0x7A, 0x3390}, {
997 0x66, 0x6D, 0x3399}, {
998 0x6E, 0x6D, 0x339A}, {
999 0x6D, 0x6D, 0x339C}, {
1000 0x63, 0x6D, 0x339D}, {
1001 0x6B, 0x6D, 0x339E}, {
1002 0x50, 0x61, 0x33A9}, {
1003 0x70, 0x73, 0x33B0}, {
1004 0x6E, 0x73, 0x33B1}, {
1005 0x6D, 0x73, 0x33B3}, {
1006 0x70, 0x56, 0x33B4}, {
1007 0x6E, 0x56, 0x33B5}, {
1008 0x6D, 0x56, 0x33B7}, {
1009 0x6B, 0x56, 0x33B8}, {
1010 0x4D, 0x56, 0x33B9}, {
1011 0x70, 0x57, 0x33BA}, {
1012 0x6E, 0x57, 0x33BB}, {
1013 0x6D, 0x57, 0x33BD}, {
1014 0x6B, 0x57, 0x33BE}, {
1015 0x4D, 0x57, 0x33BF}, {
1016 0x42, 0x71, 0x33C3}, {
1017 0x63, 0x63, 0x33C4}, {
1018 0x63, 0x64, 0x33C5}, {
1019 0x64, 0x42, 0x33C8}, {
1020 0x47, 0x79, 0x33C9}, {
1021 0x68, 0x61, 0x33CA}, {
1022 0x48, 0x50, 0x33CB}, {
1023 0x69, 0x6E, 0x33CC}, {
1024 0x4B, 0x4B, 0x33CD}, {
1025 0x4B, 0x4D, 0x33CE}, {
1026 0x6B, 0x74, 0x33CF}, {
1027 0x6C, 0x6D, 0x33D0}, {
1028 0x6C, 0x6E, 0x33D1}, {
1029 0x6C, 0x78, 0x33D3}, {
1030 0x6D, 0x62, 0x33D4}, {
1031 0x50, 0x48, 0x33D7}, {
1032 0x50, 0x52, 0x33DA}, {
1033 0x73, 0x72, 0x33DB}, {
1034 0x53, 0x76, 0x33DC}, {
1035 0x57, 0x62, 0x33DD}, {
1036 0x66, 0x66, 0xFB00}, {
1037 0x66, 0x69, 0xFB01}, {
1038 0x66, 0x6C, 0xFB02}, {
1039 0x73, 0x74, 0xFB06}, {
1040 0, 0, 0}
1041 }, *c;
1042
1043 static int recurse = 0;
1044 int nc = -1;
1045
1046 for (c = composetbl; c->first; c++) {
1047 if (c->first == first && c->second == second)
1048 return c->composed;
1049 }
1050
1051 if (recurse == 0) {
1052 recurse = 1;
1053 nc = check_compose(second, first);
1054 if (nc == -1)
1055 nc = check_compose(toupper(first), toupper(second));
1056 if (nc == -1)
1057 nc = check_compose(toupper(second), toupper(first));
1058 recurse = 0;
1059 }
1060 return nc;
1061}
1062
1063int decode_codepage(char *cp_name)
1064{
1065 char *s, *d;
1066 struct cp_list_item *cpi;
1067 int codepage = -1;
4eeb7d09 1068 CPINFO cpinfo;
1069
b8ae1f0f 1070 if (!*cp_name) {
1071 /*
1072 * Here we select a plausible default code page based on
1073 * the locale the user is in. We wish to select an ISO code
1074 * page or appropriate local default _rather_ than go with
1075 * the Win125* series, because it's more important to have
1076 * CSI and friends enabled by default than the ghastly
1077 * Windows extra quote characters, and because it's more
1078 * likely the user is connecting to a remote server that
1079 * does something Unixy or VMSy and hence standards-
1080 * compliant than that they're connecting back to a Windows
1081 * box using horrible nonstandard charsets.
1082 *
1083 * Accordingly, Robert de Bath suggests a method for
1084 * picking a default character set that runs as follows:
1085 * first call GetACP to get the system's ANSI code page
1086 * identifier, and translate as follows:
1087 *
1088 * 1250 -> ISO 8859-2
1089 * 1251 -> KOI8-U
1090 * 1252 -> ISO 8859-1
1091 * 1253 -> ISO 8859-7
1092 * 1254 -> ISO 8859-9
1093 * 1255 -> ISO 8859-8
1094 * 1256 -> ISO 8859-6
1095 * 1257 -> ISO 8859-4
1096 *
1097 * and for anything else, choose direct-to-font.
1098 */
1099 int cp = GetACP();
1100 switch (cp) {
1101 case 1250: cp_name = "ISO-8859-2"; break;
1102 case 1251: cp_name = "KOI8-U"; break;
1103 case 1252: cp_name = "ISO-8859-1"; break;
1104 case 1253: cp_name = "ISO-8859-7"; break;
1105 case 1254: cp_name = "ISO-8859-9"; break;
1106 case 1255: cp_name = "ISO-8859-8"; break;
1107 case 1256: cp_name = "ISO-8859-6"; break;
1108 case 1257: cp_name = "ISO-8859-4"; break;
1109 /* default: leave it blank, which will select -1, direct->font */
1110 }
1111 }
1112
4eeb7d09 1113 if (cp_name && *cp_name)
1114 for (cpi = cp_list; cpi->name; cpi++) {
1115 s = cp_name;
1116 d = cpi->name;
1117 for (;;) {
1118 while (*s && !isalnum(*s) && *s != ':')
1119 s++;
1120 while (*d && !isalnum(*d) && *d != ':')
1121 d++;
1122 if (*s == 0) {
1123 codepage = cpi->codepage;
1124 if (codepage == CP_UTF8)
1125 goto break_break;
792de8f6 1126 if (codepage == -1)
1127 return codepage;
4eeb7d09 1128 if (codepage == 0) {
1129 codepage = 65536 + (cpi - cp_list);
1130 goto break_break;
1131 }
1132
1133 if (GetCPInfo(codepage, &cpinfo) != 0)
1134 goto break_break;
1135 }
274a5b41 1136 if (tolower(*s++) != tolower(*d++))
4eeb7d09 1137 break;
1138 }
1139 }
1140
1141 if (cp_name && *cp_name) {
1142 d = cp_name;
2d466ffd 1143 if (tolower(d[0]) == 'c' && tolower(d[1]) == 'p')
4eeb7d09 1144 d += 2;
2d466ffd 1145 if (tolower(d[0]) == 'i' && tolower(d[1]) == 'b'
1146 && tolower(d[1]) == 'm')
4eeb7d09 1147 d += 3;
1148 for (s = d; *s >= '0' && *s <= '9'; s++);
1149 if (*s == 0 && s != d)
1150 codepage = atoi(d); /* CP999 or IBM999 */
1151
1152 if (codepage == CP_ACP)
1153 codepage = GetACP();
1154 if (codepage == CP_OEMCP)
1155 codepage = GetOEMCP();
1156 if (codepage > 65535)
1157 codepage = -2;
1158 }
1159
1160 break_break:;
1161 if (codepage != -1) {
1162 if (codepage != CP_UTF8 && codepage < 65536) {
1163 if (GetCPInfo(codepage, &cpinfo) == 0) {
1164 codepage = -2;
1165 } else if (cpinfo.MaxCharSize > 1)
1166 codepage = -3;
1167 }
1168 }
1169 if (codepage == -1 && *cp_name)
1170 codepage = -2;
1171 return codepage;
1172}
1173
1174char *cp_name(int codepage)
1175{
1176 struct cp_list_item *cpi, *cpno;
1177 static char buf[32];
b8ae1f0f 1178
1179 if (codepage == -1) {
1180 sprintf(buf, "Use font encoding");
1181 return buf;
1182 }
1183
4eeb7d09 1184 if (codepage > 0 && codepage < 65536)
1185 sprintf(buf, "CP%03d", codepage);
1186 else
1187 *buf = 0;
1188
1189 if (codepage >= 65536) {
1190 cpno = 0;
1191 for (cpi = cp_list; cpi->name; cpi++)
1192 if (cpi == cp_list + (codepage - 65536)) {
1193 cpno = cpi;
1194 break;
1195 }
1196 if (cpno)
1197 for (cpi = cp_list; cpi->name; cpi++) {
1198 if (cpno->cp_table == cpi->cp_table)
1199 return cpi->name;
1200 }
1201 } else {
1202 for (cpi = cp_list; cpi->name; cpi++) {
1203 if (codepage == cpi->codepage)
1204 return cpi->name;
1205 }
1206 }
1207 return buf;
1208}
1209
875b193f 1210/*
1211 * Return the nth code page in the list, for use in the GUI
1212 * configurer.
1213 */
1214char *cp_enumerate(int index)
1215{
1216 if (index < 0 || index >= lenof(cp_list))
1217 return NULL;
1218 return cp_list[index].name;
1219}
1220
a7419ea4 1221void get_unitab(int codepage, wchar_t * unitab, int ftype)
4eeb7d09 1222{
1223 char tbuf[4];
1224 int i, max = 256, flg = MB_ERR_INVALID_CHARS;
1225
1226 if (ftype)
1227 flg |= MB_USEGLYPHCHARS;
1228 if (ftype == 2)
1229 max = 128;
1230
d6dcf6c6 1231 if (codepage == CP_UTF8) {
1232 for (i = 0; i < max; i++)
1233 unitab[i] = i;
1234 return;
1235 }
1236
1237 if (codepage == CP_ACP)
4eeb7d09 1238 codepage = GetACP();
1239 else if (codepage == CP_OEMCP)
1240 codepage = GetOEMCP();
1241
1242 if (codepage > 0 && codepage < 65536) {
1243 for (i = 0; i < max; i++) {
1244 tbuf[0] = i;
1245
1246 if (MultiByteToWideChar(codepage, flg, tbuf, 1, unitab + i, 1)
1247 != 1)
1248 unitab[i] = 0xFFFD;
1249 }
1250 } else {
1251 int j = 256 - cp_list[codepage & 0xFFFF].cp_size;
1252 for (i = 0; i < max; i++)
1253 unitab[i] = i;
1254 for (i = j; i < max; i++)
1255 unitab[i] = cp_list[codepage & 0xFFFF].cp_table[i - j];
1256 }
1257}