#include <data.h>
#if defined(EAGAIN) && defined(EWOULDBLOCK)
#define E_TEST(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
#else
#ifdef EAGAIN
#define E_TEST(err) ((err) == EAGAIN)
#else
#define E_TEST(err) ((err) == EWOULDBLOCK)
#endif
#endif
int
getPtyData(TScreen * screen, fd_set * select_mask, PtyData * data)
{
int i;
if (FD_ISSET(screen->respond, select_mask)) {
#ifdef ALLOWLOGGING
if (screen->logging)
FlushLog(screen);
#endif
data->ptr = DecodedData(data);
data->cnt = read(screen->respond, (char *) data->buf, BUF_SIZE);
if (data->cnt <= 0) {
#if (defined(i386) && defined(SVR4) && defined(sun)) || defined(__CYGWIN__)
if (errno == EIO || errno == 0)
#else
if (errno == EIO)
#endif
Cleanup(0);
else if (!E_TEST(errno))
Panic("input: read returned unexpected error (%d)\n", errno);
} else if (data->cnt == 0) {
#if defined(__UNIXOS2__)
Cleanup(0);
#else
Panic("input: read returned zero\n", 0);
#endif
} else {
#if OPT_WIDE_CHARS
if (screen->utf8_mode) {
int j = 0;
for (i = 0; i < data->cnt; i++) {
unsigned c = data->buf[i];
if (c < 0x80) {
if (screen->utf_count > 0)
data->buf2[j++] = UCS_REPL;
data->buf2[j++] = c;
screen->utf_count = 0;
} else if (c < 0xc0) {
if (screen->utf_count < 1) {
data->buf2[j++] = UCS_REPL;
} else {
if (!screen->utf_char && !((c & 0x7f) >> (7 - screen->utf_count))) {
screen->utf_char = UCS_REPL;
}
if (screen->utf_char > 0x03ff) {
screen->utf_char = UCS_REPL;
} else {
screen->utf_char <<= 6;
screen->utf_char |= (c & 0x3f);
}
if ((screen->utf_char >= 0xd800 &&
screen->utf_char <= 0xdfff) ||
(screen->utf_char == 0xfffe) ||
(screen->utf_char == 0xffff)) {
screen->utf_char = UCS_REPL;
}
screen->utf_count--;
if (screen->utf_count == 0)
data->buf2[j++] = screen->utf_char;
}
} else {
if (screen->utf_count > 0)
data->buf2[j++] = UCS_REPL;
if (c < 0xe0) {
screen->utf_count = 1;
screen->utf_char = (c & 0x1f);
if (!(c & 0x1e))
screen->utf_char = UCS_REPL;
} else if (c < 0xf0) {
screen->utf_count = 2;
screen->utf_char = (c & 0x0f);
} else if (c < 0xf8) {
screen->utf_count = 3;
screen->utf_char = (c & 0x07);
} else if (c < 0xfc) {
screen->utf_count = 4;
screen->utf_char = (c & 0x03);
} else if (c < 0xfe) {
screen->utf_count = 5;
screen->utf_char = (c & 0x01);
} else {
data->buf2[j++] = UCS_REPL;
screen->utf_count = 0;
}
}
}
TRACE(("UTF-8 count %d, char %04X input %d/%d bytes\n",
screen->utf_count,
screen->utf_char,
data->cnt, j));
data->cnt = j;
} else {
for (i = 0; i < data->cnt; i++)
data->ptr[i] = data->buf[i];
}
#endif
if (!screen->output_eight_bits) {
for (i = 0; i < data->cnt; i++) {
data->ptr[i] &= 0x7f;
}
}
#if OPT_TRACE
for (i = 0; i < data->cnt; i++) {
if (!(i % 8))
TRACE(("%s", i ? "\n " : "READ"));
TRACE((" %04X", data->ptr[i]));
}
TRACE(("\n"));
#endif
return (data->cnt);
}
}
return 0;
}
void
initPtyData(PtyData * data)
{
data->cnt = 0;
data->ptr = DecodedData(data);
}
unsigned
usedPtyData(PtyData * data)
{
return (data->ptr - DecodedData(data));
}
#if OPT_WIDE_CHARS
Char *
convertToUTF8(Char * lp, unsigned c)
{
if (c < 0x80) {
*lp++ = (c);
} else if (c < 0x800) {
*lp++ = (0xc0 | (c >> 6));
*lp++ = (0x80 | (c & 0x3f));
} else {
*lp++ = (0xe0 | (c >> 12));
*lp++ = (0x80 | ((c >> 6) & 0x3f));
*lp++ = (0x80 | (c & 0x3f));
}
return lp;
}
void
writePtyData(int f, IChar * d, unsigned len)
{
static Char *dbuf;
static unsigned dlen;
unsigned n = (len << 1);
if (dlen <= len) {
dlen = n;
dbuf = (Char *) XtRealloc((char *) dbuf, dlen);
}
for (n = 0; n < len; n++)
dbuf[n] = d[n];
v_write(f, dbuf, n);
}
#endif