108 lines
3.0 KiB
C
108 lines
3.0 KiB
C
/*
|
|
This file is part of Furui.
|
|
|
|
Furui is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Furui is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Furui. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include "filter.h"
|
|
|
|
struct furui_filter *furui_filter_new(struct libevdev *dev, struct libevdev *model_keyboard, struct libevdev *model_mouse, void (*filter)(struct furui_filter *, unsigned int, unsigned int, int), void (*idle)(struct furui_filter *), struct timeval (*timeout)(struct furui_filter *), void *obj) {
|
|
struct furui_filter *new_obj;
|
|
|
|
new_obj = malloc(sizeof(struct furui_filter));
|
|
if (new_obj == NULL) {
|
|
perror("malloc");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
new_obj->dev = dev;
|
|
new_obj->vkeyboard = furui_vkeyboard_new(model_keyboard);
|
|
new_obj->vmouse = furui_vmouse_new(model_mouse);
|
|
new_obj->filter = filter;
|
|
new_obj->idle = idle;
|
|
new_obj->timeout = timeout;
|
|
new_obj->obj = obj;
|
|
|
|
return new_obj;
|
|
}
|
|
|
|
void furui_filter_free(struct furui_filter *filter) {
|
|
if (filter == NULL) {
|
|
return;
|
|
}
|
|
|
|
furui_vkeyboard_free(filter->vkeyboard);
|
|
furui_vmouse_free(filter->vmouse);
|
|
|
|
free(filter);
|
|
}
|
|
|
|
int furui_filter_vkeyboard_write_event(struct furui_filter *filter, unsigned int type, unsigned int code, int value) {
|
|
return libevdev_uinput_write_event(filter->vkeyboard->dev, type, code, value);
|
|
}
|
|
|
|
int furui_filter_vmouse_write_event(struct furui_filter *filter, unsigned int type, unsigned int code, int value) {
|
|
return libevdev_uinput_write_event(filter->vmouse->dev, type, code, value);
|
|
}
|
|
|
|
static void run_filter(struct furui_filter *filter) {
|
|
int fd = libevdev_get_fd(filter->dev);
|
|
fd_set rfds;
|
|
struct timeval tv;
|
|
int retval;
|
|
|
|
FD_ZERO(&rfds);
|
|
FD_SET(fd, &rfds);
|
|
|
|
tv = filter->timeout(filter);
|
|
|
|
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
|
|
if (retval == -1) {
|
|
perror("select");
|
|
exit(EXIT_FAILURE);
|
|
} else if (retval) {
|
|
struct input_event ev;
|
|
int rc;
|
|
|
|
do {
|
|
rc = libevdev_next_event(filter->dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
|
|
if (rc == LIBEVDEV_READ_STATUS_SYNC) {
|
|
do {
|
|
rc = libevdev_next_event(filter->dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
|
|
filter->filter(filter, ev.type, ev.code, ev.value);
|
|
} while (rc == LIBEVDEV_READ_STATUS_SYNC);
|
|
} else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
|
|
filter->filter(filter, ev.type, ev.code, ev.value);
|
|
}
|
|
} while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
|
|
} else {
|
|
filter->idle(filter);
|
|
}
|
|
}
|
|
|
|
int furui_filter_loop(struct furui_filter *filter) {
|
|
while (1) {
|
|
run_filter(filter);
|
|
}
|
|
|
|
/* never reached */
|
|
assert(0);
|
|
return 1;
|
|
}
|