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 (IS_SURROGATE(ch
)) {
55 #ifdef PLATFORM_IS_UTF16
57 unsigned long ch2
= widebuf
[i
+1];
58 if (IS_SURROGATE_PAIR(ch
, ch2
)) {
59 ch
= FROM_SURROGATES(ch
, ch2
);
65 /* Unrecognised UTF-16 sequence */
72 } else if (ch
< 0x800) {
73 *p
++ = (char) (0xC0 | (ch
>> 6));
74 *p
++ = (char) (0x80 | (ch
& 0x3F));
75 } else if (ch
< 0x10000) {
76 *p
++ = (char) (0xE0 | (ch
>> 12));
77 *p
++ = (char) (0x80 | ((ch
>> 6) & 0x3F));
78 *p
++ = (char) (0x80 | (ch
& 0x3F));
80 *p
++ = (char) (0xF0 | (ch
>> 18));
81 *p
++ = (char) (0x80 | ((ch
>> 12) & 0x3F));
82 *p
++ = (char) (0x80 | ((ch
>> 6) & 0x3F));
83 *p
++ = (char) (0x80 | (ch
& 0x3F));
88 rv
= wc_to_mb(ldisc
->term
->ucsdata
->line_codepage
, 0, widebuf
, len
,
89 linebuffer
, linesize
, NULL
, NULL
, ldisc
->term
->ucsdata
);
96 ldisc_send(ldisc
, linebuffer
, p
- linebuffer
, interactive
);