aboutsummaryrefslogtreecommitdiff
path: root/swt.c
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-04-30 09:35:29 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2023-04-30 09:35:29 +0200
commitbefac6668eab41849b0e638b20c2636e82328fb4 (patch)
treee1ddc08c1a0095a5948a7ee9dcc4efc1899ce629 /swt.c
parent93044651200982abc936d727c0447b911dfe36b8 (diff)
add mouse support
Diffstat (limited to 'swt.c')
-rw-r--r--swt.c175
1 files changed, 159 insertions, 16 deletions
diff --git a/swt.c b/swt.c
index a48509f..2307096 100644
--- a/swt.c
+++ b/swt.c
@@ -418,6 +418,26 @@ wsetcursor(int cursor) {
return 1;
}
+const char* modes[] = {
+ "visible",
+ "focused",
+ "appkeypad",
+ "mousebtn",
+ "mousemotion",
+ "reverse",
+ "kbdlock",
+ "hide",
+ "appcursor",
+ "mousesgr",
+ "8bit",
+ "blink",
+ "fblink",
+ "focus",
+ "mousex10",
+ "mousemany",
+ "brcktpaste",
+ "numlock",
+};
void wsetmode(int set, unsigned int flags) {
int mode = win.mode;
@@ -662,7 +682,7 @@ keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int
int
matchmod(uint32_t mask, uint32_t mod)
{
- return mask == KEY_MOD_ANY || mask & mod;
+ return mask == KEY_MOD_ANY || mask == mod;
}
@@ -697,6 +717,15 @@ kmap()
if (!matchmod(kp->mask, client.kb.event.mod))
continue;
+ if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0)
+ continue;
+ if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2)
+ continue;
+ if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0)
+ continue;
+
+ fprintf(stderr, "found kmap: %#04x, %#04x\n", XKB_KEY_F1, client.kb.event.sym);
+
return kp->s;
}
@@ -712,6 +741,9 @@ handle_keyboard_event()
int len;
char c;
+ if (IS_SET(MODE_KBDLOCK))
+ return;
+
if (client.kb.event.state == WL_KEYBOARD_KEY_STATE_PRESSED) {
if (execshortcut())
return;
@@ -727,6 +759,19 @@ handle_keyboard_event()
buf[0] -= 'a' - 1;
}
+ if (len == 1 && client.kb.event.state && client.kb.event.mod & KEY_MOD_ALT) {
+ if (IS_SET(MODE_8BIT)) {
+ if (*buf < 0177) {
+ c = *buf | 0x80;
+ len = utf8encode(c, buf);
+ }
+ } else {
+ buf[1] = buf[0];
+ buf[0] = '\033';
+ len = 2;
+ }
+ }
+
ttywrite(buf, strlen(buf), 1);
}
}
@@ -754,15 +799,91 @@ pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl
void
+reportpointer(int motion)
+{
+ int len, btn, code;
+ int x = client.pointer.position.x, y = client.pointer.position.y;
+ int state = client.pointer.buttons.state;
+ char buf[40];
+ static int ox, oy;
+
+ if (motion) {
+ if (x == ox && y == oy)
+ return;
+ if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
+ return;
+ /* MODE_MOUSEMOTION: no reporting if no button is pressed */
+ if (IS_SET(MODE_MOUSEMOTION) && !state)
+ return;
+ /* Set btn to lowest-numbered pressed button, or 12 if no
+ * buttons are pressed. */
+ btn = client.pointer.buttons.button - BTN_MOUSE + 1;
+ code = 32;
+ } else {
+ btn = client.pointer.buttons.button - BTN_MOUSE + 1;
+ /* Only buttons 1 through 11 can be encoded */
+ if (btn < 1 || btn > 11)
+ return;
+ if (!state) {
+ /* MODE_MOUSEX10: no button release reporting */
+ if (IS_SET(MODE_MOUSEX10))
+ return;
+ /* Don't send release events for the scroll wheel */
+ if (btn == 4 || btn == 5)
+ return;
+ }
+ code = 0;
+ }
+
+ ox = x;
+ oy = y;
+
+ /* Encode btn into code. If no button is pressed for a motion event in
+ * MODE_MOUSEMANY, then encode it as a release. */
+ if ((!IS_SET(MODE_MOUSESGR) && state) || btn == 12)
+ code += 3;
+ else if (btn >= 8)
+ code += 128 + btn - 8;
+ else if (btn >= 4)
+ code += 64 + btn - 4;
+ else
+ code += btn - 1;
+
+ if (!IS_SET(MODE_MOUSEX10)) {
+ code += ((client.kb.event.mod & KEY_MOD_SHIFT) ? 4 : 0)
+ + ((client.kb.event.mod & KEY_MOD_ALT) ? 8 : 0) /* meta key: alt */
+ + ((client.kb.event.mod & KEY_MOD_CTRL) ? 16 : 0);
+ }
+
+ if (IS_SET(MODE_MOUSESGR)) {
+ len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
+ code, x+1, y+1,
+ state ? 'M' : 'm');
+ } else if (x < 223 && y < 223) {
+ len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
+ 32+code, 32+x+1, 32+y+1);
+ } else {
+ return;
+ }
+
+ fprintf(stderr, "mouse: %s\n", buf + 1);
+
+ ttywrite(buf, len, 0);
+}
+
+
+void
pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
- client.pointer.position.x = wl_fixed_to_int(x);
- client.pointer.position.y = wl_fixed_to_int(y);
+ client.pointer.position.x = MIN(wintotty(wl_fixed_to_int(x), width), win.tty.width - 1);
+ client.pointer.position.y = MIN(wintotty(wl_fixed_to_int(y), height), win.tty.height - 1);
- if (client.pointer.buttons.button & BTN_LEFT) {
+ if (IS_SET(MODE_MOUSE) | IS_SET(MODE_MOUSEMOTION) | IS_SET(MODE_MOUSEMANY)) {
+ reportpointer(1);
+ } else if (client.pointer.buttons.button & BTN_LEFT) {
selextend(
- MIN(wintotty(client.pointer.position.x, width), win.tty.width - 1),
- MIN(wintotty(client.pointer.position.y, height), win.tty.height - 1),
+ client.pointer.position.x,
+ client.pointer.position.y,
SEL_REGULAR,
0
);
@@ -776,9 +897,17 @@ pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t
{
int snap;
- if (button == BTN_LEFT && state) {
- client.pointer.buttons.button |= BTN_LEFT;
+ client.pointer.buttons.state = state;
+
+ client.pointer.buttons.button = button;
+
+ if (IS_SET(MODE_MOUSE) | IS_SET(MODE_MOUSEMANY) | IS_SET(MODE_MOUSEBTN) | IS_SET(MODE_MOUSESGR)) {
+ client.pointer.buttons.button = button;
+ reportpointer(0);
+ return;
+ }
+ if (button == BTN_LEFT && state) {
if (client.pointer.buttons.click_combo == 1 && time - client.pointer.buttons.tclick <= doubleclicktimeout) {
snap = SNAP_WORD;
} else if (client.pointer.buttons.click_combo >= 2 && time - client.pointer.buttons.tclick <= tripleclicktimeout) {
@@ -791,12 +920,12 @@ pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t
client.pointer.buttons.tclick = time;
++client.pointer.buttons.click_combo;
- if (IS_SET(MODE_MOUSE) | IS_SET(MODE_MOUSEMANY) | IS_SET(MODE_MOUSEBTN)) {
- ttywrite("\031", 1, 1);
+ if (IS_SET(MODE_MOUSE) | IS_SET(MODE_MOUSEMANY) | IS_SET(MODE_MOUSEBTN) | IS_SET(MODE_MOUSESGR)) {
+ reportpointer(0);
} else {
selstart(
- MIN(wintotty(client.pointer.position.x, width), win.tty.width - 1),
- MIN(wintotty(client.pointer.position.y, height), win.tty.height - 1),
+ client.pointer.position.x,
+ client.pointer.position.y,
snap
);
}
@@ -804,20 +933,34 @@ pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t
} else if (button == BTN_LEFT && !state) {
client.pointer.buttons.button &= ~BTN_LEFT;
selextend(
- MIN(wintotty(client.pointer.position.x, width), win.tty.width - 1),
- MIN(wintotty(client.pointer.position.y, height), win.tty.height - 1),
+ client.pointer.position.x,
+ client.pointer.position.y,
SEL_REGULAR,
1
);
}
+
+ if (!state)
+ client.pointer.buttons.button = 0;
}
void
pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
{
- int v = wl_fixed_to_int(value);
- fprintf(stderr, "scroll: a: %i, v: %i\n", axis, v);
+ int v;
+ if (IS_SET(MODE_MOUSE) | IS_SET(MODE_MOUSEMANY) | IS_SET(MODE_MOUSEBTN) | IS_SET(MODE_MOUSESGR) | IS_SET(MODE_MOUSEX10)) {
+ v = wl_fixed_to_int(value);
+ client.pointer.buttons.state = 1;
+ if (v > 0)
+ client.pointer.buttons.button = BTN_MOUSE + 4;
+ else
+ client.pointer.buttons.button = BTN_MOUSE + 3;
+ reportpointer(0);
+
+ client.pointer.buttons.button = 0;
+ client.pointer.buttons.state = 0;
+ }
}