/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016--2017 SysDeer Technologies, LLC */ /* 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) { return csi_action_invoke(tctx,ptyc_sgr_handlers,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; }