Adding vt100_headless.c

This commit is contained in:
Julien Palard 2011-09-22 20:11:37 +02:00
parent 8bb410bb7f
commit aba779a6e9
5 changed files with 185 additions and 35 deletions

2
test.c
View File

@ -13,7 +13,7 @@ void disp(struct vt100_headless *vt100)
struct vt100_term *term;
const char **lines;
term = vt100->term->user_data;
term = vt100->term;
lines = vt100_dump(term);
for (y = 0; y < term->height; ++y)
{

64
vt100.c
View File

@ -170,7 +170,7 @@ static void set(struct vt100_term *headless_term,
}
char get(struct vt100_term *vt100, unsigned int x, unsigned int y)
char vt100_get(struct vt100_term *vt100, unsigned int x, unsigned int y)
{
if (y < vt100->margin_top || y > vt100->margin_bottom)
return vt100->frozen_screen[FROZEN_SCREEN_PTR(vt100, x, y)];
@ -895,9 +895,9 @@ const char **vt100_dump(struct vt100_term *vt100)
return (const char **)vt100->lines;
}
struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr))
/*TODO: put spaces instead of \0 in frozen_screen */
struct vt100_term *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr))
{
struct terminal *term;
struct vt100_term *vt100;
vt100 = calloc(1, sizeof(*vt100));
@ -911,7 +911,7 @@ struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, ch
sizeof(*vt100->frozen_screen));
vt100->tabulations = malloc(132);
if (vt100->tabulations == NULL)
return NULL; /* Need to free before returning ... */
return NULL; /*TODO: Need to free before returning ... */
vt100->margin_top = 0;
vt100->margin_bottom = vt100->height - 1;
vt100->selected_charset = 0;
@ -919,32 +919,32 @@ struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, ch
vt100->y = 0;
vt100->modes = MASK_DECANM;
vt100->top_line = 0;
term = terminal_init();
term->width = 80;
term->height = 24;
term->write = vt100_write;
term->callbacks.csi.f = HVP;
term->callbacks.csi.K = EL;
term->callbacks.csi.c = DA;
term->callbacks.csi.h = SM;
term->callbacks.csi.l = RM;
term->callbacks.csi.J = ED;
term->callbacks.csi.H = CUP;
term->callbacks.csi.C = CUF;
term->callbacks.csi.B = CUD;
term->callbacks.csi.r = DECSTBM;
term->callbacks.csi.m = SGR;
term->callbacks.csi.A = CUU;
term->callbacks.csi.g = TBC;
term->callbacks.esc.H = HTS;
term->callbacks.csi.D = CUB;
term->callbacks.esc.E = NEL;
term->callbacks.esc.D = IND;
term->callbacks.esc.M = RI;
term->callbacks.esc.n8 = DECRC;
term->callbacks.esc.n7 = DECSC;
term->callbacks.hash.n8 = DECALN;
term->user_data = vt100;
term->unimplemented = unimplemented;
return term;
vt100->terminal = terminal_init();
vt100->terminal->user_data = vt100;
vt100->terminal->width = 80;
vt100->terminal->height = 24;
vt100->terminal->write = vt100_write;
vt100->terminal->callbacks.csi.f = HVP;
vt100->terminal->callbacks.csi.K = EL;
vt100->terminal->callbacks.csi.c = DA;
vt100->terminal->callbacks.csi.h = SM;
vt100->terminal->callbacks.csi.l = RM;
vt100->terminal->callbacks.csi.J = ED;
vt100->terminal->callbacks.csi.H = CUP;
vt100->terminal->callbacks.csi.C = CUF;
vt100->terminal->callbacks.csi.B = CUD;
vt100->terminal->callbacks.csi.r = DECSTBM;
vt100->terminal->callbacks.csi.m = SGR;
vt100->terminal->callbacks.csi.A = CUU;
vt100->terminal->callbacks.csi.g = TBC;
vt100->terminal->callbacks.esc.H = HTS;
vt100->terminal->callbacks.csi.D = CUB;
vt100->terminal->callbacks.esc.E = NEL;
vt100->terminal->callbacks.esc.D = IND;
vt100->terminal->callbacks.esc.M = RI;
vt100->terminal->callbacks.esc.n8 = DECRC;
vt100->terminal->callbacks.esc.n7 = DECSC;
vt100->terminal->callbacks.hash.n8 = DECALN;
vt100->terminal->unimplemented = unimplemented;
return vt100;
}

