solved warning and cleaned up code

This commit is contained in:
Denis 2023-12-11 21:35:23 +01:00
parent 213f24c65f
commit 44326dc69c
No known key found for this signature in database
GPG key ID: DD9B63F805CF5C03
15 changed files with 40 additions and 1206 deletions

View file

@ -25,8 +25,6 @@ add_executable(${EXECUTABLE_NAME}
settings.c
virt_ds4.c
virt_ds5.c
virt_mouse_kbd.c
virt_evdev.c
devices_status.c
rog_ally.c
legion_go.c

View file

@ -2,7 +2,7 @@
CFLAGS= -std=c17 -O3 -march=znver4 -D _DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L -std=c11 -fPIE -pedantic -Wall -flto=full # -Werror
LDFLAGS=-lpthread -levdev -ludev -lconfig -lrt -lm -flto=full
CC=clang
OBJECTS=main.o dev_in.o dev_out.o dev_iio.o dev_evdev.o dev_hidraw.o settings.o virt_ds4.o virt_ds5.o virt_mouse_kbd.o virt_evdev.o devices_status.o xbox360.o rog_ally.o legion_go.o rogue_enemy.o
OBJECTS=main.o dev_in.o dev_out.o dev_iio.o dev_evdev.o dev_hidraw.o settings.o virt_ds4.o virt_ds5.o devices_status.o xbox360.o rog_ally.o legion_go.o rogue_enemy.o
TARGET=rogue-enemy
all: $(TARGET)

View file

@ -106,7 +106,6 @@ int dev_hidraw_open(
closedir(d);
}
dev_hidraw_open_err:
return res;
}

246
dev_iio.c
View file

