hl-vt100/src/lw_terminal_parser.h

228 lines
6.1 KiB
C

/*
* Copyright (c) 2016 Julien Palard.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TERMINAL_H__
#define __TERMINAL_H__
/*
**
** Introduction
** ============
**
** terminal.c is a basic level that parses escape sequences to call
** appropriated callbacks permiting you to implement a specific terminal.
**
** Callbacks
** =========
**
** terminal.c maps sequences to callbacks in this way :
** \033... maps to terminal->callbacks->esc
** \033[... maps to terminal->callbacks->csi
** \033#... maps to terminal->callbacks->hash
** and \033( and \033) maps to terminal->callbacks->scs
**
** In 'callbacks', esc, csi, hash and scs are structs ascii_callbacks
** where you can bind your callbacks.
**
** Typically when terminal parses \033[42;43m
** it calls terminal->callbacks->csi->m(terminal);
**
** Parameters (here 42;43) are stored in terminal->argc and terminal->argv
** argv is an array of integers of length argc.
**
** Public members
** ==============
**
** void *user_data :
** A (void *) where your implementation can store whatever you want
** to get it back on your callabks.
**
** void (*write)(struct terminal *, char c) :
** Hook for your implementation to recieve chars that are not
** escape sequences
**
** struct term_callbacks callbacks :
** Hooks for your callbacks to recieve escape sequences
**
** enum term_state state :
** During a callback, typically a scs, you can read here if it's a
** G1SET or a G0SET
**
** unsigned int argc :
** For your callbacks, to know how many parameters are available
** in argv.
**
** unsigned int argv[TERM_STACK_SIZE] :
** For your callbacks, parameters of escape sequences are accessible
** here.
** \033[42;43m will have 2 in argc and argv[0] = 42, argv[1] = 43
**
** char flag;
** Optinal constructor flag present before parameters, like in :
** \033[?1049h -> The flag will be '?'
** Otherwise the flag is set to '\0'
**
** void (*unimplemented)(struct terminal*, char *seq, char chr) :
** Can be NULL, you can hook here to know where the terminal parses an
** escape sequence on which you have not registered a callback.
**
** Exemple
** =======
**
** See terminal_vt100.c for a working exemple.
**
*/
#define TERM_STACK_SIZE 1024
enum term_state
{
INIT,
ESC,
HASH,
G0SET,
G1SET,
CSI
};
struct lw_terminal;
typedef void (*term_action)(struct lw_terminal *emul);
struct ascii_callbacks
{
term_action n0;
term_action n1;
term_action n2;
term_action n3;
term_action n4;
term_action n5;
term_action n6;
term_action n7;
term_action n8;
term_action n9;
term_action h3A;
term_action h3B;
term_action h3C;
term_action h3D;
term_action h3E;
term_action h3F;
term_action h40;
term_action A;
term_action B;
term_action C;
term_action D;
term_action E;
term_action F;
term_action G;
term_action H;
term_action I;
term_action J;
term_action K;
term_action L;
term_action M;
term_action N;
term_action O;
term_action P;
term_action Q;
term_action R;
term_action S;
term_action T;
term_action U;
term_action V;
term_action W;
term_action X;
term_action Y;
term_action Z;
term_action h5B;
term_action h5C;
term_action h5D;
term_action h5E;
term_action h5F;
term_action h60;
term_action a;
term_action b;
term_action c;
term_action d;
term_action e;
term_action f;
term_action g;
term_action h;
term_action i;
term_action j;
term_action k;
term_action l;
term_action m;
term_action n;
term_action o;
term_action p;
term_action q;
term_action r;
term_action s;
term_action t;
term_action u;
term_action v;
term_action w;
term_action x;
term_action y;
term_action z;
};
struct term_callbacks
{
struct ascii_callbacks esc;
struct ascii_callbacks csi;
struct ascii_callbacks hash;
struct ascii_callbacks scs;
};
struct lw_terminal
{
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 lw_terminal *, char c);
char stack[TERM_STACK_SIZE];
unsigned int stack_ptr;
struct term_callbacks callbacks;
char flag;
void *user_data;
void (*unimplemented)(struct lw_terminal*,
char *seq, char chr);
};
struct lw_terminal *lw_terminal_parser_init(void);
void lw_terminal_parser_default_unimplemented(struct lw_terminal* this, char *seq, char chr);
void lw_terminal_parser_read(struct lw_terminal *this, char c);
void lw_terminal_parser_read_str(struct lw_terminal *this, char *c);
void lw_terminal_parser_destroy(struct lw_terminal* this);
#endif