Adding vt100_headless.c
This commit is contained in:
parent
8bb410bb7f
commit
aba779a6e9
2
test.c
2
test.c
|
@ -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
64
vt100.c
|
@ -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;
|
||||
}
|
||||
|
|
5
vt100.h
5
vt100.h
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue