diff --git a/README.md b/README.md index aa96a99..394f82b 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,23 @@ using the synergy key IDs might make sense in an `id-keymap` section: with actual values based on the above process, using the `id` parameter in the server log instead of `button`. +#### Button map + +This should not be necessary in 99.9% of situations, but if you want to change +the default mouse button behavior you can include a section redefining the +button map in use: +``` +[button-map] +0 = 0 # No button +1 = 0x110 # BTN_LEFT +2 = 0x112 # BTN_MIDDLE +3 = 0x111 # BTN_RIGHT +4 = 0x113 # BTN_SIDE +5 = 0x114 # BTN_EXTRA +``` +Given here is the default; each of 6 protocol possibilities is mapped to a +value based on `/usr/include/linux/input-event-keycodes.h`. + #### Screensaver `screensaver/start` should contain a command to be run when the screensaver is diff --git a/include/wayland.h b/include/wayland.h index b54dd91..9eeecd2 100644 --- a/include/wayland.h +++ b/include/wayland.h @@ -38,6 +38,8 @@ struct wlOutput struct wlOutput *next; }; +#define WL_INPUT_BUTTON_COUNT 6 + struct wlInput { /* module-specific state */ void *state; @@ -56,6 +58,8 @@ struct wlInput { int *id_keymap; /* whether or not a given id entry should be used */ bool *id_keymap_valid; + /* mouse button map */ + int button_map[WL_INPUT_BUTTON_COUNT]; /* wayland context */ struct wlContext *wl_ctx; /* actual functions */ @@ -107,6 +111,8 @@ struct wlContext { /* (re)set the keyboard layout according to the configuration * probably not useful outside wlSetup*/ extern int wlKeySetConfigLayout(struct wlContext *ctx); +/* load button map */ +extern void wlLoadButtonMap(struct wlContext *ctx); /* set up the wayland context */ extern bool wlSetup(struct wlContext *context, int width, int height, char *backend); diff --git a/src/wl_input.c b/src/wl_input.c index 018a119..f76367f 100644 --- a/src/wl_input.c +++ b/src/wl_input.c @@ -1,10 +1,33 @@ #include "wayland.h" +#include #include #include "log.h" #include "fdio_full.h" #include +/* handle button maps */ + +void wlLoadButtonMap(struct wlContext *ctx) +{ + int i; + char *key; + int default_map[] = { + 0, + 0x110, /*BTN_LEFT*/ + 0x112, /*BTN_MIDDLE*/ + 0x111, /*BTN_RIGHT*/ + 0x113, /*BTN_SIDE*/ + 0x114, /*BTN_EXTRA*/ + }; + static_assert(sizeof(default_map)/sizeof(*default_map) == WL_INPUT_BUTTON_COUNT, "button map size mismatch"); + for (i = 0; i < WL_INPUT_BUTTON_COUNT; ++i) { + xasprintf(&key, "button-map/%d", i); + ctx->input.button_map[i] = configTryLong(key, default_map[i]); + logDbg("Set button mapping: %d -> %d", i, ctx->input.button_map[i]); + } +}; + /* Code to track keyboard state for modifier masks * because the synergy protocol is less than ideal at sending us modifiers @@ -243,8 +266,8 @@ void wlMouseMotion(struct wlContext *ctx, int x, int y) } void wlMouseButton(struct wlContext *ctx, int button, int state) { - logDbg("Mouse button: %d, state: %d", button, state); - ctx->input.mouse_button(&ctx->input, button, state); + logDbg("Mouse button: %d (mapped to %d), state: %d", button, ctx->input.button_map[button], state); + ctx->input.mouse_button(&ctx->input, ctx->input.button_map[button], state); } void wlMouseWheel(struct wlContext *ctx, signed short dx, signed short dy) { diff --git a/src/wl_input_kde.c b/src/wl_input_kde.c index ca2217d..57d73bc 100644 --- a/src/wl_input_kde.c +++ b/src/wl_input_kde.c @@ -28,21 +28,10 @@ static void mouse_motion(struct wlInput *input, int x, int y) wl_display_flush(input->wl_ctx->display); } -static int button_map[] = { - 0, - 0x110, - 0x112, - 0x111, - 0x150, - 0x151, -}; - - static void mouse_button(struct wlInput *input, int button, int state) { struct org_kde_kwin_fake_input *fake = input->state; - logDbg("mouse: button %d (mapped to %x) %s", button, button_map[button], state ? "down": "up"); - org_kde_kwin_fake_input_button(fake, button_map[button], state); + org_kde_kwin_fake_input_button(fake, button, state); wl_display_flush(input->wl_ctx->display); } @@ -80,6 +69,7 @@ bool wlInputInitKde(struct wlContext *ctx) .key = key, .key_map = key_map, }; + wlLoadButtonMap(ctx); logInfo("Using KDE fake input protocol"); return true; } diff --git a/src/wl_input_uinput.c b/src/wl_input_uinput.c index 6ca8913..bfad498 100644 --- a/src/wl_input_uinput.c +++ b/src/wl_input_uinput.c @@ -27,15 +27,6 @@ struct state_uinput { #define UINPUT_KEY_MAX 256 -static int button_map[] = { - 0, - 0x110, - 0x112, - 0x111, - 0x150, - 0x151, -}; - static void emit(int fd, int type, int code, int val) { struct input_event ie = { @@ -69,7 +60,7 @@ static void mouse_button(struct wlInput *input, int button, int state) { struct state_uinput *ui = input->state; - emit(ui->mouse_fd, EV_KEY, button_map[button], state); + emit(ui->mouse_fd, EV_KEY, button, state); emit(ui->mouse_fd, EV_SYN, SYN_REPORT, 0); } @@ -147,7 +138,7 @@ static bool init_key(struct state_uinput *ui) return true; } -static bool init_mouse(struct state_uinput *ui, int max_x, int max_y) +static bool init_mouse(struct wlContext *ctx, struct state_uinput *ui, int max_x, int max_y) { int i; @@ -172,8 +163,8 @@ static bool init_mouse(struct state_uinput *ui, int max_x, int max_y) TRY_IOCTL(ui->mouse_fd, UI_SET_EVBIT, EV_SYN); TRY_IOCTL(ui->mouse_fd, UI_SET_EVBIT, EV_KEY); - for (i = 0; i < (sizeof(button_map)/sizeof(*button_map)); ++i) { - TRY_IOCTL(ui->mouse_fd, UI_SET_KEYBIT, button_map[i]); + for (i = 0; i < WL_INPUT_BUTTON_COUNT; ++i) { + TRY_IOCTL(ui->mouse_fd, UI_SET_KEYBIT, ctx->input.button_map[i]); } TRY_IOCTL(ui->mouse_fd, UI_SET_EVBIT, EV_REL); @@ -211,11 +202,8 @@ bool wlInputInitUinput(struct wlContext *ctx) ctx->uinput_fd[0] = -1; ctx->uinput_fd[1] = -1; - if (!init_key(ui)) - goto error; - if (!init_mouse(ui, ctx->width, ctx->height)) - goto error; - + /* because we need to know the button map ahead of time, we need + * to initialize this first */ ctx->input = (struct wlInput) { .state = ui, .wl_ctx = ctx, @@ -226,6 +214,13 @@ bool wlInputInitUinput(struct wlContext *ctx) .key = key, .key_map = key_map, }; + wlLoadButtonMap(ctx); + + if (!init_key(ui)) + goto error; + if (!init_mouse(ctx, ui, ctx->width, ctx->height)) + goto error; + logInfo("Using uinput"); return true; error: diff --git a/src/wl_input_wlr.c b/src/wl_input_wlr.c index ee89f2c..8a8a74d 100644 --- a/src/wl_input_wlr.c +++ b/src/wl_input_wlr.c @@ -43,16 +43,6 @@ static void key(struct wlInput *input, int key, int state) wl_display_flush(input->wl_ctx->display); } -static int button_map[] = { - 0, - 0x110, - 0x112, - 0x111, - 0x150, - 0x151, - -1 -}; - static void mouse_rel_motion(struct wlInput *input, int dx, int dy) { struct state_wlr *wlr = input->state; @@ -70,8 +60,7 @@ static void mouse_motion(struct wlInput *input, int x, int y) static void mouse_button(struct wlInput *input, int button, int state) { struct state_wlr *wlr = input->state; - logDbg("mouse: button %d (mapped to %x) %s", button, button_map[button], state ? "down": "up"); - zwlr_virtual_pointer_v1_button(wlr->pointer, wlTS(input->wl_ctx), button_map[button], state); + zwlr_virtual_pointer_v1_button(wlr->pointer, wlTS(input->wl_ctx), button, state); zwlr_virtual_pointer_v1_frame(wlr->pointer); wl_display_flush(input->wl_ctx->display); } @@ -269,6 +258,7 @@ bool wlInputInitWlr(struct wlContext *ctx) .key = key, .key_map = key_map, }; + wlLoadButtonMap(ctx); logInfo("Using wlroots virtual input protocols"); return true; }