renaming vt100.c to term.c cause it's not specific ...
This commit is contained in:
parent
962ae481d5
commit
884e7a74b2
2
Makefile
2
Makefile
|
@ -6,7 +6,7 @@
|
|||
##
|
||||
|
||||
NAME = vt100
|
||||
SRC = vt100.c test.c
|
||||
SRC = term.c test.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
CC = gcc
|
||||
INCLUDE = .
|
||||
|
|
217
term.c
Normal file
217
term.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
#include <stdlib.h>
|
||||
#include "term.h"
|
||||
|
||||
/*
|
||||
* Source : http://vt100.net/docs/vt100-ug/chapter3.html
|
||||
http://vt100.net/docs/tp83/appendixb.html
|
||||
* It's a vt100 implementation, that implements ANSI control function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Vocabulary
|
||||
* CSI | Control Sequence Introducer | ESC [
|
||||
* Pn | Numeric parameter | [0-9]+
|
||||
* Ps | Selective parameter |
|
||||
* | Parameter string | List of parameters separated by ';'
|
||||
*/
|
||||
|
||||
/*
|
||||
* Control sequences - VT100 to host ( write )
|
||||
* CPR | Cursor Position Report | ESC [ Pn ; Pn R
|
||||
*
|
||||
*
|
||||
* Control sequencs - Host to VT100 AND VT100 to host ( read write )
|
||||
* CUB | Cursor Backward | ESC [ Pn D
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Naming convention :
|
||||
* [rw]_shortname(struct vt100emul vt100, ...);
|
||||
* So CPR is w_CPR(struct vt100emul vt100, int pn1, int pn2);
|
||||
* And CUB is r_CUB(struct vt100emul vt100, int pn1, int pn2);
|
||||
* AND w_CUB(struct vt100emul vt100, int pn1, int pn2);
|
||||
*/
|
||||
|
||||
|
||||
void term_push(struct term_emul *term, char c)
|
||||
{
|
||||
if (term->stack_ptr >= TERM_STACK_SIZE)
|
||||
return ;
|
||||
term->stack[term->stack_ptr++] = c;
|
||||
}
|
||||
|
||||
void term_parse_params(struct term_emul *term)
|
||||
{
|
||||
unsigned int i;
|
||||
int got_something;
|
||||
|
||||
got_something = 0;
|
||||
term->argc = 0;
|
||||
term->argv[0] = 0;
|
||||
for (i = 0; i < term->stack_ptr; ++i)
|
||||
{
|
||||
if (term->stack[i] >= '0' && term->stack[i] <= '9')
|
||||
{
|
||||
got_something = 1;
|
||||
term->argv[term->argc] = term->argv[term->argc] * 10
|
||||
+ term->stack[i] - '0';
|
||||
}
|
||||
else if (term->stack[i] == ';')
|
||||
{
|
||||
got_something = 0;
|
||||
term->argc += 1;
|
||||
term->argv[term->argc] = 0;
|
||||
}
|
||||
}
|
||||
term->argc += got_something;
|
||||
}
|
||||
|
||||
void term_call_CSI(struct term_emul *term, char c)
|
||||
{
|
||||
term_parse_params(term);
|
||||
if (((term_action *)&term->callbacks->csi)[c - '?'] == NULL)
|
||||
{
|
||||
if (term->unimplemented != NULL)
|
||||
term->unimplemented(term, "CSI", c);
|
||||
goto leave;
|
||||
}
|
||||
((term_action *)&term->callbacks->csi)[c - '?'](term);
|
||||
leave:
|
||||
term->state = INIT;
|
||||
term->flag = '\0';
|
||||
term->stack_ptr = 0;
|
||||
term->argc = 0;
|
||||
}
|
||||
|
||||
void term_call_ESC(struct term_emul *term, char c)
|
||||
{
|
||||
if (((term_action *)&term->callbacks->esc)[c - '0'] == NULL)
|
||||
{
|
||||
if (term->unimplemented != NULL)
|
||||
term->unimplemented(term, "ESC", c);
|
||||
goto leave;
|
||||
}
|
||||
((term_action *)&term->callbacks->esc)[c - '0'](term);
|
||||
leave:
|
||||
term->state = INIT;
|
||||
term->stack_ptr = 0;
|
||||
term->argc = 0;
|
||||
}
|
||||
|
||||
void term_call_HASH(struct term_emul *term, char c)
|
||||
{
|
||||
if (((term_action *)&term->callbacks->hash)[c - '0'] == NULL)
|
||||
{
|
||||
if (term->unimplemented != NULL)
|
||||
term->unimplemented(term, "HASH", c);
|
||||
goto leave;
|
||||
}
|
||||
((term_action *)&term->callbacks->hash)[c - '0'](term);
|
||||
leave:
|
||||
term->state = INIT;
|
||||
term->stack_ptr = 0;
|
||||
term->argc = 0;
|
||||
}
|
||||
|
||||
void term_call_GSET(struct term_emul *term, char c)
|
||||
{
|
||||
if (c < '0' || c > 'B'
|
||||
|| ((term_action *)&term->callbacks->scs)[c - '0'] == NULL)
|
||||
{
|
||||
if (term->unimplemented != NULL)
|
||||
term->unimplemented(term, "GSET", c);
|
||||
goto leave;
|
||||
}
|
||||
((term_action *)&term->callbacks->scs)[c - '0'](term);
|
||||
leave:
|
||||
term->state = INIT;
|
||||
term->stack_ptr = 0;
|
||||
term->argc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** INIT
|
||||
** \_ ESC "\033"
|
||||
** | \_ CSI "\033["
|
||||
** | | \_ c == '?' : term->flag = '?'
|
||||
** | | \_ c == ';' || (c >= '0' && c <= '9') : term_push
|
||||
** | | \_ else : term_call_CSI()
|
||||
** | \_ HASH "\033#"
|
||||
** | | \_ term_call_hash()
|
||||
** | \_ G0SET "\033("
|
||||
** | | \_ term_call_GSET()
|
||||
** | \_ G1SET "\033)"
|
||||
** | | \_ term_call_GSET()
|
||||
** \_ term->write()
|
||||
*/
|
||||
void term_read(struct term_emul *term, char c)
|
||||
{
|
||||
if (term->state == INIT)
|
||||
{
|
||||
if (c == '\033')
|
||||
term->state = ESC;
|
||||
else
|
||||
term->write(term, c);
|
||||
}
|
||||
else if (term->state == ESC)
|
||||
{
|
||||
if (c == '[')
|
||||
term->state = CSI;
|
||||
else if (c == '#')
|
||||
term->state = HASH;
|
||||
else if (c == '(')
|
||||
term->state = G0SET;
|
||||
else if (c == ')')
|
||||
term->state = G1SET;
|
||||
else if (c >= '0' && c <= 'z')
|
||||
term_call_ESC(term, c);
|
||||
else term->write(term, c);
|
||||
}
|
||||
else if (term->state == HASH)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
term_call_HASH(term, c);
|
||||
else
|
||||
term->write(term, c);
|
||||
}
|
||||
else if (term->state == G0SET || term->state == G1SET)
|
||||
{
|
||||
term_call_GSET(term, c);
|
||||
}
|
||||
else if (term->state == CSI)
|
||||
{
|
||||
if (c == '?')
|
||||
term->flag = '?';
|
||||
else if (c == ';' || (c >= '0' && c <= '9'))
|
||||
term_push(term, c);
|
||||
else if (c >= '?' && c <= 'z')
|
||||
term_call_CSI(term, c);
|
||||
else
|
||||
term->write(term, c);
|
||||
}
|
||||
}
|
||||
|
||||
void term_read_str(struct term_emul *term, char *c)
|
||||
{
|
||||
while (*c)
|
||||
term_read(term, *c++);
|
||||
}
|
||||
|
||||
struct term_emul *term_init(unsigned int width, unsigned int height,
|
||||
struct term_callbacks *callbacks,
|
||||
void (*vtwrite)(struct term_emul *, char))
|
||||
{
|
||||
struct term_emul *term;
|
||||
|
||||
term = malloc(sizeof(*term));
|
||||
term->width = width;
|
||||
term->height = height;
|
||||
term->cursor_pos_x = 0;
|
||||
term->cursor_pos_y = 0;
|
||||
term->stack_ptr = 0;
|
||||
term->callbacks = callbacks;
|
||||
term->state = INIT;
|
||||
term->write = vtwrite;
|
||||
return term;
|
||||
}
|
249
term.h
Normal file
249
term.h
Normal file
|
@ -0,0 +1,249 @@
|
|||
#ifndef __TERM_H__
|
||||
#define __TERM_H__
|
||||
|
||||
#define TERM_STACK_SIZE 1024
|
||||
|
||||
enum term_state
|
||||
{
|
||||
INIT,
|
||||
ESC,
|
||||
HASH,
|
||||
G0SET,
|
||||
G1SET,
|
||||
CSI
|
||||
};
|
||||
|
||||
struct term_emul;
|
||||
|
||||
typedef void (*term_action)(struct term_emul *emul);
|
||||
|
||||
/*
|
||||
** [w] -> VT100 to Host
|
||||
** [r] -> Host to VT100
|
||||
** [rw] -> VT100 to Host and Host to VT100
|
||||
** Please read http://vt100.net/docs/vt100-ug/chapter3.html#S3.3
|
||||
*/
|
||||
struct term_hash_callbacks
|
||||
{
|
||||
term_action hash_0;
|
||||
term_action hash_1;
|
||||
term_action hash_2;
|
||||
term_action DECDHL_TOP; /* Double Height Line ESC # 3 */
|
||||
term_action DECDHL_BOTTOM; /*Double Height Line ESC # 4 */
|
||||
term_action DECSWL; /* Single-width Line ESC # 5 */
|
||||
term_action DECDWL; /* Double-Width Line ESC # 6 */
|
||||
term_action hash_7;
|
||||
term_action DECALN; /* Screen Alignment Display ESC # 8 */
|
||||
term_action hash_9;
|
||||
};
|
||||
|
||||
struct term_SCS_callbacks
|
||||
{
|
||||
term_action SCS_0; /* Special Graphics */
|
||||
term_action SCS_1; /* Alternate Character ROM Standard Character Set */
|
||||
term_action SCS_2; /* Alternate Character ROM Special Graphics */
|
||||
term_action SCS_3;
|
||||
term_action SCS_4;
|
||||
term_action SCS_5;
|
||||
term_action SCS_6;
|
||||
term_action SCS_7;
|
||||
term_action SCS_8;
|
||||
term_action SCS_9;
|
||||
|
||||
term_action SCS_3A;
|
||||
term_action SCS_3B;
|
||||
term_action SCS_3C;
|
||||
term_action SCS_3D;
|
||||
term_action SCS_3E;
|
||||
term_action SCS_3F;
|
||||
term_action SCS_40;
|
||||
|
||||
term_action SCS_A; /* United kingdom Set */
|
||||
term_action SCS_B; /* ASCII Set*/
|
||||
};
|
||||
|
||||
struct term_ESC_callbacks
|
||||
{
|
||||
term_action ESC_0;
|
||||
term_action ESC_1;
|
||||
term_action ESC_2;
|
||||
term_action ESC_3;
|
||||
term_action ESC_4;
|
||||
term_action ESC_5;
|
||||
term_action ESC_6;
|
||||
term_action DECSC; /* Save Cursor ESC 7 */
|
||||
term_action DECRC; /* Restore Cursor ESC 8 */
|
||||
term_action ESC_9;
|
||||
|
||||
term_action ESC_3A;
|
||||
term_action ESC_3B;
|
||||
term_action ESC_3C;
|
||||
term_action DECKPAM; /* Keypad Application Mode ESC = */
|
||||
term_action DECKPNM; /* Keypad Numeric Mode ESC > */
|
||||
term_action ESC_3F;
|
||||
term_action ESC_40;
|
||||
|
||||
term_action ESC_A;
|
||||
term_action ESC_B;
|
||||
term_action ESC_C;
|
||||
term_action IND; /* Index ESC D */
|
||||
term_action NEL; /* Next Line ESC E */
|
||||
term_action ESC_F;
|
||||
term_action ESC_G;
|
||||
term_action HTS; /* Horizontal Tabulation Set ESC H */
|
||||
term_action ESC_I;
|
||||
term_action ESC_J;
|
||||
term_action ESC_K;
|
||||
term_action ESC_L;
|
||||
term_action RI; /* Reverse Index ESC M */
|
||||
term_action ESC_N;
|
||||
term_action ESC_O;
|
||||
term_action ESC_P;
|
||||
term_action ESC_Q;
|
||||
term_action CPR; /* [w] Cursor Position Report ESC [ Pn ; Pn R */
|
||||
term_action ESC_S;
|
||||
term_action ESC_T;
|
||||
term_action ESC_U;
|
||||
term_action ESC_V;
|
||||
term_action ESC_W;
|
||||
term_action ESC_X;
|
||||
term_action ESC_Y;
|
||||
term_action DECID; /* Identify Terminal ESC Z */
|
||||
|
||||
term_action ESC_5B;
|
||||
term_action ESC_5C;
|
||||
term_action ESC_5D;
|
||||
term_action ESC_5E;
|
||||
term_action ESC_5F;
|
||||
term_action ESC_60;
|
||||
|
||||
term_action ESC_a;
|
||||
term_action ESC_b;
|
||||
term_action RIS; /* Reset To Initial State ESC c */
|
||||
term_action ESC_d;
|
||||
term_action ESC_e;
|
||||
term_action ESC_f;
|
||||
term_action ESC_g;
|
||||
term_action ESC_h;
|
||||
term_action ESC_i;
|
||||
term_action ESC_j;
|
||||
term_action ESC_k;
|
||||
term_action ESC_l;
|
||||
term_action ESC_m;
|
||||
term_action ESC_n;
|
||||
term_action ESC_o;
|
||||
term_action ESC_p;
|
||||
term_action ESC_q;
|
||||
term_action ESC_r;
|
||||
term_action ESC_s;
|
||||
term_action ESC_t;
|
||||
term_action ESC_u;
|
||||
term_action ESC_v;
|
||||
term_action ESC_w;
|
||||
term_action ESC_x;
|
||||
term_action ESC_y;
|
||||
term_action ESC_z;
|
||||
};
|
||||
|
||||
struct term_CSI_callbacks
|
||||
{
|
||||
term_action CSI_3F; /* ESC [ ? */
|
||||
term_action CSI_40; /* ESC [ @ */
|
||||
term_action CUU; /* [rw] Cursor Up ESC [ Pn A */
|
||||
term_action CUD; /* [rw] Cursor Down ESC [ Pn B */
|
||||
term_action CUF; /* [rw] Cursor Forward ESC [ Pn C */
|
||||
term_action CUB; /* [rw] Cursor Backward ESC [ Pn D */
|
||||
term_action CSI_E;
|
||||
term_action CSI_F;
|
||||
term_action CSI_G;
|
||||
term_action CUP; /* [??] Cursor Position ESC [ Pn ; Pn H */
|
||||
term_action CSI_I;
|
||||
term_action ED; /* Erase In Display ESC [ Ps J */
|
||||
term_action EL; /* Erase In Line ESC [ Ps K */
|
||||
term_action CSI_L;
|
||||
term_action CSI_M;
|
||||
term_action CSI_N;
|
||||
term_action CSI_O;
|
||||
term_action CSI_P;
|
||||
term_action CSI_Q;
|
||||
term_action CPR; /* [w] Cursor Position Report ESC [ Pn ; Pn R */
|
||||
term_action CSI_S;
|
||||
term_action CSI_T;
|
||||
term_action CSI_U;
|
||||
term_action CSI_V;
|
||||
term_action CSI_W;
|
||||
term_action CSI_X;
|
||||
term_action CSI_Y;
|
||||
term_action CSI_Z;
|
||||
|
||||
term_action CSI_5B;
|
||||
term_action CSI_5C;
|
||||
term_action CSI_5D;
|
||||
term_action CSI_5E;
|
||||
term_action CSI_5F;
|
||||
term_action CSI_60;
|
||||
|
||||
term_action CSI_a;
|
||||
term_action CSI_b;
|
||||
term_action DA; /* [??] Device Attributes ESC [ Pn c */
|
||||
term_action CSI_d;
|
||||
term_action CSI_e;
|
||||
term_action HVP; /* Horiz. and Vert. Position ESC [ Pn ; Pn f */
|
||||
term_action TBC; /* Tabulation Clear ESC [ Ps g */
|
||||
term_action SM; /* Set Mode ESC [ Ps ; . . . ; Ps h */
|
||||
term_action CSI_i;
|
||||
term_action CSI_j;
|
||||
term_action CSI_k;
|
||||
term_action RM; /* Reset Mode ESC [ Ps ; Ps ; . . . ; Ps l */
|
||||
term_action SGR; /* Select Graphic Rendition ESC [ Ps ; . . . ; Ps m */
|
||||
term_action DSR; /* Device Status Report ESC [ Ps n */
|
||||
term_action CSI_o;
|
||||
term_action CSI_p;
|
||||
term_action DECLL; /* Load LEDS ESC [ Ps q */
|
||||
term_action DECSTBM; /* Set Top and Bottom Margins ESC [ Pn; Pn r */
|
||||
term_action CSI_s;
|
||||
term_action CSI_t;
|
||||
term_action CSI_u;
|
||||
term_action CSI_v;
|
||||
term_action CSI_w;
|
||||
term_action DECRE_TPARM; /* Re{port,quest} Terminal Parameters ESC [ . x */
|
||||
term_action DECTST; /* Invoke Confidence Test ESC [ 2 ; Ps y */
|
||||
term_action CSI_z;
|
||||
};
|
||||
|
||||
struct term_callbacks
|
||||
{
|
||||
struct term_ESC_callbacks esc;
|
||||
struct term_CSI_callbacks csi;
|
||||
struct term_hash_callbacks hash;
|
||||
struct term_SCS_callbacks scs;
|
||||
};
|
||||
|
||||
struct term_emul
|
||||
{
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int cursor_pos_x;
|
||||
unsigned int cursor_pos_y;
|
||||
enum term_state state;
|
||||
unsigned int argc;
|
||||
unsigned int argv[TERM_STACK_SIZE];
|
||||
void (*write)(struct term_emul *, char c);
|
||||
char stack[TERM_STACK_SIZE];
|
||||
unsigned int stack_ptr;
|
||||
struct term_callbacks *callbacks;
|
||||
char flag;
|
||||
void *user_data;
|
||||
void (*unimplemented)(struct term_emul*,
|
||||
char *seq,
|
||||
char chr);
|
||||
};
|
||||
|
||||
struct term_emul *term_init(unsigned int width, unsigned int height,
|
||||
struct term_callbacks *callbacks,
|
||||
void (*write)(struct term_emul *, char));
|
||||
|
||||
void term_read(struct term_emul *term, char c);
|
||||
void term_read_str(struct term_emul *term, char *c);
|
||||
|
||||
#endif
|
217
vt100.c
217
vt100.c
|
@ -1,217 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include "vt100.h"
|
||||
|
||||
/*
|
||||
* Source : http://vt100.net/docs/vt100-ug/chapter3.html
|
||||
http://vt100.net/docs/tp83/appendixb.html
|
||||
* It's a vt100 implementation, that implements ANSI control function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Vocabulary
|
||||
* CSI | Control Sequence Introducer | ESC [
|
||||
* Pn | Numeric parameter | [0-9]+
|
||||
* Ps | Selective parameter |
|
||||
* | Parameter string | List of parameters separated by ';'
|
||||
*/
|
||||
|
||||
/*
|
||||
* Control sequences - VT100 to host ( write )
|
||||
* CPR | Cursor Position Report | ESC [ Pn ; Pn R
|
||||
*
|
||||
*
|
||||
* Control sequencs - Host to VT100 AND VT100 to host ( read write )
|
||||
* CUB | Cursor Backward | ESC [ Pn D
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Naming convention :
|
||||
* [rw]_shortname(struct vt100emul vt100, ...);
|
||||
* So CPR is w_CPR(struct vt100emul vt100, int pn1, int pn2);
|
||||
* And CUB is r_CUB(struct vt100emul vt100, int pn1, int pn2);
|
||||
* AND w_CUB(struct vt100emul vt100, int pn1, int pn2);
|
||||
*/
|
||||
|
||||
|
||||
void vt100_push(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
if (vt100->stack_ptr >= VT100_STACK_SIZE)
|
||||
return ;
|
||||
vt100->stack[vt100->stack_ptr++] = c;
|
||||
}
|
||||
|
||||
void vt100_parse_params(struct vt100_emul *vt100)
|
||||
{
|
||||
unsigned int i;
|
||||
int got_something;
|
||||
|
||||
got_something = 0;
|
||||
vt100->argc = 0;
|
||||
vt100->argv[0] = 0;
|
||||
for (i = 0; i < vt100->stack_ptr; ++i)
|
||||
{
|
||||
if (vt100->stack[i] >= '0' && vt100->stack[i] <= '9')
|
||||
{
|
||||
got_something = 1;
|
||||
vt100->argv[vt100->argc] = vt100->argv[vt100->argc] * 10
|
||||
+ vt100->stack[i] - '0';
|
||||
}
|
||||
else if (vt100->stack[i] == ';')
|
||||
{
|
||||
got_something = 0;
|
||||
vt100->argc += 1;
|
||||
vt100->argv[vt100->argc] = 0;
|
||||
}
|
||||
}
|
||||
vt100->argc += got_something;
|
||||
}
|
||||
|
||||
void vt100_call_CSI(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
vt100_parse_params(vt100);
|
||||
if (((vt100_action *)&vt100->callbacks->csi)[c - '?'] == NULL)
|
||||
{
|
||||
if (vt100->unimplemented != NULL)
|
||||
vt100->unimplemented(vt100, "CSI", c);
|
||||
goto leave;
|
||||
}
|
||||
((vt100_action *)&vt100->callbacks->csi)[c - '?'](vt100);
|
||||
leave:
|
||||
vt100->state = INIT;
|
||||
vt100->flag = '\0';
|
||||
vt100->stack_ptr = 0;
|
||||
vt100->argc = 0;
|
||||
}
|
||||
|
||||
void vt100_call_ESC(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
if (((vt100_action *)&vt100->callbacks->esc)[c - '0'] == NULL)
|
||||
{
|
||||
if (vt100->unimplemented != NULL)
|
||||
vt100->unimplemented(vt100, "ESC", c);
|
||||
goto leave;
|
||||
}
|
||||
((vt100_action *)&vt100->callbacks->esc)[c - '0'](vt100);
|
||||
leave:
|
||||
vt100->state = INIT;
|
||||
vt100->stack_ptr = 0;
|
||||
vt100->argc = 0;
|
||||
}
|
||||
|
||||
void vt100_call_HASH(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
if (((vt100_action *)&vt100->callbacks->hash)[c - '0'] == NULL)
|
||||
{
|
||||
if (vt100->unimplemented != NULL)
|
||||
vt100->unimplemented(vt100, "HASH", c);
|
||||
goto leave;
|
||||
}
|
||||
((vt100_action *)&vt100->callbacks->hash)[c - '0'](vt100);
|
||||
leave:
|
||||
vt100->state = INIT;
|
||||
vt100->stack_ptr = 0;
|
||||
vt100->argc = 0;
|
||||
}
|
||||
|
||||
void vt100_call_GSET(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
if (c < '0' || c > 'B'
|
||||
|| ((vt100_action *)&vt100->callbacks->scs)[c - '0'] == NULL)
|
||||
{
|
||||
if (vt100->unimplemented != NULL)
|
||||
vt100->unimplemented(vt100, "GSET", c);
|
||||
goto leave;
|
||||
}
|
||||
((vt100_action *)&vt100->callbacks->scs)[c - '0'](vt100);
|
||||
leave:
|
||||
vt100->state = INIT;
|
||||
vt100->stack_ptr = 0;
|
||||
vt100->argc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** INIT
|
||||
** \_ ESC "\033"
|
||||
** | \_ CSI "\033["
|
||||
** | | \_ c == '?' : vt100->flag = '?'
|
||||
** | | \_ c == ';' || (c >= '0' && c <= '9') : vt100_push
|
||||
** | | \_ else : vt100_call_CSI()
|
||||
** | \_ HASH "\033#"
|
||||
** | | \_ vt100_call_hash()
|
||||
** | \_ G0SET "\033("
|
||||
** | | \_ vt100_call_GSET()
|
||||
** | \_ G1SET "\033)"
|
||||
** | | \_ vt100_call_GSET()
|
||||
** \_ vt100->write()
|
||||
*/
|
||||
void vt100_read(struct vt100_emul *vt100, char c)
|
||||
{
|
||||
if (vt100->state == INIT)
|
||||
{
|
||||
if (c == '\033')
|
||||
vt100->state = ESC;
|
||||
else
|
||||
vt100->write(vt100, c);
|
||||
}
|
||||
else if (vt100->state == ESC)
|
||||
{
|
||||
if (c == '[')
|
||||
vt100->state = CSI;
|
||||
else if (c == '#')
|
||||
vt100->state = HASH;
|
||||
else if (c == '(')
|
||||
vt100->state = G0SET;
|
||||
else if (c == ')')
|
||||
vt100->state = G1SET;
|
||||
else if (c >= '0' && c <= 'z')
|
||||
vt100_call_ESC(vt100, c);
|
||||
else vt100->write(vt100, c);
|
||||
}
|
||||
else if (vt100->state == HASH)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
vt100_call_HASH(vt100, c);
|
||||
else
|
||||
vt100->write(vt100, c);
|
||||
}
|
||||
else if (vt100->state == G0SET || vt100->state == G1SET)
|
||||
{
|
||||
vt100_call_GSET(vt100, c);
|
||||
}
|
||||
else if (vt100->state == CSI)
|
||||
{
|
||||
if (c == '?')
|
||||
vt100->flag = '?';
|
||||
else if (c == ';' || (c >= '0' && c <= '9'))
|
||||
vt100_push(vt100, c);
|
||||
else if (c >= '?' && c <= 'z')
|
||||
vt100_call_CSI(vt100, c);
|
||||
else
|
||||
vt100->write(vt100, c);
|
||||
}
|
||||
}
|
||||
|
||||
void vt100_read_str(struct vt100_emul *vt100, char *c)
|
||||
{
|
||||
while (*c)
|
||||
vt100_read(vt100, *c++);
|
||||
}
|
||||
|
||||
struct vt100_emul *vt100_init(unsigned int width, unsigned int height,
|
||||
struct vt100_callbacks *callbacks,
|
||||
void (*vtwrite)(struct vt100_emul *, char))
|
||||
{
|
||||
struct vt100_emul *vt100;
|
||||
|
||||
vt100 = malloc(sizeof(*vt100));
|
||||
vt100->width = width;
|
||||
vt100->height = height;
|
||||
vt100->cursor_pos_x = 0;
|
||||
vt100->cursor_pos_y = 0;
|
||||
vt100->stack_ptr = 0;
|
||||
vt100->callbacks = callbacks;
|
||||
vt100->state = INIT;
|
||||
vt100->write = vtwrite;
|
||||
return vt100;
|
||||
}
|
249
vt100.h
249
vt100.h
|
@ -1,249 +0,0 @@
|
|||
#ifndef __VT100_H__
|
||||
#define __VT100_H__
|
||||
|
||||
#define VT100_STACK_SIZE 1024
|
||||
|
||||
enum vt100_state
|
||||
{
|
||||
INIT,
|
||||
ESC,
|
||||
HASH,
|
||||
G0SET,
|
||||
G1SET,
|
||||
CSI
|
||||
};
|
||||
|
||||
struct vt100_emul;
|
||||
|
||||
typedef void (*vt100_action)(struct vt100_emul *emul);
|
||||
|
||||
/*
|
||||
** [w] -> VT100 to Host
|
||||
** [r] -> Host to VT100
|
||||
** [rw] -> VT100 to Host and Host to VT100
|
||||
** Please read http://vt100.net/docs/vt100-ug/chapter3.html#S3.3
|
||||
*/
|
||||
struct vt100_hash_callbacks
|
||||
{
|
||||
vt100_action hash_0;
|
||||
vt100_action hash_1;
|
||||
vt100_action hash_2;
|
||||
vt100_action DECDHL_TOP; /* Double Height Line ESC # 3 */
|
||||
vt100_action DECDHL_BOTTOM; /*Double Height Line ESC # 4 */
|
||||
vt100_action DECSWL; /* Single-width Line ESC # 5 */
|
||||
vt100_action DECDWL; /* Double-Width Line ESC # 6 */
|
||||
vt100_action hash_7;
|
||||
vt100_action DECALN; /* Screen Alignment Display ESC # 8 */
|
||||
vt100_action hash_9;
|
||||
};
|
||||
|
||||
struct vt100_SCS_callbacks
|
||||
{
|
||||
vt100_action SCS_0; /* Special Graphics */
|
||||
vt100_action SCS_1; /* Alternate Character ROM Standard Character Set */
|
||||
vt100_action SCS_2; /* Alternate Character ROM Special Graphics */
|
||||
vt100_action SCS_3;
|
||||
vt100_action SCS_4;
|
||||
vt100_action SCS_5;
|
||||
vt100_action SCS_6;
|
||||
vt100_action SCS_7;
|
||||
vt100_action SCS_8;
|
||||
vt100_action SCS_9;
|
||||
|
||||
vt100_action SCS_3A;
|
||||
vt100_action SCS_3B;
|
||||
vt100_action SCS_3C;
|
||||
vt100_action SCS_3D;
|
||||
vt100_action SCS_3E;
|
||||
vt100_action SCS_3F;
|
||||
vt100_action SCS_40;
|
||||
|
||||
vt100_action SCS_A; /* United kingdom Set */
|
||||
vt100_action SCS_B; /* ASCII Set*/
|
||||
};
|
||||
|
||||
struct vt100_ESC_callbacks
|
||||
{
|
||||
vt100_action ESC_0;
|
||||
vt100_action ESC_1;
|
||||
vt100_action ESC_2;
|
||||
vt100_action ESC_3;
|
||||
vt100_action ESC_4;
|
||||
vt100_action ESC_5;
|
||||
vt100_action ESC_6;
|
||||
vt100_action DECSC; /* Save Cursor ESC 7 */
|
||||
vt100_action DECRC; /* Restore Cursor ESC 8 */
|
||||
vt100_action ESC_9;
|
||||
|
||||
vt100_action ESC_3A;
|
||||
vt100_action ESC_3B;
|
||||
vt100_action ESC_3C;
|
||||
vt100_action DECKPAM; /* Keypad Application Mode ESC = */
|
||||
vt100_action DECKPNM; /* Keypad Numeric Mode ESC > */
|
||||
vt100_action ESC_3F;
|
||||
vt100_action ESC_40;
|
||||
|
||||
vt100_action ESC_A;
|
||||
vt100_action ESC_B;
|
||||
vt100_action ESC_C;
|
||||
vt100_action IND; /* Index ESC D */
|
||||
vt100_action NEL; /* Next Line ESC E */
|
||||
vt100_action ESC_F;
|
||||
vt100_action ESC_G;
|
||||
vt100_action HTS; /* Horizontal Tabulation Set ESC H */
|
||||
vt100_action ESC_I;
|
||||
vt100_action ESC_J;
|
||||
vt100_action ESC_K;
|
||||
vt100_action ESC_L;
|
||||
vt100_action RI; /* Reverse Index ESC M */
|
||||
vt100_action ESC_N;
|
||||
vt100_action ESC_O;
|
||||
vt100_action ESC_P;
|
||||
vt100_action ESC_Q;
|
||||
vt100_action CPR; /* [w] Cursor Position Report ESC [ Pn ; Pn R */
|
||||
vt100_action ESC_S;
|
||||
vt100_action ESC_T;
|
||||
vt100_action ESC_U;
|
||||
vt100_action ESC_V;
|
||||
vt100_action ESC_W;
|
||||
vt100_action ESC_X;
|
||||
vt100_action ESC_Y;
|
||||
vt100_action DECID; /* Identify Terminal ESC Z */
|
||||
|
||||
vt100_action ESC_5B;
|
||||
vt100_action ESC_5C;
|
||||
vt100_action ESC_5D;
|
||||
vt100_action ESC_5E;
|
||||
vt100_action ESC_5F;
|
||||
vt100_action ESC_60;
|
||||
|
||||
vt100_action ESC_a;
|
||||
vt100_action ESC_b;
|
||||
vt100_action RIS; /* Reset To Initial State ESC c */
|
||||
vt100_action ESC_d;
|
||||
vt100_action ESC_e;
|
||||
vt100_action ESC_f;
|
||||
vt100_action ESC_g;
|
||||
vt100_action ESC_h;
|
||||
vt100_action ESC_i;
|
||||
vt100_action ESC_j;
|
||||
vt100_action ESC_k;
|
||||
vt100_action ESC_l;
|
||||
vt100_action ESC_m;
|
||||
vt100_action ESC_n;
|
||||
vt100_action ESC_o;
|
||||
vt100_action ESC_p;
|
||||
vt100_action ESC_q;
|
||||
vt100_action ESC_r;
|
||||
vt100_action ESC_s;
|
||||
vt100_action ESC_t;
|
||||
vt100_action ESC_u;
|
||||
vt100_action ESC_v;
|
||||
vt100_action ESC_w;
|
||||
vt100_action ESC_x;
|
||||
vt100_action ESC_y;
|
||||
vt100_action ESC_z;
|
||||
};
|
||||
|
||||
struct vt100_CSI_callbacks
|
||||
{
|
||||
vt100_action CSI_3F; /* ESC [ ? */
|
||||
vt100_action CSI_40; /* ESC [ @ */
|
||||
vt100_action CUU; /* [rw] Cursor Up ESC [ Pn A */
|
||||
vt100_action CUD; /* [rw] Cursor Down ESC [ Pn B */
|
||||
vt100_action CUF; /* [rw] Cursor Forward ESC [ Pn C */
|
||||
vt100_action CUB; /* [rw] Cursor Backward ESC [ Pn D */
|
||||
vt100_action CSI_E;
|
||||
vt100_action CSI_F;
|
||||
vt100_action CSI_G;
|
||||
vt100_action CUP; /* [??] Cursor Position ESC [ Pn ; Pn H */
|
||||
vt100_action CSI_I;
|
||||
vt100_action ED; /* Erase In Display ESC [ Ps J */
|
||||
vt100_action EL; /* Erase In Line ESC [ Ps K */
|
||||
vt100_action CSI_L;
|
||||
vt100_action CSI_M;
|
||||
vt100_action CSI_N;
|
||||
vt100_action CSI_O;
|
||||
vt100_action CSI_P;
|
||||
vt100_action CSI_Q;
|
||||
vt100_action CPR; /* [w] Cursor Position Report ESC [ Pn ; Pn R */
|
||||
vt100_action CSI_S;
|
||||
vt100_action CSI_T;
|
||||
vt100_action CSI_U;
|
||||
vt100_action CSI_V;
|
||||
vt100_action CSI_W;
|
||||
vt100_action CSI_X;
|
||||
vt100_action CSI_Y;
|
||||
vt100_action CSI_Z;
|
||||
|
||||
vt100_action CSI_5B;
|
||||
vt100_action CSI_5C;
|
||||
vt100_action CSI_5D;
|
||||
vt100_action CSI_5E;
|
||||
vt100_action CSI_5F;
|
||||
vt100_action CSI_60;
|
||||
|
||||
vt100_action CSI_a;
|
||||
vt100_action CSI_b;
|
||||
vt100_action DA; /* [??] Device Attributes ESC [ Pn c */
|
||||
vt100_action CSI_d;
|
||||
vt100_action CSI_e;
|
||||
vt100_action HVP; /* Horiz. and Vert. Position ESC [ Pn ; Pn f */
|
||||
vt100_action TBC; /* Tabulation Clear ESC [ Ps g */
|
||||
vt100_action SM; /* Set Mode ESC [ Ps ; . . . ; Ps h */
|
||||
vt100_action CSI_i;
|
||||
vt100_action CSI_j;
|
||||
vt100_action CSI_k;
|
||||
vt100_action RM; /* Reset Mode ESC [ Ps ; Ps ; . . . ; Ps l */
|
||||
vt100_action SGR; /* Select Graphic Rendition ESC [ Ps ; . . . ; Ps m */
|
||||
vt100_action DSR; /* Device Status Report ESC [ Ps n */
|
||||
vt100_action CSI_o;
|
||||
vt100_action CSI_p;
|
||||
vt100_action DECLL; /* Load LEDS ESC [ Ps q */
|
||||
vt100_action DECSTBM; /* Set Top and Bottom Margins ESC [ Pn; Pn r */
|
||||
vt100_action CSI_s;
|
||||
vt100_action CSI_t;
|
||||
vt100_action CSI_u;
|
||||
vt100_action CSI_v;
|
||||
vt100_action CSI_w;
|
||||
vt100_action DECRE_TPARM; /* Re{port,quest} Terminal Parameters ESC [ . x */
|
||||
vt100_action DECTST; /* Invoke Confidence Test ESC [ 2 ; Ps y */
|
||||
vt100_action CSI_z;
|
||||
};
|
||||
|
||||
struct vt100_callbacks
|
||||
{
|
||||
struct vt100_ESC_callbacks esc;
|
||||
struct vt100_CSI_callbacks csi;
|
||||
struct vt100_hash_callbacks hash;
|
||||
struct vt100_SCS_callbacks scs;
|
||||
};
|
||||
|
||||
struct vt100_emul
|
||||
{
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int cursor_pos_x;
|
||||
unsigned int cursor_pos_y;
|
||||
enum vt100_state state;
|
||||
unsigned int argc;
|
||||
unsigned int argv[VT100_STACK_SIZE];
|
||||
void (*write)(struct vt100_emul *, char c);
|
||||
char stack[VT100_STACK_SIZE];
|
||||
unsigned int stack_ptr;
|
||||
struct vt100_callbacks *callbacks;
|
||||
char flag;
|
||||
void *user_data;
|
||||
void (*unimplemented)(struct vt100_emul*,
|
||||
char *seq,
|
||||
char chr);
|
||||
};
|
||||
|
||||
struct vt100_emul *vt100_init(unsigned int width, unsigned int height,
|
||||
struct vt100_callbacks *callbacks,
|
||||
void (*write)(struct vt100_emul *, char));
|
||||
|
||||
void vt100_read(struct vt100_emul *vt100, char c);
|
||||
void vt100_read_str(struct vt100_emul *vt100, char *c);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user