Implement DECSCUSR

This commit is contained in:
Kovid Goyal 2016-11-17 13:50:20 +05:30
parent 03fd30b4f4
commit 1edba3ce42
4 changed files with 49 additions and 8 deletions

View File

@ -320,6 +320,7 @@ void screen_set_mode(Screen *self, unsigned int mode);
void screen_reset_mode(Screen *self, unsigned int mode);
void screen_insert_characters(Screen *self, unsigned int count);
void screen_cursor_up(Screen *self, unsigned int count/*=1*/, bool do_carriage_return/*=false*/, int move_direction/*=-1*/);
void screen_set_cursor(Screen *self, unsigned int mode, uint8_t secondary);
void screen_cursor_to_column(Screen *self, unsigned int column);
void screen_cursor_down(Screen *self, unsigned int count/*=1*/);
void screen_cursor_forward(Screen *self, unsigned int count/*=1*/);

View File

@ -219,7 +219,7 @@ HANDLER(esc) {
#define MAX_PARAMS 100
static inline unsigned int fill_params(Screen *screen, unsigned int *params, unsigned int expect) {
unsigned int start_pos = 1, i = 1, pi = 0;
unsigned int start_pos = 2, i = 2, pi = 0;
uint8_t ch = 1;
screen->parser_buf[screen->parser_buf_pos] = 0;
@ -272,6 +272,12 @@ HANDLER(csi) {
name(screen, p1, private); \
END_DISPATCH;
#define CALL_CSI_HANDLER1M(name, defval) \
p1 = fill_params(screen, params, 1) > 0 ? params[0] : defval; \
REPORT_COMMAND(name, p1, screen->parser_buf[1]); \
name(screen, p1, screen->parser_buf[1]); \
END_DISPATCH;
#define CALL_CSI_HANDLER2(name, defval1, defval2) \
count = fill_params(screen, params, 2); \
p1 = count > 0 ? params[0] : defval1; \
@ -314,6 +320,7 @@ HANDLER(csi) {
case CPL: \
CALL_CSI_HANDLER1(screen_cursor_up1, 1); \
case CHA: \
case HPA: \
CALL_CSI_HANDLER1(screen_cursor_to_column, 1); \
case VPA: \
CALL_CSI_HANDLER1(screen_cursor_to_line, 1); \
@ -346,6 +353,8 @@ HANDLER(csi) {
CALL_CSI_HANDLER1P(report_device_status, 0, '?'); \
case DECSTBM: \
CALL_CSI_HANDLER2(screen_set_margins, 0, 0); \
case DECSCUSR: \
CALL_CSI_HANDLER1M(screen_set_cursor, 1); \
uint8_t ch = buf[(*pos)++];
unsigned int params[MAX_PARAMS], p1, p2, count, i;
@ -354,10 +363,11 @@ HANDLER(csi) {
case 0: // CSI starting
screen->parser_buf[0] = 0;
screen->parser_buf[1] = 0;
screen->parser_buf[2] = 0;
switch(ch) {
IS_DIGIT
screen->parser_buf_pos = 2;
screen->parser_buf[1] = ch;
screen->parser_buf_pos = 3;
screen->parser_buf[2] = ch;
break;
case '?':
case '>':
@ -372,6 +382,8 @@ HANDLER(csi) {
break;
}
break;
case 1:
screen->parser_buf_pos = 2; // we start params at 2
default: // CSI started
switch(ch) {
IS_DIGIT
@ -381,6 +393,10 @@ HANDLER(csi) {
SET_STATE(NORMAL_STATE);
} else screen->parser_buf[screen->parser_buf_pos++] = ch;
break;
case ' ':
case '"':
screen->parser_buf[1] = ch;
break;
HANDLE_BASIC_CH
DISPATCH_CSI
default:

View File

@ -792,6 +792,27 @@ void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom) {
}
}
void screen_set_cursor(Screen *self, unsigned int mode, uint8_t secondary) {
uint8_t shape; bool blink;
switch(secondary) {
case 0: // DECLL
break;
case '"': // DECCSA
break;
case ' ': // DECSCUSR
shape = 0; blink = false;
if (mode > 0) {
blink = mode % 2;
shape = (mode < 3) ? CURSOR_BLOCK : (mode < 5) ? CURSOR_UNDERLINE : (mode < 7) ? CURSOR_BEAM : 0;
}
if (shape != self->cursor->shape || blink != self->cursor->blink) {
self->cursor->shape = shape; self->cursor->blink = blink;
tracker_cursor_changed(self->change_tracker);
}
break;
}
}
// }}}
// Python interface {{{

View File

@ -6,7 +6,7 @@ from functools import partial
from . import BaseTest
from kitty.fast_data_types import parse_bytes, parse_bytes_dump
from kitty.fast_data_types import parse_bytes, parse_bytes_dump, CURSOR_BLOCK
class CmdDump(list):
@ -31,7 +31,7 @@ class Callbacks:
class TestScreen(BaseTest):
def parse_buytes_dump(self, s, x, *cmds):
def parse_bytes_dump(self, s, x, *cmds):
cd = CmdDump()
if isinstance(x, str):
x = x.encode('utf-8')
@ -40,7 +40,7 @@ class TestScreen(BaseTest):
def test_simple_parsing(self):
s = self.create_screen()
pb = partial(self.parse_buytes_dump, s)
pb = partial(self.parse_bytes_dump, s)
pb('12')
self.ae(str(s.line(0)), '12 ')
@ -60,7 +60,7 @@ class TestScreen(BaseTest):
def test_esc_codes(self):
s = self.create_screen()
pb = partial(self.parse_buytes_dump, s)
pb = partial(self.parse_bytes_dump, s)
pb('12\033Da', 'screen_index')
self.ae(str(s.line(0)), '12 ')
self.ae(str(s.line(1)), ' a ')
@ -70,7 +70,7 @@ class TestScreen(BaseTest):
def test_csi_codes(self):
s = self.create_screen()
pb = partial(self.parse_buytes_dump, s)
pb = partial(self.parse_bytes_dump, s)
pb('abcde')
s.cursor_back(5)
pb('x\033[2@y', ('screen_insert_characters', 2))
@ -120,3 +120,6 @@ class TestScreen(BaseTest):
self.ae(s.margin_top, 1), self.ae(s.margin_bottom, 3)
pb('\033[r', ('screen_set_margins', 0, 0))
self.ae(s.margin_top, 0), self.ae(s.margin_bottom, 4)
pb('\033[1 q', ('screen_set_cursor', 1, ord(' ')))
self.assertTrue(s.cursor.blink)
self.ae(s.cursor.shape, CURSOR_BLOCK)