| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.c | 11 | ||||
| -rw-r--r-- | src/config/parameters/handle_remote_client_commands.c | 302 | ||||
| -rw-r--r-- | src/config/parameters/parameters.c | 72 | ||||
| -rw-r--r-- | src/config/parameters/parameters_accessors.c | 22 | ||||
| -rw-r--r-- | src/device/axis/axis.c | 19 | ||||
| -rw-r--r-- | src/device/virtual/virtual_device.c | 93 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/server/handle_client.c | 57 | 
8 files changed, 511 insertions, 67 deletions
| diff --git a/src/client.c b/src/client.c index 6e6b036..6a4e08d 100644 --- a/src/client.c +++ b/src/client.c @@ -107,12 +107,6 @@ static int send_commands     for (i = 3; i < argc;)     { - -      if (fputs(argv[i], socket) == EOF) -      { -         // TODO: error -      } -        if (relabsd_parameters_argument_count_for(argv[i], &j) < 0)        {           RELABSD_FATAL("Unknown option '%s'.", argv[i]); @@ -121,6 +115,11 @@ static int send_commands           return -1;        } +      if (fputs(argv[i], socket) == EOF) +      { +         // TODO: error +      } +        if (fputc('\n', socket) == EOF)        {           // TODO: error diff --git a/src/config/parameters/handle_remote_client_commands.c b/src/config/parameters/handle_remote_client_commands.c index 5523e37..caa82dc 100644 --- a/src/config/parameters/handle_remote_client_commands.c +++ b/src/config/parameters/handle_remote_client_commands.c @@ -58,6 +58,10 @@ static int get_next_argument        return -1;     } +   /* +    * size is "not including the terminating null byte", so it's the '\n' +    * character. +    */     input->buffer[(input->size - 1)] = '\0';     return 0; @@ -89,7 +93,7 @@ static void finalize_client_input  static int handle_timeout_change  (     struct relabsd_parameters_client_input input [const restrict static 1], -   struct relabsd_parameters parameters [const static 1] +   struct relabsd_parameters parameters [const restrict static 1]  )  {     int timeout_msec; @@ -113,12 +117,281 @@ static int handle_timeout_change     return 0;  } -static int handle_inputs +static int handle_name_change +( +   struct relabsd_parameters_client_input input [const restrict static 1], +   struct relabsd_parameters parameters [const restrict static 1] +) +{ +   const char * device_name; + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR("Could not get device name value from client."); + +      return -1; +   } + +   device_name = +      (const char *) calloc((size_t) (input->size - 1), sizeof(char)); + +   if (device_name == (const char *) NULL) +   { +      RELABSD_S_ERROR +      ( +         "Could not allocate memory to store the device name requested by" +         " the client." +      ); + +      return -1; +   } + +   (void) memcpy +   ( +      (void *) device_name, +      (const void *) input->buffer, +      (size_t) (input->size - 1) +   ); + +   if (parameters->device_name_was_modified) +   { +      free((void *) parameters->device_name); +   } + +   parameters->device_name = device_name; +   parameters->device_name_was_modified = 1; + +   return 0; +} + +static int handle_axis_mod  (     struct relabsd_parameters_client_input input [const restrict static 1],     struct relabsd_parameters parameters [const static 1]  )  { +   enum relabsd_axis_name axis_name; +   int * value_to_modify; +   int min_value; +   int input_value; + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR("Could not get name of axis to modify from client."); + +      return -1; +   } + +   axis_name = relabsd_axis_parse_name(input->buffer); + +   if (axis_name == RELABSD_UNKNOWN) +   { +      RELABSD_ERROR +      ( +         "Client requested modification on unknown axis \"%s\".", +         input->buffer +      ); + +      return -1; +   } + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR("Could not get parameter of axis to modify from client."); + +      return -1; +   } + +   if (RELABSD_STRING_EQUALS("min", input->buffer)) +   { +      value_to_modify = &(parameters->axes[axis_name].min); +      min_value = INT_MIN; +   } +   else if (RELABSD_STRING_EQUALS("max", input->buffer)) +   { +      value_to_modify = &(parameters->axes[axis_name].max); +      min_value = INT_MIN; +   } +   else if (RELABSD_STRING_EQUALS("fuzz", input->buffer)) +   { +      value_to_modify = &(parameters->axes[axis_name].fuzz); +      min_value = 0; +   } +   else if (RELABSD_STRING_EQUALS("flat", input->buffer)) +   { +      value_to_modify = &(parameters->axes[axis_name].flat); +      min_value = 0; +   } +   else if (RELABSD_STRING_EQUALS("resolution", input->buffer)) +   { +      value_to_modify = &(parameters->axes[axis_name].resolution); +      min_value = 0; +   } +   else +   { +      RELABSD_ERROR +      ( +         "Client requested modification on unknown axis parameter \"%s\".", +         input->buffer +      ); + +      return -1; +   } + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR +      ( +         "Could not get new value for axis modification requested by client." +      ); + +      return -1; +   } + +   if +   ( +      relabsd_util_parse_int +      ( +         (input->buffer + 1), +         min_value, +         INT_MAX, +         &input_value +      ) +      < 0 +   ) +   { +      RELABSD_ERROR +      ( +         "Invalid value \"%s\"for axis modification requested by client.", +         (input->buffer + 1) +      ); + +      return -1; +   } + +   switch (input->buffer[0]) +   { +      case '=': +         *value_to_modify = input_value; +         break; + +      case '-': +         if (input_value == INT_MIN) +         { +            input_value = INT_MAX; +         } +         else +         { +            input_value = -input_value; +         } +         /* fall through */ +      case '+': +         if +         ( +            ( +               (input_value > 0) +               && (*value_to_modify > (INT_MAX - input_value)) +            ) +            || +            ( +               (input_value < 0) +               && (*value_to_modify < (min_value - input_value)) +            ) +         ) +         { +            RELABSD_S_WARNING +            ( +               "Client request would make axis parameter over/underflow." +            ); + +            *value_to_modify = (input_value < 0) ? min_value : INT_MAX; +         } +         else +         { +            *value_to_modify += input_value; +         } +         break; +   } + +   parameters->axes[axis_name].previous_value = 0; +   parameters->axes[axis_name].attributes_were_modified = 1; + +   return 0; +} + +static int handle_option_toggle +( +   struct relabsd_parameters_client_input input [const restrict static 1], +   struct relabsd_parameters parameters [const restrict static 1] +) +{ +   enum relabsd_axis_name axis_name; + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR("Could not get name of axis to modify from client."); + +      return -1; +   } + +   axis_name = relabsd_axis_parse_name(input->buffer); + +   if (axis_name == RELABSD_UNKNOWN) +   { +      RELABSD_ERROR +      ( +         "Client requested modification on unknown axis \"%s\".", +         input->buffer +      ); + +      return -1; +   } + +   if (get_next_argument(input) < 0) +   { +      RELABSD_S_ERROR("Could not get option of axis to modify from client."); + +      return -1; +   } + +   if (RELABSD_STRING_EQUALS("framed", input->buffer)) +   { +      parameters->axes[axis_name].flags[RELABSD_FRAMED] ^= 1; +   } +   else if (RELABSD_STRING_EQUALS("direct", input->buffer)) +   { +      parameters->axes[axis_name].flags[RELABSD_DIRECT] ^= 1; +   } +   else if (RELABSD_STRING_EQUALS("real_fuzz", input->buffer)) +   { +      parameters->axes[axis_name].flags[RELABSD_REAL_FUZZ] ^= 1; +   } +   else if (RELABSD_STRING_EQUALS("enable", input->buffer)) +   { +      parameters->axes[axis_name].is_enabled ^= 1; +   } +   else +   { +      RELABSD_ERROR +      ( +         "Client requested toggle of unknown axis option \"%s\".", +         input->buffer +      ); + +      return -1; +   } + +   parameters->axes[axis_name].previous_value = 0; + +   return 0; +} + +static int handle_inputs +( +   struct relabsd_parameters_client_input input [const restrict static 1], +   struct relabsd_parameters parameters [const restrict static 1] +) +{     for (;;)     {        if (get_next_argument(input) < 0) @@ -148,7 +421,7 @@ static int handle_inputs        {           if (handle_timeout_change(input, parameters) < 0)           { -            return 0; +            return -1;           }        }        else if @@ -157,8 +430,10 @@ static int handle_inputs           || RELABSD_STRING_EQUALS("--name", input->buffer)        )        { -         /* TODO: implement */ -         RELABSD_PROG_ERROR("Unimplemented command \"%s\".", input->buffer); +         if (handle_name_change(input, parameters) < 0) +         { +            return -1; +         }        }        else if        ( @@ -166,8 +441,21 @@ static int handle_inputs           || RELABSD_STRING_EQUALS("--mod-axis", input->buffer)        )        { -         /* TODO: implement */ -         RELABSD_PROG_ERROR("Unimplemented command \"%s\".", input->buffer); +         if (handle_axis_mod(input, parameters) < 0) +         { +            return -1; +         } +      } +      else if +      ( +         RELABSD_STRING_EQUALS("-o", input->buffer) +         || RELABSD_STRING_EQUALS("--toggle-option", input->buffer) +      ) +      { +         if (handle_option_toggle(input, parameters) < 0) +         { +            return -1; +         }        }        else        { diff --git a/src/config/parameters/parameters.c b/src/config/parameters/parameters.c index 84b348c..04ee498 100644 --- a/src/config/parameters/parameters.c +++ b/src/config/parameters/parameters.c @@ -315,6 +315,21 @@ int relabsd_parameters_parse_options              return -1;           }        } +      else if +      ( +         RELABSD_STRING_EQUALS("-m", argv[i]) +         || RELABSD_STRING_EQUALS("--mod-axis", argv[i]) +         || RELABSD_STRING_EQUALS("-o", argv[i]) +         || RELABSD_STRING_EQUALS("--toggle-argv[i]", argv[i]) +         ||RELABSD_STRING_EQUALS("-q", argv[i]) +         || RELABSD_STRING_EQUALS("--quit", argv[i]) +      ) +      { +         RELABSD_FATAL("\"%s\" is not available in this mode.", argv[i]); +         relabsd_parameters_print_usage(argv[0]); + +         return -1; +      }        else        {           RELABSD_FATAL("Unknown <OPTION> \"%s\".", argv[i]); @@ -361,14 +376,6 @@ int relabsd_parameters_argument_count_for     }     else if     ( -      RELABSD_STRING_EQUALS("-a", option) -      || RELABSD_STRING_EQUALS("--axis", option) -   ) -   { -      *result = 7; -   } -   else if -   (        RELABSD_STRING_EQUALS("-m", option)        || RELABSD_STRING_EQUALS("--mod-axis", option)     ) @@ -377,19 +384,24 @@ int relabsd_parameters_argument_count_for     }     else if     ( -      RELABSD_STRING_EQUALS("-f", option) -      || RELABSD_STRING_EQUALS("--config", option) +      RELABSD_STRING_EQUALS("-o", option) +      || RELABSD_STRING_EQUALS("--toggle-option", option)     )     { -      *result = 1; +      *result = 2;     }     else if     ( -      RELABSD_STRING_EQUALS("-q", option) -      || RELABSD_STRING_EQUALS("--quit", option) +      RELABSD_STRING_EQUALS("-d", option) +      || RELABSD_STRING_EQUALS("--daemon", option) +      || RELABSD_STRING_EQUALS("-f", option) +      || RELABSD_STRING_EQUALS("--config", option) +      || RELABSD_STRING_EQUALS("-a", option) +      || RELABSD_STRING_EQUALS("--axis", option)     )     { -      *result = 0; +      RELABSD_ERROR("\"%s\" is not available in this mode.", option); +      relabsd_parameters_print_usage("relabsd");     }     else     { @@ -412,46 +424,48 @@ void relabsd_parameters_print_usage (const char exec [const restrict static 1])           "\t\tDevice & configuration compatibility test.\n\n"           "\t%s [-c | --client] <server_file> " -            "[(<CLIENT_OPTION>|<GLOBAL_CONF_OPTION>)+]" -         "\n" +            "[(<CLIENT_OPTION>|<GLOBAL_CONF_OPTION>)+]\n"           "\t\tSends the commands to a given server instance.\n\n"           "\t%s [-s | --server] <server_file> <physical_device_file>" -         " [(<SERVER_OPTION>|<CONF_OPTION>)+]:\n" +         " [(<SERVER_OPTION>|<CONF_OPTION>)+]\n"              "\t\tCreates a named server instance.\n\n"           "\t%s [-1 | --self] <physical_device_file>" -         " [(<SERVER_OPTION>|<CONF_OPTION>)+]:\n" +         " [(<SERVER_OPTION>|<CONF_OPTION>)+]\n"              "\t\tCreates an unnamed server instance.\n\n"        "<GLOBAL_CONF_OPTION>:\n" -      "\t[-n | --name] <relabsd_device_name>:\n" +      "\t[-n | --name] <relabsd_device_name>\n"           "\t\tNames the virtual device.\n\n" -      "\t[-t | --timeout] <timeout_in_ms>:\n" +      "\t[-t | --timeout] <timeout_in_ms>\n"           "\t\tSets a zeroing timeout (0 to disable).\n\n" -      "\t[-m | --mod-axis] <name> [min|max|fuzz|flat|resolution|enable]" -         " [+|-|=]<value>:\n" -         "\t\tModifies an axis.\n\n" -        "<CONF_OPTION>:\n"        "\t<GLOBAL_CONF_OPTION>\n\n"        "\t[-a | --axis] <name> <min> <max> <fuzz> <flat> <resolution> " -         "<options>:\n" +         "<options>\n"           "\t\t(Re)defines an axis.\n\n" -      "\t[-f | --config] <config_file>" +      "\t[-f | --config] <config_file>\n"           "\t\tUse the options defined in <config_file>.\n\n"        "<SERVER_OPTION>:\n" -      "\t[-d | --daemon]:\n" +      "\t[-d | --daemon]\n"           "\t\tRuns server instance in the background.\n\n"        "<CLIENT_OPTION>:\n" -      "\t[-q | --quit]:\n" -         "\t\tTerminates the targeted server instance.\n", +      "\t[-q | --quit]\n" +         "\t\tTerminates the targeted server instance.\n\n" + +      "\t[-m | --mod-axis] <axis_name> [min|max|fuzz|flat|resolution]" +         " [+|-|=]<value>\n" +         "\t\tModifies an axis.\n\n" + +      "\t[-o | --toggle-option] <axis_name> [direct|real_fuzz|framed|enable]\n" +         "\t\tToggles an axis option.\n",        exec,        exec,        exec, diff --git a/src/config/parameters/parameters_accessors.c b/src/config/parameters/parameters_accessors.c index f47ff63..2ce5b22 100644 --- a/src/config/parameters/parameters_accessors.c +++ b/src/config/parameters/parameters_accessors.c @@ -26,6 +26,7 @@ void relabsd_parameters_initialize_options     parameters->device_name = (const char *) NULL;     parameters->physical_device_file_name = (const char *) NULL;     parameters->configuration_file = (const char *) NULL; +   parameters->device_name_was_modified = 0;     for (i = 0; i < RELABSD_AXIS_VALID_AXES_COUNT; ++i)     { @@ -125,3 +126,24 @@ struct timeval relabsd_parameters_get_timeout  {     return parameters->timeout;  } + +int relabsd_parameters_device_name_is_dirty +( +   const struct relabsd_parameters parameters [const restrict static 1] +) +{ +   return parameters->device_name_was_modified; +} + +void relabsd_parameters_clean_device_name +( +   struct relabsd_parameters parameters [const restrict static 1] +) +{ +   if (parameters->device_name_was_modified) +   { +      free((void *) parameters->device_name); +      parameters->device_name = (const char *) NULL; +      parameters->device_name_was_modified = 0; +   } +} diff --git a/src/device/axis/axis.c b/src/device/axis/axis.c index 5fe313e..e854e37 100644 --- a/src/device/axis/axis.c +++ b/src/device/axis/axis.c @@ -24,7 +24,7 @@ void relabsd_axis_initialize  void relabsd_axis_to_absinfo  ( -   struct relabsd_axis axis [const restrict static 1], +   const struct relabsd_axis axis [const restrict static 1],     struct input_absinfo absinfo [const restrict static 1]  )  { @@ -51,3 +51,20 @@ int relabsd_axis_is_enabled  {     return axis->is_enabled;  } + +int relabsd_axis_attributes_are_dirty +( +   const struct relabsd_axis axis [const restrict static 1] +) +{ +   return axis->attributes_were_modified; +} + +void relabsd_axis_set_attributes_are_dirty +( +   const int val, +   struct relabsd_axis axis [const restrict static 1] +) +{ +   axis->attributes_were_modified = val; +} diff --git a/src/device/virtual/virtual_device.c b/src/device/virtual/virtual_device.c index bd73743..d4be1b8 100644 --- a/src/device/virtual/virtual_device.c +++ b/src/device/virtual/virtual_device.c @@ -39,31 +39,21 @@ static void replace_rel_axes        if (relabsd_axis_is_enabled(axis))        { -         struct input_absinfo absinfo; - -         relabsd_axis_to_absinfo(axis, &absinfo); - -         /* TODO: report failure? 0 on success, -1 otherwise, no cause given. */ -         (void) libevdev_disable_event_code +         (void) relabsd_virtual_device_update_axis_absinfo           ( -            device->libevdev, -            EV_REL, -            relabsd_axis_name_to_evdev_rel(axis_name) -         ); - -         (void) libevdev_enable_event_code -         ( -            device->libevdev, -            EV_ABS, -            relabsd_axis_name_to_evdev_abs(axis_name), -            &absinfo +            axis_name, +            axis, +            device           );        }     } -  } -static int rename_device + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_virtual_device_rename  (     const struct relabsd_parameters parameters [const restrict static 1],     const struct relabsd_virtual_device device [const restrict static 1] @@ -146,9 +136,36 @@ static int rename_device     return 0;  } -/******************************************************************************/ -/**** EXPORTED FUNCTIONS ******************************************************/ -/******************************************************************************/ +int relabsd_virtual_device_update_axis_absinfo +( +   const enum relabsd_axis_name axis_name, +   const struct relabsd_axis axis [const restrict static 1], +   const struct relabsd_virtual_device device [const restrict static 1] +) +{ +   struct input_absinfo absinfo; + +   relabsd_axis_to_absinfo(axis, &absinfo); + +   /* TODO: report failure? 0 on success, -1 otherwise, no cause given. */ +   (void) libevdev_disable_event_code +   ( +      device->libevdev, +      EV_REL, +      relabsd_axis_name_to_evdev_rel(axis_name) +   ); + +   (void) libevdev_enable_event_code +   ( +      device->libevdev, +      EV_ABS, +      relabsd_axis_name_to_evdev_abs(axis_name), +      &absinfo +   ); + +   return 0; +} +  int relabsd_virtual_device_create_from  (     struct relabsd_parameters parameters [const restrict static 1], @@ -202,7 +219,7 @@ int relabsd_virtual_device_create_from     device->libevdev = physical_device_libevdev;     /* Not exactly fatal, is it? */ -   (void) rename_device(parameters, device); +   (void) relabsd_virtual_device_rename(parameters, device);     libevdev_enable_event_type(physical_device_libevdev, EV_ABS); @@ -244,6 +261,36 @@ int relabsd_virtual_device_create_from     return 0;  } +int relabsd_virtual_device_recreate +( +   struct relabsd_virtual_device device [const restrict static 1] +) +{ +   int err; +   RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Recreating virtual device..."); + +   libevdev_uinput_destroy(device->uinput_device); + +   err = +      libevdev_uinput_create_from_device +      ( +         (device->libevdev), +         /* See top of the file. */ +         LIBEVDEV_UINPUT_OPEN_MANAGED, +         &(device->uinput_device) +      ); + +   if (err !=  0) +   { +      RELABSD_FATAL("Could not recreate uinput device: %s.", strerror(-err)); + +      return -1; +   } + +   RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Recreated virtual device."); +   return 0; +} +  void relabsd_virtual_device_destroy  (     const struct relabsd_virtual_device device [const restrict static 1] @@ -25,7 +25,7 @@ int main (int const argc, const char * const * const argv)     if (relabsd_parameters_parse_execution_mode(argc, argv, ¶ms) < 0)     { -      RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd crashing"); +      RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd crashed.");        return -1;     } diff --git a/src/server/handle_client.c b/src/server/handle_client.c index 5212440..a213fe2 100644 --- a/src/server/handle_client.c +++ b/src/server/handle_client.c @@ -15,12 +15,68 @@  #include <relabsd/debug.h>  #include <relabsd/server.h> +#include <relabsd/device/virtual_device.h> +#include <relabsd/device/axis.h> +  #include <relabsd/config/parameters.h>  /******************************************************************************/  /**** LOCAL FUNCTIONS *********************************************************/  /******************************************************************************/ +static void propagate_changes +( +   struct relabsd_server server [const static 1] +) +{ +   struct relabsd_axis * axis; +   int i; +   int virtual_device_is_dirty; + +   virtual_device_is_dirty = 0; + +   for (i = 0; i < RELABSD_AXIS_VALID_AXES_COUNT; ++i) +   { +      axis = +         relabsd_parameters_get_axis +         ( +            (enum relabsd_axis_name) i, +            &(server->parameters) +         ); + +      if (relabsd_axis_attributes_are_dirty(axis)) +      { +         (void) relabsd_virtual_device_update_axis_absinfo +         ( +            (enum relabsd_axis_name) i, +            axis, +            &(server->virtual_device) +         ); + +         relabsd_axis_set_attributes_are_dirty(0, axis); + +         virtual_device_is_dirty = 1; +      } +   } + +   if (relabsd_parameters_device_name_is_dirty(&(server->parameters))) +   { +      (void) relabsd_virtual_device_rename +      ( +         &(server->parameters), +         &(server->virtual_device) +      ); + +      relabsd_parameters_clean_device_name(&(server->parameters)); +      virtual_device_is_dirty = 1; +   } + +   if (virtual_device_is_dirty) +   { +      (void) relabsd_virtual_device_recreate(&(server->virtual_device)); +   } +} +  /******************************************************************************/  /**** EXPORTED FUNCTIONS ******************************************************/  /******************************************************************************/ @@ -54,6 +110,7 @@ int relabsd_server_handle_client        socket_as_file,        &(server->parameters)     ); +   propagate_changes(server);     pthread_mutex_unlock(&(server->mutex));     /* This also closes 'socket' */ | 


