mirror of
https://github.com/rfivet/uemacs.git
synced 2024-11-05 03:47:17 -05:00
Use utf8 helper functions for keyboard input
ttgetc() used some homebrew utf8 to unicode translation, limited to just the normal latin1 characters. Use the utf8 helper functions to get it right for the more complex cases. NOTE! We don't actually handle characters > 0xff right anyway. And we still end up doing Latin1 in the buffers on input. One small step at a time. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
6b793211c2
commit
ec6f4f36ec
68
posix.c
68
posix.c
@ -150,10 +150,10 @@ void ttflush(void)
|
||||
*/
|
||||
int ttgetc(void)
|
||||
{
|
||||
static unsigned char buffer[32];
|
||||
static char buffer[32];
|
||||
static int pending;
|
||||
unsigned char c, second;
|
||||
int count;
|
||||
unicode_t c;
|
||||
int count, bytes = 1;
|
||||
|
||||
count = pending;
|
||||
if (!count) {
|
||||
@ -163,7 +163,7 @@ int ttgetc(void)
|
||||
pending = count;
|
||||
}
|
||||
|
||||
c = buffer[0];
|
||||
c = (unsigned char) buffer[0];
|
||||
if (c >= 32 && c < 128)
|
||||
goto done;
|
||||
|
||||
@ -181,56 +181,24 @@ int ttgetc(void)
|
||||
ntermios.c_cc[VTIME] = 0;
|
||||
tcsetattr(0, TCSANOW, &ntermios);
|
||||
|
||||
if (n <= 0)
|
||||
if (n > 0)
|
||||
pending += n;
|
||||
}
|
||||
if (pending > 1) {
|
||||
unsigned char second = buffer[1];
|
||||
|
||||
/* Turn ESC+'[' into CSI */
|
||||
if (c == 27 && second == '[') {
|
||||
bytes = 2;
|
||||
c = 128+27;
|
||||
goto done;
|
||||
pending += n;
|
||||
}
|
||||
}
|
||||
second = buffer[1];
|
||||
|
||||
/* Turn ESC+'[' into CSI */
|
||||
if (c == 27 && second == '[') {
|
||||
pending -= 2;
|
||||
memmove(buffer, buffer+2, pending);
|
||||
return 128+27;
|
||||
}
|
||||
|
||||
/* Normal 7-bit? */
|
||||
if (!(c & 0x80))
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Unexpected UTF-8 continuation character? Maybe
|
||||
* we're in non-UTF mode, or maybe it's a control
|
||||
* character.. Regardless, just pass it on.
|
||||
*/
|
||||
if (!(c & 0x40))
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Multi-byte sequences.. Right now we only
|
||||
* want to get characters that can be represented
|
||||
* in a single byte, so we're not interested in
|
||||
* anything else..
|
||||
*/
|
||||
if (c & 0x3c)
|
||||
goto done;
|
||||
|
||||
if ((second & 0xc0) != 0x80)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Ok, it's a two-byte UTF-8 character that can be represented
|
||||
* as a single-byte Latin1 character!
|
||||
*/
|
||||
c = (c << 6) | (second & 0x3f);
|
||||
pending -= 2;
|
||||
memmove(buffer, buffer+2, pending);
|
||||
|
||||
return c;
|
||||
bytes = utf8_to_unicode(buffer, 0, pending, &c);
|
||||
|
||||
done:
|
||||
pending--;
|
||||
memmove(buffer, buffer+1, pending);
|
||||
pending -= bytes;
|
||||
memmove(buffer, buffer+bytes, pending);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user