1709795f |
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <ctype.h> |
4 | |
5 | #include <time.h> |
6 | #include "putty.h" |
7 | #include "misc.h" |
8 | |
9 | /* |
10 | * Unix Unicode-handling routines. |
11 | * |
12 | * FIXME: currently trivial stub versions assuming all codepages |
13 | * are ISO8859-1. |
14 | */ |
15 | |
16 | void lpage_send(int codepage, char *buf, int len, int interactive) |
17 | { |
18 | ldisc_send(buf, len, interactive); |
19 | } |
20 | |
21 | void luni_send(wchar_t * widebuf, int len, int interactive) |
22 | { |
23 | static char *linebuffer = 0; |
24 | static int linesize = 0; |
25 | int ratio = (in_utf)?6:1; |
26 | int i; |
27 | char *p; |
28 | |
29 | if (len * ratio > linesize) { |
30 | sfree(linebuffer); |
31 | linebuffer = smalloc(len * ratio * 2 * sizeof(wchar_t)); |
32 | linesize = len * ratio * 2; |
33 | } |
34 | |
35 | if (in_utf) { |
36 | /* UTF is a simple algorithm */ |
37 | for (p = linebuffer, i = 0; i < len; i++) { |
38 | wchar_t ch = widebuf[i]; |
39 | |
40 | if ((ch&0xF800) == 0xD800) ch = '.'; |
41 | |
42 | if (ch < 0x80) { |
43 | *p++ = (char) (ch); |
44 | } else if (ch < 0x800) { |
45 | *p++ = (0xC0 | (ch >> 6)); |
46 | *p++ = (0x80 | (ch & 0x3F)); |
47 | } else if (ch < 0x10000) { |
48 | *p++ = (0xE0 | (ch >> 12)); |
49 | *p++ = (0x80 | ((ch >> 6) & 0x3F)); |
50 | *p++ = (0x80 | (ch & 0x3F)); |
51 | } else if (ch < 0x200000) { |
52 | *p++ = (0xF0 | (ch >> 18)); |
53 | *p++ = (0x80 | ((ch >> 12) & 0x3F)); |
54 | *p++ = (0x80 | ((ch >> 6) & 0x3F)); |
55 | *p++ = (0x80 | (ch & 0x3F)); |
56 | } else if (ch < 0x4000000) { |
57 | *p++ = (0xF8 | (ch >> 24)); |
58 | *p++ = (0x80 | ((ch >> 18) & 0x3F)); |
59 | *p++ = (0x80 | ((ch >> 12) & 0x3F)); |
60 | *p++ = (0x80 | ((ch >> 6) & 0x3F)); |
61 | *p++ = (0x80 | (ch & 0x3F)); |
62 | } else { |
63 | *p++ = (0xFC | (ch >> 30)); |
64 | *p++ = (0x80 | ((ch >> 24) & 0x3F)); |
65 | *p++ = (0x80 | ((ch >> 18) & 0x3F)); |
66 | *p++ = (0x80 | ((ch >> 12) & 0x3F)); |
67 | *p++ = (0x80 | ((ch >> 6) & 0x3F)); |
68 | *p++ = (0x80 | (ch & 0x3F)); |
69 | } |
70 | } |
71 | } else { |
72 | for (p = linebuffer, i = 0; i < len; i++) { |
73 | wchar_t ch = widebuf[i]; |
74 | if (ch < 0x100) |
75 | *p++ = (char) ch; |
76 | else |
77 | *p++ = '.'; |
78 | } |
79 | } |
80 | if (p > linebuffer) |
81 | ldisc_send(linebuffer, p - linebuffer, interactive); |
82 | } |
83 | |
84 | int is_dbcs_leadbyte(int codepage, char byte) |
85 | { |
86 | return 0; /* we don't do DBCS */ |
87 | } |
88 | |
89 | int mb_to_wc(int codepage, int flags, char *mbstr, int mblen, |
90 | wchar_t *wcstr, int wclen) |
91 | { |
92 | int ret = 0; |
93 | while (mblen > 0 && wclen > 0) { |
94 | *wcstr++ = (unsigned char) *mbstr++; |
e6346999 |
95 | mblen--, wclen--, ret++; |
96 | } |
97 | return ret; /* FIXME: check error codes! */ |
98 | } |
99 | |
100 | int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, |
101 | char *mbstr, int mblen, char *defchr, int *defused) |
102 | { |
103 | int ret = 0; |
104 | if (defused) |
105 | *defused = 0; |
106 | while (mblen > 0 && wclen > 0) { |
107 | if (*wcstr >= 0x100) { |
108 | if (defchr) |
109 | *mbstr++ = *defchr; |
110 | else |
111 | *mbstr++ = '\xBF'; |
112 | if (defused) |
113 | *defused = 1; |
114 | } else |
115 | *mbstr++ = (unsigned char) *wcstr; |
116 | wcstr++; |
117 | mblen--, wclen--, ret++; |
1709795f |
118 | } |
119 | return ret; /* FIXME: check error codes! */ |
120 | } |
121 | |
122 | void init_ucs(void) |
123 | { |
124 | int i; |
125 | /* Find the line control characters. FIXME: this is not right. */ |
126 | for (i = 0; i < 256; i++) |
127 | if (i < ' ' || (i >= 0x7F && i < 0xA0)) |
128 | unitab_ctrl[i] = i; |
129 | else |
130 | unitab_ctrl[i] = 0xFF; |
131 | |
132 | for (i = 0; i < 256; i++) { |
133 | unitab_line[i] = unitab_scoacs[i] = i; |
2c0380dc |
134 | unitab_xterm[i] = (i+1) & 0x1F; |
1709795f |
135 | } |
126ce234 |
136 | } |