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;
|
struct vt100_term *term;
|
||||||
const char **lines;
|
const char **lines;
|
||||||
|
|
||||||
term = vt100->term->user_data;
|
term = vt100->term;
|
||||||
lines = vt100_dump(term);
|
lines = vt100_dump(term);
|
||||||
for (y = 0; y < term->height; ++y)
|
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)
|
if (y < vt100->margin_top || y > vt100->margin_bottom)
|
||||||
return vt100->frozen_screen[FROZEN_SCREEN_PTR(vt100, x, y)];
|
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;
|
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;
|
struct vt100_term *vt100;
|
||||||
|
|
||||||
vt100 = calloc(1, sizeof(*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));
|
sizeof(*vt100->frozen_screen));
|
||||||
vt100->tabulations = malloc(132);
|
vt100->tabulations = malloc(132);
|
||||||
if (vt100->tabulations == NULL)
|
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_top = 0;
|
||||||
vt100->margin_bottom = vt100->height - 1;
|
vt100->margin_bottom = vt100->height - 1;
|
||||||
vt100->selected_charset = 0;
|
vt100->selected_charset = 0;
|
||||||
|
@ -919,32 +919,32 @@ struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, ch
|
||||||
vt100->y = 0;
|
vt100->y = 0;
|
||||||
vt100->modes = MASK_DECANM;
|
vt100->modes = MASK_DECANM;
|
||||||
vt100->top_line = 0;
|
vt100->top_line = 0;
|
||||||
term = terminal_init();
|
vt100->terminal = terminal_init();
|
||||||
term->width = 80;
|
vt100->terminal->user_data = vt100;
|
||||||
term->height = 24;
|
vt100->terminal->width = 80;
|
||||||
term->write = vt100_write;
|
vt100->terminal->height = 24;
|
||||||
term->callbacks.csi.f = HVP;
|
vt100->terminal->write = vt100_write;
|
||||||
term->callbacks.csi.K = EL;
|
vt100->terminal->callbacks.csi.f = HVP;
|
||||||
term->callbacks.csi.c = DA;
|
vt100->terminal->callbacks.csi.K = EL;
|
||||||
term->callbacks.csi.h = SM;
|
vt100->terminal->callbacks.csi.c = DA;
|
||||||
term->callbacks.csi.l = RM;
|
vt100->terminal->callbacks.csi.h = SM;
|
||||||
term->callbacks.csi.J = ED;
|
vt100->terminal->callbacks.csi.l = RM;
|
||||||
term->callbacks.csi.H = CUP;
|
vt100->terminal->callbacks.csi.J = ED;
|
||||||
term->callbacks.csi.C = CUF;
|
vt100->terminal->callbacks.csi.H = CUP;
|
||||||
term->callbacks.csi.B = CUD;
|
vt100->terminal->callbacks.csi.C = CUF;
|
||||||
term->callbacks.csi.r = DECSTBM;
|
vt100->terminal->callbacks.csi.B = CUD;
|
||||||
term->callbacks.csi.m = SGR;
|
vt100->terminal->callbacks.csi.r = DECSTBM;
|
||||||
term->callbacks.csi.A = CUU;
|
vt100->terminal->callbacks.csi.m = SGR;
|
||||||
term->callbacks.csi.g = TBC;
|
vt100->terminal->callbacks.csi.A = CUU;
|
||||||
term->callbacks.esc.H = HTS;
|
vt100->terminal->callbacks.csi.g = TBC;
|
||||||
term->callbacks.csi.D = CUB;
|
vt100->terminal->callbacks.esc.H = HTS;
|
||||||
term->callbacks.esc.E = NEL;
|
vt100->terminal->callbacks.csi.D = CUB;
|
||||||
term->callbacks.esc.D = IND;
|
vt100->terminal->callbacks.esc.E = NEL;
|
||||||
term->callbacks.esc.M = RI;
|
vt100->terminal->callbacks.esc.D = IND;
|
||||||
term->callbacks.esc.n8 = DECRC;
|
vt100->terminal->callbacks.esc.M = RI;
|
||||||
term->callbacks.esc.n7 = DECSC;
|
vt100->terminal->callbacks.esc.n8 = DECRC;
|
||||||
term->callbacks.hash.n8 = DECALN;
|
vt100->terminal->callbacks.esc.n7 = DECSC;
|
||||||
term->user_data = vt100;
|
vt100->terminal->callbacks.hash.n8 = DECALN;
|
||||||
term->unimplemented = unimplemented;
|
vt100->terminal->unimplemented = unimplemented;
|
||||||
return term;
|
return vt100;
|
||||||
}
|
}
|
||||||
|
|
5
vt100.h
5
vt100.h
|
@ -46,6 +46,7 @@
|
||||||
*/
|
*/
|
||||||
struct vt100_term
|
struct vt100_term
|
||||||
{
|
{
|
||||||
|
struct terminal *terminal;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
|
@ -63,7 +64,7 @@ struct vt100_term
|
||||||
char *lines[80];
|
char *lines[80];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr));
|
struct vt100_term *vt100_init(void (*unimplemented)(struct terminal* term_emul, char *seq, char chr));
|
||||||
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);
|
||||||
const char **vt100_dump(struct vt100_term *vt100);
|
const char **vt100_dump(struct vt100_term *vt100);
|
||||||
#endif
|
#endif
|
||||||
|
|
131
vt100_headless.c
Normal file
131
vt100_headless.c
Normal 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
18
vt100_headless.h
Normal 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
|
Loading…
Reference in New Issue
Block a user