b004d06c23
This is a daemon which allows you to emulate middle and right click as well as a mouse wheel. It was originally written for Apple PowerPC laptops with a single button, but can be used on any hardware.
235 lines
6.9 KiB
Diff
235 lines
6.9 KiB
Diff
Author: Colin Watson <cjwatson@ubuntu.com>
|
|
Description: No description.
|
|
--- a/mouseemu.c
|
|
+++ b/mouseemu.c
|
|
@@ -187,52 +187,68 @@
|
|
}
|
|
}
|
|
|
|
-void keyboard_handler (int fd)
|
|
+void keyboard_handler (struct input_event inp)
|
|
{
|
|
- struct input_event inp;
|
|
- if (read(fd, &inp, sizeof(inp)) == sizeof(inp)) {
|
|
- if (!event_parse(inp.code, inp.value) && !is_modifier(inp)) {
|
|
- last_key = (inp.time.tv_sec*1000000 + inp.time.tv_usec);
|
|
- }
|
|
+ if (inp.type != EV_KEY && inp.type != EV_REP) {
|
|
+ passthrough(ui_keyb_fd, inp);
|
|
+ return;
|
|
+ }
|
|
+ if (inp.type == EV_KEY && (inp.code == BTN_LEFT || inp.code == BTN_MIDDLE || inp.code == BTN_RIGHT))
|
|
+ return;
|
|
+
|
|
+ if (!event_parse(inp.code, inp.value) && !is_modifier(inp)) {
|
|
+ last_key = (inp.time.tv_sec*1000000 + inp.time.tv_usec);
|
|
+ }
|
|
/* I think its best not to pass scroll, or experiment with not passing the release if
|
|
* we actually used it for scrolling (but some apps may get stuck?)
|
|
*/
|
|
- if (inp.code != b2_key && inp.code != b3_key) {
|
|
- passthrough(ui_keyb_fd, inp);
|
|
- }
|
|
+ if (inp.code != b2_key && inp.code != b3_key) {
|
|
+ passthrough(ui_keyb_fd, inp);
|
|
}
|
|
}
|
|
|
|
-static void mouse_handler (int fd)
|
|
+static void mouse_handler (struct input_event inp)
|
|
+{
|
|
+ if (inp.type != EV_KEY && inp.type != EV_REL && inp.type != EV_SYN)
|
|
+ return;
|
|
+ if (inp.type == EV_KEY && inp.code != BTN_LEFT && inp.code != BTN_MIDDLE && inp.code != BTN_RIGHT)
|
|
+ return;
|
|
+
|
|
+ if (inp.type == EV_KEY && inp.code == BTN_LEFT) {
|
|
+ if (b2_key == BTN_LEFT && b2_mod_pressed)
|
|
+ report_click(BTN_MIDDLE, inp.value);
|
|
+ else if (b3_key == BTN_LEFT && b3_mod_pressed)
|
|
+ report_click(BTN_RIGHT, inp.value);
|
|
+ else
|
|
+ passthrough(ui_mouse_fd, inp);
|
|
+ }
|
|
+ else if (scroll_mod_pressed
|
|
+ && inp.type == EV_REL
|
|
+ && (inp.code == REL_Y || inp.code == REL_X)) {
|
|
+ report_scroll (inp.value);
|
|
+ //printf("inp.value %d\n", inp.value);
|
|
+ } else {
|
|
+ if ((inp.time.tv_sec*1000000+inp.time.tv_usec)-last_key > typing_block_delay*1000
|
|
+ || inp.type == EV_REL)
|
|
+ passthrough(ui_mouse_fd, inp);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void event_handler (int mode, int fd)
|
|
{
|
|
- int count;
|
|
struct input_event inp;
|
|
|
|
- if ((count = read(fd, &inp, sizeof(inp))) == sizeof(inp)) {
|
|
- if (inp.type == EV_KEY && inp.code == BTN_LEFT) {
|
|
- if (b2_key == BTN_LEFT && b2_mod_pressed)
|
|
- report_click(BTN_MIDDLE, inp.value);
|
|
- else if (b3_key == BTN_LEFT && b3_mod_pressed)
|
|
- report_click(BTN_RIGHT, inp.value);
|
|
- else
|
|
- passthrough(ui_mouse_fd, inp);
|
|
- }
|
|
- else if (scroll_mod_pressed
|
|
- && inp.type == EV_REL
|
|
- && (inp.code == REL_Y || inp.code == REL_X)) {
|
|
- report_scroll (inp.value);
|
|
- //printf("inp.value %d\n", inp.value);
|
|
- } else {
|
|
- if ((inp.time.tv_sec*1000000+inp.time.tv_usec)-last_key > typing_block_delay*1000
|
|
- || inp.type == EV_REL)
|
|
- passthrough(ui_mouse_fd, inp);
|
|
- }
|
|
+ if (read(fd, &inp, sizeof(inp)) == sizeof(inp)) {
|
|
+ if (mode & HANDLER_KEYBOARD)
|
|
+ keyboard_handler(inp);
|
|
+ if (mode & HANDLER_MOUSE)
|
|
+ mouse_handler(inp);
|
|
}
|
|
}
|
|
|
|
void scan_for_devs()
|
|
{
|
|
- int n, m, fd;
|
|
+ int n, m, fd, mode;
|
|
char filename[20];
|
|
unsigned long bit[NBITS(EV_MAX)];
|
|
unsigned short id[EVENT_DEVS];
|
|
@@ -240,47 +256,47 @@
|
|
for (n = 0, m = 0; n < EVENT_DEVS; n++) {
|
|
sprintf(filename, "/dev/input/event%d", n);
|
|
if ((fd = open(filename, O_RDONLY)) >= 0) {
|
|
+ mode = 0;
|
|
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit);
|
|
+ ioctl(fd, EVIOCGID, id);
|
|
if (test_bit(EV_KEY, bit) && test_bit(EV_REP, bit)) {
|
|
- ioctl(fd, EVIOCGID, id);
|
|
/* our own virtual keyboard (on rescans)*/
|
|
if (id[ID_PRODUCT] == 0x1F && id[ID_VENDOR] == 0x1F) {
|
|
close(fd);
|
|
continue;
|
|
}
|
|
+ mode |= HANDLER_KEYBOARD;
|
|
if (id[ID_PRODUCT] != eventdevs[m].product ||
|
|
id[ID_VENDOR] != eventdevs[m].vendor) {
|
|
- if (eventdevs[m].handle >= 0) {
|
|
- unregister_inputhandler(eventdevs[m].handle);
|
|
- close(eventdevs[m].handle);
|
|
- }
|
|
debugf("keyboard: fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]);
|
|
- eventdevs[m].handle= fd;
|
|
- eventdevs[m].product = id[ID_PRODUCT];
|
|
- eventdevs[m].vendor = id[ID_VENDOR];
|
|
- register_inputhandler(fd, keyboard_handler, 1);
|
|
}
|
|
- m++;
|
|
- } else if (test_bit(EV_REL, bit)) {
|
|
- ioctl(fd, EVIOCGID, id);
|
|
+ }
|
|
+ if (test_bit(EV_REL, bit)) {
|
|
/* our own virtual mouse (on rescans)*/
|
|
if (id[ID_PRODUCT] == 0x1E && id[ID_VENDOR] == 0x1F) {
|
|
close(fd);
|
|
continue;
|
|
}
|
|
+ mode |= HANDLER_MOUSE;
|
|
+ if (id[ID_PRODUCT] != eventdevs[m].product ||
|
|
+ id[ID_VENDOR] != eventdevs[m].vendor) {
|
|
+ debugf("mouse : fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]);
|
|
+ }
|
|
+ }
|
|
+ if (mode) {
|
|
if (id[ID_PRODUCT] != eventdevs[m].product ||
|
|
id[ID_VENDOR] != eventdevs[m].vendor) {
|
|
if (eventdevs[m].handle >= 0) {
|
|
unregister_inputhandler(eventdevs[m].handle);
|
|
close(eventdevs[m].handle);
|
|
}
|
|
- debugf("mouse : fd %d event%d, vendor %4x product %4x\n", fd, n, id[ID_VENDOR], id[ID_PRODUCT]);
|
|
eventdevs[m].handle= fd;
|
|
eventdevs[m].product = id[ID_PRODUCT];
|
|
eventdevs[m].vendor = id[ID_VENDOR];
|
|
- register_inputhandler(fd, mouse_handler, 1);
|
|
- }
|
|
- m++;
|
|
+ register_inputhandler(mode, fd, event_handler, 1);
|
|
+ } else
|
|
+ close(fd);
|
|
+ m++;
|
|
} else
|
|
close(fd);
|
|
}
|
|
@@ -313,12 +329,13 @@
|
|
scan_for_devs();
|
|
}
|
|
|
|
-int register_inputhandler (int fd, void (*func)(int fd), int grab)
|
|
+int register_inputhandler (int mode, int fd, void (*func)(int mode, int fd), int grab)
|
|
{
|
|
int n;
|
|
|
|
for (n=0; n < EVENT_DEVS; n++)
|
|
if (ihandler[n].fd == -1) {
|
|
+ ihandler[n].mode = mode;
|
|
ihandler[n].fd = fd;
|
|
ihandler[n].handler = func;
|
|
ihandler[n].grab = grab;
|
|
@@ -335,6 +352,7 @@
|
|
|
|
for (n = 0; n < EVENT_DEVS; n++)
|
|
if (found) {
|
|
+ ihandler[n-1].mode = ihandler[n].mode;
|
|
ihandler[n-1].fd = ihandler[n].fd;
|
|
ihandler[n-1].handler = ihandler[n].handler;
|
|
} else if (ihandler[n].fd == fd) {
|
|
@@ -367,7 +385,7 @@
|
|
for (n=0; n < EVENT_DEVS; n++) {
|
|
if (ihandler[n].fd == -1) continue;
|
|
if (FD_ISSET(ihandler[n].fd, inset))
|
|
- ihandler[n].handler (ihandler[n].fd);
|
|
+ ihandler[n].handler (ihandler[n].mode, ihandler[n].fd);
|
|
}
|
|
}
|
|
|
|
@@ -816,6 +834,7 @@
|
|
eventdevs[i].product= 0;
|
|
|
|
ihandler[i].handler=0;
|
|
+ ihandler[i].mode=0;
|
|
ihandler[i].fd=-1;
|
|
}
|
|
|
|
--- a/mouseemu.h
|
|
+++ b/mouseemu.h
|
|
@@ -33,6 +33,9 @@
|
|
#define BTN2 0x04
|
|
#define BTN3 0x02
|
|
|
|
+#define HANDLER_KEYBOARD (1 << 0)
|
|
+#define HANDLER_MOUSE (1 << 1)
|
|
+
|
|
/* device structure */
|
|
typedef struct _kdev {
|
|
int handle;
|
|
@@ -42,11 +45,12 @@
|
|
|
|
/* handler structure */
|
|
typedef struct _ihandler {
|
|
- void (*handler)(int fd);
|
|
+ void (*handler)(int mode, int fd);
|
|
+ int mode;
|
|
int fd;
|
|
int grab;
|
|
} input_handler;
|
|
|
|
void unregister_inputhandler (int fd);
|
|
-int register_inputhandler(int fd, void (*func)(int fd), int grab);
|
|
+int register_inputhandler(int mode, int fd, void (*func)(int mode, int fd), int grab);
|
|
#endif
|