From cbb507a6b5909744e4fda6d34c43df2696717e05 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sat, 20 May 2006 14:05:45 +0200 Subject: [PATCH] WIN32 port: introduced VT100 decoder. ELinks is able to display first page of the document. Keyboard doesn't work, Windows style path either. I tested it only under Wine. --- src/main/select.c | 7 ++- src/osdep/win32/Makefile | 2 +- src/osdep/win32/overrides.c | 7 ++- src/osdep/win32/vt100.c | 113 ++++++++++++++++++++++++++++++++++++ src/osdep/win32/vt100.h | 15 +++++ src/util/time.c | 4 +- src/util/time.h | 2 +- 7 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 src/osdep/win32/vt100.c create mode 100644 src/osdep/win32/vt100.h diff --git a/src/main/select.c b/src/main/select.c index 08cd4d563..ebb6ccd83 100644 --- a/src/main/select.c +++ b/src/main/select.c @@ -243,7 +243,7 @@ select_loop(void (*init)(void)) #endif if (has_timer) { /* Be sure timeout is not negative. */ - timeval_limit_to_zero(&t); + timeval_limit_to_zero_or_one(&t); timeout = (struct timeval *) &t; } @@ -335,5 +335,10 @@ can_read(int fd) int can_write(int fd) { +#ifdef CONFIG_OS_WIN32 + /* temporary hack. ELinks didn't start properly under Wine */ + return 1; +#else return can_read_or_write(fd, 1); +#endif } diff --git a/src/osdep/win32/Makefile b/src/osdep/win32/Makefile index b8ca9775d..09bfb1623 100644 --- a/src/osdep/win32/Makefile +++ b/src/osdep/win32/Makefile @@ -1,6 +1,6 @@ top_builddir=../../.. include $(top_builddir)/Makefile.config -OBJS = win32.o overrides.o +OBJS = overrides.o vt100.o win32.o include $(top_srcdir)/Makefile.lib diff --git a/src/osdep/win32/overrides.c b/src/osdep/win32/overrides.c index 652497d81..2f77386ef 100644 --- a/src/osdep/win32/overrides.c +++ b/src/osdep/win32/overrides.c @@ -25,6 +25,7 @@ #include "intl/gettext/libintl.h" #include "osdep/osdep.h" #include "osdep/win32/overrides.h" +#include "osdep/win32/vt100.h" #include "osdep/win32/win32.h" #include "terminal/mouse.h" #include "terminal/terminal.h" @@ -209,9 +210,11 @@ win32_write(int fd, const void *buf, unsigned len) case FDT_TERMINAL: if (isatty(STDOUT_FILENO) > 0) { - /* TODO: pass to VT100 decoder */ - WriteConsole ((HANDLE) fd, buf, len, &written, NULL); +#if 0 + WriteConsole ((HANDLE) fd, buf, len, &written, NULL); rc = written; +#endif + rc = VT100_decode((HANDLE) fd, buf, len); } else { /* stdout redirected */ rc = write(STDOUT_FILENO, buf, len); diff --git a/src/osdep/win32/vt100.c b/src/osdep/win32/vt100.c new file mode 100644 index 000000000..918dcc2b1 --- /dev/null +++ b/src/osdep/win32/vt100.c @@ -0,0 +1,113 @@ + +/* VT 100 emulation */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "osdep/system.h" + +#include +#include +#include +#include +#include +#include + +#include "elinks.h" + +#include "osdep/osdep.h" +#include "osdep/win32/win32.h" + + +int +VT100_decode(HANDLE fd, const void *b, int len) +{ + static unsigned char intensity = 0; + static unsigned char fore = 7; + static unsigned char back = 0; + char *buf = (char *)b; + + int length = len; + int i = 0; + + while (1) { + if (len <= 0) return length; + for (i = 0; i < len && buf[i] != 27; i++); + if (i) { + DWORD w; + + WriteConsole(fd, buf, i, &w, NULL); + len -= w; + if (len <= 0) return length; + buf += w; + } + if (!strncmp(buf, "\033)0\0337", 5)) { + buf += 5; + len -= 5; + continue; + } + if (!strncmp(buf, "\033[?47h", 6)) { + buf += 6; + len -= 6; + continue; + } + if (!strncmp(buf, "\033[?47l", 6)) { + buf += 6; + len -= 6; + continue; + } + if (!strncmp(buf, "\033[2J", 4)) { + /* Clear screen */ + buf += 4; + len -= 4; + continue; + } + if (buf[1] == '[') { + char *tail; + char *begin; + char *end; + COORD pos; + + buf += 2; + len -= 2; + int k = strspn(buf, "0123456789;"); + if (!k) continue; + switch (buf[k]) { + case 'H': + pos.Y = (short)strtol(buf, &tail, 10) - 1; + pos.X = (short)strtol(tail + 1, NULL, 10) - 1; + SetConsoleCursorPosition(fd, pos); + break; + case 'm': + end = buf + k; + begin = tail = buf; + while (tail < end) { + static unsigned char kolors[8] = {0, 4, 2, 6, 1, 5, 3, 7}; + unsigned char kod = (unsigned char)strtol(begin, &tail, 10); + + begin = tail + 1; + if (kod == 0) { + intensity = 0; + } else if (kod == 1) { + intensity = 8; + } else if (kod >= 30 && kod <= 37) { + fore = kolors[kod - 30]; + } else if (kod >= 40 && kod <= 47) { + back = kolors[kod - 40]; + } + } + SetConsoleTextAttribute(fd, fore | intensity | back << 4); + break; + default: + break; + } + k++; + buf += k; + len -= k; + } else { + buf += 2; + len -= 2; + } + } +} diff --git a/src/osdep/win32/vt100.h b/src/osdep/win32/vt100.h new file mode 100644 index 000000000..4fd393adf --- /dev/null +++ b/src/osdep/win32/vt100.h @@ -0,0 +1,15 @@ +#ifndef EL__OSDEP_WIN32_VT100_H +#define EL__OSDEP_WIN32_VT100_H + +#ifdef CONFIG_OS_WIN32 + +#ifdef HAVE_WINDOWS_H +#include +#endif + +int VT100_decode(HANDLE, const void *, int); + +#endif + +#endif + diff --git a/src/util/time.c b/src/util/time.c index 4492b74e6..8e0637ea3 100644 --- a/src/util/time.c +++ b/src/util/time.c @@ -198,10 +198,12 @@ timeval_is_positive(timeval_T *t) /* Be sure timeval is not negative. */ void -timeval_limit_to_zero(timeval_T *t) +timeval_limit_to_zero_or_one(timeval_T *t) { if (t->sec < 0) t->sec = 0; if (t->usec < 0) t->usec = 0; +/* Under Windows I got 300 seconds timeout, so 1 second should not hurt --witekfl */ + if (t->sec > 1) t->sec = 1; } /* Returns 1 if t1 > t2 diff --git a/src/util/time.h b/src/util/time.h index e80417caa..6fa73b0b9 100644 --- a/src/util/time.h +++ b/src/util/time.h @@ -37,7 +37,7 @@ milliseconds_T timeval_to_milliseconds(timeval_T *t); long timeval_to_seconds(timeval_T *t); int timeval_is_positive(timeval_T *t); -void timeval_limit_to_zero(timeval_T *t); +void timeval_limit_to_zero_or_one(timeval_T *t); timeval_T *timeval_now(timeval_T *t); timeval_T *timeval_sub(timeval_T *res, timeval_T *older, timeval_T *newer); timeval_T *timeval_add(timeval_T *res, timeval_T *base, timeval_T *t);