WIP: input device
This commit is contained in:
parent
75abf3c6e8
commit
d6aee2c63d
9 changed files with 151 additions and 58 deletions
4
Makefile
4
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
CFLAGS=-g -std=c11 -pedantic -Wall # -Werror
|
||||
CFLAGS=-g -O0 -std=c11 -fPIE -pedantic -Wall # -Werror
|
||||
LDFLAGS=-lpthread
|
||||
CC=gcc
|
||||
OBJECTS=main.o input_dev.o output_dev.o
|
||||
OBJECTS=main.o input_dev.o output_dev.o queue.o
|
||||
TARGET=rogue_enemy
|
||||
|
||||
all: $(TARGET)
|
||||
|
|
|
|||
15
input_dev.c
15
input_dev.c
|
|
@ -9,6 +9,21 @@
|
|||
|
||||
#include "input_dev.h"
|
||||
|
||||
void *input_dev_thread_func(void *ptr) {
|
||||
input_dev_t *out_dev = (input_dev_t*)ptr;
|
||||
|
||||
for (;;) {
|
||||
uint32_t flags = out_dev->crtl_flags;
|
||||
if (flags & INPUT_DEV_CTRL_FLAG_EXIT) {
|
||||
out_dev->crtl_flags &= ~INPUT_DEV_CTRL_FLAG_EXIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int open_and_hide_input() {
|
||||
int fd = -1;
|
||||
char buf[256];
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
#define INPUT_DEV_CTRL_FLAG_EXIT 0x00000001U
|
||||
|
||||
typedef struct input_dev {
|
||||
pthread_mutex_t ctrl_mutex;
|
||||
uint32_t crtl_flags;
|
||||
volatile uint32_t crtl_flags;
|
||||
} input_dev_t;
|
||||
|
||||
void *input_dev_thread_func(void *ptr);
|
||||
|
||||
int open_and_hide_input();
|
||||
56
main.c
56
main.c
|
|
@ -3,30 +3,44 @@
|
|||
#include "input_dev.h"
|
||||
#include "output_dev.h"
|
||||
|
||||
ev_queue_t imu_ev;
|
||||
ev_queue_t gamepad_ev;
|
||||
|
||||
output_dev_t imu_dev = {
|
||||
.fd = -1,
|
||||
.ctrl_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
.crtl_flags = 0x00000000U,
|
||||
.max_events = 32,
|
||||
.events_list = NULL,
|
||||
.queue = &imu_ev,
|
||||
};
|
||||
|
||||
output_dev_t gamepadd_dev = {
|
||||
.fd = -1,
|
||||
.ctrl_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
.crtl_flags = 0x00000000U,
|
||||
.max_events = 32,
|
||||
.events_list = NULL,
|
||||
.queue = &gamepad_ev,
|
||||
};
|
||||
|
||||
input_dev_t in_asus_kb_1_dev = {
|
||||
.crtl_flags = 0x00000000U,
|
||||
};
|
||||
|
||||
input_dev_t in_asus_kb_2_dev = {
|
||||
.crtl_flags = 0x00000000U,
|
||||
};
|
||||
|
||||
input_dev_t in_asus_kb_3_dev = {
|
||||
.crtl_flags = 0x00000000U,
|
||||
};
|
||||
|
||||
input_dev_t in_asus_kb_4_dev = {
|
||||
.crtl_flags = 0x00000000U,
|
||||
};
|
||||
|
||||
input_dev_t in_xbox_dev = {
|
||||
.crtl_flags = 0x00000000U,
|
||||
};
|
||||
|
||||
void request_termination() {
|
||||
pthread_mutex_lock(&imu_dev.ctrl_mutex);
|
||||
imu_dev.crtl_flags |= OUTPUT_DEV_CTRL_FLAG_EXIT;
|
||||
pthread_mutex_unlock(&imu_dev.ctrl_mutex);
|
||||
|
||||
pthread_mutex_lock(&gamepadd_dev.ctrl_mutex);
|
||||
gamepadd_dev.crtl_flags |= OUTPUT_DEV_CTRL_FLAG_EXIT;
|
||||
pthread_mutex_unlock(&gamepadd_dev.ctrl_mutex);
|
||||
}
|
||||
|
||||
void sig_handler(int signo)
|
||||
|
|
@ -38,23 +52,11 @@ void sig_handler(int signo)
|
|||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
imu_dev.events_list = calloc(sizeof(struct input_event), imu_dev.max_events);
|
||||
if (imu_dev.events_list == NULL) {
|
||||
fprintf(stderr, "Unable to allocate events list for IMU output\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
imu_dev.events_list = calloc(sizeof(struct input_event), imu_dev.max_events);
|
||||
if (gamepadd_dev.events_list == NULL) {
|
||||
free(imu_dev.events_list);
|
||||
fprintf(stderr, "Unable to allocate events list for gamepad output\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
imu_dev.fd = create_output_dev("/dev/uinput", "Virtual IMU - ROGueENEMY", output_dev_imu);
|
||||
if (imu_dev.fd < 0) {
|
||||
free(imu_dev.events_list);
|
||||
free(gamepadd_dev.events_list);
|
||||
// TODO: free(imu_dev.events_list);
|
||||
// TODO: free(gamepadd_dev.events_list);
|
||||
fprintf(stderr, "Unable to create IMU virtual device\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -104,8 +106,8 @@ imu_thread_err:
|
|||
if (!(imu_dev.fd < 0))
|
||||
close(imu_dev.fd);
|
||||
|
||||
free(imu_dev.events_list);
|
||||
free(gamepadd_dev.events_list);
|
||||
// TODO: free(imu_dev.events_list);
|
||||
// TODO: free(gamepadd_dev.events_list);
|
||||
|
||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
20
output_dev.c
20
output_dev.c
|
|
@ -150,25 +150,11 @@ void *output_dev_thread_func(void *ptr) {
|
|||
output_dev_t *out_dev = (output_dev_t*)ptr;
|
||||
|
||||
for (;;) {
|
||||
pthread_mutex_lock(&out_dev->ctrl_mutex);
|
||||
|
||||
if (out_dev->crtl_flags & OUTPUT_DEV_CTRL_FLAG_EXIT) {
|
||||
pthread_mutex_unlock(&out_dev->ctrl_mutex);
|
||||
uint32_t flags = out_dev->crtl_flags;
|
||||
if (flags & OUTPUT_DEV_CTRL_FLAG_EXIT) {
|
||||
out_dev->crtl_flags &= ~OUTPUT_DEV_CTRL_FLAG_EXIT;
|
||||
break;
|
||||
} else if (out_dev->crtl_flags & OUTPUT_DEV_CTRL_FLAG_DATA) {
|
||||
const uint32_t events_count = out_dev->events_count;
|
||||
for (uint32_t i = 0; i < events_count; ++i) {
|
||||
// send the event
|
||||
write(out_dev->fd, (const void*)&out_dev->events_list[i], sizeof(struct input_event));
|
||||
|
||||
out_dev->events_count -= 1;
|
||||
}
|
||||
|
||||
// clear out the data present flag
|
||||
out_dev->crtl_flags &= ~OUTPUT_DEV_CTRL_FLAG_DATA;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&out_dev->ctrl_mutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "rogue_enemy.h"
|
||||
#include "queue.h"
|
||||
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x4532
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x0924
|
||||
|
|
@ -21,12 +22,9 @@ typedef enum output_dev_type {
|
|||
typedef struct output_dev {
|
||||
int fd;
|
||||
|
||||
pthread_mutex_t ctrl_mutex;
|
||||
uint32_t crtl_flags;
|
||||
volatile uint32_t crtl_flags;
|
||||
|
||||
uint32_t max_events;
|
||||
uint32_t events_count;
|
||||
struct input_event *events_list;
|
||||
ev_queue_t *queue;
|
||||
} output_dev_t;
|
||||
|
||||
int create_output_dev(const char* uinput_path, const char* name, output_dev_type_t type);
|
||||
|
|
|
|||
67
queue.c
Normal file
67
queue.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#include "queue.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int queue_init(ev_queue_t* queue, key_t sem_key, size_t max_elements) {
|
||||
queue->array_size = max_elements;
|
||||
queue->array = calloc(sizeof(void*), max_elements);
|
||||
if (queue->array == NULL) {
|
||||
perror("calloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int semid = semget(sem_key, 1, IPC_CREAT | 0666);
|
||||
if (semid < 0)
|
||||
{
|
||||
free(queue->array);
|
||||
perror("semget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (semctl(semid, 0, SETVAL, 1) < 0)
|
||||
{
|
||||
free(queue->array);
|
||||
perror("semctl");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void queue_destroy(ev_queue_t* queue) {
|
||||
free(queue->array);
|
||||
queue->array = NULL;
|
||||
}
|
||||
|
||||
int queue_push(ev_queue_t* queue, void *in_item) {
|
||||
struct sembuf sem_op;
|
||||
sem_op.sem_num = 0;
|
||||
sem_op.sem_op = -1;
|
||||
sem_op.sem_flg = 0;
|
||||
semop(queue->sem_id, &sem_op, 1);
|
||||
|
||||
queue->array[queue->in] = in_item;
|
||||
queue->in = (queue->in + 1) % queue->array_size;
|
||||
|
||||
sem_op.sem_num = 0;
|
||||
sem_op.sem_op = 1;
|
||||
semop(queue->sem_id, &sem_op, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int queue_pop(ev_queue_t* queue, void **out_item) {
|
||||
struct sembuf sem_op;
|
||||
sem_op.sem_num = 0;
|
||||
sem_op.sem_op = -1;
|
||||
sem_op.sem_flg = 0;
|
||||
semop(queue->sem_id, &sem_op, 1);
|
||||
|
||||
*out_item = queue->array[queue->out];
|
||||
queue->out = (queue->out + 1) % queue->array_size;
|
||||
|
||||
sem_op.sem_num = 0;
|
||||
sem_op.sem_op = 1;
|
||||
semop(queue->sem_id, &sem_op, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
21
queue.h
Normal file
21
queue.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "rogue_enemy.h"
|
||||
|
||||
typedef struct ev_queue {
|
||||
int sem_id;
|
||||
|
||||
size_t in;
|
||||
size_t out;
|
||||
|
||||
size_t array_size;
|
||||
void** array;
|
||||
} ev_queue_t;
|
||||
|
||||
int queue_init(ev_queue_t* queue, key_t sem_key, size_t max_elements);
|
||||
|
||||
void queue_destroy(ev_queue_t* queue);
|
||||
|
||||
int queue_push(ev_queue_t* queue, void *in_item);
|
||||
|
||||
int queue_pop(ev_queue_t* queue, void **out_item);
|
||||
|
|
@ -1,14 +1,17 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#include <linux/uinput.h>
|
||||
#include <linux/input.h>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue