Add helpers for improved mouse button parsing

The following helper functions have been added to aid with parsing mouse
buttons from a string:

1. `get_mouse_bindsym`: attempts to parse the string as an x11 button
(button[1-9]) or as an event name (ex BTN_LEFT or BTN_SIDE)
2. `get_mouse_bindcode`: attempts to parse the string as an event code
and validates that the event code is a button (starts with `BTN_`).
3. `get_mouse_button`: this is a conveniency function for callers that
do not care whether a bindsym or bindcode are used and attempts to parse
the string as a bindsym and then bindcode.

None of these functions are used in this commit. The sole purpose of
this commit is to make the larger set more granular and easier to
review/manipulate. There will be a series of commits following this one
that will modify any command which uses a mouse button to use these
helpers.
This commit is contained in:
Brian Ashworth 2018-12-28 13:48:09 -05:00
parent 14cab78612
commit 6f6a9af60e
2 changed files with 73 additions and 0 deletions

View File

@ -86,4 +86,12 @@ void cursor_warp_to_container(struct sway_cursor *cursor,
void cursor_warp_to_workspace(struct sway_cursor *cursor,
struct sway_workspace *workspace);
uint32_t get_mouse_bindsym(const char *name, char **error);
uint32_t get_mouse_bindcode(const char *name, char **error);
// Considers both bindsym and bindcode
uint32_t get_mouse_button(const char *name, char **error);
#endif

View File

@ -2,8 +2,10 @@
#include <math.h>
#include <libevdev/libevdev.h>
#include <linux/input-event-codes.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <strings.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_idle.h>
@ -1527,3 +1529,66 @@ void cursor_warp_to_workspace(struct sway_cursor *cursor,
wlr_cursor_warp(cursor->cursor, NULL, x, y);
}
uint32_t get_mouse_bindsym(const char *name, char **error) {
if (strncasecmp(name, "button", strlen("button")) == 0) {
// Map to x11 mouse buttons
int number = name[strlen("button")] - '0';
if (number < 1 || number > 9 || strlen(name) > strlen("button0")) {
*error = strdup("Only buttons 1-9 are supported. For other mouse "
"buttons, use the name of the event code.");
return 0;
}
static const uint32_t buttons[] = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT,
SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA};
return buttons[number - 1];
} else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) {
// Get event code from name
int code = libevdev_event_code_from_name(EV_KEY, name);
if (code == -1) {
size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1;
*error = malloc(len);
if (*error) {
snprintf(*error, len, "Unknown event %s", name);
}
return 0;
}
return code;
}
return 0;
}
uint32_t get_mouse_bindcode(const char *name, char **error) {
// Validate event code
errno = 0;
char *endptr;
int code = strtol(name, &endptr, 10);
if (endptr == name && code <= 0) {
*error = strdup("Button event code must be a positive integer.");
return 0;
} else if (errno == ERANGE) {
*error = strdup("Button event code out of range.");
return 0;
}
const char *event = libevdev_event_code_get_name(EV_KEY, code);
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button",
code, event) + 1;
*error = malloc(len);
if (*error) {
snprintf(*error, len, "Event code %d (%s) is not a button",
code, event);
}
return 0;
}
return code;
}
uint32_t get_mouse_button(const char *name, char **error) {
uint32_t button = get_mouse_bindsym(name, error);
if (!button && !error) {
button = get_mouse_bindcode(name, error);
}
return button;
}