]> git.mdlowis.com Git - proto/labwc.git/commitdiff
config: add tablet button mapping configuration
authorJens Peters <jp7677@gmail.com>
Fri, 29 Dec 2023 09:06:17 +0000 (10:06 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Fri, 29 Dec 2023 20:22:46 +0000 (20:22 +0000)
Co-authored-by: Consolatis <35009135+Consolatis@users.noreply.github.com>
docs/rc.xml.all
include/config/rcxml.h
include/config/tablet.h [new file with mode: 0644]
src/config/meson.build
src/config/rcxml.c
src/config/tablet.c [new file with mode: 0644]

index bc0e092c1b335b1e5eb6f0b4328848c0eeb3ed9f..bbf61189311b9a7b46faf761949e4d52b7e18d19 100644 (file)
 
   </mouse>
 
+  <!--
+    Tablet buttons emulate regular mouse buttons.
+
+    The tablet *button* can be set to any of [tip|stylus|stylus2|stylus3].
+    Valid *to* mouse buttons are [left|right|middle].
+  -->
+  <tablet>
+    <map button="tip" to="left" />
+    <map button="stylus" to="right" />
+    <map button="stylus2" to="middle" />
+  </tablet>
+
   <!--
     The *category* element can be set to touch, touchpad, non-touch, default or
     the name of a device. You can obtain device names by running *libinput
index a1978d86cffcc8dc48c1165c90dd1759bc52d9a4..ead62c781e08097a486ad59fd2eb64fd05bcf2cb 100644 (file)
@@ -9,6 +9,7 @@
 #include "common/border.h"
 #include "common/buf.h"
 #include "common/font.h"
+#include "config/tablet.h"
 #include "config/libinput.h"
 #include "resize_indicator.h"
 #include "theme.h"
@@ -80,6 +81,12 @@ struct rcxml {
        struct wl_list mousebinds; /* struct mousebind.link */
        double scroll_factor;
 
+       /* graphics tablet */
+       struct tablet_config {
+               uint16_t button_map_count;
+               struct button_map_entry button_map[BUTTON_MAP_MAX];
+       } tablet;
+
        /* libinput */
        struct wl_list libinput_categories;
 
diff --git a/include/config/tablet.h b/include/config/tablet.h
new file mode 100644 (file)
index 0000000..25a232c
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef LABWC_TABLET_CONFIG_H
+#define LABWC_TABLET_CONFIG_H
+
+#include <stdint.h>
+
+#define BUTTON_MAP_MAX 16
+struct button_map_entry {
+       uint32_t from;
+       uint32_t to;
+};
+
+uint32_t tablet_button_from_str(const char *button);
+uint32_t mouse_button_from_str(const char *button);
+void tablet_button_mapping_add(uint32_t from, uint32_t to);
+void tablet_load_default_button_mappings(void);
+
+#endif /* LABWC_TABLET_CONFIG_H */
index 95afc7bc2c013269e33b5952bd67532e6f65dff5..a0968da81191100fbe05ed77e5df34d7d6a53e36 100644 (file)
@@ -3,5 +3,6 @@ labwc_sources += files(
   'keybind.c',
   'session.c',
   'mousebind.c',
+  'tablet.c',
   'libinput.c',
 )
index d5d575924889fe38b47f94f89b6d087147a0889d..321a51977f9d177fa8f3fa7c8b35e116e6df0248 100644 (file)
@@ -23,6 +23,7 @@
 #include "config/keybind.h"
 #include "config/libinput.h"
 #include "config/mousebind.h"
+#include "config/tablet.h"
 #include "config/rcxml.h"
 #include "labwc.h"
 #include "regions.h"
@@ -615,6 +616,8 @@ entry(xmlNode *node, char *nodename, char *content)
        /* current <theme><font place=""></font></theme> */
        static enum font_place font_place = FONT_PLACE_NONE;
 
+       static uint32_t button_map_from;
+
        if (!nodename) {
                return;
        }
@@ -683,6 +686,11 @@ entry(xmlNode *node, char *nodename, char *content)
                return;
        }
 
+       if (!strcasecmp(nodename, "map.tablet")) {
+               button_map_from = UINT32_MAX;
+               return;
+       }
+
        /* handle the rest */
        if (!content) {
                return;
@@ -818,6 +826,17 @@ entry(xmlNode *node, char *nodename, char *content)
                } else {
                        wlr_log(WLR_ERROR, "Invalid value for <resize popupShow />");
                }
+       } else if (!strcasecmp(nodename, "button.map.tablet")) {
+               button_map_from = tablet_button_from_str(content);
+       } else if (!strcasecmp(nodename, "to.map.tablet")) {
+               if (button_map_from != UINT32_MAX) {
+                       uint32_t button_map_to = mouse_button_from_str(content);
+                       if (button_map_to != UINT32_MAX) {
+                               tablet_button_mapping_add(button_map_from, button_map_to);
+                       }
+               } else {
+                       wlr_log(WLR_ERROR, "Missing 'button' argument for tablet button mapping");
+               }
        }
 }
 