View File

@ -46,6 +46,7 @@
*/
struct vt100_term
{
struct terminal *terminal;
unsigned int width;
unsigned int height;
unsigned int x;
@ -63,7 +64,7 @@ struct vt100_term
char *lines[80];
};
struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr));
char get(struct vt100_term *vt100, unsigned int x, unsigned int y);
struct vt100_term *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr));
char vt100_get(struct vt100_term *vt100, unsigned int x, unsigned int y);
const char **vt100_dump(struct vt100_term *vt100);
#endif

131
vt100_headless.c Normal file
View File

@ -0,0 +1,131 @@
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <utmp.h>
#include <string.h>
#include <pty.h>
#include <stdlib.h>
#include "vt100_headless.h"
#include "vt100.h"
struct vt100_headless *vt100_headless_init(void)
{
return malloc(sizeof(struct vt100_headless));
}
static void set_non_canonical(struct vt100_headless *this, int fd)
{
struct termios termios;
ioctl(fd, TCGETS, &this->backup);
ioctl(fd, TCGETS, &termios);
termios.c_iflag |= ICANON;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
ioctl(fd, TCSETS, &termios);
}
static void restore_termios(struct vt100_headless *this, int fd)
{
ioctl(fd, TCSETS, &this->backup);
}
/* static void debug(struct vt100_headless *this, char *title) */
/* { */
/* unsigned int argc; */
/* fprintf(stderr, "%s ", title); */
/* for (argc = 0; argc < this->term->argc; ++argc) */
/* { */
/* fprintf(stderr, "%d", this->term->argv[argc]); */
/* if (argc != this->term->argc - 1) */
/* fprintf(stderr, ", "); */
/* } */
/* fprintf(stderr, "\n"); */
/* } */
static void strdump(char *str)
{
while (*str != '\0')
{
if (*str >= ' ' && *str <= '~')
fprintf(stderr, "%c", *str);
else
fprintf(stderr, "\\0%o", *str);
str += 1;
}
fprintf(stderr, "\n");
}
static int main_loop(struct vt100_headless *this)
{
char buffer[4096];
fd_set rfds;
int retval;
ssize_t read_size;
while (42)
{
FD_ZERO(&rfds);
FD_SET(this->master, &rfds);
FD_SET(0, &rfds);
retval = select(this->master + 1, &rfds, NULL, NULL, NULL);
if (retval == -1)
{
perror("select()");
}
if (FD_ISSET(0, &rfds))
{
read_size = read(0, &buffer, 4096);
if (read_size == -1)
{
perror("read");
return EXIT_FAILURE;
}
buffer[read_size] = '\0';
write(this->master, buffer, read_size);
}
if (FD_ISSET(this->master, &rfds))
{
read_size = read(this->master, &buffer, 4096);
if (read_size == -1)
{
perror("read");
return EXIT_FAILURE;
}
buffer[read_size] = '\0';
strdump(buffer);
terminal_read_str(this->term->terminal, buffer);
this->changed(this);
}
}
}
void vt100_headless_fork(struct vt100_headless *this,
const char *progname,
char *const argv[])
{
int child;
struct winsize winsize;
set_non_canonical(this, 0);
winsize.ws_row = 24;
winsize.ws_col = 24;
child = forkpty(&this->master, NULL, NULL, NULL);
if (child == CHILD)
{
setsid();
putenv("TERM=vt100");
execvp(progname, argv);
return ;
}
else
{
this->term = vt100_init(terminal_default_unimplemented);
ioctl(this->master, TIOCSWINSZ, &winsize);
this->term->terminal->fd = this->master;
main_loop(this);
}
restore_termios(this, 0);
}

18
vt100_headless.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __VT100_HEADLESS_H__
#define __VT100_HEADLESS_H__
#define CHILD 0
struct vt100_headless
{
int master;
struct termios backup;
struct vt100_term *term;
void (*changed)(struct vt100_headless *this);
};
void vt100_headless_fork(struct vt100_headless *this, const char *progname, char *const argv[]);
struct vt100_headless *vt100_headless_init(void);
#endif