Now that we have Subversion's file renaming ability, it's time at
[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
21d2b241 439void init_ucs(Config *cfg, struct unicode_data *ucsdata)
4eeb7d09 440{
441 int i, j;
442 int used_dtf = 0;
443 char tbuf[256];
dc3c8261 444
4eeb7d09 445 for (i = 0; i < 256; i++)
446 tbuf[i] = i;
447
448 /* Decide on the Line and Font codepages */
21d2b241 449 ucsdata->line_codepage = decode_codepage(cfg->line_codepage);
4eeb7d09 450
21d2b241 451 if (ucsdata->font_codepage <= 0) {
452 ucsdata->font_codepage=0;
453 ucsdata->dbcs_screenfont=0;
8f22582c 454 }
455
8772ac69 456 if (cfg->vtmode == VT_OEMONLY) {
21d2b241 457 ucsdata->font_codepage = 437;
458 ucsdata->dbcs_screenfont = 0;
459 if (ucsdata->line_codepage <= 0)
460 ucsdata->line_codepage = GetACP();
461 } else if (ucsdata->line_codepage <= 0)
462 ucsdata->line_codepage = ucsdata->font_codepage;
4eeb7d09 463
464 /* Collect screen font ucs table */
21d2b241 465 if (ucsdata->dbcs_screenfont || ucsdata->font_codepage == 0) {
466 get_unitab(ucsdata->font_codepage, ucsdata->unitab_font, 2);
4eeb7d09 467 for (i = 128; i < 256; i++)
36566009 468 ucsdata->unitab_font[i] = (WCHAR) (CSET_ACP + i);
4eeb7d09 469 } else {
21d2b241 470 get_unitab(ucsdata->font_codepage, ucsdata->unitab_font, 1);
4eeb7d09 471
472 /* CP437 fonts are often broken ... */
21d2b241 473 if (ucsdata->font_codepage == 437)
474 ucsdata->unitab_font[0] = ucsdata->unitab_font[255] = 0xFFFF;
4eeb7d09 475 }
8772ac69 476 if (cfg->vtmode == VT_XWINDOWS)
21d2b241 477 memcpy(ucsdata->unitab_font + 1, unitab_xterm_std,
4eeb7d09 478 sizeof(unitab_xterm_std));
479
480 /* Collect OEMCP ucs table */
21d2b241 481 get_unitab(CP_OEMCP, ucsdata->unitab_oemcp, 1);
4eeb7d09 482
d3cb5465 483 /* Collect CP437 ucs table for SCO acs */
8772ac69 484 if (cfg->vtmode == VT_OEMANSI || cfg->vtmode == VT_XWINDOWS)
21d2b241 485 memcpy(ucsdata->unitab_scoacs, ucsdata->unitab_oemcp,
486 sizeof(ucsdata->unitab_scoacs));
d3cb5465 487 else
21d2b241 488 get_unitab(437, ucsdata->unitab_scoacs, 1);
d3cb5465 489
4eeb7d09 490 /* Collect line set ucs table */
21d2b241 491 if (ucsdata->line_codepage == ucsdata->font_codepage &&
492 (ucsdata->dbcs_screenfont ||
493 cfg->vtmode == VT_POORMAN || ucsdata->font_codepage==0)) {
4eeb7d09 494
495 /* For DBCS and POOR fonts force direct to font */
496 used_dtf = 1;
497 for (i = 0; i < 32; i++)
21d2b241 498 ucsdata->unitab_line[i] = (WCHAR) i;
4eeb7d09 499 for (i = 32; i < 256; i++)
36566009 500 ucsdata->unitab_line[i] = (WCHAR) (CSET_ACP + i);
21d2b241 501 ucsdata->unitab_line[127] = (WCHAR) 127;
4eeb7d09 502 } else {
21d2b241 503 get_unitab(ucsdata->line_codepage, ucsdata->unitab_line, 0);
4eeb7d09 504 }
505
506#if 0
507 debug(
21d2b241 508 ("Line cp%d, Font cp%d%s\n", ucsdata->line_codepage,
509 ucsdata->font_codepage, ucsdata->dbcs_screenfont ? " DBCS" : ""));
4eeb7d09 510
511 for (i = 0; i < 256; i += 16) {
512 for (j = 0; j < 16; j++) {
21d2b241 513 debug(("%04x%s", ucsdata->unitab_line[i + j], j == 15 ? "" : ","));
4eeb7d09 514 }
515 debug(("\n"));
516 }
517#endif
518
519 /* VT100 graphics - NB: Broken for non-ascii CP's */
21d2b241 520 memcpy(ucsdata->unitab_xterm, ucsdata->unitab_line,
521 sizeof(ucsdata->unitab_xterm));
522 memcpy(ucsdata->unitab_xterm + '`', unitab_xterm_std,
523 sizeof(unitab_xterm_std));
524 ucsdata->unitab_xterm['_'] = ' ';
4eeb7d09 525
526 /* Generate UCS ->line page table. */
21d2b241 527 if (ucsdata->uni_tbl) {
4eeb7d09 528 for (i = 0; i < 256; i++)
21d2b241 529 if (ucsdata->uni_tbl[i])
530 sfree(ucsdata->uni_tbl[i]);
531 sfree(ucsdata->uni_tbl);
532 ucsdata->uni_tbl = 0;
4eeb7d09 533 }
534 if (!used_dtf) {
535 for (i = 0; i < 256; i++) {
21d2b241 536 if (DIRECT_CHAR(ucsdata->unitab_line[i]))
4eeb7d09 537 continue;
21d2b241 538 if (DIRECT_FONT(ucsdata->unitab_line[i]))
4eeb7d09 539 continue;
21d2b241 540 if (!ucsdata->uni_tbl) {
3d88e64d 541 ucsdata->uni_tbl = snewn(256, char *);
21d2b241 542 memset(ucsdata->uni_tbl, 0, 256 * sizeof(char *));
4eeb7d09 543 }
21d2b241 544 j = ((ucsdata->unitab_line[i] >> 8) & 0xFF);
545 if (!ucsdata->uni_tbl[j]) {
3d88e64d 546 ucsdata->uni_tbl[j] = snewn(256, char);
21d2b241 547 memset(ucsdata->uni_tbl[j], 0, 256 * sizeof(char));
4eeb7d09 548 }
21d2b241 549 ucsdata->uni_tbl[j][ucsdata->unitab_line[i] & 0xFF] = i;
4eeb7d09 550 }
551 }
552
553 /* Find the line control characters. */
554 for (i = 0; i < 256; i++)
21d2b241 555 if (ucsdata->unitab_line[i] < ' '
556 || (ucsdata->unitab_line[i] >= 0x7F &&
557 ucsdata->unitab_line[i] < 0xA0))
558 ucsdata->unitab_ctrl[i] = i;
4eeb7d09 559 else
21d2b241 560 ucsdata->unitab_ctrl[i] = 0xFF;
4eeb7d09 561
562 /* Generate line->screen direct conversion links. */
8772ac69 563 if (cfg->vtmode == VT_OEMANSI || cfg->vtmode == VT_XWINDOWS)
36566009 564 link_font(ucsdata->unitab_scoacs, ucsdata->unitab_oemcp, CSET_OEMCP);
d3cb5465 565
36566009 566 link_font(ucsdata->unitab_line, ucsdata->unitab_font, CSET_ACP);
567 link_font(ucsdata->unitab_scoacs, ucsdata->unitab_font, CSET_ACP);
568 link_font(ucsdata->unitab_xterm, ucsdata->unitab_font, CSET_ACP);
4eeb7d09 569
8772ac69 570 if (cfg->vtmode == VT_OEMANSI || cfg->vtmode == VT_XWINDOWS) {
36566009 571 link_font(ucsdata->unitab_line, ucsdata->unitab_oemcp, CSET_OEMCP);
572 link_font(ucsdata->unitab_xterm, ucsdata->unitab_oemcp, CSET_OEMCP);
4eeb7d09 573 }
574
21d2b241 575 if (ucsdata->dbcs_screenfont &&
576 ucsdata->font_codepage != ucsdata->line_codepage) {
5a73255e 577 /* F***ing Microsoft fonts, Japanese and Korean codepage fonts
578 * have a currency symbol at 0x5C but their unicode value is
579 * still given as U+005C not the correct U+00A5. */
36566009 580 ucsdata->unitab_line['\\'] = CSET_OEMCP + '\\';
5a73255e 581 }
582
4eeb7d09 583 /* Last chance, if !unicode then try poorman links. */
8772ac69 584 if (cfg->vtmode != VT_UNICODE) {
c85623f9 585 static const char poorman_scoacs[] =
d3cb5465 586 "CueaaaaceeeiiiAAE**ooouuyOUc$YPsaiounNao?++**!<>###||||++||++++++--|-+||++--|-+----++++++++##||#aBTPEsyt******EN=+><++-=... n2* ";
c85623f9 587 static const char poorman_latin1[] =
4eeb7d09 588 " !cL.Y|S\"Ca<--R~o+23'u|.,1o>///?AAAAAAACEEEEIIIIDNOOOOOxOUUUUYPBaaaaaaaceeeeiiiionooooo/ouuuuypy";
c85623f9 589 static const char poorman_vt100[] = "*#****o~**+++++-----++++|****L.";
4eeb7d09 590
591 for (i = 160; i < 256; i++)
21d2b241 592 if (!DIRECT_FONT(ucsdata->unitab_line[i]) &&
593 ucsdata->unitab_line[i] >= 160 &&
594 ucsdata->unitab_line[i] < 256) {
595 ucsdata->unitab_line[i] =
36566009 596 (WCHAR) (CSET_ACP +
21d2b241 597 poorman_latin1[ucsdata->unitab_line[i] - 160]);
598 }
4eeb7d09 599 for (i = 96; i < 127; i++)
21d2b241 600 if (!DIRECT_FONT(ucsdata->unitab_xterm[i]))
601 ucsdata->unitab_xterm[i] =
36566009 602 (WCHAR) (CSET_ACP + poorman_vt100[i - 96]);
d3cb5465 603 for(i=128;i<256;i++)
21d2b241 604 if (!DIRECT_FONT(ucsdata->unitab_scoacs[i]))
605 ucsdata->unitab_scoacs[i] =
36566009 606 (WCHAR) (CSET_ACP + poorman_scoacs[i - 128]);
4eeb7d09 607 }
608}
609
610static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr)
611{
614e8f54 612 int font_index, line_index, i;
613 for (line_index = 0; line_index < 256; line_index++) {
614 if (DIRECT_FONT(line_tbl[line_index]))
4eeb7d09 615 continue;
614e8f54 616 for(i = 0; i < 256; i++) {
617 font_index = ((32 + i) & 0xFF);
618 if (line_tbl[line_index] == font_tbl[font_index]) {
619 line_tbl[line_index] = (WCHAR) (attr + font_index);
4eeb7d09 620 break;
621 }
622 }
623 }
624}
625
a9c02454 626wchar_t xlat_uskbd2cyrllic(int ch)
627{
c85623f9 628 static const wchar_t cyrtab[] = {
a9c02454 629 0, 1, 2, 3, 4, 5, 6, 7,
630 8, 9, 10, 11, 12, 13, 14, 15,
631 16, 17, 18, 19, 20, 21, 22, 23,
632 24, 25, 26, 27, 28, 29, 30, 31,
633 32, 33, 0x042d, 35, 36, 37, 38, 0x044d,
634 40, 41, 42, 0x0406, 0x0431, 0x0454, 0x044e, 0x002e,
635 48, 49, 50, 51, 52, 53, 54, 55,
636 56, 57, 0x0416, 0x0436, 0x0411, 0x0456, 0x042e, 0x002c,
637 64, 0x0424, 0x0418, 0x0421, 0x0412, 0x0423, 0x0410, 0x041f,
638 0x0420, 0x0428, 0x041e, 0x041b, 0x0414, 0x042c, 0x0422, 0x0429,
639 0x0417, 0x0419, 0x041a, 0x042b, 0x0415, 0x0413, 0x041c, 0x0426,
640 0x0427, 0x041d, 0x042f, 0x0445, 0x0457, 0x044a, 94, 0x0404,
641 96, 0x0444, 0x0438, 0x0441, 0x0432, 0x0443, 0x0430, 0x043f,
642 0x0440, 0x0448, 0x043e, 0x043b, 0x0434, 0x044c, 0x0442, 0x0449,
643 0x0437, 0x0439, 0x043a, 0x044b, 0x0435, 0x0433, 0x043c, 0x0446,
644 0x0447, 0x043d, 0x044f, 0x0425, 0x0407, 0x042a, 126, 127
645 };
646 return cyrtab[ch&0x7F];
647}
648
c85623f9 649int check_compose_internal(int first, int second, int recurse)
4eeb7d09 650{
651
c85623f9 652 static const struct {
4eeb7d09 653 char first, second;
654 wchar_t composed;
655 } composetbl[] = {
656 {
657 0x2b, 0x2b, 0x0023}, {
658 0x41, 0x41, 0x0040}, {
659 0x28, 0x28, 0x005b}, {
660 0x2f, 0x2f, 0x005c}, {
661 0x29, 0x29, 0x005d}, {
662 0x28, 0x2d, 0x007b}, {
663 0x2d, 0x29, 0x007d}, {
664 0x2f, 0x5e, 0x007c}, {
665 0x21, 0x21, 0x00a1}, {
666 0x43, 0x2f, 0x00a2}, {
667 0x43, 0x7c, 0x00a2}, {
668 0x4c, 0x2d, 0x00a3}, {
5a73255e 669 0x4c, 0x3d, 0x20a4}, {
4eeb7d09 670 0x58, 0x4f, 0x00a4}, {
671 0x58, 0x30, 0x00a4}, {
672 0x59, 0x2d, 0x00a5}, {
673 0x59, 0x3d, 0x00a5}, {
674 0x7c, 0x7c, 0x00a6}, {
675 0x53, 0x4f, 0x00a7}, {
676 0x53, 0x21, 0x00a7}, {
677 0x53, 0x30, 0x00a7}, {
678 0x22, 0x22, 0x00a8}, {
679 0x43, 0x4f, 0x00a9}, {
680 0x43, 0x30, 0x00a9}, {
681 0x41, 0x5f, 0x00aa}, {
682 0x3c, 0x3c, 0x00ab}, {
683 0x2c, 0x2d, 0x00ac}, {
684 0x2d, 0x2d, 0x00ad}, {
685 0x52, 0x4f, 0x00ae}, {
686 0x2d, 0x5e, 0x00af}, {
687 0x30, 0x5e, 0x00b0}, {
688 0x2b, 0x2d, 0x00b1}, {
689 0x32, 0x5e, 0x00b2}, {
690 0x33, 0x5e, 0x00b3}, {
691 0x27, 0x27, 0x00b4}, {
692 0x2f, 0x55, 0x00b5}, {
693 0x50, 0x21, 0x00b6}, {
694 0x2e, 0x5e, 0x00b7}, {
695 0x2c, 0x2c, 0x00b8}, {
696 0x31, 0x5e, 0x00b9}, {
697 0x4f, 0x5f, 0x00ba}, {
698 0x3e, 0x3e, 0x00bb}, {
699 0x31, 0x34, 0x00bc}, {
700 0x31, 0x32, 0x00bd}, {
701 0x33, 0x34, 0x00be}, {
702 0x3f, 0x3f, 0x00bf}, {
703 0x60, 0x41, 0x00c0}, {
704 0x27, 0x41, 0x00c1}, {
705 0x5e, 0x41, 0x00c2}, {
706 0x7e, 0x41, 0x00c3}, {
707 0x22, 0x41, 0x00c4}, {
708 0x2a, 0x41, 0x00c5}, {
709 0x41, 0x45, 0x00c6}, {
710 0x2c, 0x43, 0x00c7}, {
711 0x60, 0x45, 0x00c8}, {
712 0x27, 0x45, 0x00c9}, {
713 0x5e, 0x45, 0x00ca}, {
714 0x22, 0x45, 0x00cb}, {
715 0x60, 0x49, 0x00cc}, {
716 0x27, 0x49, 0x00cd}, {
717 0x5e, 0x49, 0x00ce}, {
718 0x22, 0x49, 0x00cf}, {
719 0x2d, 0x44, 0x00d0}, {
720 0x7e, 0x4e, 0x00d1}, {
721 0x60, 0x4f, 0x00d2}, {
722 0x27, 0x4f, 0x00d3}, {
723 0x5e, 0x4f, 0x00d4}, {
724 0x7e, 0x4f, 0x00d5}, {
725 0x22, 0x4f, 0x00d6}, {
726 0x58, 0x58, 0x00d7}, {
727 0x2f, 0x4f, 0x00d8}, {
728 0x60, 0x55, 0x00d9}, {
729 0x27, 0x55, 0x00da}, {
730 0x5e, 0x55, 0x00db}, {
731 0x22, 0x55, 0x00dc}, {
732 0x27, 0x59, 0x00dd}, {
733 0x48, 0x54, 0x00de}, {
734 0x73, 0x73, 0x00df}, {
735 0x60, 0x61, 0x00e0}, {
736 0x27, 0x61, 0x00e1}, {
737 0x5e, 0x61, 0x00e2}, {
738 0x7e, 0x61, 0x00e3}, {
739 0x22, 0x61, 0x00e4}, {
740 0x2a, 0x61, 0x00e5}, {
741 0x61, 0x65, 0x00e6}, {
742 0x2c, 0x63, 0x00e7}, {
743 0x60, 0x65, 0x00e8}, {
744 0x27, 0x65, 0x00e9}, {
745 0x5e, 0x65, 0x00ea}, {
746 0x22, 0x65, 0x00eb}, {
747 0x60, 0x69, 0x00ec}, {
748 0x27, 0x69, 0x00ed}, {
749 0x5e, 0x69, 0x00ee}, {
750 0x22, 0x69, 0x00ef}, {
751 0x2d, 0x64, 0x00f0}, {
752 0x7e, 0x6e, 0x00f1}, {
753 0x60, 0x6f, 0x00f2}, {
754 0x27, 0x6f, 0x00f3}, {
755 0x5e, 0x6f, 0x00f4}, {
756 0x7e, 0x6f, 0x00f5}, {
757 0x22, 0x6f, 0x00f6}, {
758 0x3a, 0x2d, 0x00f7}, {
759 0x6f, 0x2f, 0x00f8}, {
760 0x60, 0x75, 0x00f9}, {
761 0x27, 0x75, 0x00fa}, {
762 0x5e, 0x75, 0x00fb}, {
763 0x22, 0x75, 0x00fc}, {
764 0x27, 0x79, 0x00fd}, {
765 0x68, 0x74, 0x00fe}, {
766 0x22, 0x79, 0x00ff},
767 /* Unicode extras. */
768 {
769 0x6f, 0x65, 0x0153}, {
770 0x4f, 0x45, 0x0152},
771 /* Compose pairs from UCS */
772 {
773 0x41, 0x2D, 0x0100}, {
774 0x61, 0x2D, 0x0101}, {
775 0x43, 0x27, 0x0106}, {
776 0x63, 0x27, 0x0107}, {
777 0x43, 0x5E, 0x0108}, {
778 0x63, 0x5E, 0x0109}, {
779 0x45, 0x2D, 0x0112}, {
780 0x65, 0x2D, 0x0113}, {
781 0x47, 0x5E, 0x011C}, {
782 0x67, 0x5E, 0x011D}, {
783 0x47, 0x2C, 0x0122}, {
784 0x67, 0x2C, 0x0123}, {
785 0x48, 0x5E, 0x0124}, {
786 0x68, 0x5E, 0x0125}, {
787 0x49, 0x7E, 0x0128}, {
788 0x69, 0x7E, 0x0129}, {
789 0x49, 0x2D, 0x012A}, {
790 0x69, 0x2D, 0x012B}, {
791 0x4A, 0x5E, 0x0134}, {
792 0x6A, 0x5E, 0x0135}, {
793 0x4B, 0x2C, 0x0136}, {
794 0x6B, 0x2C, 0x0137}, {
795 0x4C, 0x27, 0x0139}, {
796 0x6C, 0x27, 0x013A}, {
797 0x4C, 0x2C, 0x013B}, {
798 0x6C, 0x2C, 0x013C}, {
799 0x4E, 0x27, 0x0143}, {
800 0x6E, 0x27, 0x0144}, {
801 0x4E, 0x2C, 0x0145}, {
802 0x6E, 0x2C, 0x0146}, {
803 0x4F, 0x2D, 0x014C}, {
804 0x6F, 0x2D, 0x014D}, {
805 0x52, 0x27, 0x0154}, {
806 0x72, 0x27, 0x0155}, {
807 0x52, 0x2C, 0x0156}, {
808 0x72, 0x2C, 0x0157}, {
809 0x53, 0x27, 0x015A}, {
810 0x73, 0x27, 0x015B}, {
811 0x53, 0x5E, 0x015C}, {
812 0x73, 0x5E, 0x015D}, {
813 0x53, 0x2C, 0x015E}, {
814 0x73, 0x2C, 0x015F}, {
815 0x54, 0x2C, 0x0162}, {
816 0x74, 0x2C, 0x0163}, {
817 0x55, 0x7E, 0x0168}, {
818 0x75, 0x7E, 0x0169}, {
819 0x55, 0x2D, 0x016A}, {
820 0x75, 0x2D, 0x016B}, {
821 0x55, 0x2A, 0x016E}, {
822 0x75, 0x2A, 0x016F}, {
823 0x57, 0x5E, 0x0174}, {
824 0x77, 0x5E, 0x0175}, {
825 0x59, 0x5E, 0x0176}, {
826 0x79, 0x5E, 0x0177}, {
827 0x59, 0x22, 0x0178}, {
828 0x5A, 0x27, 0x0179}, {
829 0x7A, 0x27, 0x017A}, {
830 0x47, 0x27, 0x01F4}, {
831 0x67, 0x27, 0x01F5}, {
832 0x4E, 0x60, 0x01F8}, {
833 0x6E, 0x60, 0x01F9}, {
834 0x45, 0x2C, 0x0228}, {
835 0x65, 0x2C, 0x0229}, {
836 0x59, 0x2D, 0x0232}, {
837 0x79, 0x2D, 0x0233}, {
838 0x44, 0x2C, 0x1E10}, {
839 0x64, 0x2C, 0x1E11}, {
840 0x47, 0x2D, 0x1E20}, {
841 0x67, 0x2D, 0x1E21}, {
842 0x48, 0x22, 0x1E26}, {
843 0x68, 0x22, 0x1E27}, {
844 0x48, 0x2C, 0x1E28}, {
845 0x68, 0x2C, 0x1E29}, {
846 0x4B, 0x27, 0x1E30}, {
847 0x6B, 0x27, 0x1E31}, {
848 0x4D, 0x27, 0x1E3E}, {
849 0x6D, 0x27, 0x1E3F}, {
850 0x50, 0x27, 0x1E54}, {
851 0x70, 0x27, 0x1E55}, {
852 0x56, 0x7E, 0x1E7C}, {
853 0x76, 0x7E, 0x1E7D}, {
854 0x57, 0x60, 0x1E80}, {
855 0x77, 0x60, 0x1E81}, {
856 0x57, 0x27, 0x1E82}, {
857 0x77, 0x27, 0x1E83}, {
858 0x57, 0x22, 0x1E84}, {
859 0x77, 0x22, 0x1E85}, {
860 0x58, 0x22, 0x1E8C}, {
861 0x78, 0x22, 0x1E8D}, {
862 0x5A, 0x5E, 0x1E90}, {
863 0x7A, 0x5E, 0x1E91}, {
864 0x74, 0x22, 0x1E97}, {
865 0x77, 0x2A, 0x1E98}, {
866 0x79, 0x2A, 0x1E99}, {
867 0x45, 0x7E, 0x1EBC}, {
868 0x65, 0x7E, 0x1EBD}, {
869 0x59, 0x60, 0x1EF2}, {
870 0x79, 0x60, 0x1EF3}, {
871 0x59, 0x7E, 0x1EF8}, {
872 0x79, 0x7E, 0x1EF9},
873 /* Compatible/possibles from UCS */
874 {
875 0x49, 0x4A, 0x0132}, {
876 0x69, 0x6A, 0x0133}, {
877 0x4C, 0x4A, 0x01C7}, {
878 0x4C, 0x6A, 0x01C8}, {
879 0x6C, 0x6A, 0x01C9}, {
880 0x4E, 0x4A, 0x01CA}, {
881 0x4E, 0x6A, 0x01CB}, {
882 0x6E, 0x6A, 0x01CC}, {
883 0x44, 0x5A, 0x01F1}, {
884 0x44, 0x7A, 0x01F2}, {
885 0x64, 0x7A, 0x01F3}, {
886 0x2E, 0x2E, 0x2025}, {
887 0x21, 0x21, 0x203C}, {
888 0x3F, 0x21, 0x2048}, {
889 0x21, 0x3F, 0x2049}, {
890 0x52, 0x73, 0x20A8}, {
891 0x4E, 0x6F, 0x2116}, {
892 0x53, 0x4D, 0x2120}, {
893 0x54, 0x4D, 0x2122}, {
894 0x49, 0x49, 0x2161}, {
895 0x49, 0x56, 0x2163}, {
896 0x56, 0x49, 0x2165}, {
897 0x49, 0x58, 0x2168}, {
898 0x58, 0x49, 0x216A}, {
899 0x69, 0x69, 0x2171}, {
900 0x69, 0x76, 0x2173}, {
901 0x76, 0x69, 0x2175}, {
902 0x69, 0x78, 0x2178}, {
903 0x78, 0x69, 0x217A}, {
904 0x31, 0x30, 0x2469}, {
905 0x31, 0x31, 0x246A}, {
906 0x31, 0x32, 0x246B}, {
907 0x31, 0x33, 0x246C}, {
908 0x31, 0x34, 0x246D}, {
909 0x31, 0x35, 0x246E}, {
910 0x31, 0x36, 0x246F}, {
911 0x31, 0x37, 0x2470}, {
912 0x31, 0x38, 0x2471}, {
913 0x31, 0x39, 0x2472}, {
914 0x32, 0x30, 0x2473}, {
915 0x31, 0x2E, 0x2488}, {
916 0x32, 0x2E, 0x2489}, {
917 0x33, 0x2E, 0x248A}, {
918 0x34, 0x2E, 0x248B}, {
919 0x35, 0x2E, 0x248C}, {
920 0x36, 0x2E, 0x248D}, {
921 0x37, 0x2E, 0x248E}, {
922 0x38, 0x2E, 0x248F}, {
923 0x39, 0x2E, 0x2490}, {
924 0x64, 0x61, 0x3372}, {
925 0x41, 0x55, 0x3373}, {
926 0x6F, 0x56, 0x3375}, {
927 0x70, 0x63, 0x3376}, {
928 0x70, 0x41, 0x3380}, {
929 0x6E, 0x41, 0x3381}, {
930 0x6D, 0x41, 0x3383}, {
931 0x6B, 0x41, 0x3384}, {
932 0x4B, 0x42, 0x3385}, {
933 0x4D, 0x42, 0x3386}, {
934 0x47, 0x42, 0x3387}, {
935 0x70, 0x46, 0x338A}, {
936 0x6E, 0x46, 0x338B}, {
937 0x6D, 0x67, 0x338E}, {
938 0x6B, 0x67, 0x338F}, {
939 0x48, 0x7A, 0x3390}, {
940 0x66, 0x6D, 0x3399}, {
941 0x6E, 0x6D, 0x339A}, {
942 0x6D, 0x6D, 0x339C}, {
943 0x63, 0x6D, 0x339D}, {
944 0x6B, 0x6D, 0x339E}, {
945 0x50, 0x61, 0x33A9}, {
946 0x70, 0x73, 0x33B0}, {
947 0x6E, 0x73, 0x33B1}, {
948 0x6D, 0x73, 0x33B3}, {
949 0x70, 0x56, 0x33B4}, {
950 0x6E, 0x56, 0x33B5}, {
951 0x6D, 0x56, 0x33B7}, {
952 0x6B, 0x56, 0x33B8}, {
953 0x4D, 0x56, 0x33B9}, {
954 0x70, 0x57, 0x33BA}, {
955 0x6E, 0x57, 0x33BB}, {
956 0x6D, 0x57, 0x33BD}, {
957 0x6B, 0x57, 0x33BE}, {
958 0x4D, 0x57, 0x33BF}, {
959 0x42, 0x71, 0x33C3}, {
960 0x63, 0x63, 0x33C4}, {
961 0x63, 0x64, 0x33C5}, {
962 0x64, 0x42, 0x33C8}, {
963 0x47, 0x79, 0x33C9}, {
964 0x68, 0x61, 0x33CA}, {
965 0x48, 0x50, 0x33CB}, {
966 0x69, 0x6E, 0x33CC}, {
967 0x4B, 0x4B, 0x33CD}, {
968 0x4B, 0x4D, 0x33CE}, {
969 0x6B, 0x74, 0x33CF}, {
970 0x6C, 0x6D, 0x33D0}, {
971 0x6C, 0x6E, 0x33D1}, {
972 0x6C, 0x78, 0x33D3}, {
973 0x6D, 0x62, 0x33D4}, {
974 0x50, 0x48, 0x33D7}, {
975 0x50, 0x52, 0x33DA}, {
976 0x73, 0x72, 0x33DB}, {
977 0x53, 0x76, 0x33DC}, {
978 0x57, 0x62, 0x33DD}, {
979 0x66, 0x66, 0xFB00}, {
980 0x66, 0x69, 0xFB01}, {
981 0x66, 0x6C, 0xFB02}, {
982 0x73, 0x74, 0xFB06}, {
983 0, 0, 0}
984 }, *c;
985
4eeb7d09 986 int nc = -1;
987
988 for (c = composetbl; c->first; c++) {
989 if (c->first == first && c->second == second)
990 return c->composed;
991 }
992
993 if (recurse == 0) {
c85623f9 994 nc = check_compose_internal(second, first, 1);
4eeb7d09 995 if (nc == -1)
07b2a9cd 996 nc = check_compose_internal(toupper(first), toupper(second), 1);
4eeb7d09 997 if (nc == -1)
07b2a9cd 998 nc = check_compose_internal(toupper(second), toupper(first), 1);
4eeb7d09 999 }
1000 return nc;
1001}
1002
c85623f9 1003int check_compose(int first, int second)
1004{
1005 return check_compose_internal(first, second, 0);
1006}
1007
4eeb7d09 1008int decode_codepage(char *cp_name)
1009{
1010 char *s, *d;
c4399982 1011 const struct cp_list_item *cpi;
4eeb7d09 1012 int codepage = -1;
4eeb7d09 1013 CPINFO cpinfo;
1014
b8ae1f0f 1015 if (!*cp_name) {
1016 /*
1017 * Here we select a plausible default code page based on
1018 * the locale the user is in. We wish to select an ISO code
1019 * page or appropriate local default _rather_ than go with
1020 * the Win125* series, because it's more important to have
1021 * CSI and friends enabled by default than the ghastly
1022 * Windows extra quote characters, and because it's more
1023 * likely the user is connecting to a remote server that
1024 * does something Unixy or VMSy and hence standards-
1025 * compliant than that they're connecting back to a Windows
1026 * box using horrible nonstandard charsets.
1027 *
1028 * Accordingly, Robert de Bath suggests a method for
1029 * picking a default character set that runs as follows:
1030 * first call GetACP to get the system's ANSI code page
1031 * identifier, and translate as follows:
1032 *
1033 * 1250 -> ISO 8859-2
1034 * 1251 -> KOI8-U
1035 * 1252 -> ISO 8859-1
1036 * 1253 -> ISO 8859-7
1037 * 1254 -> ISO 8859-9
1038 * 1255 -> ISO 8859-8
1039 * 1256 -> ISO 8859-6
a86d1f85 1040 * 1257 -> ISO 8859-13 (changed from 8859-4 on advice of a Lithuanian)
b8ae1f0f 1041 *
1042 * and for anything else, choose direct-to-font.
1043 */
1044 int cp = GetACP();
1045 switch (cp) {
1046 case 1250: cp_name = "ISO-8859-2"; break;
1047 case 1251: cp_name = "KOI8-U"; break;
1048 case 1252: cp_name = "ISO-8859-1"; break;
1049 case 1253: cp_name = "ISO-8859-7"; break;
1050 case 1254: cp_name = "ISO-8859-9"; break;
1051 case 1255: cp_name = "ISO-8859-8"; break;
1052 case 1256: cp_name = "ISO-8859-6"; break;
a86d1f85 1053 case 1257: cp_name = "ISO-8859-13"; break;
b8ae1f0f 1054 /* default: leave it blank, which will select -1, direct->font */
1055 }
1056 }
1057
4eeb7d09 1058 if (cp_name && *cp_name)
1059 for (cpi = cp_list; cpi->name; cpi++) {
1060 s = cp_name;
1061 d = cpi->name;
1062 for (;;) {
1063 while (*s && !isalnum(*s) && *s != ':')
1064 s++;
1065 while (*d && !isalnum(*d) && *d != ':')
1066 d++;
1067 if (*s == 0) {
1068 codepage = cpi->codepage;
1069 if (codepage == CP_UTF8)
1070 goto break_break;
792de8f6 1071 if (codepage == -1)
1072 return codepage;
4eeb7d09 1073 if (codepage == 0) {
1074 codepage = 65536 + (cpi - cp_list);
1075 goto break_break;
1076 }
1077
1078 if (GetCPInfo(codepage, &cpinfo) != 0)
1079 goto break_break;
1080 }
274a5b41 1081 if (tolower(*s++) != tolower(*d++))
4eeb7d09 1082 break;
1083 }
1084 }
1085
1086 if (cp_name && *cp_name) {
1087 d = cp_name;
2d466ffd 1088 if (tolower(d[0]) == 'c' && tolower(d[1]) == 'p')
4eeb7d09 1089 d += 2;
2d466ffd 1090 if (tolower(d[0]) == 'i' && tolower(d[1]) == 'b'
1091 && tolower(d[1]) == 'm')
4eeb7d09 1092 d += 3;
1093 for (s = d; *s >= '0' && *s <= '9'; s++);
1094 if (*s == 0 && s != d)
1095 codepage = atoi(d); /* CP999 or IBM999 */
1096
1097 if (codepage == CP_ACP)
1098 codepage = GetACP();
1099 if (codepage == CP_OEMCP)
1100 codepage = GetOEMCP();
1101 if (codepage > 65535)
1102 codepage = -2;
1103 }
1104
1105 break_break:;
1106 if (codepage != -1) {
1107 if (codepage != CP_UTF8 && codepage < 65536) {
1108 if (GetCPInfo(codepage, &cpinfo) == 0) {
1109 codepage = -2;
1110 } else if (cpinfo.MaxCharSize > 1)
1111 codepage = -3;
1112 }
1113 }
1114 if (codepage == -1 && *cp_name)
1115 codepage = -2;
1116 return codepage;
1117}
1118
d4413bd2 1119const char *cp_name(int codepage)
4eeb7d09 1120{
c4399982 1121 const struct cp_list_item *cpi, *cpno;
4eeb7d09 1122 static char buf[32];
b8ae1f0f 1123
1124 if (codepage == -1) {
1125 sprintf(buf, "Use font encoding");
1126 return buf;
1127 }
1128
4eeb7d09 1129 if (codepage > 0 && codepage < 65536)
1130 sprintf(buf, "CP%03d", codepage);
1131 else
1132 *buf = 0;
1133
1134 if (codepage >= 65536) {
1135 cpno = 0;
1136 for (cpi = cp_list; cpi->name; cpi++)
1137 if (cpi == cp_list + (codepage - 65536)) {
1138 cpno = cpi;
1139 break;
1140 }
1141 if (cpno)
1142 for (cpi = cp_list; cpi->name; cpi++) {
1143 if (cpno->cp_table == cpi->cp_table)
1144 return cpi->name;
1145 }
1146 } else {
1147 for (cpi = cp_list; cpi->name; cpi++) {
1148 if (codepage == cpi->codepage)
1149 return cpi->name;
1150 }
1151 }
1152 return buf;
1153}
1154
875b193f 1155/*
1156 * Return the nth code page in the list, for use in the GUI
1157 * configurer.
1158 */
d4413bd2 1159const char *cp_enumerate(int index)
875b193f 1160{
1161 if (index < 0 || index >= lenof(cp_list))
1162 return NULL;
1163 return cp_list[index].name;
1164}
1165
a7419ea4 1166void get_unitab(int codepage, wchar_t * unitab, int ftype)
4eeb7d09 1167{
1168 char tbuf[4];
1169 int i, max = 256, flg = MB_ERR_INVALID_CHARS;
1170
1171 if (ftype)
1172 flg |= MB_USEGLYPHCHARS;
1173 if (ftype == 2)
1174 max = 128;
1175
d6dcf6c6 1176 if (codepage == CP_UTF8) {
1177 for (i = 0; i < max; i++)
1178 unitab[i] = i;
1179 return;
1180 }
1181
1182 if (codepage == CP_ACP)
4eeb7d09 1183 codepage = GetACP();
1184 else if (codepage == CP_OEMCP)
1185 codepage = GetOEMCP();
1186
1187 if (codepage > 0 && codepage < 65536) {
1188 for (i = 0; i < max; i++) {
1189 tbuf[0] = i;
1190
1709795f 1191 if (mb_to_wc(codepage, flg, tbuf, 1, unitab + i, 1)
4eeb7d09 1192 != 1)
1193 unitab[i] = 0xFFFD;
1194 }
1195 } else {
1196 int j = 256 - cp_list[codepage & 0xFFFF].cp_size;
1197 for (i = 0; i < max; i++)
1198 unitab[i] = i;
1199 for (i = j; i < max; i++)
1200 unitab[i] = cp_list[codepage & 0xFFFF].cp_table[i - j];
1201 }
1202}
5def7522 1203
1204int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
21d2b241 1205 char *mbstr, int mblen, char *defchr, int *defused,
1206 struct unicode_data *ucsdata)
5def7522 1207{
1208 char *p;
1209 int i;
21d2b241 1210 if (ucsdata && codepage == ucsdata->line_codepage && ucsdata->uni_tbl) {
5def7522 1211 /* Do this by array lookup if we can. */
1212 if (wclen < 0) {
1213 for (wclen = 0; wcstr[wclen++] ;); /* will include the NUL */
1214 }
1215 for (p = mbstr, i = 0; i < wclen; i++) {
1216 wchar_t ch = wcstr[i];
1217 int by;
1218 char *p1;
21d2b241 1219 if (ucsdata->uni_tbl && (p1 = ucsdata->uni_tbl[(ch >> 8) & 0xFF])
5def7522 1220 && (by = p1[ch & 0xFF]))
1221 *p++ = by;
1222 else if (ch < 0x80)
1223 *p++ = (char) ch;
1224 else if (defchr) {
1225 int j;
1226 for (j = 0; defchr[j]; j++)
1227 *p++ = defchr[j];
1228 if (defused) *defused = 1;
1229 }
1230#if 1
1231 else
1232 *p++ = '.';
1233#endif
1234 assert(p - mbstr < mblen);
1235 }
1236 return p - mbstr;
1237 } else
1238 return WideCharToMultiByte(codepage, flags, wcstr, wclen,
1239 mbstr, mblen, defchr, defused);
1240}
1241
1242int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
1243 wchar_t *wcstr, int wclen)
1244{
1245 return MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
1246}
1247
1248int is_dbcs_leadbyte(int codepage, char byte)
1249{
1250 return IsDBCSLeadByteEx(codepage, byte);
1251}