@ -143,21 +143,12 @@ static int dev_iio_create(int fd, const char* path, dev_iio_t **const out_iio) {
// ========================================== in_anglvel_scale ==============================================
{
const char* preferred_scale = LSB_PER_RAD_S_2000_DEG_S_STR;
const char *scale_main_file = "/in_anglvel_scale";
char* const anglvel_scale = read_file((*out_iio)->path, scale_main_file);
if (anglvel_scale != NULL) {
(*out_iio)->flags |= DEV_IIO_HAS_ANGLVEL;
(*out_iio)->anglvel_scale_x = (*out_iio)->anglvel_scale_y = (*out_iio)->anglvel_scale_z = strtod(anglvel_scale, NULL);
free((void*)anglvel_scale);
if (write_file((*out_iio)->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) {
(*out_iio)->anglvel_scale_x = (*out_iio)->anglvel_scale_y = (*out_iio)->anglvel_scale_z = LSB_PER_RAD_S_2000_DEG_S;
printf("anglvel scale changed to %f for device %s\n", (*out_iio)->anglvel_scale_x, (*out_iio)->name);
} else {
fprintf(stderr, "Unable to set preferred in_anglvel_scale for device %s.\n", (*out_iio)->name);
}
} else {
// TODO: what about if those are split in in_anglvel_{x,y,z}_scale?
fprintf(stderr, "Unable to read in_anglvel_scale from path %s%s.\n", (*out_iio)->path, scale_main_file);
@ -171,21 +162,12 @@ static int dev_iio_create(int fd, const char* path, dev_iio_t **const out_iio) {
// =========================================== in_accel_scale ===============================================
{
const char* preferred_scale = LSB_PER_16G_STR;
const char *scale_main_file = "/in_accel_scale";
char* const accel_scale = read_file((*out_iio)->path, scale_main_file);
if (accel_scale != NULL) {
(*out_iio)->flags |= DEV_IIO_HAS_ACCEL;
(*out_iio)->accel_scale_x = (*out_iio)->accel_scale_y = (*out_iio)->accel_scale_z = strtod(accel_scale, NULL);
free((void*)accel_scale);
if (write_file((*out_iio)->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) {
(*out_iio)->accel_scale_x = (*out_iio)->accel_scale_y = (*out_iio)->accel_scale_z = LSB_PER_16G;
printf("accel scale changed to %f for device %s\n", (*out_iio)->accel_scale_x, (*out_iio)->name);
} else {
fprintf(stderr, "Unable to set preferred in_accel_scale for device %s.\n", (*out_iio)->name);
}
} else {
// TODO: what about if those are plit in in_accel_{x,y,z}_scale?
fprintf(stderr, "Unable to read in_accel_scale file from path %s%s.\n", (*out_iio)->path, scale_main_file);
@ -221,45 +203,27 @@ dev_iio_create_err:
return res;
}
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac) {
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz) {
int res = -EINVAL;
if (!dev_iio_has_anglvel(iio)) {
res = -ENOENT;
goto dev_iio_change_anglvel_sampling_freq_err;
}
char freq_str[16] = {};
snprintf(freq_str, sizeof(freq_str), "%u.%u", (unsigned)freq_hz, (unsigned)freq_hz_frac);
const char* const preferred_samplig_freq = " 1600.000000";
const size_t preferred_samplig_freq_len = strlen(preferred_samplig_freq);
if (write_file(iio->path, "/in_accel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len) >= 0) {
printf("Accel sampling frequency changed to %s\n", preferred_samplig_freq);
} else {
fprintf(stderr, "Could not change accel sampling frequency\n");
}
res = write_file(iio->path, "/in_anglvel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len);
res = write_file(iio->path, "/in_anglvel_sampling_frequency", freq_str_hz, strlen(freq_str_hz));
dev_iio_change_anglvel_sampling_freq_err:
return res;
}
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac) {
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz) {
int res = -EINVAL;
if (!dev_iio_has_anglvel(iio)) {
res = -ENOENT;
goto dev_iio_change_accel_sampling_freq_err;
}
char freq_str[16] = {};
snprintf(freq_str, sizeof(freq_str), "%u.%u", (unsigned)freq_hz, (unsigned)freq_hz_frac);
const char* const preferred_samplig_freq = " 1600.000000";
const size_t preferred_samplig_freq_len = strlen(preferred_samplig_freq);
res = write_file(iio->path, "/in_accel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len);
res = write_file(iio->path, "/in_accel_sampling_frequency", freq_str_hz, strlen(freq_str_hz));
dev_iio_change_accel_sampling_freq_err:
return res;
@ -301,6 +265,16 @@ static bool iio_matches(
}
/*
// Load the kernel module
int result = syscall(__NR_finit_module, -1, "iio-trig-hrtimer", 0);
if (result == 0) {
printf("Kernel module '%s' loaded successfully.\n", "iio-trig-hrtimer");
} else {
perror("Error loading kernel module");
}
modprobe industrialio-sw-trigger
modprobe iio-trig-sysfs
modprobe iio-trig-hrtimer
@ -328,7 +302,7 @@ mount -t configfs none /home/config
mkdir /home/config
mkdir /home/config/iio/triggers/hrtimer/rogue
*/
static const char *const iio_hrtrigger_name = "iio-trig-hrtimer";
//static const char *const iio_hrtrigger_name = "iio-trig-hrtimer";
static const char *const iio_path = "/sys/bus/iio/devices/";
@ -377,197 +351,9 @@ int dev_iio_open(
closedir(d);
}
/*
// Load the kernel module
int result = syscall(__NR_finit_module, -1, iio_hrtrigger_name, 0);
if (result == 0) {
printf("Kernel module '%s' loaded successfully.\n", iio_hrtrigger_name);
} else {
perror("Error loading kernel module");
}
*/
dev_iio_open_err:
return res;
}
static void multiplyMatrixVector(const double matrix[3][3], const double vector[3], double result[3]) {
result[0] = matrix[0][0] * vector[0] + matrix[1][0] * vector[1] + matrix[2][0] * vector[2];
result[1] = matrix[0][1] * vector[0] + matrix[1][1] * vector[1] + matrix[2][1] * vector[2];
result[2] = matrix[0][2] * vector[0] + matrix[1][2] * vector[1] + matrix[2][2] * vector[2];
}
/*
int dev_iio_read_imu(const dev_iio_t *const iio, imu_in_message_t *const out) {
struct timeval read_time;
gettimeofday(&read_time, NULL);
out->flags = 0x00000000U;
char tmp[128];
double gyro_in[3];
double accel_in[3];
double gyro_out[3];
double accel_out[3];
if (iio->accel_x_fd != NULL) {
rewind(iio->accel_x_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_x_fd);
if (tmp_read >= 0) {
out->accel_x_raw = strtol(&tmp[0], NULL, 10);
accel_in[0] = (double)out->accel_x_raw * iio->accel_scale_x;
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
out->accel_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
}
} else {
fprintf(stderr, "While reading accel(x): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->accel_y_fd != NULL) {
rewind(iio->accel_y_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_y_fd);
if (tmp_read >= 0) {
out->accel_y_raw = strtol(&tmp[0], NULL, 10);
accel_in[1] = (double)out->accel_y_raw * iio->accel_scale_y;
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
out->accel_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
}
} else {
fprintf(stderr, "While reading accel(y): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->accel_z_fd != NULL) {
rewind(iio->accel_z_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_z_fd);
if (tmp_read >= 0) {
out->accel_z_raw = strtol(&tmp[0], NULL, 10);
accel_in[2] = (double)out->accel_z_raw * iio->accel_scale_z;
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
out->accel_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
}
} else {
fprintf(stderr, "While reading accel(z): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->anglvel_x_fd != NULL) {
rewind(iio->anglvel_x_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_x_fd);
if (tmp_read >= 0) {
out->gyro_x_raw = strtol(&tmp[0], NULL, 10);
gyro_in[0] = (double)out->gyro_x_raw * iio->anglvel_scale_x;
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
out->gyro_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
}
} else {
fprintf(stderr, "While reading anglvel(x): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->anglvel_y_fd != NULL) {
rewind(iio->anglvel_y_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_y_fd);
if (tmp_read >= 0) {
out->gyro_y_raw = strtol(&tmp[0], NULL, 10);
gyro_in[1] = (double)out->gyro_y_raw *iio->anglvel_scale_y;
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
out->gyro_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
}
} else {
fprintf(stderr, "While reading anglvel(y): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->anglvel_z_fd != NULL) {
rewind(iio->anglvel_z_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_z_fd);
if (tmp_read >= 0) {
out->gyro_z_raw = strtol(&tmp[0], NULL, 10);
gyro_in[2] = (double)out->gyro_z_raw *iio->anglvel_scale_z;
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
out->gyro_read_time = read_time;
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
}
} else {
fprintf(stderr, "While reading anglvel(z): %d\n", tmp_read);
return tmp_read;
}
}
if (iio->temp_fd != NULL) {
rewind(iio->temp_fd);
memset((void*)&tmp[0], 0, sizeof(tmp));
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->temp_fd);
if (tmp_read >= 0) {
out->temp_raw = strtol(&tmp[0], NULL, 10);
out->temp_in_k = (double)out->temp_raw *iio->temp_scale;
} else {
fprintf(stderr, "While reading temp: %d\n", tmp_read);
return tmp_read;
}
}
multiplyMatrixVector(iio->mount_matrix, gyro_in, gyro_out);
multiplyMatrixVector(iio->mount_matrix, accel_in, accel_out);
memcpy(out->accel_m2s, accel_out, sizeof(double[3]));
memcpy(out->gyro_rad_s, gyro_out, sizeof(double[3]));
return 0;
}
*/
int dev_iio_has_anglvel(const dev_iio_t* iio) {
return (iio->flags & DEV_IIO_HAS_ANGLVEL) != 0;
}
@ -578,4 +364,4 @@ int dev_iio_has_accel(const dev_iio_t* iio) {
int dev_iio_get_buffer_fd(const dev_iio_t *const iio) {
return iio->fd;
}
}

View file

@ -54,6 +54,6 @@ int dev_iio_has_anglvel(const dev_iio_t* iio);
int dev_iio_has_accel(const dev_iio_t* iio);
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac);
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz);
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac);
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz);

View file

@ -154,7 +154,7 @@ int64_t get_timediff_usec(const struct timeval *const past, const struct timeval
struct timeval tdiff;
timersub(now, past, &tdiff);
const int64_t sgn = ((now->tv_sec > past->tv_sec) || ((now->tv_sec == past->tv_sec) && (now->tv_usec > past->tv_usec))) ? -1 : +1;
//const int64_t sgn = ((now->tv_sec > past->tv_sec) || ((now->tv_sec == past->tv_sec) && (now->tv_usec > past->tv_usec))) ? -1 : +1;
return (int64_t)(tdiff.tv_sec) * (int64_t)1000000 + (int64_t)(tdiff.tv_usec);
}
@ -198,8 +198,8 @@ void *dev_out_thread_func(void *ptr) {
gettimeofday(&now, NULL);
struct timeval gamepad_last_hid_report_sent = now;
struct timeval mouse_last_hid_report_sent = now;
struct timeval keyboard_last_hid_report_sent = now;
//struct timeval mouse_last_hid_report_sent = now;
//struct timeval keyboard_last_hid_report_sent = now;
uint8_t tmp_buf[256];

View file

@ -50,8 +50,7 @@ typedef struct hidraw_callbacks {
} hidraw_callbacks_t;
typedef struct iio_settings {
uint16_t sampling_freq_hz;
uint16_t sampling_freq_hz_frac;
const char* const sampling_freq_hz;
int8_t post_matrix[3][3];
} iio_settings_t;

View file

@ -24,6 +24,16 @@ static input_dev_t in_iio_dev = {
.name = "gyro_3d",
}
},
.map = {
.iio_settings = {
.sampling_freq_hz = "70.000",
.post_matrix = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
}
}
}
};
static struct llg_hidraw_data {
@ -40,7 +50,7 @@ static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_dat
}
// here we have llg_data->last_packet filled with 64 bytes from the input device
/*
const in_message_t current_message = {
.type = GAMEPAD_SET_ELEMENT,
.data = {
@ -53,7 +63,6 @@ static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_dat
}
};
/*
// this does send messages to the output device
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)&current_message, sizeof(in_message_t));
@ -116,9 +125,9 @@ input_dev_composite_t legion_composite = {
.dev = {
&in_hidraw_dev,
&in_xbox_dev,
// &in_iio_dev,
&in_iio_dev,
},
.dev_count = 2,
.dev_count = 3,
.init_fn = legion_platform_init,
.leds_fn = legion_platform_leds,
.deinit_fn = legion_platform_deinit,

199
logic.c
View file

@ -1,199 +0,0 @@
#include "virt_ds4.h"
#include "virt_ds5.h"
#include "virt_evdev.h"
#include "virt_mouse_kbd.h"
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
int logic_create(logic_t *const logic) {
int ret = 0;
logic->flags = 0x00000000U;
init_config(&logic->controller_settings);
const int fill_config_res = fill_config(&logic->controller_settings, configuration_file);
if (fill_config_res != 0) {
fprintf(stderr, "Unable to fill configuration from file %s -- defaults will be used\n", configuration_file);
}
devices_status_init(&logic->dev_stats);
ret = pthread_mutex_init(&logic->dev_stats.mutex, NULL);
if (ret != 0) {
fprintf(stderr, "Unable to create mutex: %d\n", ret);
goto logic_create_err;
}
bool lizard_thread_started = false;
const int init_platform_res = init_platform(&logic->platform);
if (init_platform_res == 0) {
printf("RC71L platform correctly initialized\n");
logic->flags |= LOGIC_FLAGS_PLATFORM_ENABLE;
if (is_mouse_mode(&logic->platform)) {
printf("Device is in lizard mode\n");
// TODO: start the appropriate output thread
lizard_thread_started = true;
}
} else {
fprintf(stderr, "Unable to initialize Asus RC71L MCU: %d\n", init_platform_res);
}
if (!lizard_thread_started) {
logic_start_output_dev_thread(logic);
}
logic_create_err:
return ret;
}
int is_rc71l_ready(const logic_t *const logic) {
return logic->flags & LOGIC_FLAGS_PLATFORM_ENABLE;
}
void logic_terminate_output_thread(logic_t *const logic) {
if (logic->virt_dev_thread_running) {
void* thread_return = NULL;
pthread_join(logic->virt_dev_thread, &thread_return);
}
}
int logic_start_output_mouse_kbd_thread(logic_t *const logic) {
logic->dev_stats.kbd.connected = true;
const int ret = pthread_create(&logic->virt_dev_thread, NULL, virt_mouse_kbd_thread_func, (void*)(&logic->dev_stats));
logic->virt_dev_thread_running = ret == 0;
return ret;
}
int logic_start_output_dev_thread(logic_t *const logic) {
logic->dev_stats.gamepad.connected = true;
int ret = -EINVAL;
switch (logic->controller_settings.gamepad_output_device) {
case 0:
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_evdev_thread_func, (void*)(&logic->dev_stats));
break;
case 1:
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_ds5_thread_func, (void*)(&logic->dev_stats));
break;
case 2:
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_ds4_thread_func, (void*)(&logic->dev_stats));
break;
default:
fprintf(stderr, "Invalid output device specified\n");
ret = -EINVAL;
break;
}
logic->virt_dev_thread_running = ret == 0;
return ret;
}
/*
int logic_copy_gamepad_status(logic_t *const logic, gamepad_status_t *const out) {
int res = 0;
res = pthread_mutex_lock(&logic->gamepad_mutex);
if (res != 0) {
goto logic_copy_gamepad_status_err;
}
static struct timeval press_time;
if (logic->gamepad.flags & GAMEPAD_STATUS_FLAGS_PRESS_AND_REALEASE_CENTER) {
struct timeval now;
gettimeofday(&now, NULL);
// Calculate elapsed time in milliseconds
int64_t elapsed_time = (now.tv_sec - press_time.tv_sec) * 1000 +
(now.tv_usec - press_time.tv_usec) / 1000;
if (logic->gamepad.center) {
// If the center button is pressed and at least X ms have passed
if (elapsed_time >= PRESS_AND_RELEASE_DURATION_FOR_CENTER_BUTTON_MS) {
logic->gamepad.center = 0;
logic->gamepad.flags &= ~GAMEPAD_STATUS_FLAGS_PRESS_AND_REALEASE_CENTER;
}
} else {
// If the center button is pressed
logic->gamepad.center = 1;
gettimeofday(&press_time, NULL);
}
} else if (logic->gamepad.flags & GAMEPAD_STATUS_FLAGS_OPEN_STEAM_QAM) {
struct timeval now;
gettimeofday(&now, NULL);
static int releasing = 0;
// Calculate elapsed time in milliseconds
int64_t elapsed_time = (now.tv_sec - press_time.tv_sec) * 1000 +
(now.tv_usec - press_time.tv_usec) / 1000;
if ((logic->gamepad.center) && (!logic->gamepad.cross)) {
if ((!releasing) && (elapsed_time >= PRESS_TIME_BEFORE_CROSS_BUTTON_MS)) {
logic->gamepad.center = 1;
logic->gamepad.cross = 1;
press_time = now;
} else if ((releasing) && (elapsed_time >= PRESS_TIME_AFTER_CROSS_BUTTON_MS)) {
logic->gamepad.center = 0;
logic->gamepad.cross = 0;
press_time = now;
logic->gamepad.flags &= ~GAMEPAD_STATUS_FLAGS_OPEN_STEAM_QAM;
}
} else if ((logic->gamepad.center) && (logic->gamepad.cross)) {
if (elapsed_time >= PRESS_TIME_CROSS_BUTTON_MS) {
logic->gamepad.center = 1;
logic->gamepad.cross = 0;
releasing = 1;
press_time = now;
}
} else {
logic->gamepad.center = 1;
logic->gamepad.cross = 0;
releasing = 0;
gettimeofday(&press_time, NULL);
}
}
*out = logic->gamepad;
pthread_mutex_unlock(&logic->gamepad_mutex);
logic_copy_gamepad_status_err:
return res;
}
int logic_begin_status_update(logic_t *const logic) {
int res = 0;
res = pthread_mutex_lock(&logic->gamepad_mutex);
if (res != 0) {
goto logic_begin_status_update_err;
}
logic_begin_status_update_err:
return res;
}
void logic_end_status_update(logic_t *const logic) {
pthread_mutex_unlock(&logic->gamepad_mutex);
}
*/
void logic_request_termination(logic_t *const logic) {
logic->flags |= LOGIC_FLAGS_TERMINATION_REQUESTED;
}
int logic_termination_requested(logic_t *const logic) {
return (logic->flags & LOGIC_FLAGS_TERMINATION_REQUESTED) != 0;
}

View file

@ -539,8 +539,7 @@ static input_dev_t in_iio_dev = {
},
.map = {
.iio_settings = {
.sampling_freq_hz = 1600,
.sampling_freq_hz_frac = 000,
.sampling_freq_hz = "1600.000",
.post_matrix =
/*
// this is the testing but "wrong" mount matrix

View file

@ -31,7 +31,7 @@
static const char* path = "/dev/uhid";
static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74";
//static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74";
static const uint8_t MAC_ADDR[] = { 0x74, 0xe7, 0xd6, 0x3a, 0x47, 0xe8 };
static unsigned char rdesc[] = {
@ -93,6 +93,8 @@ static int create(int fd)
ev.u.create.product = 0x0df2;
ev.u.create.version = 0;
ev.u.create.country = 0;
memset(&ev.u.create.uniq, 0, sizeof(ev.u.create.uniq));
memcpy(&ev.u.create.uniq, (void*)MAC_ADDR, sizeof(MAC_ADDR));
return uhid_write(fd, &ev);
}

View file

@ -1,571 +0,0 @@
#include "virt_evdev.h"
#include "devices_status.h"
static const char* uinput_path = "/dev/uinput";
static int create_gamepad_uinput(void) {
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
if(fd < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_setup dev = {0};
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
#if defined(OUTPUT_DEV_BUS_TYPE)
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
#else
dev.id.bustype = BUS_VIRTUAL;
#endif
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
#if defined(OUTPUT_DEV_VERSION)
dev.id.version = OUTPUT_DEV_VERSION;
#endif
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
//}
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
}
#if !defined(UI_SET_PHYS_STR)
#warning Will not change the PHYS
#endif
#if !defined(UI_SET_UNIQ_STR)
#warning Will not change the UNIQ
#endif
#if defined(UI_SET_PHYS_STR)
ioctl(fd, UI_SET_PHYS_STR(18), PHYS_STR);
#else
fprintf(stderr, "UI_SET_PHYS_STR unavailable.\n");
#endif
#if defined(UI_SET_UNIQ_STR)
ioctl(fd, UI_SET_UNIQ_STR(18), PHYS_STR);
#else
fprintf(stderr, "UI_SET_UNIQ_STR unavailable.\n");
#endif
//ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_BUTTONPAD);
ioctl(fd, UI_SET_EVBIT, EV_ABS);
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_EVBIT, EV_SYN);
#if defined(INCLUDE_TIMESTAMP)
ioctl(fd, UI_SET_EVBIT, EV_MSC);
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
#endif
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_ABSBIT, ABS_HAT0X);
ioctl(fd, UI_SET_ABSBIT, ABS_HAT0Y);
ioctl(fd, UI_SET_ABSBIT, ABS_HAT2X);
ioctl(fd, UI_SET_ABSBIT, ABS_HAT2Y);
ioctl(fd, UI_SET_KEYBIT, BTN_SOUTH);
ioctl(fd, UI_SET_KEYBIT, BTN_EAST);
ioctl(fd, UI_SET_KEYBIT, BTN_NORTH);
ioctl(fd, UI_SET_KEYBIT, BTN_WEST);
ioctl(fd, UI_SET_KEYBIT, BTN_TL);
ioctl(fd, UI_SET_KEYBIT, BTN_TR);
ioctl(fd, UI_SET_KEYBIT, BTN_TL2);
ioctl(fd, UI_SET_KEYBIT, BTN_TR2);
ioctl(fd, UI_SET_KEYBIT, BTN_SELECT);
ioctl(fd, UI_SET_KEYBIT, BTN_START);
ioctl(fd, UI_SET_KEYBIT, BTN_MODE);
ioctl(fd, UI_SET_KEYBIT, BTN_THUMBL);
ioctl(fd, UI_SET_KEYBIT, BTN_THUMBR);
ioctl(fd, UI_SET_KEYBIT, BTN_GEAR_DOWN);
ioctl(fd, UI_SET_KEYBIT, BTN_GEAR_UP);
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_UP);
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_DOWN);
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_LEFT);
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_RIGHT);
const struct uinput_abs_setup devAbsX = {
.code = ABS_X,
.absinfo = {
.value = 0,
.minimum = -32768,
.maximum = +32768,
.resolution = 1,
.fuzz = 16,
.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsX) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsY = {
.code = ABS_Y,
.absinfo = {
.value = 0,
.minimum = -32768,
.maximum = +32768,
.resolution = 1,
.fuzz = 16,
.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsY) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsZ = {
.code = ABS_Z,
.absinfo = {
.value = 0,
.minimum = 0,
.maximum = 255,
.resolution = 1,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsZ) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsRX = {
.code = ABS_RX,
.absinfo = {
.value = 0,
.minimum = -32768,
.maximum = +32768,
.resolution = 1,
.fuzz = 16,
.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsRX) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsRY = {
.code = ABS_RY,
.absinfo = {
.value = -1,
.minimum = -32768,
.maximum = +32768,
.resolution = 1,
.fuzz = 16,
.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsRY) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsRZ = {
.code = ABS_RZ,
.absinfo = {
.value = 0,
.minimum = 0,
.maximum = 255,
.resolution = 1,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsRZ) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsHat0X = {
.code = ABS_HAT0X,
.absinfo = {
.value = 0,
.minimum = -1,
.maximum = 1,
.resolution = 1,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat0X) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsHat0Y = {
.code = ABS_HAT0Y,
.absinfo = {
.value = 0,
.minimum = -1,
.maximum = 1,
.resolution = 1,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat0Y) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsHat2X = {
.code = ABS_HAT2X,
.absinfo = {
.value = 0,
.minimum = 0,
.maximum = 255,
.resolution = 51,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat2X) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
struct uinput_abs_setup devAbsHat2Y = {
.code = ABS_HAT2Y,
.absinfo = {
.value = 0,
.minimum = 0,
.maximum = 255,
.resolution = 51,
//.fuzz = 16,
//.flat = 128,
}
};
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat2Y) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
if(ioctl(fd, UI_DEV_CREATE) < 0) {
fd = -1;
close(fd);
goto create_gamepad_uinput_err;
}
create_gamepad_uinput_err:
return fd;
}
static int create_imu_uinput() {
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
if(fd < 0) {
fd = -1;
close(fd);
goto create_imu_uinput_err;
}
struct uinput_setup dev = {0};
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
#if defined(OUTPUT_DEV_BUS_TYPE)
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
#else
dev.id.bustype = BUS_VIRTUAL;
#endif
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
#if defined(OUTPUT_DEV_VERSION)
dev.id.version = OUTPUT_DEV_VERSION;
#endif
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
//}
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
}
#if !defined(UI_SET_PHYS_STR)
#warning Will not change the PHYS
#endif
#if !defined(UI_SET_UNIQ_STR)
#warning Will not change the UNIQ
#endif
#if defined(UI_SET_PHYS_STR)
ioctl(fd, UI_SET_PHYS_STR(18), PHYS_STR);
#else
fprintf(stderr, "UI_SET_PHYS_STR unavailable.\n");
#endif
#if defined(UI_SET_UNIQ_STR)
ioctl(fd, UI_SET_UNIQ_STR(18), PHYS_STR);
#else
fprintf(stderr, "UI_SET_UNIQ_STR unavailable.\n");
#endif
ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_ACCELEROMETER);
ioctl(fd, UI_SET_EVBIT, EV_ABS);
#if defined(INCLUDE_TIMESTAMP)
ioctl(fd, UI_SET_EVBIT, EV_MSC);
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
#endif
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_imu_uinput_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_imu_uinput_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_imu_uinput_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_imu_uinput_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_imu_uinput_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_imu_uinput_err;
}
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
fd = -1;
close(fd);
goto create_imu_uinput_err;
}
if(ioctl(fd, UI_DEV_CREATE) < 0) {
fd = -1;
close(fd);
goto create_imu_uinput_err;
}
create_imu_uinput_err:
return fd;
}
void *virt_evdev_thread_func(void *ptr) {
devices_status_t *const stats = (devices_status_t*)ptr;
const int gamepad_fd = create_gamepad_uinput();
if (gamepad_fd < 0) {
fprintf(stderr, "Unable to create the virtual evdev gamepad device: %d\n", gamepad_fd);
return NULL;
}
const int imu_fd = create_imu_uinput();
if (imu_fd < 0) {
fprintf(stderr, "Unable to create the virtual evdev imu device: %d\n", gamepad_fd);
return NULL;
}
for (;;) {
usleep(1250);
const int lock_res = pthread_mutex_lock(&stats->mutex);
if (lock_res != 0) {
printf("Unable to lock gamepad mutex: %d\n", lock_res);
continue;
}
// main virtual device logic
{
//event(fd, &stats->gamepad);
if (stats->gamepad.connected) {
// TODO: do whatever it takes...
} else {
pthread_mutex_unlock(&stats->mutex);
printf("kbd&mouse has been terminated: closing the device.\n");
break;
}
}
pthread_mutex_unlock(&stats->mutex);
}
return NULL;
}
/*
static void emit_ev(output_dev_t *const out_dev, const in_message_t *const msg) {
// if events are flagged as do not emit... Do NOT emit!
if (msg->flags & INPUT_FILTER_FLAGS_DO_NOT_EMIT) {
return;
}
int fd = out_dev->gamepad_fd;
const uint32_t msg_flags = msg->data.event.ev_flags;
if ((msg_flags & EV_MESSAGE_FLAGS_IMU) != 0) {
fd = out_dev->imu_fd;
} else if ((msg_flags & EV_MESSAGE_FLAGS_MOUSE) != 0) {
fd = out_dev->mouse_fd;
} else {
fd = out_dev->gamepad_fd;
}
for (uint32_t i = 0; i < msg->data.event.ev_count; ++i) {
struct input_event ev = {
.code = msg->data.event.ev[i].code,
.type = msg->data.event.ev[i].type,
.value = msg->data.event.ev[i].value,
.time = msg->data.event.ev[i].time,
};
if ((msg_flags & EV_MESSAGE_FLAGS_PRESERVE_TIME) == 0) {
gettimeofday(&ev.time, NULL);
}
#if defined(INCLUDE_OUTPUT_DEBUG)
printf(
"Output: Received event %s (%s): %d\n",
libevdev_event_type_get_name(ev.type),
libevdev_event_code_get_name(ev.type, ev.code),
ev.value
);
#endif
const ssize_t written = write(fd, (void*)&ev, sizeof(ev));
if (written != sizeof(ev)) {
fprintf(
stderr,
"Error writing event %s %s %d: written %ld bytes out of %ld\n",
libevdev_event_type_get_name(ev.type),
libevdev_event_code_get_name(ev.type, ev.code),
ev.value,
written,
sizeof(ev)
);
}
}
#if defined(INCLUDE_TIMESTAMP)
gettimeofday(&now, NULL);
const struct input_event timestamp_ev = {
.code = MSC_TIMESTAMP,
.type = EV_MSC,
.value = (now.tv_sec - secAtInit)*1000000 + (now.tv_usec - usecAtInit),
.time = now,
};
const ssize_t timestamp_written = write(fd, (void*)&timestamp_ev, sizeof(timestamp_ev));
if (timestamp_written != sizeof(timestamp_ev)) {
fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", timestamp_written, sizeof(timestamp_ev));
}
#endif
struct timeval now = {0};
gettimeofday(&now, NULL);
const struct input_event syn_ev = {
.code = SYN_REPORT,
.type = EV_SYN,
.value = 0,
.time = now,
};
const ssize_t sync_written = write(fd, (void*)&syn_ev, sizeof(syn_ev));
if (sync_written != sizeof(syn_ev)) {
fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev));
}
}
*/

View file

@ -1,47 +0,0 @@
#pragma once
#include "rogue_enemy.h"
#undef VIRT_EVDEV_DEBUG
// Emulates a "Generic" controller:
#define OUTPUT_DEV_NAME "ROGueENEMY"
#define OUTPUT_DEV_VENDOR_ID 0x108c
#define OUTPUT_DEV_PRODUCT_ID 0x0323
#define OUTPUT_DEV_VERSION 0x0111
/*
// Emulates a steam controller
#define OUTPUT_DEV_NAME "Steam Controller"
#define OUTPUT_DEV_VENDOR_ID 0x28de
#define OUTPUT_DEV_PRODUCT_ID 0x1102
#define OUTPUT_DEV_VERSION 0x0111
#define OUTPUT_DEV_BUS_TYPE BUS_USB
*/
/*
//Emulates an Xbox one wireless controller:
#define OUTPUT_DEV_NAME "Xbox Wireless Controller"
#define OUTPUT_DEV_VENDOR_ID 0x045e
#define OUTPUT_DEV_PRODUCT_ID 0x028e
#define OUTPUT_DEV_BUS_TYPE BUS_BLUETOOTH
*/
/*
// Emulates a DualShock controller
#define OUTPUT_DEV_NAME "Sony Interactive Entertainment DualSense Wireless Controller"
#define OUTPUT_DEV_VENDOR_ID 0x054c
#define OUTPUT_DEV_PRODUCT_ID 0x0ce6
#define OUTPUT_DEV_VERSION 0x8111
#define OUTPUT_DEV_BUS_TYPE BUS_USB
*/
#define PHYS_STR "00:11:22:33:44:55"
#define ACCEL_RANGE 512
#define GYRO_RANGE 2000 // max range is +/- 35 radian/s
#define GYRO_DEADZONE 1 // degrees/s to count as zero movement
void *virt_evdev_thread_func(void *ptr);

View file

@ -1,126 +0,0 @@
#include "virt_mouse_kbd.h"
#include "devices_status.h"
static const char* uinput_path = "/dev/uinput";
static int create_mouse_uinput(void) {
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
if(fd < 0) {
fd = -1;
close(fd);
goto create_mouse_uinput_err;
}
struct uinput_setup dev = {0};
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
#if defined(OUTPUT_DEV_BUS_TYPE)
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
#else
dev.id.bustype = BUS_VIRTUAL;
#endif
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
#if defined(OUTPUT_DEV_VERSION)
dev.id.version = OUTPUT_DEV_VERSION;
#endif
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
//}
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
}
#if !defined(UI_SET_PHYS_STR)
#warning Will not change the PHYS
#endif
#if !defined(UI_SET_UNIQ_STR)
#warning Will not change the UNIQ
#endif
ioctl(fd, UI_SET_EVBIT, EV_REL);
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_EVBIT, EV_MSC);
ioctl(fd, UI_SET_EVBIT, EV_SYN);
#if defined(INCLUDE_TIMESTAMP)
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
#endif
ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
//ioctl(fd, UI_SET_KEYBIT, BTN_SIDE);
//ioctl(fd, UI_SET_KEYBIT, BTN_EXTRA);
ioctl(fd, UI_SET_RELBIT, REL_X);
ioctl(fd, UI_SET_RELBIT, REL_Y);
ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
fd = -1;
close(fd);
goto create_mouse_uinput_err;
}
if(ioctl(fd, UI_DEV_CREATE) < 0) {
fd = -1;
close(fd);
goto create_mouse_uinput_err;
}
create_mouse_uinput_err:
return fd;
}
static int create_kb_uinput(void) {
return -EINVAL;
}
void *virt_mouse_kbd_thread_func(void *ptr) {
devices_status_t *const stats = (devices_status_t*)ptr;
const int mouse_fd = create_mouse_uinput();
if (mouse_fd < 0) {
fprintf(stderr, "Unable to create the mouse virtual evdev: %d\n", mouse_fd);
return NULL;
}
keyboard_status_t prev_kbd_stats;
kbd_status_init(&prev_kbd_stats);
for (;;) {
usleep(1250);
const int lock_res = pthread_mutex_lock(&stats->mutex);
if (lock_res != 0) {
printf("Unable to lock gamepad mutex: %d\n", lock_res);
continue;
}
// main virtual device logic
{
//event(fd, &stats->gamepad);
if (stats->kbd.connected) {
// TODO: do whatever it takes...
} else {
pthread_mutex_unlock(&stats->mutex);
printf("kbd&mouse has been terminated: closing the device.\n");
break;
}
}
pthread_mutex_unlock(&stats->mutex);
}
return NULL;
}

View file

@ -1,15 +0,0 @@
#pragma once
#include "rogue_enemy.h"
#undef VIRT_EVDEV_DEBUG
// Emulates a "Generic" controller:
#define OUTPUT_DEV_NAME "ROGueENEMY"
#define OUTPUT_DEV_VENDOR_ID 0x108c
#define OUTPUT_DEV_PRODUCT_ID 0x0323
#define OUTPUT_DEV_VERSION 0x0111
#define PHYS_STR "00:11:22:33:44:55"
void *virt_mouse_kbd_thread_func(void *ptr);