76a3e871 |
1 | /* $Id$ */ |
d082ac49 |
2 | |
3 | #include <stdio.h> |
4 | #include <stdlib.h> |
5 | #include <ctype.h> |
6 | |
7 | #include <time.h> |
8 | #include "putty.h" |
76a3e871 |
9 | #include "charset.h" |
d082ac49 |
10 | #include "terminal.h" |
11 | #include "misc.h" |
2f9549c7 |
12 | #include "mac.h" |
d082ac49 |
13 | |
14 | /* |
15 | * Mac Unicode-handling routines. |
16 | * |
76a3e871 |
17 | * BJH: |
d082ac49 |
18 | * What we _should_ do is to use the Text Encoding Conversion Manager |
19 | * when it's available, and have our own routines for converting to |
20 | * standard Mac OS scripts when it's not. Support for ATSUI might be |
21 | * nice, too. |
76a3e871 |
22 | * |
23 | * I (OSD) am unsure any of the above is necessary if we just use |
24 | * libcharset */ |
d082ac49 |
25 | |
e530c9fa |
26 | /* |
27 | * Determine whether a byte is the first byte of a double-byte |
28 | * character in a system character set. Only MI use is by clipme() |
29 | * when copying direct-to-font text to the clipboard. |
30 | */ |
d082ac49 |
31 | int is_dbcs_leadbyte(int codepage, char byte) |
32 | { |
33 | return 0; /* we don't do DBCS */ |
34 | } |
35 | |
e530c9fa |
36 | /* |
37 | * Convert from Unicode to a system character set. MI uses are: |
38 | * (1) by lpage_send(), whose only MI use is to convert the answerback |
39 | * string to Unicode, and |
40 | * (2) by clipme() when copying direct-to-font text to the clipboard. |
41 | */ |
d082ac49 |
42 | int mb_to_wc(int codepage, int flags, char *mbstr, int mblen, |
43 | wchar_t *wcstr, int wclen) |
44 | { |
45 | int ret = 0; |
46 | while (mblen > 0 && wclen > 0) { |
47 | *wcstr++ = (unsigned char) *mbstr++; |
48 | mblen--, wclen--, ret++; |
49 | } |
50 | return ret; /* FIXME: check error codes! */ |
51 | } |
52 | |
e530c9fa |
53 | /* |
54 | * Convert from a system character set to Unicode. Used by luni_send |
55 | * to convert Unicode into the line character set. |
56 | */ |
d082ac49 |
57 | int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, |
c31f6c61 |
58 | char *mbstr, int mblen, char *defchr, int *defused, |
59 | struct unicode_data *ucsdata) |
d082ac49 |
60 | { |
61 | int ret = 0; |
62 | if (defused) |
63 | *defused = 0; |
64 | while (mblen > 0 && wclen > 0) { |
65 | if (*wcstr >= 0x100) { |
66 | if (defchr) |
67 | *mbstr++ = *defchr; |
68 | else |
69 | *mbstr++ = '.'; |
70 | if (defused) |
71 | *defused = 1; |
72 | } else |
73 | *mbstr++ = (unsigned char) *wcstr; |
74 | wcstr++; |
75 | mblen--, wclen--, ret++; |
76 | } |
77 | return ret; /* FIXME: check error codes! */ |
78 | } |
79 | |
bbe29f1f |
80 | /* Character conversion array, |
81 | * the xterm one has the four scanlines that have no unicode 2.0 |
82 | * equivalents mapped to their unicode 3.0 locations. |
83 | */ |
84 | static const wchar_t unitab_xterm_std[32] = { |
85 | 0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, |
86 | 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba, |
87 | 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c, |
88 | 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020 |
89 | }; |
90 | |
c31f6c61 |
91 | void init_ucs(Session *s) |
d082ac49 |
92 | { |
93 | int i; |
c31f6c61 |
94 | |
76a3e871 |
95 | s->ucsdata.line_codepage = decode_codepage(s->cfg.line_codepage); |
96 | |
d082ac49 |
97 | /* Find the line control characters. FIXME: this is not right. */ |
98 | for (i = 0; i < 256; i++) |
99 | if (i < ' ' || (i >= 0x7F && i < 0xA0)) |
c31f6c61 |
100 | s->ucsdata.unitab_ctrl[i] = i; |
d082ac49 |
101 | else |
c31f6c61 |
102 | s->ucsdata.unitab_ctrl[i] = 0xFF; |
d082ac49 |
103 | |
bbe29f1f |
104 | for (i = 0; i < 256; i++) |
c31f6c61 |
105 | s->ucsdata.unitab_line[i] = s->ucsdata.unitab_scoacs[i] = i; |
bbe29f1f |
106 | |
107 | /* VT100 graphics - NB: Broken for non-ascii CP's */ |
108 | memcpy(s->ucsdata.unitab_xterm, s->ucsdata.unitab_line, |
109 | sizeof(s->ucsdata.unitab_xterm)); |
110 | memcpy(s->ucsdata.unitab_xterm + '`', unitab_xterm_std, |
111 | sizeof(unitab_xterm_std)); |
112 | s->ucsdata.unitab_xterm['_'] = ' '; |
113 | |
d082ac49 |
114 | } |
8a7e67ec |
115 | |
116 | int decode_codepage(char *cp_name) |
117 | { |
76a3e871 |
118 | if (!*cp_name) |
119 | return CS_NONE; /* use font encoding */ |
120 | return charset_from_localenc(cp_name); |
8a7e67ec |
121 | } |
122 | |
06567a99 |
123 | char const *cp_enumerate (int index) |
8a7e67ec |
124 | { |
76a3e871 |
125 | int charset; |
126 | if (index == 0) |
127 | return "Use font encoding"; |
128 | charset = charset_localenc_nth(index-1); |
129 | if (charset == CS_NONE) |
130 | return NULL; |
131 | return charset_to_localenc(charset); |
8a7e67ec |
132 | } |
133 | |
06567a99 |
134 | char const *cp_name(int codepage) |
8a7e67ec |
135 | { |
76a3e871 |
136 | if (codepage == CS_NONE) |
137 | return "Use font encoding"; |
138 | return charset_to_localenc(codepage); |
8a7e67ec |
139 | } |