diff --git a/project/common.mk b/project/common.mk index cf5cf90..cf47564 100644 --- a/project/common.mk +++ b/project/common.mk @@ -1,4 +1,5 @@ COMMON_SRCS = \ + src/bridge/ptyc_term_csi.c \ src/bridge/ptyc_term_esi.c \ src/console/ptyc_console_alloc.c \ src/console/ptyc_console_ctrl.c \ diff --git a/src/bridge/ptyc_term_csi.c b/src/bridge/ptyc_term_csi.c new file mode 100644 index 0000000..c856c35 --- /dev/null +++ b/src/bridge/ptyc_term_csi.c @@ -0,0 +1,227 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include + +#include +#include "ptycon_bridge_impl.h" + +/* forward declarations: csi sequence parameters */ +static ptyc_term_handler csi_illegal_code; +static ptyc_term_handler csi_param_decimal_digit; +static ptyc_term_handler csi_param_semicolon; + +/* forward declarations: csi sequence commands */ +static ptyc_term_handler csi_action_select_sgr; +static ptyc_term_handler csi_action_process_params; + +ptyc_term_handler * const ptyc_csi_handlers[PTYC_CSI_ARRAY_SIZE] = { + csi_illegal_code, /* 0x00 */ + csi_illegal_code, /* 0x01 */ + csi_illegal_code, /* 0x02 */ + csi_illegal_code, /* 0x03 */ + csi_illegal_code, /* 0x04 */ + csi_illegal_code, /* 0x05 */ + csi_illegal_code, /* 0x06 */ + csi_illegal_code, /* 0x07 */ + csi_illegal_code, /* 0x08 */ + csi_illegal_code, /* 0x09 */ + csi_illegal_code, /* 0x0a */ + csi_illegal_code, /* 0x0b */ + csi_illegal_code, /* 0x0c */ + csi_illegal_code, /* 0x0d */ + csi_illegal_code, /* 0x0e */ + csi_illegal_code, /* 0x0f */ + csi_illegal_code, /* 0x10 */ + csi_illegal_code, /* 0x11 */ + csi_illegal_code, /* 0x12 */ + csi_illegal_code, /* 0x13 */ + csi_illegal_code, /* 0x14 */ + csi_illegal_code, /* 0x15 */ + csi_illegal_code, /* 0x16 */ + csi_illegal_code, /* 0x17 */ + csi_illegal_code, /* 0x18 */ + csi_illegal_code, /* 0x19 */ + csi_illegal_code, /* 0x1a */ + csi_illegal_code, /* 0x1b */ + csi_illegal_code, /* 0x1c */ + csi_illegal_code, /* 0x1d */ + csi_illegal_code, /* 0x1e */ + csi_illegal_code, /* 0x1f */ + csi_illegal_code, /* 0x20 */ + csi_illegal_code, /* 0x21 */ + csi_illegal_code, /* 0x22 */ + csi_illegal_code, /* 0x23 */ + csi_illegal_code, /* 0x24 */ + csi_illegal_code, /* 0x25 */ + csi_illegal_code, /* 0x26 */ + csi_illegal_code, /* 0x27 */ + csi_illegal_code, /* 0x28 */ + csi_illegal_code, /* 0x29 */ + csi_illegal_code, /* 0x2a */ + csi_illegal_code, /* 0x2b */ + csi_illegal_code, /* 0x2c */ + csi_illegal_code, /* 0x2d */ + csi_illegal_code, /* 0x2e */ + csi_illegal_code, /* 0x2f */ + csi_param_decimal_digit, /* 0x30 */ /* null */ + csi_param_decimal_digit, /* 0x31 */ /* eins */ + csi_param_decimal_digit, /* 0x32 */ /* zwei */ + csi_param_decimal_digit, /* 0x33 */ /* drei */ + csi_param_decimal_digit, /* 0x34 */ /* vier */ + csi_param_decimal_digit, /* 0x35 */ /* fünf */ + csi_param_decimal_digit, /* 0x36 */ /* sechs */ + csi_param_decimal_digit, /* 0x37 */ /* sieben */ + csi_param_decimal_digit, /* 0x38 */ /* acht */ + csi_param_decimal_digit, /* 0x39 */ /* neun */ + csi_illegal_code, /* 0x3a */ + csi_param_semicolon, /* 0x3b */ /* semicolon */ + csi_illegal_code, /* 0x3c */ + csi_illegal_code, /* 0x3d */ + csi_illegal_code, /* 0x3e */ + csi_illegal_code, /* 0x3f */ + csi_illegal_code, /* 0x40 */ + csi_illegal_code, /* 0x41 */ + csi_illegal_code, /* 0x42 */ + csi_illegal_code, /* 0x43 */ + csi_illegal_code, /* 0x44 */ + csi_illegal_code, /* 0x45 */ + csi_illegal_code, /* 0x46 */ + csi_illegal_code, /* 0x47 */ + csi_illegal_code, /* 0x48 */ + csi_illegal_code, /* 0x49 */ + csi_illegal_code, /* 0x4a */ + csi_illegal_code, /* 0x4b */ + csi_illegal_code, /* 0x4c */ + csi_illegal_code, /* 0x4d */ + csi_illegal_code, /* 0x4e */ + csi_illegal_code, /* 0x4f */ + csi_illegal_code, /* 0x50 */ + csi_illegal_code, /* 0x51 */ + csi_illegal_code, /* 0x52 */ + csi_illegal_code, /* 0x53 */ + csi_illegal_code, /* 0x54 */ + csi_illegal_code, /* 0x55 */ + csi_illegal_code, /* 0x56 */ + csi_illegal_code, /* 0x57 */ + csi_illegal_code, /* 0x58 */ + csi_illegal_code, /* 0x59 */ + csi_illegal_code, /* 0x5a */ + csi_illegal_code, /* 0x5b */ + csi_illegal_code, /* 0x5c */ + csi_illegal_code, /* 0x5d */ + csi_illegal_code, /* 0x5e */ + csi_illegal_code, /* 0x5f */ + csi_illegal_code, /* 0x60 */ + csi_illegal_code, /* 0x61 */ + csi_illegal_code, /* 0x62 */ + csi_illegal_code, /* 0x63 */ + csi_illegal_code, /* 0x64 */ + csi_illegal_code, /* 0x65 */ + csi_illegal_code, /* 0x66 */ + csi_illegal_code, /* 0x67 */ + csi_illegal_code, /* 0x68 */ + csi_illegal_code, /* 0x69 */ + csi_illegal_code, /* 0x6a */ + csi_illegal_code, /* 0x6b */ + csi_illegal_code, /* 0x6c */ + csi_action_select_sgr, /* 0x6d */ /* lowercase m: sgr */ + csi_illegal_code +}; + + +static void * __fastcall csi_illegal_code(struct ptyc_term_ctx * tctx) +{ + /* defer to the screen handler routine */ + return tctx->char_handler; +} + + +static void * __fastcall csi_param_decimal_digit(struct ptyc_term_ctx * tctx) +{ + /* add digit to current control parameter */ + *tctx->ctrl_param *= 10; + *tctx->ctrl_param += *tctx->wch_pty - '0'; + + /* advance the stream pointer */ + tctx->wch_pty++; + + /* retain mode */ + return tctx->ctrl_handler; +} + + +static void * __fastcall csi_param_semicolon(struct ptyc_term_ctx * tctx) +{ + /* boundary check */ + if (tctx->ctrl_param == &tctx->ctrl_params[PTYC_CTRL_PARAMS-1]) + return csi_illegal_code(tctx); + + /* prepare to read the next ctrl param */ + tctx->ctrl_param++; + *tctx->ctrl_param = 0; + + /* advance the stream pointer */ + tctx->wch_pty++; + + /* retain mode */ + return tctx->ctrl_handler; +} + + +static void * __fastcall csi_action_invoke( + struct ptyc_term_ctx * tctx, + ptyc_term_handler * const * handlers, + unsigned int ctrl_cap) +{ + /* ctrl_actions */ + tctx->ctrl_state = PTYC_CTRL_STATE_COMMAND_HANDLERS; + tctx->ctrl_handlers[tctx->ctrl_state] = handlers; + + /* ctrl_cap */ + tctx->ctrl_cap = ctrl_cap; + + /* ctrl_command */ + tctx->ctrl_command = csi_action_process_params; + + /* execute */ + tctx->ctrl_command(tctx); + + /* advance the stream pointer */ + tctx->wch_pty++; + + /* switch mode */ + return tctx->char_handler; +} + + +static void * __fastcall csi_action_select_sgr(struct ptyc_term_ctx * tctx) +{ + /* todo: pass ptyc_sgr_handlers */ + return csi_action_invoke(tctx,0,PTYC_SGR_ARRAY_SIZE); +} + +static void * __fastcall csi_action_process_params(struct ptyc_term_ctx * tctx) +{ + ptyc_term_handler * pfn_action; + unsigned int action_idx; + + tctx->ctrl_mark = tctx->ctrl_params; + + while (tctx->ctrl_mark <= tctx->ctrl_param) { + action_idx = (*tctx->ctrl_mark < tctx->ctrl_cap) + ? *tctx->ctrl_mark + : tctx->ctrl_cap - 1; + + pfn_action = tctx->ctrl_handlers[tctx->ctrl_state][action_idx]; + pfn_action(tctx); + + tctx->ctrl_mark++; + } + + /* return value not used */ + return tctx->ctrl_mark; +} diff --git a/src/bridge/ptyc_term_esi.c b/src/bridge/ptyc_term_esi.c index aa105e6..b3e3bf4 100644 --- a/src/bridge/ptyc_term_esi.c +++ b/src/bridge/ptyc_term_esi.c @@ -148,8 +148,7 @@ static void * __fastcall esi_select( static void * __fastcall esi_left_bracket(struct ptyc_term_ctx * tctx) { - /* todo: pass ptyc_csi_handlers */ - return esi_select(tctx,0,PTYC_CSI_ARRAY_SIZE); + return esi_select(tctx,ptyc_csi_handlers,PTYC_CSI_ARRAY_SIZE); }