/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016--2017 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ptycon/ptycon.h>
#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;
}