summaryrefslogtreecommitdiff
path: root/src/wayland/pointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland/pointer.c')
-rw-r--r--src/wayland/pointer.c124
1 files changed, 76 insertions, 48 deletions
diff --git a/src/wayland/pointer.c b/src/wayland/pointer.c
index f2902b4..d434047 100644
--- a/src/wayland/pointer.c
+++ b/src/wayland/pointer.c
@@ -25,9 +25,9 @@ struct tablet_pad {
struct zwp_tablet_pad_v2 *proxy;
};
-static int device_px_round(double v)
+static inline int device_px_round(double v)
{
- return (int)(v < 0 ? v - 0.5 : v + 0.5);
+ return (int)lrint(v);
}
static struct yasl_vector2i device_from_fixed(const struct wayland_surface *w,
@@ -39,12 +39,44 @@ static struct yasl_vector2i device_from_fixed(const struct wayland_surface *w,
};
}
-static int motion_button(uint64_t buttons)
-{
- for (int b = 0; b <= 7; b++)
- if (buttons & (1ull << b))
- return b;
- return 3;
+static inline int motion_button(uint64_t buttons)
+{
+ static const uint8_t motion_btn_lut[256] = {
+ [0] = 3,
+ [1] = 0, [2] = 1, [3] = 0, [4] = 2, [5] = 0, [6] = 1, [7] = 0,
+ [8] = 3, [9] = 0, [10] = 1, [11] = 0, [12] = 2, [13] = 0, [14] = 1, [15] = 0,
+ [16] = 4, [17] = 0, [18] = 1, [19] = 0, [20] = 2, [21] = 0, [22] = 1, [23] = 0,
+ [24] = 3, [25] = 0, [26] = 1, [27] = 0, [28] = 2, [29] = 0, [30] = 1, [31] = 0,
+ [32] = 5, [33] = 0, [34] = 1, [35] = 0, [36] = 2, [37] = 0, [38] = 1, [39] = 0,
+ [40] = 3, [41] = 0, [42] = 1, [43] = 0, [44] = 2, [45] = 0, [46] = 1, [47] = 0,
+ [48] = 4, [49] = 0, [50] = 1, [51] = 0, [52] = 2, [53] = 0, [54] = 1, [55] = 0,
+ [56] = 3, [57] = 0, [58] = 1, [59] = 0, [60] = 2, [61] = 0, [62] = 1, [63] = 0,
+ [64] = 6, [65] = 0, [66] = 1, [67] = 0, [68] = 2, [69] = 0, [70] = 1, [71] = 0,
+ [72] = 3, [73] = 0, [74] = 1, [75] = 0, [76] = 2, [77] = 0, [78] = 1, [79] = 0,
+ [80] = 4, [81] = 0, [82] = 1, [83] = 0, [84] = 2, [85] = 0, [86] = 1, [87] = 0,
+ [88] = 3, [89] = 0, [90] = 1, [91] = 0, [92] = 2, [93] = 0, [94] = 1, [95] = 0,
+ [96] = 5, [97] = 0, [98] = 1, [99] = 0, [100] = 2, [101] = 0, [102] = 1, [103] = 0,
+ [104] = 3, [105] = 0, [106] = 1, [107] = 0, [108] = 2, [109] = 0, [110] = 1, [111] = 0,
+ [112] = 4, [113] = 0, [114] = 1, [115] = 0, [116] = 2, [117] = 0, [118] = 1, [119] = 0,
+ [120] = 3, [121] = 0, [122] = 1, [123] = 0, [124] = 2, [125] = 0, [126] = 1, [127] = 0,
+ [128] = 7, [129] = 0, [130] = 1, [131] = 0, [132] = 2, [133] = 0, [134] = 1, [135] = 0,
+ [136] = 3, [137] = 0, [138] = 1, [139] = 0, [140] = 2, [141] = 0, [142] = 1, [143] = 0,
+ [144] = 4, [145] = 0, [146] = 1, [147] = 0, [148] = 2, [149] = 0, [150] = 1, [151] = 0,
+ [152] = 3, [153] = 0, [154] = 1, [155] = 0, [156] = 2, [157] = 0, [158] = 1, [159] = 0,
+ [160] = 5, [161] = 0, [162] = 1, [163] = 0, [164] = 2, [165] = 0, [166] = 1, [167] = 0,
+ [168] = 3, [169] = 0, [170] = 1, [171] = 0, [172] = 2, [173] = 0, [174] = 1, [175] = 0,
+ [176] = 4, [177] = 0, [178] = 1, [179] = 0, [180] = 2, [181] = 0, [182] = 1, [183] = 0,
+ [184] = 3, [185] = 0, [186] = 1, [187] = 0, [188] = 2, [189] = 0, [190] = 1, [191] = 0,
+ [192] = 6, [193] = 0, [194] = 1, [195] = 0, [196] = 2, [197] = 0, [198] = 1, [199] = 0,
+ [200] = 3, [201] = 0, [202] = 1, [203] = 0, [204] = 2, [205] = 0, [206] = 1, [207] = 0,
+ [208] = 4, [209] = 0, [210] = 1, [211] = 0, [212] = 2, [213] = 0, [214] = 1, [215] = 0,
+ [216] = 3, [217] = 0, [218] = 1, [219] = 0, [220] = 2, [221] = 0, [222] = 1, [223] = 0,
+ [224] = 5, [225] = 0, [226] = 1, [227] = 0, [228] = 2, [229] = 0, [230] = 1, [231] = 0,
+ [232] = 3, [233] = 0, [234] = 1, [235] = 0, [236] = 2, [237] = 0, [238] = 1, [239] = 0,
+ [240] = 4, [241] = 0, [242] = 1, [243] = 0, [244] = 2, [245] = 0, [246] = 1, [247] = 0,
+ [248] = 3, [249] = 0, [250] = 1, [251] = 0, [252] = 2, [253] = 0, [254] = 1, [255] = 0,
+ };
+ return motion_btn_lut[(uint8_t)buttons];
}
void seat_note_input(struct seat *s, uint32_t serial)
@@ -222,12 +254,12 @@ static void press_queue_flush(struct seat *s, struct press_queue *q,
continue;
}
if (!p.surface) continue;
- if (p.release) *buttons &= ~(1ull << p.button);
- else *buttons |= 1ull << p.button;
+ uint64_t mask = 1ull << p.button;
+ *buttons = (*buttons & ~mask) | ((uint64_t)(!p.release) << p.button);
struct yasl_mouse_event ev = like;
ev.pos = p.pos;
ev.button = p.button;
- ev.kind = p.release ? YASL_PTR_RELEASE : YASL_PTR_PRESS;
+ ev.kind = (enum yasl_pointer_kind)p.release;
push_mouse(s, p.surface, ev);
}
q->n = kept;
@@ -333,18 +365,24 @@ static void pointer_button(void *data, struct wl_pointer *pointer,
(void)pointer; (void)time;
struct seat *s = data;
struct wayland_surface *w = s->pointer_focus;
- if (!w) return;
- int b;
- switch (button) {
- case BTN_LEFT: b = 0; break;
- case BTN_MIDDLE: b = 1; break;
- case BTN_RIGHT: b = 2; break;
- case BTN_BACK: b = 3; break;
- case BTN_FORWARD: b = 4; break;
- default: return;
- }
+ if (unlikely(!w)) return;
+
+ static const int8_t btn_map[8] = {
+ [0] = 0, /* BTN_LEFT (0x110) */
+ [1] = 2, /* BTN_RIGHT (0x111) */
+ [2] = 1, /* BTN_MIDDLE (0x112) */
+ [3] = 3, /* BTN_SIDE (0x113) */
+ [4] = 4, /* BTN_EXTRA (0x114) */
+ [5] = 4, /* BTN_FORWARD (0x115) */
+ [6] = 3, /* BTN_BACK (0x116) */
+ [7] = -1,
+ };
+ unsigned idx = button - 0x110;
+ if (unlikely(idx >= 7)) return;
+ int b = btn_map[idx];
+ if (unlikely(b < 0)) return;
seat_note_input(s, serial);
- bool release = state == WL_POINTER_BUTTON_STATE_RELEASED;
+ bool release = (state == WL_POINTER_BUTTON_STATE_RELEASED);
if (!release) {
s->press_serial = serial;
s->press_surface = w;
@@ -358,13 +396,11 @@ static void pointer_axis(void *data, struct wl_pointer *pointer,
{
(void)pointer; (void)time;
struct seat *s = data;
- if (!s->pointer_focus) return;
+ if (unlikely(!s->pointer_focus)) return;
double v = wl_fixed_to_double(value);
- if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
- s->axis_v += v;
- s->frame_v += v;
- } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
- s->axis_h += v;
+ if (likely(axis < 2)) {
+ (&s->axis_v)[axis] += v;
+ s->frame_v += v * (!axis);
}
pointer_event_done(s);
}
@@ -373,21 +409,17 @@ static void pointer_axis_source(void *data, struct wl_pointer *pointer, uint32_t
{
(void)pointer;
struct seat *s = data;
- if (axis_source == WL_POINTER_AXIS_SOURCE_FINGER ||
- axis_source == WL_POINTER_AXIS_SOURCE_CONTINUOUS)
- s->axis_smooth = true;
+ s->axis_smooth = (axis_source == WL_POINTER_AXIS_SOURCE_FINGER ||
+ axis_source == WL_POINTER_AXIS_SOURCE_CONTINUOUS);
}
static void pointer_axis_stop(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis)
{
(void)pointer; (void)time;
struct seat *s = data;
- if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
- s->axis_value120_v = 0;
- s->axis_has_v120_v = false;
- } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
- s->axis_value120_h = 0;
- s->axis_has_v120_h = false;
+ if (likely(axis < 2)) {
+ (&s->axis_value120_v)[axis] = 0;
+ (&s->axis_has_v120_v)[axis] = false;
}
}
@@ -395,23 +427,18 @@ static void pointer_axis_discrete(void *data, struct wl_pointer *pointer, uint32
{
(void)pointer;
struct seat *s = data;
- if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
- s->axis_discrete_v += discrete;
- else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
- s->axis_discrete_h += discrete;
+ if (likely(axis < 2))
+ (&s->axis_discrete_v)[axis] += discrete;
}
static void pointer_axis_value120(void *data, struct wl_pointer *pointer, uint32_t axis, int32_t value120)
{
(void)pointer;
struct seat *s = data;
- if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
- s->axis_value120_v += value120;
- s->frame_v120 += value120;
- s->axis_has_v120_v = true;
- } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
- s->axis_value120_h += value120;
- s->axis_has_v120_h = true;
+ if (likely(axis < 2)) {
+ (&s->axis_value120_v)[axis] += value120;
+ (&s->axis_has_v120_v)[axis] = true;
+ s->frame_v120 += value120 * (!axis);
}
}
@@ -757,6 +784,7 @@ static void tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool)
struct seat *s = ((struct tablet_tool *)data)->seat;
struct wayland_surface *w = s->tablet_focus;
if (!w) return;
+ s->pen.pressure = 0;
press_queue_push(&s->tool_presses, w, s->tool_pos, 0, true);
}