mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-15 22:05:24 -05:00
vt: add support for mouse motion reports
This commit is contained in:
parent
e5fc266cdb
commit
1610828b8c
4 changed files with 135 additions and 69 deletions
12
csi.c
12
csi.c
|
|
@ -597,28 +597,26 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
break;
|
||||
|
||||
case 1002:
|
||||
LOG_WARN("unimplemented: report button and mouse motion");
|
||||
/* term->mouse_tracking = MOUSE_DRAG; */
|
||||
term->mouse_tracking = MOUSE_DRAG;
|
||||
break;
|
||||
|
||||
case 1003:
|
||||
LOG_WARN("unimplemented: report all mouse events");
|
||||
/* term->mouse_tracking = MOUSE_MOTION; */
|
||||
term->mouse_tracking = MOUSE_MOTION;
|
||||
break;
|
||||
|
||||
case 1005:
|
||||
LOG_WARN("unimplemented: UTF-8 mouse");
|
||||
/* term->mouse_reporting = MOUSE_UTF8 */
|
||||
/* term->mouse_reporting = MOUSE_UTF8; */
|
||||
break;
|
||||
|
||||
case 1006:
|
||||
LOG_WARN("unimplemented: SGR mouse");
|
||||
/* term->mouse_reporting = MOUSE_SGR */
|
||||
term->mouse_reporting = MOUSE_SGR;
|
||||
break;
|
||||
|
||||
case 1015:
|
||||
LOG_WARN("unimplemented: URXVT mosue");
|
||||
/* term->mouse_reporting = MOUSE_URXVT */
|
||||
/* term->mouse_reporting = MOUSE_URXVT; */
|
||||
break;
|
||||
|
||||
case 1049:
|
||||
|
|
|
|||
82
input.c
82
input.c
|
|
@ -33,6 +33,10 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
/* TODO: initialize in enter? */
|
||||
term->kbd.xkb_state = xkb_state_new(term->kbd.xkb_keymap);
|
||||
|
||||
term->kbd.mod_shift = xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Shift");
|
||||
term->kbd.mod_alt = xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Mod1") ;
|
||||
term->kbd.mod_ctrl = xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Control");
|
||||
|
||||
munmap(map_str, size);
|
||||
close(fd);
|
||||
}
|
||||
|
|
@ -147,19 +151,11 @@ static void
|
|||
keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||
uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
static bool mod_masks_initialized = false;
|
||||
static xkb_mod_mask_t ctrl = -1;
|
||||
static xkb_mod_mask_t alt = -1;
|
||||
static xkb_mod_mask_t shift = -1;
|
||||
|
||||
struct terminal *term = data;
|
||||
|
||||
if (!mod_masks_initialized) {
|
||||
mod_masks_initialized = true;
|
||||
ctrl = 1 << xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Control");
|
||||
alt = 1 << xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Mod1");
|
||||
shift = 1 << xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Shift");
|
||||
}
|
||||
const xkb_mod_mask_t ctrl = 1 << term->kbd.mod_ctrl;
|
||||
const xkb_mod_mask_t alt = 1 << term->kbd.mod_alt;
|
||||
const xkb_mod_mask_t shift = 1 << term->kbd.mod_shift;
|
||||
|
||||
if (state == XKB_KEY_UP) {
|
||||
mtx_lock(&term->kbd.repeat.mutex);
|
||||
|
|
@ -262,6 +258,14 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
|
||||
xkb_state_update_mask(
|
||||
term->kbd.xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||
|
||||
/* Update state of modifiers we're interrested in for e.g mouse events */
|
||||
term->kbd.shift = xkb_state_mod_index_is_active(
|
||||
term->kbd.xkb_state, term->kbd.mod_shift, XKB_STATE_MODS_DEPRESSED);
|
||||
term->kbd.alt = xkb_state_mod_index_is_active(
|
||||
term->kbd.xkb_state, term->kbd.mod_alt, XKB_STATE_MODS_DEPRESSED);
|
||||
term->kbd.ctrl = xkb_state_mod_index_is_active(
|
||||
term->kbd.xkb_state, term->kbd.mod_ctrl, XKB_STATE_MODS_DEPRESSED);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -295,8 +299,12 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
|
|||
wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||
{
|
||||
struct terminal *term = data;
|
||||
term->mouse.x = wl_fixed_to_int(surface_x);
|
||||
term->mouse.y = wl_fixed_to_int(surface_y);
|
||||
|
||||
int x = wl_fixed_to_int(surface_x) * 1; //scale
|
||||
int y = wl_fixed_to_int(surface_y) * 1; //scale
|
||||
|
||||
term->mouse.col = x / term->cell_width;
|
||||
term->mouse.row = y / term->cell_height;
|
||||
|
||||
render_update_cursor_surface(term);
|
||||
}
|
||||
|
|
@ -312,8 +320,22 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
|||
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||
{
|
||||
struct terminal *term = data;
|
||||
term->mouse.x = wl_fixed_to_int(surface_x) * 1;//backend->monitor->scale;
|
||||
term->mouse.y = wl_fixed_to_int(surface_y) * 1;//backend->monitor->scale;
|
||||
|
||||
int x = wl_fixed_to_int(surface_x) * 1;//backend->monitor->scale;
|
||||
int y = wl_fixed_to_int(surface_y) * 1;//backend->monitor->scale;
|
||||
|
||||
int col = x / term->cell_width;
|
||||
int row = y / term->cell_width;
|
||||
|
||||
if (col == term->mouse.col && row == term->mouse.row)
|
||||
return;
|
||||
|
||||
term->mouse.col = x / term->cell_width;
|
||||
term->mouse.row = y / term->cell_height;
|
||||
|
||||
term_mouse_motion(
|
||||
term, term->mouse.button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -324,35 +346,17 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
|
||||
struct terminal *term = data;
|
||||
|
||||
static bool mods_initialized = false;
|
||||
static xkb_mod_index_t shift, alt, ctrl;
|
||||
|
||||
if (!mods_initialized) {
|
||||
struct xkb_keymap *map = term->kbd.xkb_keymap;
|
||||
shift = xkb_keymap_mod_get_index(map, "Shift");
|
||||
alt = xkb_keymap_mod_get_index(map, "Mod1") ;
|
||||
ctrl = xkb_keymap_mod_get_index(map, "Control");
|
||||
mods_initialized = true;
|
||||
}
|
||||
|
||||
int col = term->mouse.x / term->cell_width;
|
||||
int row = term->mouse.y / term->cell_height;
|
||||
|
||||
struct xkb_state *xkb = term->kbd.xkb_state;
|
||||
bool shift_active = xkb_state_mod_index_is_active(
|
||||
xkb, shift, XKB_STATE_MODS_DEPRESSED);
|
||||
bool alt_active = xkb_state_mod_index_is_active(
|
||||
xkb, alt, XKB_STATE_MODS_DEPRESSED);
|
||||
bool ctrl_active = xkb_state_mod_index_is_active(
|
||||
xkb, ctrl, XKB_STATE_MODS_DEPRESSED);
|
||||
|
||||
switch (state) {
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
term_mouse_down(term, button, row, col, shift_active, alt_active, ctrl_active);
|
||||
term->mouse.button = button; /* For motion events */
|
||||
term_mouse_down(term, button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
break;
|
||||
|
||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||
term_mouse_up(term, button, row, col, shift_active, alt_active, ctrl_active);
|
||||
term->mouse.button = 0; /* For motion events */
|
||||
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
94
terminal.c
94
terminal.c
|
|
@ -423,35 +423,36 @@ encode_xbutton(int xbutton)
|
|||
}
|
||||
|
||||
static void
|
||||
report_mouse_click(struct terminal *term, int button, int row, int col,
|
||||
bool release, bool shift, bool alt, bool ctrl)
|
||||
report_mouse_click(struct terminal *term, int encoded_button, int row, int col,
|
||||
bool release)
|
||||
{
|
||||
/* Map libevent button event code to X button number */
|
||||
int xbutton = linux_mouse_button_to_x(button);
|
||||
if (xbutton == -1)
|
||||
return;
|
||||
|
||||
if (release && (xbutton == 4 || xbutton == 5)) {
|
||||
/* No button release events for scroll buttons */
|
||||
return;
|
||||
}
|
||||
|
||||
int encoded = release ? 3 : encode_xbutton(xbutton);
|
||||
if (encoded == -1)
|
||||
return;
|
||||
|
||||
encoded += (shift ? 4 : 0) + (alt ? 8 : 0) + (ctrl ? 16 : 0);
|
||||
|
||||
char response[16];
|
||||
snprintf(response, sizeof(response), "\033[M%c%c%c",
|
||||
32 + encoded, 32 + col + 1, 32 + row + 1);
|
||||
32 + encoded_button, 32 + col + 1, 32 + row + 1);
|
||||
write(term->ptmx, response, strlen(response));
|
||||
}
|
||||
|
||||
static void
|
||||
report_mouse_motion(struct terminal *term, int encoded_button, int row, int col)
|
||||
{
|
||||
report_mouse_click(term, encoded_button, row, col, false);
|
||||
}
|
||||
|
||||
void
|
||||
term_mouse_down(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl)
|
||||
{
|
||||
/* Map libevent button event code to X button number */
|
||||
int xbutton = linux_mouse_button_to_x(button);
|
||||
if (xbutton == -1)
|
||||
return;
|
||||
|
||||
int encoded = encode_xbutton(xbutton);
|
||||
if (encoded == -1)
|
||||
return;
|
||||
|
||||
encoded += (shift ? 4 : 0) + (alt ? 8 : 0) + (ctrl ? 16 : 0);
|
||||
|
||||
switch (term->mouse_tracking) {
|
||||
case MOUSE_NONE:
|
||||
break;
|
||||
|
|
@ -460,7 +461,7 @@ term_mouse_down(struct terminal *term, int button, int row, int col,
|
|||
case MOUSE_CLICK:
|
||||
case MOUSE_DRAG:
|
||||
case MOUSE_MOTION:
|
||||
report_mouse_click(term, button, row, col, false, shift, alt, ctrl);
|
||||
report_mouse_click(term, encoded, row, col, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -469,6 +470,19 @@ void
|
|||
term_mouse_up(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl)
|
||||
{
|
||||
/* Map libevent button event code to X button number */
|
||||
int xbutton = linux_mouse_button_to_x(button);
|
||||
if (xbutton == -1)
|
||||
return;
|
||||
|
||||
if (xbutton == 4 || xbutton == 5) {
|
||||
/* No release events for scroll buttons */
|
||||
return;
|
||||
}
|
||||
|
||||
int encoded = 3;
|
||||
encoded += (shift ? 4 : 0) + (alt ? 8 : 0) + (ctrl ? 16 : 0);
|
||||
|
||||
switch (term->mouse_tracking) {
|
||||
case MOUSE_NONE:
|
||||
break;
|
||||
|
|
@ -477,7 +491,45 @@ term_mouse_up(struct terminal *term, int button, int row, int col,
|
|||
case MOUSE_CLICK:
|
||||
case MOUSE_DRAG:
|
||||
case MOUSE_MOTION:
|
||||
report_mouse_click(term, button, row, col, true, shift, alt, ctrl);
|
||||
report_mouse_click(term, encoded, row, col, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
term_mouse_motion(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl)
|
||||
{
|
||||
int encoded = 0;
|
||||
|
||||
if (button != 0) {
|
||||
/* Map libevent button event code to X button number */
|
||||
int xbutton = linux_mouse_button_to_x(button);
|
||||
if (xbutton == -1)
|
||||
return;
|
||||
|
||||
encoded = encode_xbutton(xbutton);
|
||||
if (encoded == -1)
|
||||
return;
|
||||
} else
|
||||
encoded = 3; /* "released" */
|
||||
|
||||
encoded += 32; /* Motion event */
|
||||
encoded += (shift ? 4 : 0) + (alt ? 8 : 0) + (ctrl ? 16 : 0);
|
||||
|
||||
switch (term->mouse_tracking) {
|
||||
case MOUSE_NONE:
|
||||
case MOUSE_X10:
|
||||
case MOUSE_CLICK:
|
||||
return;
|
||||
|
||||
case MOUSE_DRAG:
|
||||
if (button == 0)
|
||||
return;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case MOUSE_MOTION:
|
||||
report_mouse_motion(term, encoded, row, col);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
terminal.h
16
terminal.h
|
|
@ -145,6 +145,15 @@ struct kbd {
|
|||
int32_t rate;
|
||||
uint32_t key;
|
||||
} repeat;
|
||||
|
||||
xkb_mod_index_t mod_shift;
|
||||
xkb_mod_index_t mod_alt;
|
||||
xkb_mod_index_t mod_ctrl;
|
||||
|
||||
/* Enabled modifiers */
|
||||
bool shift;
|
||||
bool alt;
|
||||
bool ctrl;
|
||||
};
|
||||
|
||||
enum decckm { DECCKM_CSI, DECCKM_SS3 };
|
||||
|
|
@ -202,8 +211,9 @@ struct terminal {
|
|||
struct rgba background;
|
||||
|
||||
struct {
|
||||
int x;
|
||||
int y;
|
||||
int row;
|
||||
int col;
|
||||
int button;
|
||||
} mouse;
|
||||
|
||||
struct cursor cursor;
|
||||
|
|
@ -250,3 +260,5 @@ void term_mouse_down(struct terminal *term, int button, int row, int col,
|
|||
bool shift, bool alt, bool ctrl);
|
||||
void term_mouse_up(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl);
|
||||
void term_mouse_motion(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue