Basic xterm (?1000 and ?1002) mouse support

This commit is contained in:
Kevin Lange 2015-04-26 17:14:14 -07:00
parent 278059d6a2
commit a3f9ab465b
3 changed files with 61 additions and 0 deletions

View File

@ -290,6 +290,21 @@ static void _ansi_put(term_state_t * s, char c) {
if (!strcmp(argv[0], "?1049")) {
callbacks->cls(2);
callbacks->set_csr(0,0);
} else if (!strcmp(argv[0], "?1000")) {
s->mouse_on = 1;
} else if (!strcmp(argv[0], "?1002")) {
s->mouse_on = 2;
}
}
break;
case ANSI_HIDE:
if (argc > 0) {
if (!strcmp(argv[0], "?1049")) {
/* TODO: Unimplemented */
} else if (!strcmp(argv[0], "?1000")) {
s->mouse_on = 0;
} else if (!strcmp(argv[0], "?1002")) {
s->mouse_on = 0;
}
}
break;
@ -512,6 +527,7 @@ term_state_t * ansi_init(term_state_t * s, int w, int y, term_callbacks_t * call
s->box = 0;
s->callbacks = callbacks_in;
s->callbacks->set_color(s->fg, s->bg);
s->mouse_on = 0;
return s;
}

View File

@ -44,6 +44,7 @@ typedef struct {
char buffer[TERM_BUF_LEN]; /* Previous buffer */
term_callbacks_t * callbacks;
int volatile lock;
uint8_t mouse_on;
} term_state_t;
/* Triggers escape mode. */

View File

@ -76,6 +76,10 @@ uint8_t _force_kernel = 0;
uint8_t _hold_out = 0; /* state indicator on last cell ignore \n */
uint8_t _free_size = 1; /* Disable rounding when resized */
int last_mouse_x = -1;
int last_mouse_y = -1;
int button_state = 0;
static volatile int display_lock = 0;
yutani_window_t * window = NULL; /* GUI window */
@ -1087,6 +1091,12 @@ static void resize_finish(int width, int height) {
yutani_flip(yctx, window);
}
void mouse_event(int button, int x, int y) {
char buf[7];
sprintf(buf, "\033[M%c%c%c", button + 32, x + 33, y + 33);
handle_input_s(buf);
}
void * handle_incoming(void * garbage) {
while (!exit_application) {
yutani_msg_t * m = yutani_poll(yctx);
@ -1128,6 +1138,40 @@ void * handle_incoming(void * garbage) {
if (decor_handle_event(yctx, m) == DECOR_CLOSE) {
kill(child_pid, SIGKILL);
exit_application = 1;
break;
}
}
/* Map Cursor Action */
if (ansi_state->mouse_on) {
int new_x = me->new_x;
int new_y = me->new_y;
if (!_no_frame) {
new_x -= decor_left_width;
new_y -= decor_top_height;
}
/* Convert from coordinate to cell positon */
new_x /= char_width;
new_y /= char_height;
if (me->buttons != button_state) {
/* Figure out what changed */
if (me->buttons & YUTANI_MOUSE_BUTTON_LEFT && !(button_state & YUTANI_MOUSE_BUTTON_LEFT)) mouse_event(0, new_x, new_y);
if (me->buttons & YUTANI_MOUSE_BUTTON_MIDDLE && !(button_state & YUTANI_MOUSE_BUTTON_MIDDLE)) mouse_event(1, new_x, new_y);
if (me->buttons & YUTANI_MOUSE_BUTTON_RIGHT && !(button_state & YUTANI_MOUSE_BUTTON_RIGHT)) mouse_event(2, new_x, new_y);
if (!(me->buttons & YUTANI_MOUSE_BUTTON_LEFT) && button_state & YUTANI_MOUSE_BUTTON_LEFT) mouse_event(3, new_x, new_y);
if (!(me->buttons & YUTANI_MOUSE_BUTTON_MIDDLE) && button_state & YUTANI_MOUSE_BUTTON_MIDDLE) mouse_event(3, new_x, new_y);
if (!(me->buttons & YUTANI_MOUSE_BUTTON_RIGHT) && button_state & YUTANI_MOUSE_BUTTON_RIGHT) mouse_event(3, new_x, new_y);
last_mouse_x = new_x;
last_mouse_y = new_y;
button_state = me->buttons;
} else if (ansi_state->mouse_on == 2) {
/* Report motion for pressed buttons */
if (last_mouse_x == new_x && last_mouse_y == new_y) break;
if (button_state & YUTANI_MOUSE_BUTTON_LEFT) mouse_event(32, new_x, new_y);
if (button_state & YUTANI_MOUSE_BUTTON_MIDDLE) mouse_event(33, new_x, new_y);
if (button_state & YUTANI_MOUSE_BUTTON_RIGHT) mouse_event(34, new_x, new_y);
last_mouse_x = new_x;
last_mouse_y = new_y;
}
}
}