More work on making Screen native
This commit is contained in:
parent
2c0523246d
commit
bead388d81
65
kitty/control-codes.h
Normal file
65
kitty/control-codes.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* control_codes.h
|
||||
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Space
|
||||
#define SP ' '
|
||||
|
||||
// *Null*: Does nothing.
|
||||
#define NUL 0
|
||||
|
||||
// *Bell*: Beeps.
|
||||
#define BEL 0x07
|
||||
|
||||
// *Backspace*: Backspace one column, but not past the begining of the
|
||||
// line.
|
||||
#define BS 0x08
|
||||
|
||||
// *Horizontal tab*: Move cursor to the next tab stop, or to the end
|
||||
// of the line if there is no earlier tab stop.
|
||||
#define HT 0x09
|
||||
|
||||
// *Linefeed*: Give a line feed, and, if :data:`pyte.modes.LNM` (new
|
||||
// line mode) is set also a carriage return.
|
||||
#define LF 10
|
||||
|
||||
// *Vertical tab*: Same as :data:`LF`.
|
||||
#define VT 0x0b
|
||||
// *Form feed*: Same as :data:`LF`.
|
||||
#define FF 0x0c
|
||||
|
||||
// *Carriage return*: Move cursor to left margin on current line.
|
||||
#define CR 13
|
||||
|
||||
// *Shift out*: Activate G1 character set.
|
||||
#define SO 0x0e
|
||||
|
||||
// *Shift in*: Activate G0 character set.
|
||||
#define SI 0x0f
|
||||
|
||||
// *Cancel*: Interrupt escape sequence. If received during an escape or
|
||||
// control sequence, cancels the sequence and displays substitution
|
||||
// character.
|
||||
#define CAN 0x18
|
||||
// *Substitute*: Same as :data:`CAN`.
|
||||
#define SUB 0x1a
|
||||
|
||||
// *Escape*: Starts an escape sequence.
|
||||
#define ESC 0x1b
|
||||
|
||||
// *Delete*: Is ignored.
|
||||
#define DEL 0x7f
|
||||
|
||||
// *Control sequence introducer*: An equivalent for ``ESC [``.
|
||||
#define CSI 0x9b
|
||||
|
||||
// *String terminator*.
|
||||
#define ST 0x9c
|
||||
|
||||
// *Operating system command*.
|
||||
#define OSC 0x9d
|
||||
@ -209,6 +209,11 @@ typedef struct {
|
||||
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
|
||||
ChangeTracker *change_tracker;
|
||||
ScreenModes modes;
|
||||
|
||||
uint8_t parser_buf[8192];
|
||||
unsigned int parser_state, parser_text_start;
|
||||
bool parser_has_pending_text;
|
||||
|
||||
} Screen;
|
||||
|
||||
Line* alloc_line();
|
||||
|
||||
118
kitty/parser.c
118
kitty/parser.c
@ -6,8 +6,107 @@
|
||||
*/
|
||||
|
||||
#include "data-types.h"
|
||||
#include "control-codes.h"
|
||||
|
||||
extern PyTypeObject Screen_Type;
|
||||
|
||||
#define NORMAL_STATE 0
|
||||
#define ESC_STATE 1
|
||||
#define CSI_STATE 2
|
||||
#define OSC_STATE 3
|
||||
#define DCS_STATE 4
|
||||
|
||||
#define DECLARE_CH_SCREEN_HANDLER(name) extern bool screen_##name(Screen *screen, uint8_t ch);
|
||||
DECLARE_CH_SCREEN_HANDLER(bell)
|
||||
DECLARE_CH_SCREEN_HANDLER(backspace)
|
||||
DECLARE_CH_SCREEN_HANDLER(tab)
|
||||
DECLARE_CH_SCREEN_HANDLER(linefeed)
|
||||
DECLARE_CH_SCREEN_HANDLER(carriage_return)
|
||||
DECLARE_CH_SCREEN_HANDLER(shift_out)
|
||||
DECLARE_CH_SCREEN_HANDLER(shift_in)
|
||||
extern bool screen_draw(Screen *screen, uint8_t *buf, unsigned int buflen);
|
||||
|
||||
static inline bool
|
||||
read_text(Screen *screen, uint8_t *buf, unsigned int buflen, unsigned int *pos) {
|
||||
bool ret;
|
||||
uint8_t ch;
|
||||
|
||||
while(*pos < buflen) {
|
||||
ch = buf[(*pos)++];
|
||||
#define DRAW_TEXT \
|
||||
if (screen->parser_has_pending_text) { \
|
||||
screen->parser_has_pending_text = false; \
|
||||
ret = screen_draw(screen, buf + screen->parser_text_start, (*pos) - screen->parser_text_start); \
|
||||
screen->parser_text_start = 0; \
|
||||
if (!ret) return false; \
|
||||
}
|
||||
|
||||
#define CALL_SCREEN_HANDLER(name) \
|
||||
DRAW_TEXT; \
|
||||
if (!screen_##name(screen, ch)) return false;
|
||||
|
||||
#define CHANGE_PARSER_STATE(state) screen->parser_state = state; return true;
|
||||
switch(ch) {
|
||||
case BEL:
|
||||
CALL_SCREEN_HANDLER(bell);
|
||||
case BS:
|
||||
CALL_SCREEN_HANDLER(backspace);
|
||||
case HT:
|
||||
CALL_SCREEN_HANDLER(tab);
|
||||
case LF:
|
||||
case VT:
|
||||
case FF:
|
||||
CALL_SCREEN_HANDLER(linefeed);
|
||||
case CR:
|
||||
CALL_SCREEN_HANDLER(carriage_return);
|
||||
case SO:
|
||||
CALL_SCREEN_HANDLER(shift_out);
|
||||
case SI:
|
||||
CALL_SCREEN_HANDLER(shift_in);
|
||||
case ESC:
|
||||
CHANGE_PARSER_STATE(ESC_STATE);
|
||||
case CSI:
|
||||
CHANGE_PARSER_STATE(CSI_STATE);
|
||||
case NUL:
|
||||
case DEL:
|
||||
break;
|
||||
case OSC:
|
||||
CHANGE_PARSER_STATE(OSC_STATE);
|
||||
default:
|
||||
if (!screen->parser_has_pending_text) {
|
||||
screen->parser_has_pending_text = true;
|
||||
screen->parser_text_start = (*pos) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
DRAW_TEXT;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
read_esc(Screen *screen, uint8_t *buf, unsigned int buflen, unsigned int *pos) {
|
||||
screen->parser_state = NORMAL_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
read_csi(Screen *screen, uint8_t *buf, unsigned int buflen, unsigned int *pos) {
|
||||
screen->parser_state = NORMAL_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
read_osc(Screen *screen, uint8_t *buf, unsigned int buflen, unsigned int *pos) {
|
||||
screen->parser_state = NORMAL_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
read_dcs(Screen *screen, uint8_t *buf, unsigned int buflen, unsigned int *pos) {
|
||||
screen->parser_state = NORMAL_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
#ifdef DUMP_COMMANDS
|
||||
parse_bytes_dump(PyObject UNUSED *self, PyObject *args) {
|
||||
@ -22,5 +121,24 @@ parse_bytes(PyObject UNUSED *self, PyObject *args) {
|
||||
#else
|
||||
if (!PyArg_ParseTuple(args, "O!y*", &Screen_Type, &screen, &pybuf)) return NULL;
|
||||
#endif
|
||||
uint8_t *buf = pybuf.buf;
|
||||
unsigned int i = 0;
|
||||
#define CALL_HANDLER(name) \
|
||||
if (!name(screen, buf, pybuf.len, &i)) return NULL; break; \
|
||||
|
||||
while (i < pybuf.len) {
|
||||
switch(screen->parser_state) {
|
||||
case ESC_STATE:
|
||||
CALL_HANDLER(read_esc);
|
||||
case CSI_STATE:
|
||||
CALL_HANDLER(read_csi);
|
||||
case OSC_STATE:
|
||||
CALL_HANDLER(read_osc);
|
||||
case DCS_STATE:
|
||||
CALL_HANDLER(read_dcs);
|
||||
default:
|
||||
CALL_HANDLER(read_text);
|
||||
}
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user