@@ -977,6 +996,10 @@ rcxml_init(void)
 
        rc.doubleclick_time = 500;
        rc.scroll_factor = 1.0;
+
+       rc.tablet.button_map_count = 0;
+       tablet_load_default_button_mappings();
+
        rc.repeat_rate = 25;
        rc.repeat_delay = 600;
        rc.kb_numlock_enable = true;
diff --git a/src/config/tablet.c b/src/config/tablet.c
new file mode 100644 (file)
index 0000000..5d138af
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _POSIX_C_SOURCE 200809L
+#include <linux/input-event-codes.h>
+#include <stdint.h>
+#include <strings.h>
+#include <wlr/util/log.h>
+#include "config/tablet.h"
+#include "config/rcxml.h"
+
+uint32_t tablet_button_from_str(const char *button)
+{
+       if (!strcasecmp(button, "Tip")) {
+               return BTN_TOOL_PEN;
+       } else if (!strcasecmp(button, "Stylus")) {
+               return BTN_STYLUS;
+       } else if (!strcasecmp(button, "Stylus2")) {
+               return BTN_STYLUS2;
+       } else if (!strcasecmp(button, "Stylus3")) {
+               return BTN_STYLUS3;
+       }
+       wlr_log(WLR_ERROR, "Invalid value for tablet button: %s", button);
+       return UINT32_MAX;
+}
+
+uint32_t mouse_button_from_str(const char *button)
+{
+       if (!strcasecmp(button, "Left")) {
+               return BTN_LEFT;
+       } else if (!strcasecmp(button, "Right")) {
+               return BTN_RIGHT;
+       } else if (!strcasecmp(button, "Middle")) {
+               return BTN_MIDDLE;
+       }
+       wlr_log(WLR_ERROR, "Invalid value for mouse button: %s", button);
+       return UINT32_MAX;
+}
+
+void tablet_button_mapping_add(uint32_t from, uint32_t to)
+{
+       struct button_map_entry *entry;
+       for (size_t i = 0; i < rc.tablet.button_map_count; i++) {
+               entry = &rc.tablet.button_map[i];
+               if (entry->from == from) {
+                       entry->to = to;
+                       wlr_log(WLR_INFO, "Overwriting button map for 0x%x with 0x%x", from, to);
+                       return;
+               }
+       }
+       if (rc.tablet.button_map_count == BUTTON_MAP_MAX) {
+               wlr_log(WLR_ERROR,
+                       "Failed to add button mapping: only supporting up to %u mappings",
+                       BUTTON_MAP_MAX);
+               return;
+       }
+       wlr_log(WLR_INFO, "Adding button map for 0x%x with 0x%x", from, to);
+       entry = &rc.tablet.button_map[rc.tablet.button_map_count];
+       entry->from = from;
+       entry->to = to;
+       rc.tablet.button_map_count++;
+}
+
+void tablet_load_default_button_mappings(void)
+{
+       tablet_button_mapping_add(BTN_TOOL_PEN, BTN_LEFT); /* Used for the pen tip */
+       tablet_button_mapping_add(BTN_STYLUS, BTN_RIGHT);
+       tablet_button_mapping_add(BTN_STYLUS2, BTN_MIDDLE);
+}