Commit e4d1354e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Implement window resizing in the terminal emulation

parent a8a3049d
...@@ -32,5 +32,9 @@ process p1 -write {dek} ...@@ -32,5 +32,9 @@ process p1 -write {dek}
delay 1 delay 1
process p1 -need-bytes 5000 -screen_dump -write {q} -wait process p1 -need-bytes 5000 -screen_dump
process p1 -winsz 25 132
process p1 -need-bytes 7000 -screen_dump -write {q} -wait
...@@ -139,6 +139,7 @@ void vtc_expect(struct vtclog *, const char *, const char *, const char *, ...@@ -139,6 +139,7 @@ void vtc_expect(struct vtclog *, const char *, const char *, const char *,
const char *, const char *); const char *, const char *);
/* vtc_term.c */ /* vtc_term.c */
struct term *Term_New(struct vtclog *); struct term *Term_New(struct vtclog *, int, int);
void Term_Feed(struct term *, const char *, const char *); void Term_Feed(struct term *, const char *, const char *);
void Term_Dump(const struct term *); void Term_Dump(const struct term *);
void Term_SetSize(struct term *, int, int);
...@@ -88,7 +88,8 @@ struct process { ...@@ -88,7 +88,8 @@ struct process {
int status; int status;
struct term *term; struct term *term;
int lin;
int col;
}; };
static VTAILQ_HEAD(, process) processes = static VTAILQ_HEAD(, process) processes =
...@@ -133,7 +134,9 @@ process_new(const char *name) ...@@ -133,7 +134,9 @@ process_new(const char *name)
p->fd_term = -1; p->fd_term = -1;
VTAILQ_INSERT_TAIL(&processes, p, list); VTAILQ_INSERT_TAIL(&processes, p, list);
p->term = Term_New(p->vl); p->lin = 25;
p->col = 80;
p->term = Term_New(p->vl, p->lin, p->col);
AN(p->term); AN(p->term);
return (p); return (p);
} }
...@@ -340,18 +343,26 @@ process_thread(void *priv) ...@@ -340,18 +343,26 @@ process_thread(void *priv)
} }
static void static void
process_init_term(struct process *p, int fd) process_winsz(struct process *p, int fd, int lin, int col)
{ {
struct winsize ws; struct winsize ws;
struct termios tt;
int i; int i;
memset(&ws, 0, sizeof ws); memset(&ws, 0, sizeof ws);
ws.ws_row = 25; ws.ws_row = (short)lin;
ws.ws_col = 80; ws.ws_col = (short)col;
i = ioctl(fd, TIOCSWINSZ, &ws); i = ioctl(fd, TIOCSWINSZ, &ws);
if (i) if (i)
vtc_log(p->vl, 4, "TIOCWINSZ %d %s", i, strerror(errno)); vtc_log(p->vl, 4, "TIOCWINSZ %d %s", i, strerror(errno));
}
static void
process_init_term(struct process *p, int fd)
{
struct termios tt;
int i;
process_winsz(p, fd, p->lin, p->col);
memset(&tt, 0, sizeof tt); memset(&tt, 0, sizeof tt);
tt.c_cflag = CREAD | CS8 | HUPCL; tt.c_cflag = CREAD | CS8 | HUPCL;
...@@ -751,6 +762,15 @@ cmd_process(CMD_ARGS) ...@@ -751,6 +762,15 @@ cmd_process(CMD_ARGS)
process_wait(p); process_wait(p);
continue; continue;
} }
if (!strcmp(*av, "-winsz")) {
p->lin = atoi(av[1]);
assert(p->lin > 1);
p->col = atoi(av[2]);
assert(p->col > 1);
av += 2;
Term_SetSize(p->term, p->lin, p->col);
process_winsz(p, p->fd_term, p->lin, p->col);
}
if (!strcmp(*av, "-write")) { if (!strcmp(*av, "-write")) {
process_write(p, av[1]); process_write(p, av[1]);
av++; av++;
......
...@@ -53,13 +53,13 @@ struct term { ...@@ -53,13 +53,13 @@ struct term {
}; };
static void static void
term_clear(const struct term *tp) term_clear(char * const *vram, int lin, int col)
{ {
int i; int i;
for (i = 0; i < tp->nlin; i++) { for (i = 0; i < lin; i++) {
memset(tp->vram[i], ' ', tp->ncol); memset(vram[i], ' ', col);
tp->vram[i][tp->ncol] = '\0'; vram[i][col] = '\0';
} }
} }
...@@ -126,7 +126,9 @@ term_escape(struct term *tp, int c, int n) ...@@ -126,7 +126,9 @@ term_escape(struct term *tp, int c, int n)
tp->col = 0; tp->col = 0;
break; break;
case 'h': case 'h':
// SM - Set Mode (ignored XXX?) // SM - Set Mode (mostly ignored XXX?)
tp->col = 0;
tp->line = 0;
break; break;
case 'H': case 'H':
// CUP - Cursor Position // CUP - Cursor Position
...@@ -142,7 +144,7 @@ term_escape(struct term *tp, int c, int n) ...@@ -142,7 +144,7 @@ term_escape(struct term *tp, int c, int n)
// ED - Erase in Display (0=below, 1=above, 2=all) // ED - Erase in Display (0=below, 1=above, 2=all)
switch(tp->arg[0]) { switch(tp->arg[0]) {
case 2: case 2:
term_clear(tp); term_clear(tp->vram, tp->nlin, tp->ncol);
break; break;
default: default:
vtc_fatal(tp->vl, "ANSI J[%d]", tp->arg[0]); vtc_fatal(tp->vl, "ANSI J[%d]", tp->arg[0]);
...@@ -213,8 +215,10 @@ term_char(struct term *tp, char c) ...@@ -213,8 +215,10 @@ term_char(struct term *tp, char c)
if (c < ' ' || c > '~') if (c < ' ' || c > '~')
c = '?'; c = '?';
tp->vram[tp->line][tp->col++] = c; tp->vram[tp->line][tp->col++] = c;
if (tp->col >= tp->ncol) if (tp->col >= tp->ncol) {
tp->col = tp->ncol - 1; tp->col = 0;
term_char(tp, '\n');
}
} }
} }
...@@ -277,24 +281,46 @@ Term_Feed(struct term *tp, const char *b, const char *e) ...@@ -277,24 +281,46 @@ Term_Feed(struct term *tp, const char *b, const char *e)
} }
} }
void
Term_SetSize(struct term *tp, int lin, int col)
{
char **vram;
int i, j;
vram = calloc(lin, sizeof *tp->vram);
AN(vram);
for (i = 0; i < lin; i++) {
vram[i] = malloc(col + 1L);
AN(vram[i]);
}
term_clear(vram, lin, col);
if (tp->vram != NULL) {
for (i = 0; i < lin; i++) {
if (i >= tp->nlin)
break;
j = col;
if (j > tp->ncol)
j = tp->ncol;
memcpy(vram[i], tp->vram[i], j);
}
for (i = 0; i < tp->nlin; i++)
free(tp->vram[i]);
free(tp->vram);
}
tp->vram = vram;
tp->nlin = lin;
tp->ncol = col;
}
struct term * struct term *
Term_New(struct vtclog *vl) Term_New(struct vtclog *vl, int lin, int col)
{ {
struct term *tp; struct term *tp;
int i;
ALLOC_OBJ(tp, TERM_MAGIC); ALLOC_OBJ(tp, TERM_MAGIC);
AN(tp); AN(tp);
tp->vl = vl; tp->vl = vl;
tp->nlin = 25; Term_SetSize(tp, lin, col);
tp->ncol = 80;
tp->vram = calloc(tp->nlin, sizeof *tp->vram);
AN(tp->vram);
for (i = 0; i < tp->nlin; i++) {
tp->vram[i] = malloc(tp->ncol + 1L);
AN(tp->vram[i]);
}
term_clear(tp);
tp->line = tp->nlin - 1; tp->line = tp->nlin - 1;
return (tp); return (tp);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment