Blame src/bridge/ptyc_term_csi.c

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