Start work on connecting CSI callbacks
This commit is contained in:
parent
e50fc2067c
commit
d0c2821339
@ -313,6 +313,7 @@ void screen_reverse_index(Screen *self);
|
|||||||
void screen_index(Screen *self);
|
void screen_index(Screen *self);
|
||||||
void screen_reset(Screen *self);
|
void screen_reset(Screen *self);
|
||||||
void screen_set_tab_stop(Screen *self);
|
void screen_set_tab_stop(Screen *self);
|
||||||
|
void screen_insert_characters(Screen *self, unsigned int count);
|
||||||
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen, uint8_t ch);
|
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen, uint8_t ch);
|
||||||
DECLARE_CH_SCREEN_HANDLER(bell)
|
DECLARE_CH_SCREEN_HANDLER(bell)
|
||||||
DECLARE_CH_SCREEN_HANDLER(backspace)
|
DECLARE_CH_SCREEN_HANDLER(backspace)
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
#include "control-codes.h"
|
#include "control-codes.h"
|
||||||
|
|
||||||
@ -214,6 +215,26 @@ HANDLER(esc) {
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Parse CSI {{{
|
// Parse CSI {{{
|
||||||
|
|
||||||
|
#define MAX_PARAMS 8
|
||||||
|
|
||||||
|
static inline unsigned int fill_params(Screen *screen, unsigned int *params, unsigned int expect) {
|
||||||
|
unsigned int start_pos = 1, i = 1, pi = 0;
|
||||||
|
uint8_t ch;
|
||||||
|
screen->parser_buf[screen->parser_buf_pos++] = ';';
|
||||||
|
|
||||||
|
while (pi < MIN(MAX_PARAMS, expect) && i < PARSER_BUF_SZ - 1) {
|
||||||
|
ch = screen->parser_buf[i++];
|
||||||
|
if (ch == 0 || ch == ';') {
|
||||||
|
if (start_pos < i - 1) {
|
||||||
|
params[pi++] = atoi((const char *)screen->parser_buf + start_pos);
|
||||||
|
}
|
||||||
|
start_pos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pi;
|
||||||
|
}
|
||||||
|
|
||||||
HANDLER(csi) {
|
HANDLER(csi) {
|
||||||
#define CALL_BASIC_HANDLER(name) REPORT_COMMAND(screen, ch); name(screen, ch); break;
|
#define CALL_BASIC_HANDLER(name) REPORT_COMMAND(screen, ch); name(screen, ch); break;
|
||||||
#define HANDLE_BASIC_CH \
|
#define HANDLE_BASIC_CH \
|
||||||
@ -232,8 +253,17 @@ HANDLER(csi) {
|
|||||||
case NUL: \
|
case NUL: \
|
||||||
case DEL: \
|
case DEL: \
|
||||||
break; // no-op
|
break; // no-op
|
||||||
|
#define CALL_CSI_HANDLER1(name) \
|
||||||
|
if (fill_params(screen, params, 1) != 1) { REPORT_ERROR("Expected parameter for CSI escape sequence: %s missing", #name); } \
|
||||||
|
else { \
|
||||||
|
REPORT_COMMAND(name, params[0]); \
|
||||||
|
screen_insert_characters(screen, params[0]); \
|
||||||
|
} \
|
||||||
|
SET_STATE(NORMAL_STATE); \
|
||||||
|
break;
|
||||||
|
|
||||||
uint8_t ch = buf[(*pos)++];
|
uint8_t ch = buf[(*pos)++];
|
||||||
|
unsigned int params[MAX_PARAMS];
|
||||||
switch(screen->parser_buf_pos) {
|
switch(screen->parser_buf_pos) {
|
||||||
case 0: // CSI starting
|
case 0: // CSI starting
|
||||||
screen->parser_buf[0] = 0;
|
screen->parser_buf[0] = 0;
|
||||||
@ -250,9 +280,9 @@ HANDLER(csi) {
|
|||||||
break;
|
break;
|
||||||
HANDLE_BASIC_CH
|
HANDLE_BASIC_CH
|
||||||
default:
|
default:
|
||||||
REPORT_ERROR("%s%d", "Invalid first character for CSI: ", (int)ch);
|
REPORT_ERROR("Invalid first character for CSI: 0x%x", ch);
|
||||||
SET_STATE(NORMAL_STATE);
|
SET_STATE(NORMAL_STATE);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // CSI started
|
default: // CSI started
|
||||||
@ -264,12 +294,21 @@ HANDLER(csi) {
|
|||||||
SET_STATE(NORMAL_STATE);
|
SET_STATE(NORMAL_STATE);
|
||||||
} else screen->parser_buf[screen->parser_buf_pos++] = ch;
|
} else screen->parser_buf[screen->parser_buf_pos++] = ch;
|
||||||
break;
|
break;
|
||||||
|
HANDLE_BASIC_CH
|
||||||
|
default:
|
||||||
|
REPORT_ERROR("Invalid character for CSI: 0x%x", ch);
|
||||||
|
SET_STATE(NORMAL_STATE);
|
||||||
|
break;
|
||||||
|
case ICH:
|
||||||
|
CALL_CSI_HANDLER1(screen_insert_characters);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#undef CALL_BASIC_HANDLER
|
#undef CALL_BASIC_HANDLER
|
||||||
#undef HANDLE_BASIC_CH
|
#undef HANDLE_BASIC_CH
|
||||||
|
#undef CALL_CSI_HANDLER1
|
||||||
}
|
}
|
||||||
|
#undef MAX_PARAMS
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Parse OSC {{{
|
// Parse OSC {{{
|
||||||
|
|||||||
@ -55,3 +55,14 @@ class TestScreen(BaseTest):
|
|||||||
pb('\033x', 'Unknown char in escape_dispatch: %d' % ord('x'))
|
pb('\033x', 'Unknown char in escape_dispatch: %d' % ord('x'))
|
||||||
pb('\033c123', 'screen_reset')
|
pb('\033c123', 'screen_reset')
|
||||||
self.ae(str(s.line(0)), '123 ')
|
self.ae(str(s.line(0)), '123 ')
|
||||||
|
|
||||||
|
def test_csi_codes(self):
|
||||||
|
s = self.create_screen()
|
||||||
|
pb = partial(self.parse_buytes_dump, s)
|
||||||
|
pb('abcde')
|
||||||
|
s.cursor_back(5)
|
||||||
|
pb('x\033[2@y', ('screen_insert_characters', 2))
|
||||||
|
self.ae(str(s.line(0)), 'xy bc')
|
||||||
|
pb('x\033[2;3@y', ('screen_insert_characters', 2))
|
||||||
|
pb('x\033[@y', 'Invalid first character for CSI: 0x%x' % ord('@'))
|
||||||
|
s.reset()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user