login

<     >

2020-12-25 11:34:00 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

Merge pull request #5 from rdebath/patch-bugs

Patch bugs in GIF encoding, charset conversion and cursor positioning

diff --git a/cs_vtg.h b/cs_vtg.h
index c2c45d8..0bc69d3 100644
--- a/cs_vtg.h
+++ b/cs_vtg.h
@@ -10,9 +10,9 @@ static uint16_t cs_vtg[0x100] = {
     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
     0x0048, 0x2603, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
-    0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
-    0x25C6, 0x2592, 0x0062, 0x0063, 0x0064, 0x0065, 0x00B0, 0x00B1,
-    0x2591, 0x0069, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
+    0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x00A0,
+    0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x00B0, 0x00B1,
+    0x2591, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
     0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
     0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F,
     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,

diff --git a/gen-maps.lua b/gen-maps.lua
index b94fac5..81a1fa7 100644
--- a/gen-maps.lua
+++ b/gen-maps.lua
@@ -9,6 +9,9 @@ local function build_vtg()
         {0x73, 0x23BD}, {0x74, 0x251C}, {0x75, 0x2524}, {0x76, 0x2534},
         {0x77, 0x252C}, {0x78, 0x2502}, {0x79, 0x2264}, {0x7A, 0x2265},
         {0x7B, 0x03C0}, {0x7C, 0x2260}, {0x7D, 0x00A3}, {0x7E, 0x00B7},
+
+        {0x5F, 0x00A0}, {0x62, 0x2409}, {0x63, 0x240c}, {0x64, 0x240d},
+        {0x65, 0x240a}, {0x69, 0x240b},
     }
     local vtg = {}
     for i, kv in ipairs(vtg_kv) do

diff --git a/gif.c b/gif.c
index 47d36c5..f43192e 100644
--- a/gif.c
+++ b/gif.c
@@ -120,8 +120,10 @@ end_key(GIF *gif)
     byte_offset = gif->offset / 8;
     if (gif->offset % 8)
         gif->buffer[byte_offset++] = gif->partial & 0xFF;
-    write(gif->fd, (uint8_t []) {byte_offset}, 1);
-    write(gif->fd, gif->buffer, byte_offset);
+    if (byte_offset) {
+	write(gif->fd, (uint8_t []) {byte_offset}, 1);
+	write(gif->fd, gif->buffer, byte_offset);
+    }
     write(gif->fd, "\0", 1);
     gif->offset = gif->partial = 0;
 }

diff --git a/term.c b/term.c
index f7bbdc0..79f9f1b 100644
--- a/term.c
+++ b/term.c
@@ -10,6 +10,9 @@
 #include "cs_437.h"
 
 #define MAX(A, B)   ((A) > (B) ? (A) : (B))
+#define CLEARWRAP   do{ if (term->col >= term->cols) term->col = term->cols-1; }while(0)
+#define CLIPROW(X)  if (term->row<0 || term->row >= term->rows) term->row = X
+#define CLIPCOL(X)  if (term->col<0 || term->col >= term->cols) term->col = X
 
 static int verbose = 0;
 
