-
-
Save CyberShadow/ae30a8d9f86c170c2451c3dd7edb649c to your computer and use it in GitHub Desktop.
| /uinput-filter-mouse | |
| /config.h |
| #define UPSTREAM_UINPUT_DEVICE "/dev/input/by-id/usb-Logitech_G700_Laser_Mouse_37ADAF750037-event-mouse" |
| uinput-filter-mouse: Makefile uinput-filter-mouse.c config.h | |
| gcc -o $@ [email protected] | |
| config.h: | |
| @echo "Copy and edit \`config.h.sample' to \`config.h' first." | |
| @exit 1 | |
| install: | |
| install uinput-filter-mouse /usr/local/bin/ | |
| install -m 644 uinput-filter-mouse.service /etc/systemd/system |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <errno.h> | |
| #include <linux/input.h> | |
| #include <linux/uinput.h> | |
| #include "config.h" | |
| #define die(str, args...) do { \ | |
| perror(str); \ | |
| exit(EXIT_FAILURE); \ | |
| } while(0) | |
| int | |
| main(int argc, char* argv[]) | |
| { | |
| int fdo, fdi; | |
| struct uinput_user_dev uidev; | |
| struct input_event ev; | |
| int i; | |
| //if(argc != 2) die("error: specify input device"); | |
| fdo = open("/dev/uinput", O_WRONLY | O_NONBLOCK); | |
| if(fdo < 0) die("error: open"); | |
| //fdi = open(argv[1], O_RDONLY); | |
| fdi = open(UPSTREAM_UINPUT_DEVICE, O_RDONLY); | |
| if(fdi < 0) die("error: open"); | |
| if(ioctl(fdi, EVIOCGRAB, 1) < 0) die("error: ioctl"); | |
| if(ioctl(fdo, UI_SET_EVBIT, EV_SYN) < 0) die("error: ioctl"); | |
| if(ioctl(fdo, UI_SET_EVBIT, EV_KEY) < 0) die("error: ioctl"); | |
| if(ioctl(fdo, UI_SET_EVBIT, EV_REL) < 0) die("error: ioctl"); | |
| if(ioctl(fdo, UI_SET_EVBIT, EV_MSC) < 0) die("error: ioctl"); | |
| for(i = 0; i < KEY_MAX; ++i) | |
| if(ioctl(fdo, UI_SET_KEYBIT, i) < 0) die("error: ioctl"); | |
| for(i = 0; i < REL_MAX; ++i) | |
| if(ioctl(fdo, UI_SET_RELBIT, i) < 0) die("error: ioctl"); | |
| memset(&uidev, 0, sizeof(uidev)); | |
| snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "my-uinput-filter"); | |
| uidev.id.bustype = BUS_USB; | |
| uidev.id.vendor = 0x1; | |
| uidev.id.product = 0x1; | |
| uidev.id.version = 1; | |
| if(write(fdo, &uidev, sizeof(uidev)) < 0) die("error: write"); | |
| if(ioctl(fdo, UI_DEV_CREATE) < 0) die("error: ioctl"); | |
| while(1) | |
| { | |
| if(read(fdi, &ev, sizeof(struct input_event)) < 0) | |
| die("error: read"); | |
| //printf("Got event! type=%d code=%d value=%d\n", ev.type, ev.code, ev.value); | |
| //ev.time.tv_sec = 0; | |
| //ev.time.tv_usec = 0; | |
| if (ev.type == EV_KEY) | |
| { | |
| int key = ev.code; | |
| if (key == BTN_EXTRA || key == BTN_SIDE) | |
| { | |
| ev.code = KEY_LEFTMETA; | |
| if(write(fdo, &ev, sizeof(struct input_event)) < 0) | |
| die("error: write"); | |
| if (key == BTN_EXTRA) | |
| ev.code = BTN_LEFT; | |
| if (key == BTN_SIDE) | |
| ev.code = BTN_RIGHT; | |
| if(write(fdo, &ev, sizeof(struct input_event)) < 0) | |
| die("error: write"); | |
| } | |
| } | |
| if(write(fdo, &ev, sizeof(struct input_event)) < 0) | |
| die("error: write"); | |
| } | |
| if(ioctl(fdo, UI_DEV_DESTROY) < 0) die("error: ioctl"); | |
| close(fdi); | |
| close(fdo); | |
| return 0; | |
| } |
| [Unit] | |
| Description=uinput mouse filter | |
| [Service] | |
| ExecStart=/usr/local/bin/uinput-filter-mouse | |
| Restart=always | |
| [Install] | |
| WantedBy=default.target |
@aksel Sorry for the late reply, I don't think I saw your message until now. I'm not quite clear on what you're trying to achieve - you want to translate key 0x118 to KEY_LEFTMETA + BTN_LEFT, but also translate KEY_LEFTMETA + 0x118 to BTN_RIGHT?
I haven't seen your reply until now
Gist stuff doesn't trigger a notification, apparently
But yeah, that was what I wanted to do.
0x118 -> KEY_LEFTMETA + BTN_LEFT (for moving floating)
KEY_LEFTMETA + 0x118 -> KEY_LEFTMETA + BTN_RIGHT (for resizing)
I have since gotten a new mouse, that has an extra button that I have bound to resizing. But for future reference, how
would I have achieved the other thing?
Hahaha, how to contact you... Maybe a ping @CyberShadow will work?
Gist stuff doesn't trigger a notification, apparently
It seems to be a long-standing omission: isaacs/github#21
These's apparently a third-party service: https://giscus.co/
But for future reference, how
would I have achieved the other thing?
Your code looks correct... I don't know why it wouldn't work.
I would try debugging it with more logging in the program, and looking at what ends up in xev.
I'm don't have a lot of experience in C, so I was wondering, can you help me out a little bit?
The button code I'm trying to map is 0x118. I have gotten it to work with binding it to KEY_LEFTMETA + BTN_LEFT.
I would also like to bind it to BTN_RIGHT when leftmeta is already pressed. However, it doesn't seem to work. Any pointers what I'm doing wrong?
Here's the modified code.