Port mouse event encoding code to C
This commit is contained in:
parent
b9ac13c379
commit
43c4c71abd
@ -237,3 +237,30 @@ decode_utf8(uint32_t* state, uint32_t* codep, uint8_t byte) {
|
|||||||
*state = utf8_data[256 + *state*16 + type];
|
*state = utf8_data[256 + *state*16 + type];
|
||||||
return *state;
|
return *state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
encode_utf8(uint32_t ch, char* dest) {
|
||||||
|
if (ch < 0x80) {
|
||||||
|
dest[0] = (char)ch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ch < 0x800) {
|
||||||
|
dest[0] = (ch>>6) | 0xC0;
|
||||||
|
dest[1] = (ch & 0x3F) | 0x80;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (ch < 0x10000) {
|
||||||
|
dest[0] = (ch>>12) | 0xE0;
|
||||||
|
dest[1] = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
dest[2] = (ch & 0x3F) | 0x80;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (ch < 0x110000) {
|
||||||
|
dest[0] = (ch>>18) | 0xF0;
|
||||||
|
dest[1] = ((ch>>12) & 0x3F) | 0x80;
|
||||||
|
dest[2] = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
dest[3] = (ch & 0x3F) | 0x80;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -296,6 +296,7 @@ void parse_worker_dump(Screen *screen, PyObject *dump_callback);
|
|||||||
PyObject* parse_bytes_dump(PyObject UNUSED *, PyObject *);
|
PyObject* parse_bytes_dump(PyObject UNUSED *, PyObject *);
|
||||||
PyObject* parse_bytes(PyObject UNUSED *, PyObject *);
|
PyObject* parse_bytes(PyObject UNUSED *, PyObject *);
|
||||||
uint32_t decode_utf8(uint32_t*, uint32_t*, uint8_t byte);
|
uint32_t decode_utf8(uint32_t*, uint32_t*, uint8_t byte);
|
||||||
|
unsigned int encode_utf8(uint32_t ch, char* dest);
|
||||||
void cursor_reset(Cursor*);
|
void cursor_reset(Cursor*);
|
||||||
Cursor* cursor_copy(Cursor*);
|
Cursor* cursor_copy(Cursor*);
|
||||||
void cursor_copy_to(Cursor *src, Cursor *dest);
|
void cursor_copy_to(Cursor *src, Cursor *dest);
|
||||||
|
|||||||
@ -8,11 +8,13 @@
|
|||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "lineops.h"
|
#include "lineops.h"
|
||||||
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
extern void set_mouse_cursor(MouseShape);
|
extern void set_mouse_cursor(MouseShape);
|
||||||
static MouseShape mouse_cursor_shape = BEAM;
|
static MouseShape mouse_cursor_shape = BEAM;
|
||||||
|
typedef enum MouseActions { PRESS, RELEASE, DRAG, MOVE } MouseAction;
|
||||||
|
|
||||||
#define call_boss(name, ...) { \
|
#define call_boss(name, ...) { \
|
||||||
PyObject *cret_ = PyObject_CallMethod(global_state.boss, #name, __VA_ARGS__); \
|
PyObject *cret_ = PyObject_CallMethod(global_state.boss, #name, __VA_ARGS__); \
|
||||||
@ -20,6 +22,74 @@ static MouseShape mouse_cursor_shape = BEAM;
|
|||||||
else Py_DECREF(cret_); \
|
else Py_DECREF(cret_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SHIFT_INDICATOR (1 << 2)
|
||||||
|
#define ALT_INDICATOR (1 << 3)
|
||||||
|
#define CONTROL_INDICATOR (1 << 4)
|
||||||
|
#define MOTION_INDICATOR (1 << 5)
|
||||||
|
#define EXTRA_BUTTON_INDICATOR (1 << 6)
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
button_map(int button) {
|
||||||
|
switch(button) {
|
||||||
|
case GLFW_MOUSE_BUTTON_1:
|
||||||
|
return 0;
|
||||||
|
case GLFW_MOUSE_BUTTON_2:
|
||||||
|
return 1;
|
||||||
|
case GLFW_MOUSE_BUTTON_3:
|
||||||
|
return 2;
|
||||||
|
case GLFW_MOUSE_BUTTON_4:
|
||||||
|
return EXTRA_BUTTON_INDICATOR;
|
||||||
|
case GLFW_MOUSE_BUTTON_5:
|
||||||
|
return EXTRA_BUTTON_INDICATOR | 1;
|
||||||
|
default:
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char mouse_event_buf[64];
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
||||||
|
unsigned int x = w->mouse_cell_x + 1, y = w->mouse_cell_y + 1; // 1 based indexing
|
||||||
|
unsigned int cb = 0;
|
||||||
|
Screen *screen = w->render_data.screen;
|
||||||
|
|
||||||
|
if (action == MOVE) {
|
||||||
|
if (screen->modes.mouse_tracking_protocol != SGR_PROTOCOL) cb = 3;
|
||||||
|
} else {
|
||||||
|
cb = button_map(button);
|
||||||
|
if (cb == UINT_MAX) return 0;
|
||||||
|
}
|
||||||
|
if (action == DRAG || action == MOVE) cb |= MOTION_INDICATOR;
|
||||||
|
else if (action == RELEASE && screen->modes.mouse_tracking_protocol != SGR_PROTOCOL) cb = 3;
|
||||||
|
if (mods & GLFW_MOD_SHIFT) cb |= SHIFT_INDICATOR;
|
||||||
|
if (mods & GLFW_MOD_ALT) cb |= ALT_INDICATOR;
|
||||||
|
if (mods & GLFW_MOD_CONTROL) cb |= CONTROL_INDICATOR;
|
||||||
|
switch(screen->modes.mouse_tracking_protocol) {
|
||||||
|
case SGR_PROTOCOL:
|
||||||
|
return snprintf(mouse_event_buf, sizeof(mouse_event_buf), "\033[<%d;%d;%d%s", cb, x, y, action == RELEASE ? "m" : "M");
|
||||||
|
break;
|
||||||
|
case URXVT_PROTOCOL:
|
||||||
|
return snprintf(mouse_event_buf, sizeof(mouse_event_buf), "\033[%d;%d;%dM", cb, x, y);
|
||||||
|
break;
|
||||||
|
case UTF8_PROTOCOL:
|
||||||
|
mouse_event_buf[0] = 033; mouse_event_buf[1] = '['; mouse_event_buf[2] = cb + 32;
|
||||||
|
unsigned int sz = 3;
|
||||||
|
sz += encode_utf8(x + 32, mouse_event_buf + sz);
|
||||||
|
sz += encode_utf8(y + 32, mouse_event_buf + sz);
|
||||||
|
return sz;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (x > 223 || y > 223) return 0;
|
||||||
|
else {
|
||||||
|
mouse_event_buf[0] = 033; mouse_event_buf[1] = '['; mouse_event_buf[2] = 'M'; mouse_event_buf[3] = cb + 32; mouse_event_buf[4] = x + 32; mouse_event_buf[5] = y + 32;
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
contains_mouse(Window *w) {
|
contains_mouse(Window *w) {
|
||||||
WindowGeometry *g = &w->geometry;
|
WindowGeometry *g = &w->geometry;
|
||||||
|
|||||||
@ -1,62 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# vim:fileencoding=utf-8
|
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
||||||
|
|
||||||
from .fast_data_types import (
|
|
||||||
GLFW_MOUSE_BUTTON_2, GLFW_MOUSE_BUTTON_3, GLFW_MOD_ALT, GLFW_MOD_CONTROL,
|
|
||||||
GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_4, GLFW_MOUSE_BUTTON_5,
|
|
||||||
GLFW_MOUSE_BUTTON_1,
|
|
||||||
)
|
|
||||||
|
|
||||||
PRESS, RELEASE, DRAG, MOVE = range(4)
|
|
||||||
SHIFT_INDICATOR = 1 << 2
|
|
||||||
ALT_INDICATOR = 1 << 3
|
|
||||||
CONTROL_INDICATOR = 1 << 4
|
|
||||||
MOTION_INDICATOR = 1 << 5
|
|
||||||
EXTRA_BUTTON_INDICATOR = 1 << 6
|
|
||||||
|
|
||||||
cb_map = {
|
|
||||||
GLFW_MOUSE_BUTTON_1: 0,
|
|
||||||
GLFW_MOUSE_BUTTON_2: 0b1,
|
|
||||||
GLFW_MOUSE_BUTTON_3: 0b10,
|
|
||||||
GLFW_MOUSE_BUTTON_4: EXTRA_BUTTON_INDICATOR,
|
|
||||||
GLFW_MOUSE_BUTTON_5: EXTRA_BUTTON_INDICATOR | 0b1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def encode_mouse_event(tracking_mode, tracking_protocol, button, action, mods, x, y):
|
|
||||||
x, y = x + 1, y + 1 # One based indexing
|
|
||||||
cb = 0
|
|
||||||
if action is MOVE:
|
|
||||||
if tracking_protocol != SGR_PROTOCOL:
|
|
||||||
cb = 0b11
|
|
||||||
else:
|
|
||||||
cb = cb_map.get(button)
|
|
||||||
if cb is None:
|
|
||||||
return
|
|
||||||
if action in (DRAG, MOVE):
|
|
||||||
cb |= MOTION_INDICATOR
|
|
||||||
elif action is RELEASE:
|
|
||||||
if tracking_protocol != SGR_PROTOCOL:
|
|
||||||
cb = 0b11
|
|
||||||
if mods & GLFW_MOD_SHIFT:
|
|
||||||
cb |= SHIFT_INDICATOR
|
|
||||||
if mods & GLFW_MOD_ALT:
|
|
||||||
cb |= ALT_INDICATOR
|
|
||||||
if mods & GLFW_MOD_CONTROL:
|
|
||||||
cb |= CONTROL_INDICATOR
|
|
||||||
ans = None
|
|
||||||
if tracking_protocol == SGR_PROTOCOL:
|
|
||||||
ans = '\033[<%d;%d;%d%s' % (cb, x, y, 'm' if action is RELEASE else 'M')
|
|
||||||
ans = ans.encode('ascii')
|
|
||||||
elif tracking_protocol == URXVT_PROTOCOL:
|
|
||||||
ans = '\033[%d;%d;%dM' % (cb + 32, x, y)
|
|
||||||
ans = ans.encode('ascii')
|
|
||||||
elif tracking_protocol == UTF8_PROTOCOL:
|
|
||||||
ans = bytearray([0o33, ord('['), cb + 32])
|
|
||||||
ans.extend(chr(x + 32).encode('utf-8') + chr(y + 32).encode('utf-8'))
|
|
||||||
ans = bytes(ans)
|
|
||||||
else:
|
|
||||||
if x <= 223 and y <= 223:
|
|
||||||
ans = bytearray([0o33, ord('['), ord('M'), cb + 32, x + 32, y + 32])
|
|
||||||
return ans
|
|
||||||
@ -26,7 +26,6 @@ from .fast_data_types import (
|
|||||||
update_window_title, update_window_visibility
|
update_window_title, update_window_visibility
|
||||||
)
|
)
|
||||||
from .keys import get_key_map
|
from .keys import get_key_map
|
||||||
from .mouse import DRAG, MOVE, PRESS, RELEASE, encode_mouse_event
|
|
||||||
from .rgb import to_color
|
from .rgb import to_color
|
||||||
from .terminfo import get_capabilities
|
from .terminfo import get_capabilities
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user