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