From dfcb16032128bcc120004299ce9177d5f1380fb8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 6 Mar 2024 14:44:23 +1000 Subject: [PATCH] backends: Add helpers to convert from clutter tool button to evcode This complements the existing clutter->evdev and evdev->clutter helpers, but this time for buttons we expect from a stylus tool. We also need to convert left/middle/right for the Wacom puck/lens cursor tools but that particular conversion is lossy. Note that these are more restrictive than the normal codes - if we get "other" buttons from a stylus we don't really know what they could possibly map to. So we safely map what looks like buttons from a mouse but otherwise complain and return zero. Part-of: --- src/backends/meta-backend-private.h | 6 ++ src/backends/meta-backend.c | 49 +++++++++++++++ src/tests/button-transform-tests.c | 97 +++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 334d03c16..4b0e1b2ae 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -223,5 +223,11 @@ char * meta_backend_get_vendor_name (MetaBackend *backend, META_EXPORT_TEST uint32_t meta_clutter_button_to_evdev (uint32_t clutter_button); +META_EXPORT_TEST +uint32_t meta_clutter_tool_button_to_evdev (uint32_t clutter_button); + META_EXPORT_TEST uint32_t meta_evdev_button_to_clutter (uint32_t evdev_button); + +META_EXPORT_TEST +uint32_t meta_evdev_tool_button_to_clutter (uint32_t evdev_button); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index c3a57206e..4d997e13a 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -123,6 +123,11 @@ static guint signals[N_SIGNALS]; #define BTN_LEFT 0x110 #define BTN_RIGHT 0x111 #define BTN_MIDDLE 0x112 +#define BTN_STYLUS3 0x149 +#define BTN_TOUCH 0x14a +#define BTN_STYLUS 0x14b +#define BTN_STYLUS2 0x14c +#define BTN_JOYSTICK 0x120 #endif struct _MetaBackendPrivate @@ -1853,6 +1858,50 @@ meta_clutter_button_to_evdev (uint32_t clutter_button) return (clutter_button + (BTN_LEFT - 1)) - 4; } +uint32_t +meta_clutter_tool_button_to_evdev (uint32_t clutter_button) +{ + switch (clutter_button) + { + case CLUTTER_BUTTON_PRIMARY: + return BTN_TOUCH; + case CLUTTER_BUTTON_MIDDLE: + return BTN_STYLUS; + case CLUTTER_BUTTON_SECONDARY: + return BTN_STYLUS2; + case 8: + return BTN_STYLUS3; + } + + return (clutter_button + (BTN_LEFT - 1)) - 5; +} + +uint32_t +meta_evdev_tool_button_to_clutter (uint32_t evdev_button) +{ + switch (evdev_button) + { + case BTN_TOUCH: + case BTN_LEFT: + return CLUTTER_BUTTON_PRIMARY; + case BTN_STYLUS: + case BTN_MIDDLE: + return CLUTTER_BUTTON_MIDDLE; + case BTN_STYLUS2: + case BTN_RIGHT: + return CLUTTER_BUTTON_SECONDARY; + case BTN_STYLUS3: + return 8; + } + + g_return_val_if_fail (evdev_button > BTN_LEFT, 0); + g_return_val_if_fail (evdev_button < BTN_JOYSTICK, 0); + + /* For compatibility reasons, all additional buttons (i.e. BTN_SIDE and + * higher) go after the old 4-7 scroll ones and 8 for BTN_STYLUS3 */ + return (evdev_button - (BTN_LEFT - 1)) + 5; +} + uint32_t meta_evdev_button_to_clutter (uint32_t evdev_button) { diff --git a/src/tests/button-transform-tests.c b/src/tests/button-transform-tests.c index 1d6b250e7..be1fc54d1 100644 --- a/src/tests/button-transform-tests.c +++ b/src/tests/button-transform-tests.c @@ -106,6 +106,97 @@ meta_test_evdev_to_clutter_to_evdev (void) } } +static void +meta_test_evdev_tool_to_clutter (void) +{ + struct { + uint32_t evdev_button; + uint32_t clutter_button; + } test_cases[] = { + { .evdev_button = BTN_TOUCH, .clutter_button = CLUTTER_BUTTON_PRIMARY }, + { .evdev_button = BTN_STYLUS, .clutter_button = CLUTTER_BUTTON_MIDDLE }, + { .evdev_button = BTN_STYLUS2, .clutter_button = CLUTTER_BUTTON_SECONDARY }, + { .evdev_button = BTN_STYLUS3, .clutter_button = 8 }, + { .evdev_button = BTN_LEFT, .clutter_button = CLUTTER_BUTTON_PRIMARY }, + { .evdev_button = BTN_MIDDLE, .clutter_button = CLUTTER_BUTTON_MIDDLE }, + { .evdev_button = BTN_RIGHT, .clutter_button = CLUTTER_BUTTON_SECONDARY }, + /* fallback behavior */ + { .evdev_button = BTN_SIDE, .clutter_button = 9 }, + { .evdev_button = BTN_EXTRA, .clutter_button = 10 }, + }; + size_t i; + + for (i = 0; i < G_N_ELEMENTS (test_cases); i++) + { + uint32_t evdev_button; + uint32_t expected_clutter_button; + uint32_t clutter_button; + + evdev_button = test_cases[i].evdev_button; + expected_clutter_button = test_cases[i].clutter_button; + + clutter_button = meta_evdev_tool_button_to_clutter (evdev_button); + g_assert_cmpuint (clutter_button, ==, expected_clutter_button); + } +} + +static void +meta_test_clutter_tool_to_evdev (void) +{ + struct { + uint32_t clutter_button; + uint32_t evdev_button; + } test_cases[] = { + { .clutter_button = CLUTTER_BUTTON_PRIMARY, .evdev_button = BTN_TOUCH }, + { .clutter_button = CLUTTER_BUTTON_MIDDLE, .evdev_button = BTN_STYLUS }, + { .clutter_button = CLUTTER_BUTTON_SECONDARY, .evdev_button = BTN_STYLUS2 }, + { .clutter_button = 8, .evdev_button = BTN_STYLUS3 }, + /* fallback behavior */ + { .clutter_button = 9, .evdev_button = BTN_SIDE }, + { .clutter_button = 10, .evdev_button = BTN_EXTRA }, + }; + size_t i; + + for (i = 0; i < G_N_ELEMENTS (test_cases); i++) + { + uint32_t clutter_button; + uint32_t expected_evdev_button; + uint32_t evdev_button; + + clutter_button = test_cases[i].clutter_button; + expected_evdev_button = test_cases[i].evdev_button; + + evdev_button = meta_clutter_tool_button_to_evdev (clutter_button); + g_assert_cmpuint (evdev_button, ==, expected_evdev_button); + } +} + +static void +meta_test_evdev_tool_to_clutter_tool_to_evdev (void) +{ + uint32_t test_cases[] = { + BTN_TOUCH, + BTN_STYLUS, + BTN_STYLUS2, + BTN_STYLUS3, + }; + size_t i; + + for (i = 0; i < G_N_ELEMENTS (test_cases); i++) + { + uint32_t evdev_button; + uint32_t expected_evdev_button; + uint32_t clutter_button; + + evdev_button = test_cases[i]; + expected_evdev_button = evdev_button; + + clutter_button = meta_evdev_tool_button_to_clutter (evdev_button); + evdev_button = meta_clutter_tool_button_to_evdev (clutter_button); + g_assert_cmpuint (evdev_button, ==, expected_evdev_button); + } +} + void init_button_transform_tests (void) { @@ -115,4 +206,10 @@ init_button_transform_tests (void) meta_test_evdev_to_clutter); g_test_add_func ("/backends/button-transform/evdev-clutter-evdev", meta_test_evdev_to_clutter_to_evdev); + g_test_add_func ("/backends/button-transform/evdev-tool-clutter", + meta_test_evdev_tool_to_clutter); + g_test_add_func ("/backends/button-transform/clutter-tool-to-evdev", + meta_test_clutter_tool_to_evdev); + g_test_add_func ("/backends/button-transform/evdev-tool-clutter-tool-evdev", + meta_test_evdev_tool_to_clutter_tool_to_evdev); }