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