2 * ldisc.c: PuTTY line discipline. Sits between the input coming
3 * from keypresses in the window, and the output channel leading to
4 * the back end. Implements echo and/or local line editing,
5 * depending on what's currently configured.
15 void lpage_send(void *handle
,
16 int codepage
, char *buf
, int len
, int interactive
)
18 Ldisc ldisc
= (Ldisc
)handle
;
19 wchar_t *widebuffer
= 0;
24 ldisc_send(ldisc
, buf
, len
, interactive
);
29 widebuffer
= snewn(widesize
, wchar_t);
31 wclen
= mb_to_wc(codepage
, 0, buf
, len
, widebuffer
, widesize
);
32 luni_send(ldisc
, widebuffer
, wclen
, interactive
);
37 void luni_send(void *handle
, wchar_t * widebuf
, int len
, int interactive
)
39 Ldisc ldisc
= (Ldisc
)handle
;
40 int ratio
= (in_utf(ldisc
->term
))?
3:1;
46 linesize
= len
* ratio
* 2;
47 linebuffer
= snewn(linesize
, char);
49 if (in_utf(ldisc
->term
)) {
50 /* UTF is a simple algorithm */
51 for (p
= linebuffer
, i
= 0; i
< len
; i
++) {
52 unsigned long ch
= widebuf
[i
];
54 if ((ch
& 0xF800) == 0xD800) {
55 #ifdef PLATFORM_IS_UTF16
57 unsigned long ch2
= widebuf
[i
+1];
58 if ((ch
& 0xFC00) == 0xD800 &&
59 (ch2
& 0xFC00) == 0xDC00) {
60 ch
= 0x10000 + ((ch
& 0x3FF) << 10) + (ch2
& 0x3FF);
66 /* Unrecognised UTF-16 sequence */
73 } else if (ch
< 0x800) {
74 *p
++ = (char) (0xC0 | (ch
>> 6));
75 *p
++ = (char) (0x80 | (ch
& 0x3F));
76 } else if (ch
< 0x10000) {
77 *p
++ = (char) (0xE0 | (ch
>> 12));
78 *p
++ = (char) (0x80 | ((ch
>> 6) & 0x3F));
79 *p
++ = (char) (0x80 | (ch
& 0x3F));
81 *p
++ = (char) (0xF0 | (ch
>> 18));
82 *p
++ = (char) (0x80 | ((ch
>> 12) & 0x3F));
83 *p
++ = (char) (0x80 | ((ch
>> 6) & 0x3F));
84 *p
++ = (char) (0x80 | (ch
& 0x3F));
89 rv
= wc_to_mb(ldisc
->term
->ucsdata
->line_codepage
, 0, widebuf
, len
,
90 linebuffer
, linesize
, NULL
, NULL
, ldisc
->term
->ucsdata
);
97 ldisc_send(ldisc
, linebuffer
, p
- linebuffer
, interactive
);