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