summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/conversion_main_loop.c')
-rw-r--r--src/server/conversion_main_loop.c331
1 files changed, 192 insertions, 139 deletions
diff --git a/src/server/conversion_main_loop.c b/src/server/conversion_main_loop.c
index b5b97db..c948954 100644
--- a/src/server/conversion_main_loop.c
+++ b/src/server/conversion_main_loop.c
@@ -1,192 +1,245 @@
-#include <fcntl.h>
+/**** POSIX *******************************************************************/
+#include <sys/select.h>
+
#include <errno.h>
#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include "pervasive.h"
-#include "error.h"
-#include "config.h"
-#include "input.h"
-#include "relabsd_device.h"
-static void handle_relative_axis_event
-(
- struct relabsd_config * const conf,
- const struct relabsd_device * const dev,
- unsigned int const input_type,
- unsigned int const input_code,
- int value
-)
-{
- unsigned int abs_code;
- enum relabsd_axis rad_code;
+/**** RELABSD *****************************************************************/
+#include <relabsd/debug.h>
+#include <relabsd/server.h>
- rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code);
+#include <relabsd/config/parameters.h>
- switch (relabsd_config_filter(conf, rad_code, &value))
- {
- case -1:
- /* 'conf' doesn't want the event to be transmitted. */
- break;
-
- case 0:
- /* 'conf' wants the event to be transmitted as is. */
- relabsd_device_write_evdev_event(dev, input_type, input_code, value);
- break;
-
- case 1:
- /* 'conf' allows the value to be emitted */
- relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value);
- break;
- }
-}
+#include <relabsd/device/axis.h>
+#include <relabsd/device/physical_device.h>
+#include <relabsd/device/virtual_device.h>
+/******************************************************************************/
+/**** LOCAL FUNCTIONS *********************************************************/
+/******************************************************************************/
static void convert_input
(
- struct relabsd_config * const conf,
- struct relabsd_input * const input,
- const struct relabsd_device * const dev
+ struct relabsd_server server [const restrict static 1]
)
{
unsigned int input_type, input_code;
int value;
- RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Handling input events...");
-
- input->timed_out = 1;
+ if
+ (
+ relabsd_physical_device_read
+ (
+ &(server->physical_device),
+ &input_type,
+ &input_code,
+ &value
+ )
+ < 0
+ )
+ {
+ return;
+ }
- while (RELABSD_RUN == 1)
+ if (input_type == EV_REL)
{
- if (conf->enable_timeout)
- {
- switch (relabsd_input_wait_for_next_event(input, conf))
- {
- case 1:
- input->timed_out = 0;
- break;
-
- case 0:
- relabsd_device_set_axes_to_zero(dev, conf);
- input->timed_out = 1;
- break;
-
- case -1:
- continue;
- }
- }
+ unsigned int abs_code;
+ enum relabsd_axis_name axis_name;
- if (relabsd_input_read(input, &input_type, &input_code, &value) < 0)
- {
- /*
- * The next event should not be retransmitted, or some kind of error
- * happened.
- */
- /* TODO: error handling. */
- continue;
- }
+ axis_name =
+ relabsd_axis_name_and_evdev_abs_from_evdev_rel(input_code, &abs_code);
- if (input_type == EV_REL)
+ if (axis_name == RELABSD_UNKNOWN)
{
- /* We might have to convert the event. */
- handle_relative_axis_event(conf, dev, input_type, input_code, value);
+ return;
}
- else
+
+ switch
+ (
+ relabsd_axis_filter_new_value
+ (
+ relabsd_parameters_get_axis(axis_name, &(server->parameters)),
+ &value
+ )
+ )
{
- /* Any other event is retransmitted as is. */
- relabsd_device_write_evdev_event(dev, input_type, input_code, value);
+ case -1:
+ /* Doesn't want the event to be transmitted. */
+ return;
+
+ case 1:
+ (void) relabsd_virtual_device_write_evdev_event
+ (
+ &(server->virtual_device),
+ EV_ABS,
+ abs_code,
+ value
+ );
+ return;
+
+ case 0:
+ (void) relabsd_virtual_device_write_evdev_event
+ (
+ &(server->virtual_device),
+ input_type,
+ input_code,
+ value
+ );
+ return;
}
}
+ else
+ {
+ /* Any other event is retransmitted as is. */
+ (void) relabsd_virtual_device_write_evdev_event
+ (
+ &(server->virtual_device),
+ input_type,
+ input_code,
+ value
+ );
+ }
}
-int relabsd_server_conversion_loop
+static void reset_axes
(
- struct relabsd_server server [const static 1]
+ struct relabsd_server server [const restrict static 1]
)
{
- return 0;
+ relabsd_virtual_device_set_axes_to_zero
+ (
+ &(server->parameters),
+ &(server->virtual_device)
+ );
}
-
-int wait_for_next_event
+static int wait_for_next_event
(
- const struct relabsd_physical_device * const input,
- const struct relabsd_config * const config
+ fd_set ready_to_read [const restrict static 1],
+ struct relabsd_server server [const static 1]
)
{
- int ready_fds;
- const int old_errno = errno;
- fd_set ready_to_read;
- struct timeval curr_timeout;
+ int ready_fds, physical_device_fd, interruption_fd, highest_fd;
- FD_ZERO(&ready_to_read);
- FD_SET(input->fd, &ready_to_read);
+ FD_ZERO(ready_to_read);
- /* call to select may alter timeout */
- memcpy
- (
- (void *) &(curr_timeout),
- (const void *) &(config->timeout),
- sizeof(struct timeval)
- );
+ physical_device_fd =
+ relabsd_physical_device_get_file_descriptor(&(server->physical_device));
- errno = 0;
+ FD_SET(physical_device_fd, ready_to_read);
- RELABSD_S_ERROR
- (
- "Waiting for input to be ready..."
- );
+ if (relabsd_physical_device_is_late(&(server->physical_device)))
+ {
+ return 1;
+ }
- ready_fds = select
- (
- (input->fd + 1),
- &ready_to_read,
- (fd_set *) NULL,
- (fd_set *) NULL,
- (input->timed_out) ? NULL : &(curr_timeout)
- );
+ interruption_fd = relabsd_server_get_interruption_file_descriptor();
- if (errno != 0)
- {
- RELABSD_ERROR
- (
- "Unable to wait for timeout: %s (errno: %d).",
- strerror(errno),
- errno
- );
+ FD_SET(interruption_fd, ready_to_read);
- if (errno == EINTR)
- {
- /* Signal interruption? */
- }
- else
- {
- /* TODO: error message */
- }
+ if (interruption_fd > physical_device_fd)
+ {
+ highest_fd = interruption_fd;
+ }
+ {
+ highest_fd = physical_device_fd;
+ }
- errno = old_errno;
+ errno = 0;
- return -1;
+ if (relabsd_parameters_use_timeout(&(server->parameters)))
+ {
+ struct timeval curr_timeout;
+
+ /* TODO: mutex lock */
+ /* call to select may alter timeout */
+ curr_timeout = relabsd_parameters_get_timeout(&(server->parameters));
+ /* TODO: mutex unlock */
+
+ ready_fds =
+ select
+ (
+ (highest_fd + 1),
+ ready_to_read,
+ (fd_set *) NULL,
+ (fd_set *) NULL,
+ (struct timeval *) &curr_timeout
+ );
+ }
+ else
+ {
+ ready_fds =
+ select
+ (
+ (highest_fd + 1),
+ ready_to_read,
+ (fd_set *) NULL,
+ (fd_set *) NULL,
+ (struct timeval *) NULL
+ );
}
if (ready_fds == -1)
{
- /* TODO: error message */
-
- RELABSD_S_ERROR
+ RELABSD_ERROR
(
- "Unable to wait for timeout, yet errno was not set to anything."
+ "Error while waiting for new input from the physical device: %s.",
+ strerror(errno)
);
- errno = old_errno;
+ FD_ZERO(ready_to_read);
- return -1;
+ return 1;
}
- RELABSD_ERROR
- (
- "Input is ready, ready_fds = %d", ready_fds
- );
-
+ /* ready_fds == 0 on timeout */
return ready_fds;
}
+
+/******************************************************************************/
+/**** EXPORTED FUNCTIONS ******************************************************/
+/******************************************************************************/
+int relabsd_server_conversion_loop
+(
+ struct relabsd_server server [const static 1]
+)
+{
+ fd_set ready_to_read;
+
+ for (;;)
+ {
+ switch (wait_for_next_event(&ready_to_read, server))
+ {
+ case 1:
+ case 2:
+ if (!relabsd_server_keep_running())
+ {
+ return 0;
+ }
+
+ if
+ (
+ FD_ISSET
+ (
+ relabsd_physical_device_get_file_descriptor
+ (
+ &(server->physical_device)
+ ),
+ &ready_to_read
+ )
+ )
+ {
+ /* TODO: mutex lock */
+ convert_input(server);
+ /* TODO: mutex unlock */
+ }
+
+ break;
+
+ case 0:
+ /* TODO: mutex lock */
+ reset_axes(server);
+ /* TODO: mutex unlock */
+ break;
+ }
+ }
+}