diff --git a/src/device.c b/src/device.c index 5910f73..8a0da4f 100644 --- a/src/device.c +++ b/src/device.c @@ -45,7 +45,7 @@ * corresponding device should be considered invalid by the caller. */ -static uint8_t resolve_device_type(int fd) +static uint8_t resolve_device_capabilities(int fd) { const uint32_t keyboard_mask = 1<name)), dev->name) == -1) { perror("ioctl EVIOCGNAME"); return -1; } - dbg2("device type of %s (%s): %x", path, dev->name, type); + if (capabilities & CAP_MOUSE_ABS) { + if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) < 0) { + perror("ioctl"); + return 0; + } + + dev->_minx = absinfo.minimum; + dev->_maxx = absinfo.maximum; + + if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) < 0) { + perror("ioctl"); + return 0; + } + + dev->_miny = absinfo.minimum; + dev->_maxy = absinfo.maximum; + } + + dbg2("capabilities of %s (%s): %x", path, dev->name, capabilities); - if (type) { + if (capabilities) { struct input_id info; if (ioctl(fd, EVIOCGID, &info) == -1) { @@ -109,7 +136,7 @@ static int device_init(const char *path, struct device *dev) dev->path[sizeof(dev->path)-1] = 0; dev->fd = fd; - dev->type = type; + dev->capabilities = capabilities; dev->vendor_id = info.vendor; dev->product_id = info.product; @@ -347,6 +374,26 @@ struct device_event *device_read_event(struct device *dev) return NULL; } + break; + case EV_ABS: + switch (ev.code) { + case ABS_X: + devev.type = DEV_MOUSE_MOVE_ABS; + devev.x = (ev.value * 1024) / (dev->_maxx - dev->_minx); + devev.y = 0; + + break; + case ABS_Y: + devev.type = DEV_MOUSE_MOVE_ABS; + devev.y = (ev.value * 1024) / (dev->_maxy - dev->_miny); + devev.x = 0; + + break; + default: + fprintf(stderr, "Unrecognized EV_ABS code: %d\n", ev.code); + break; + } + break; case EV_KEY: /* Ignore repeat events */ @@ -386,6 +433,8 @@ struct device_event *device_read_event(struct device *dev) break; default: + if (ev.type) + dbg2("unrecognized evdev event type: %d %d %d", ev.type, ev.code, ev.value); return NULL; } diff --git a/src/device.h b/src/device.h index 1e3b73e..7948cde 100644 --- a/src/device.h +++ b/src/device.h @@ -13,8 +13,15 @@ #define DEV_KEY 2 #define DEV_REMOVED 3 -#define DEVT_MOUSE 0x1 -#define DEVT_KEYBOARD 0x2 +/* + * All absolute values are relative to a resolution + * of 1024x1024 + */ +#define DEV_MOUSE_MOVE_ABS 4 + +#define CAP_MOUSE 0x1 +#define CAP_MOUSE_ABS 0x2 +#define CAP_KEYBOARD 0x4 #define MAX_DEVICES 64 @@ -25,12 +32,18 @@ struct device { */ int fd; - uint8_t type; + uint8_t capabilities; uint16_t product_id; uint16_t vendor_id; char name[64]; char path[256]; + /* Internal. */ + uint32_t _maxx; + uint32_t _maxy; + uint32_t _minx; + uint32_t _miny; + /* Reserved for the user. */ void *data; }; diff --git a/src/keyd.c b/src/keyd.c index a299886..8568614 100644 --- a/src/keyd.c +++ b/src/keyd.c @@ -118,7 +118,7 @@ static void daemon_add_cb(struct device *dev) * between these two, so we take a permissive approach and leave it up to * the user to blacklist mice which emit key events. */ - if (!exact_match && !(dev->type & DEVT_KEYBOARD)) { + if (!exact_match && !(dev->capabilities & CAP_KEYBOARD)) { dbg("Ignoring %s (not a keyboard)", dev->name); return; } @@ -188,7 +188,7 @@ static int daemon_event_cb(struct device *dev, struct device_event *ev) panic_check(code, pressed); - if (dev->type & DEVT_KEYBOARD) + if (dev->capabilities & CAP_KEYBOARD) active_kbd = kbd; dbg2("Processing %04x:%04x (%s): %s %s", @@ -215,6 +215,9 @@ static int daemon_event_cb(struct device *dev, struct device_event *ev) case DEV_MOUSE_MOVE: vkbd_mouse_move(vkbd, ev->x, ev->y); break; + case DEV_MOUSE_MOVE_ABS: + vkbd_mouse_move_abs(vkbd, ev->x, ev->y); + break; } return 0; @@ -277,6 +280,9 @@ static int monitor_event_cb(struct device *dev, struct device_event *ev) case DEV_MOUSE_MOVE: dbg("%s: move %d %d", dev->name, ev->x, ev->y); break; + case DEV_MOUSE_MOVE_ABS: + dbg("%s: move abs %d %d", dev->name, ev->x, ev->y); + break; case DEV_MOUSE_SCROLL: dbg("%s: scroll %d %d", dev->name, ev->x, ev->y); break; diff --git a/src/vkbd/uinput.c b/src/vkbd/uinput.c index cd6d8b9..fa29f57 100644 --- a/src/vkbd/uinput.c +++ b/src/vkbd/uinput.c @@ -197,8 +197,9 @@ void write_key_event(const struct vkbd *vkbd, uint8_t code, int state) * to prevent X from identifying the virtual * keyboard as a mouse. */ - if (is_btn) + if (is_btn) { fd = vkbd->pfd; + } ev.value = state; @@ -319,23 +320,27 @@ void vkbd_mouse_move_abs(const struct vkbd *vkbd, int x, int y) { struct input_event ev; - ev.type = EV_ABS; - ev.code = ABS_X; - ev.value = x; + if (x) { + ev.type = EV_ABS; + ev.code = ABS_X; + ev.value = x; - ev.time.tv_sec = 0; - ev.time.tv_usec = 0; + ev.time.tv_sec = 0; + ev.time.tv_usec = 0; - write(vkbd->pfd, &ev, sizeof(ev)); + write(vkbd->pfd, &ev, sizeof(ev)); + } - ev.type = EV_ABS; - ev.code = ABS_Y; - ev.value = y; + if (y) { + ev.type = EV_ABS; + ev.code = ABS_Y; + ev.value = y; - ev.time.tv_sec = 0; - ev.time.tv_usec = 0; + ev.time.tv_sec = 0; + ev.time.tv_usec = 0; - write(vkbd->pfd, &ev, sizeof(ev)); + write(vkbd->pfd, &ev, sizeof(ev)); + } ev.type = EV_SYN; ev.code = 0;