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}
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 *,
const char *, const char *);
/* 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_Dump(const struct term *);
void Term_SetSize(struct term *, int, int);
......@@ -88,7 +88,8 @@ struct process {
int status;
struct term *term;
int lin;
int col;
};
static VTAILQ_HEAD(, process) processes =
......@@ -133,7 +134,9 @@ process_new(const char *name)
p->fd_term = -1;
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);
return (p);
}
......@@ -340,18 +343,26 @@ process_thread(void *priv)
}
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 termios tt;
int i;
memset(&ws, 0, sizeof ws);
ws.ws_row = 25;
ws.ws_col = 80;
ws.ws_row = (short)lin;
ws.ws_col = (short)col;
i = ioctl(fd, TIOCSWINSZ, &ws);
if (i)
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);
tt.c_cflag = CREAD | CS8 | HUPCL;
......@@ -751,6 +762,15 @@ cmd_process(CMD_ARGS)
process_wait(p);
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")) {
process_write(p, av[1]);
av++;
......
......@@ -53,13 +53,13 @@ struct term {
};
static void
term_clear(const struct term *tp)
term_clear(char * const *vram, int lin, int col)
{
int i;
for (i = 0; i < tp->nlin; i++) {
memset(tp->vram[i], ' ', tp->ncol);
tp->vram[i][tp->ncol] = '\0';
for (i = 0; i < lin; i++) {
memset(vram[i], ' ', col);
vram[i][col] = '\0';
}
}
......@@ -126,7 +126,9 @@ term_escape(struct term *tp, int c, int n)
tp->col = 0;
break;
case 'h':
// SM - Set Mode (ignored XXX?)
// SM - Set Mode (mostly ignored XXX?)
tp->col = 0;
tp->line = 0;
break;
case 'H':
// CUP - Cursor Position
......@@ -142,7 +144,7 @@ term_escape(struct term *tp, int c, int n)
// ED - Erase in Display (0=below, 1=above, 2=all)
switch(tp->arg[0]) {
case 2:
term_clear(tp);
term_clear(tp->vram, tp->nlin, tp->ncol);
break;
default:
vtc_fatal(tp->vl, "ANSI J[%d]", tp->arg[0]);
......@@ -213,8 +215,10 @@ term_char(struct term *tp, char c)
if (c < ' ' || c > '~')
c = '?';
tp->vram[tp->line][tp->col++] = c;
if (tp->col >= tp->ncol)
tp->col = tp->ncol - 1;
if (tp->col >= tp->ncol) {
tp->col = 0;
term_char(tp, '\n');
}
}
}
......@@ -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 *
Term_New(struct vtclog *vl)
Term_New(struct vtclog *vl, int lin, int col)
{
struct term *tp;
int i;
ALLOC_OBJ(tp, TERM_MAGIC);
AN(tp);
tp->vl = vl;
tp->nlin = 25;
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);
Term_SetSize(tp, lin, col);
tp->line = tp->nlin - 1;
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