@@ -220,6 +223,7 @@ ctrlchar(Term *term, uint8_t byte)
 {
     switch (byte) {
     case 0x08:
+        CLEARWRAP;
         if (term->col) term->col--;
         break;
     case 0x09:
@@ -227,6 +231,7 @@ ctrlchar(Term *term, uint8_t byte)
         logfmt("NYI: Control Character 0x09 (TAB)\n");
         break;
     case 0x0A: case 0x0B: case 0x0C:
+        CLEARWRAP;
         linefeed(term);
         break;
     case 0x0D:
@@ -258,12 +263,14 @@ escseq(Term *term, uint8_t byte)
         reset(term);
         break;
     case 'D':
+        CLEARWRAP;
         if (term->row == term->bot)
             scroll_down(term);
         else
             term->row++;
         break;
     case 'E':
+        CLEARWRAP;
         if (term->row == term->bot) {
             scroll_down(term);
             term->col = 0;
@@ -287,9 +294,11 @@ escseq(Term *term, uint8_t byte)
         /* since there is no application listening, we can ignore this */
         break;
     case '7':
+        CLEARWRAP;
         save_misc(term);
         break;
     case '8':
+        CLEARWRAP;
         load_misc(term);
         break;
     case '%':
@@ -523,43 +532,61 @@ ctrlseq(Term *term, uint8_t byte)
     k1 = k ? k : 1;
     switch (byte) {
     case '@':
+        CLEARWRAP;
         /* TODO: insert the indicated # of blank characters */
         logfmt("NYI: Control Sequence @ (ICH)\n");
         break;
     case 'A':
+        CLEARWRAP;
         term->row -= k1;
+        CLIPROW(0);
         break;
     case 'B': case 'e':
+        CLEARWRAP;
         term->row += k1;
+        CLIPROW(term->rows-1);
         break;
     case 'C': case 'a':
+        CLEARWRAP;
         term->col += k1;
+        CLIPCOL(term->cols-1);
         break;
     case 'D':
+        CLEARWRAP;
         term->col -= k1;
+        CLIPCOL(0);
         break;
     case 'E':
         term->row += k1;
         term->col = 0;
+        CLIPROW(term->rows-1);
         break;
     case 'F':
         term->row -= k1;
         term->col = 0;
+        CLIPROW(0);
         break;
     case 'G': case '`':
         term->col = k1 - 1;
+        CLIPCOL(term->cols-1);
         break;
     case 'H': case 'f':
         if (n == 2) {
             term->row = MAX(params[0], 1) - 1;
             term->col = MAX(params[1], 1) - 1;
+        } else if (n == 1) {
+            term->row = MAX(params[0], 1) - 1;
+            term->col = 0;
         } else {
             term->row = term->col = 0;
         }
         if (term->mode & M_ORIGIN)
             term->row += term->top;
+        CLIPROW(term->rows-1);
+        CLIPCOL(term->cols-1);
         break;
     case 'J':
+        CLEARWRAP;
         ra = 0; rb = term->rows - 1;
         ca = 0; cb = term->cols - 1;
         if (k == 0) {
@@ -580,6 +607,7 @@ ctrlseq(Term *term, uint8_t byte)
             term->addr[rb][j] = BLANK;
         break;
     case 'K':
+        CLEARWRAP;
         ca = 0; cb = term->cols - 1;
         if (k == 0)
             ca = term->col;
@@ -589,6 +617,7 @@ ctrlseq(Term *term, uint8_t byte)
             term->addr[term->row][j] = BLANK;
         break;
     case 'L':
+        CLEARWRAP;
         if (term->row < term->top || term->row > term->bot)
             break;
         /* This is implemented naively:
@@ -602,6 +631,7 @@ ctrlseq(Term *term, uint8_t byte)
         term->top = i;
         break;
     case 'M':
+        CLEARWRAP;
         if (term->row < term->top || term->row > term->bot)
             break;
         /* This is implemented naively:
@@ -620,6 +650,7 @@ ctrlseq(Term *term, uint8_t byte)
         term->top = i;
         break;
     case 'P':
+        CLEARWRAP;
         cell = term->addr[term->row][term->cols-1];
         cell.code = EMPTY;
         for (j = term->col; j < term->cols-k1; j++)
@@ -628,6 +659,7 @@ ctrlseq(Term *term, uint8_t byte)
             term->addr[term->row][j] = cell;
         break;
     case 'X':
+        CLEARWRAP;
         for (j = 0; j < k1; j++)
             term->addr[term->row][term->col+j] = BLANK;
         break;
@@ -637,6 +669,7 @@ ctrlseq(Term *term, uint8_t byte)
         /* since there is no application listening, we can ignore this */
         break;
     case 'd':
+        CLEARWRAP;
         term->row = k1 - 1;
         break;
     case 'g':