From f8cd79ee993e7226ea16c93f49ec862ab97c3957 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 1 Jun 2017 05:34:56 -0400 Subject: add a function to generate response codes for mouse movement events --- src/screen.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/screen.h | 18 +++++++++ 2 files changed, 141 insertions(+) (limited to 'src') diff --git a/src/screen.c b/src/screen.c index c471ebd..245e0a8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,3 +1,4 @@ +#include #include #include @@ -925,6 +926,128 @@ int vt100_screen_row_max_col(VT100Screen *vt, int row) return max + ((max < vt->grid->max.col - 1 && cells[max].is_wide) ? 2 : 1); } +int vt100_screen_format_mouse_reporting_response( + VT100Screen *vt, char *buf, size_t len, struct vt100_loc loc, + int event_type, int button, int shift, int alt, int ctrl) +{ + unsigned char status; + int x, y; + + if (button > VT100_BUTTON_RIGHT) { + /* don't care about button release events for scroll wheel */ + if (event_type == VT100_BUTTONEVENT_RELEASE) { + return 0; + } + + /* don't care about scroll wheel events for x10 mode */ + if (!vt100_screen_mouse_reporting_wants_button_release(vt)) { + return 0; + } + } + + if (event_type == VT100_BUTTONEVENT_RELEASE) { + status = 3; + } + else { + switch (button) { + case VT100_BUTTON_LEFT: + status = 0; + break; + case VT100_BUTTON_MIDDLE: + status = 1; + break; + case VT100_BUTTON_RIGHT: + status = 2; + break; + case VT100_BUTTON_SCROLL_UP: + status = 64; + break; + case VT100_BUTTON_SCROLL_DOWN: + status = 65; + break; + case VT100_BUTTON_NONE: + status = 3; + break; + default: + return 0; + } + } + + /* don't care about modifier keys in x10 mode */ + if (vt100_screen_mouse_reporting_wants_button_release(vt)) { + if (shift) { + status |= 4; + } + if (alt) { + status |= 8; + } + if (ctrl) { + status |= 16; + } + } + + if (event_type == VT100_BUTTONEVENT_MOTION) { + status += 32; + } + + status += 32; + x = loc.col + 1 + 32; + y = loc.row + 1 + 32; + + switch (vt->mouse_reporting_mode) { + case VT100_MOUSEREPORTING_NORMAL: + if (x > 255 || y > 255) { + return 0; + } + + return snprintf(buf, len, "\033[M%c%c%c", status, x, y); + case VT100_MOUSEREPORTING_UTF8: { + char status_bytes[2], x_bytes[2], y_bytes[2]; + int status_len, x_len, y_len; + + if (status > 0x7F) { + status_bytes[0] = 0xC0 | (status >> 3); + status_bytes[1] = 0x80 | (status & 0x6F); + status_len = 2; + } + else { + status_bytes[0] = status; + status_len = 1; + } + + if (x > 0x7F) { + x_bytes[0] = 0xC0 | (x >> 6); + x_bytes[1] = 0x80 | (x & 0x3F); + x_len = 2; + } + else { + x_bytes[0] = x; + x_len = 1; + } + + if (y > 0x7F) { + y_bytes[0] = 0xC0 | (y >> 6); + y_bytes[1] = 0x80 | (y & 0x3F); + y_len = 2; + } + else { + y_bytes[0] = y; + y_len = 1; + } + + return snprintf( + buf, len, "\033[M%.*s%.*s%.*s", status_len, status_bytes, x_len, + x_bytes, y_len, y_bytes); + } + case VT100_MOUSEREPORTING_SGR: + return snprintf( + buf, len, "\033[<%d;%d;%d%c", status - 32, x - 32, y - 32, + event_type == VT100_BUTTONEVENT_RELEASE ? 'm' : 'M'); + default: + return 0; + } +} + void vt100_screen_cleanup(VT100Screen *vt) { int i; diff --git a/src/screen.h b/src/screen.h index cea9205..36cd9b2 100644 --- a/src/screen.h +++ b/src/screen.h @@ -16,6 +16,21 @@ enum VT100MouseReportingModeType { VT100_MOUSEREPORTING_SGR }; +enum VT100ButtonEventType { + VT100_BUTTONEVENT_PRESS, + VT100_BUTTONEVENT_RELEASE, + VT100_BUTTONEVENT_MOTION +}; + +enum VT100ButtonType { + VT100_BUTTON_NONE, + VT100_BUTTON_LEFT, + VT100_BUTTON_MIDDLE, + VT100_BUTTON_RIGHT, + VT100_BUTTON_SCROLL_UP, + VT100_BUTTON_SCROLL_DOWN +}; + struct vt100_loc { int row; int col; @@ -199,6 +214,9 @@ void vt100_screen_reset_origin_mode(VT100Screen *vt); void vt100_screen_set_window_title(VT100Screen *vt, char *buf, size_t len); void vt100_screen_set_icon_name(VT100Screen *vt, char *buf, size_t len); int vt100_screen_row_max_col(VT100Screen *vt, int row); +int vt100_screen_format_mouse_reporting_response( + VT100Screen *vt, char *buf, size_t len, struct vt100_loc loc, + int event_type, int button, int shift, int alt, int ctrl); void vt100_screen_cleanup(VT100Screen *vt); void vt100_screen_delete(VT100Screen *vt); -- cgit v1.2.3-54-g00ecf