Added libevdev node
This commit is contained in:
parent
d3a3217e88
commit
65769a7442
4
Makefile
4
Makefile
|
@ -1,4 +1,4 @@
|
||||||
DEPS =
|
DEPS = libevdev
|
||||||
CFLAGS = -Wall -Wextra
|
CFLAGS = -Wall -Wextra
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS += -Og -gdwarf-2
|
CFLAGS += -Og -gdwarf-2
|
||||||
|
@ -10,7 +10,7 @@ CPPFLAGS += $(shell pkg-config --cflags $(DEPS))
|
||||||
LDLIBS += $(shell pkg-config --libs $(DEPS))
|
LDLIBS += $(shell pkg-config --libs $(DEPS))
|
||||||
INTERP ?=
|
INTERP ?=
|
||||||
MAIN = main
|
MAIN = main
|
||||||
OBJS = main.o events.o processing.o graph.o nodes/getchar.o nodes/print.o
|
OBJS = main.o events.o processing.o graph.o nodes/getchar.o nodes/print.o nodes/evdev.o
|
||||||
|
|
||||||
all: $(MAIN)
|
all: $(MAIN)
|
||||||
|
|
||||||
|
|
9
main.c
9
main.c
|
@ -1,6 +1,7 @@
|
||||||
#include "processing.h"
|
#include "processing.h"
|
||||||
#include "nodes/print.h"
|
#include "nodes/print.h"
|
||||||
#include "nodes/getchar.h"
|
#include "nodes/getchar.h"
|
||||||
|
#include "nodes/evdev.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char ** argv)
|
main(int argc, char ** argv)
|
||||||
|
@ -17,15 +18,19 @@ main(int argc, char ** argv)
|
||||||
|
|
||||||
GraphNode * input_node = graph_node_new(&nodespec_getchar);
|
GraphNode * input_node = graph_node_new(&nodespec_getchar);
|
||||||
GraphNode * output_node = graph_node_new(&nodespec_print);
|
GraphNode * output_node = graph_node_new(&nodespec_print);
|
||||||
GraphChannel chan;
|
GraphNode * evdev_node = graph_node_new(&nodespec_evdev);
|
||||||
graph_channel_init(&chan, input_node, 0, output_node, 0);
|
GraphChannel chan[2];
|
||||||
|
graph_channel_init(&chan[0], input_node, 0, output_node, 0);
|
||||||
|
graph_channel_init(&chan[1], evdev_node, 0, output_node, 1);
|
||||||
graph_node_register_io(input_node, &state);
|
graph_node_register_io(input_node, &state);
|
||||||
graph_node_register_io(output_node, &state);
|
graph_node_register_io(output_node, &state);
|
||||||
|
graph_node_register_io(evdev_node, &state);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
process_iteration(&state);
|
process_iteration(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graph_node_delete(evdev_node);
|
||||||
graph_node_delete(output_node);
|
graph_node_delete(output_node);
|
||||||
graph_node_delete(input_node);
|
graph_node_delete(input_node);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include <libevdev/libevdev.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "evdev.h"
|
||||||
|
#include "../processing.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GraphNode as_GraphNode;
|
||||||
|
IOHandling subscription;
|
||||||
|
struct libevdev *dev;
|
||||||
|
int fd;
|
||||||
|
} EvdevGraphNode;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_io(EventPositionBase * self, int fd, bool is_output)
|
||||||
|
{
|
||||||
|
(void) is_output;
|
||||||
|
(void) fd;
|
||||||
|
EvdevGraphNode * node = DOWNCAST(EvdevGraphNode, GraphNode, DOWNCAST(GraphNode, EventPositionBase, self));
|
||||||
|
int err = 0;
|
||||||
|
AbsoluteTime realtime;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &realtime.absolute);
|
||||||
|
AbsoluteTime monotime = get_current_time();
|
||||||
|
RelativeTime realtime_adj = absolute_time_sub_absolute(realtime, monotime);
|
||||||
|
while (!err) {
|
||||||
|
struct input_event buf;
|
||||||
|
err = libevdev_next_event(node->dev, LIBEVDEV_READ_FLAG_NORMAL, &buf);
|
||||||
|
if (err) {
|
||||||
|
if (err == -EAGAIN || err == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node->subscription.enabled = false;
|
||||||
|
if (err < 0) {
|
||||||
|
errno = -err;
|
||||||
|
perror("Failed to read evdev event");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
realtime.absolute.tv_sec = buf.time.tv_sec;
|
||||||
|
realtime.absolute.tv_nsec = buf.time.tv_usec * (long) 1000;
|
||||||
|
monotime = absolute_time_sub_relative(realtime, realtime_adj);
|
||||||
|
EventData data = {
|
||||||
|
.code = {
|
||||||
|
.ns = 1,
|
||||||
|
.value = (((int32_t) buf.type) << 16) | buf.code,
|
||||||
|
},
|
||||||
|
.ttl = 100,
|
||||||
|
.priority = 10,
|
||||||
|
.payload = buf.value,
|
||||||
|
.modifiers = EMPTY_MODIFIER_SET,
|
||||||
|
.time = monotime,
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < node->as_GraphNode.outputs.length; ++i) {
|
||||||
|
EventNode *ev = event_create(&data);
|
||||||
|
if (!ev) {
|
||||||
|
perror("Failed to create event");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ev->position = &node->as_GraphNode.outputs.elements[i]->as_EventPositionBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GraphNode *
|
||||||
|
create(GraphNodeSpecification * spec)
|
||||||
|
{
|
||||||
|
EvdevGraphNode * node = calloc(1, sizeof(EvdevGraphNode));
|
||||||
|
if (!node) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int fd = open("/dev/input/event7", O_RDONLY | O_NONBLOCK);
|
||||||
|
int err;
|
||||||
|
if ((err = libevdev_new_from_fd(fd, &node->dev)) < 0) {
|
||||||
|
errno = -err;
|
||||||
|
free(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*node = (EvdevGraphNode) {
|
||||||
|
.as_GraphNode = {
|
||||||
|
.as_EventPositionBase = {
|
||||||
|
.handle_event = NULL,
|
||||||
|
.waiting_new_event = false,
|
||||||
|
},
|
||||||
|
.specification = spec,
|
||||||
|
.inputs = EMPTY_GRAPH_CHANNEL_LIST,
|
||||||
|
.outputs = EMPTY_GRAPH_CHANNEL_LIST,
|
||||||
|
},
|
||||||
|
.subscription = {
|
||||||
|
.self = &node->as_GraphNode.as_EventPositionBase,
|
||||||
|
.handle_io = handle_io,
|
||||||
|
.enabled = true,
|
||||||
|
},
|
||||||
|
.dev = node->dev,
|
||||||
|
.fd = fd,
|
||||||
|
};
|
||||||
|
return &node->as_GraphNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy
|
||||||
|
(GraphNodeSpecification * self, GraphNode * target)
|
||||||
|
{
|
||||||
|
(void) self;
|
||||||
|
EvdevGraphNode * node = DOWNCAST(EvdevGraphNode, GraphNode, target);
|
||||||
|
if (node->dev) {
|
||||||
|
libevdev_free(node->dev);
|
||||||
|
node->dev = NULL;
|
||||||
|
close(node->fd);
|
||||||
|
}
|
||||||
|
free(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_io(GraphNodeSpecification * self, GraphNode * target, ProcessingState * state)
|
||||||
|
{
|
||||||
|
(void) self;
|
||||||
|
EvdevGraphNode * node = DOWNCAST(EvdevGraphNode, GraphNode, target);
|
||||||
|
io_subscription_list_add(&state->wait_input, node->fd, &node->subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphNodeSpecification nodespec_evdev = (GraphNodeSpecification) {
|
||||||
|
.create = &create,
|
||||||
|
.destroy = &destroy,
|
||||||
|
.register_io = ®ister_io,
|
||||||
|
.name = "evdev",
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef NODES_EVDEV_H_
|
||||||
|
#define NODES_EVDEV_H_
|
||||||
|
|
||||||
|
#include "../graph.h"
|
||||||
|
|
||||||
|
extern GraphNodeSpecification nodespec_evdev;
|
||||||
|
|
||||||
|
#endif /* end of include guard: NODES_EVDEV_H_ */
|
Loading…
Reference in New Issue