161 lines
4.1 KiB
C
161 lines
4.1 KiB
C
#include "output_dev.h"
|
|
|
|
int create_output_dev(const char* uinput_path, const char* name, output_dev_type_t type) {
|
|
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
|
|
if(fd < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_setup dev = {0};
|
|
if (strlen(name) < UINPUT_MAX_NAME_SIZE) {
|
|
strcpy(dev.name, name);
|
|
} else {
|
|
strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1);
|
|
}
|
|
|
|
dev.id.bustype = BUS_VIRTUAL;
|
|
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
|
|
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
|
|
|
|
switch (type) {
|
|
case output_dev_imu: {
|
|
ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_ACCELEROMETER);
|
|
ioctl(fd, UI_SET_EVBIT, EV_ABS);
|
|
//ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
|
ioctl(fd, UI_SET_EVBIT, EV_MSC);
|
|
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
|
|
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_X);
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_Y);
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_Z);
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_RX);
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_RY);
|
|
ioctl(fd, UI_SET_ABSBIT, ABS_RZ);
|
|
|
|
//ioctl(fd, UI_SET_KEYBIT, BTN_TRIGGER);
|
|
//ioctl(fd, UI_SET_KEYBIT, BTN_THUMB);
|
|
|
|
struct uinput_abs_setup devAbsX = {0};
|
|
devAbsX.code = ABS_X;
|
|
devAbsX.absinfo.minimum = -ACCEL_RANGE;
|
|
devAbsX.absinfo.maximum = ACCEL_RANGE;
|
|
devAbsX.absinfo.resolution = 255; // 255 units = 1g
|
|
devAbsX.absinfo.fuzz = 5;
|
|
devAbsX.absinfo.flat = 0;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsX) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_abs_setup devAbsY = {0};
|
|
devAbsY.code = ABS_Y;
|
|
devAbsY.absinfo.minimum = -ACCEL_RANGE;
|
|
devAbsY.absinfo.maximum = ACCEL_RANGE;
|
|
devAbsY.absinfo.resolution = 255; // 255 units = 1g
|
|
devAbsY.absinfo.fuzz = 5;
|
|
devAbsY.absinfo.flat = 0;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsY) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_abs_setup devAbsZ = {0};
|
|
devAbsZ.code = ABS_Z;
|
|
devAbsZ.absinfo.minimum = -ACCEL_RANGE;
|
|
devAbsZ.absinfo.maximum = ACCEL_RANGE;
|
|
devAbsZ.absinfo.resolution = 255; // 255 units = 1g
|
|
devAbsZ.absinfo.fuzz = 5;
|
|
devAbsZ.absinfo.flat = 0;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsZ) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_abs_setup devAbsRX = {0};
|
|
devAbsRX.code = ABS_RX;
|
|
devAbsRX.absinfo.minimum = -GYRO_RANGE;
|
|
devAbsRX.absinfo.maximum = GYRO_RANGE;
|
|
devAbsRX.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
|
devAbsRX.absinfo.fuzz = 0;
|
|
devAbsRX.absinfo.flat = GYRO_DEADZONE;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsRX) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_abs_setup devAbsRY = {0};
|
|
devAbsRY.code = ABS_RY;
|
|
devAbsRY.absinfo.minimum = -GYRO_RANGE;
|
|
devAbsRY.absinfo.maximum = GYRO_RANGE;
|
|
devAbsRY.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
|
devAbsRY.absinfo.fuzz = 0;
|
|
devAbsRY.absinfo.flat = GYRO_DEADZONE;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsRY) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
struct uinput_abs_setup devAbsRZ = {0};
|
|
devAbsRZ.code = ABS_RZ;
|
|
devAbsRZ.absinfo.minimum = -GYRO_RANGE;
|
|
devAbsRZ.absinfo.maximum = GYRO_RANGE;
|
|
devAbsRZ.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
|
devAbsRZ.absinfo.fuzz = 0;
|
|
devAbsRZ.absinfo.flat = GYRO_DEADZONE;
|
|
if(ioctl(fd, UI_ABS_SETUP, &devAbsRZ) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
if(ioctl(fd, UI_DEV_CREATE) < 0) {
|
|
fd = -1;
|
|
close(fd);
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case output_dev_gamepad: {
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
// error
|
|
close(fd);
|
|
fd = -1;
|
|
goto create_output_dev_err;
|
|
}
|
|
|
|
create_output_dev_err:
|
|
return fd;
|
|
}
|
|
|
|
void *output_dev_thread_func(void *ptr) {
|
|
output_dev_t *out_dev = (output_dev_t*)ptr;
|
|
|
|
for (;;) {
|
|
const uint32_t flags = out_dev->crtl_flags;
|
|
if (flags & OUTPUT_DEV_CTRL_FLAG_EXIT) {
|
|
out_dev->crtl_flags &= ~OUTPUT_DEV_CTRL_FLAG_EXIT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|