Splitted Options related stuff into separate files

This commit is contained in:
Ingo Ruhnke 2011-01-25 23:34:18 +01:00
parent e5895d4a25
commit 7ec53fa23a
16 changed files with 459 additions and 62 deletions

View file

@ -106,6 +106,8 @@ enum {
OPTION_DETACH_KERNEL_DRIVER,
OPTION_DAEMON_DETACH,
OPTION_DAEMON_PID_FILE,
OPTION_DAEMON_MATCH,
OPTION_DAEMON_MATCH_GROUP,
OPTION_HELP_DEVICES,
OPTION_LIST_ALL,
OPTION_LIST_ABS,
@ -167,6 +169,8 @@ CommandLineParser::init_argp()
.add_option(OPTION_DAEMON_PID_FILE, 0, "pid-file", "FILE", "Write daemon pid to FILE")
.add_option(OPTION_DAEMON_ON_CONNECT, 0, "on-connect", "FILE", "Launch EXE when a new controller is connected")
.add_option(OPTION_DAEMON_ON_DISCONNECT, 0, "on-disconnect", "FILE", "Launch EXE when a controller is disconnected")
.add_option(OPTION_DAEMON_MATCH, 0, "match", "RULES", "Only allow controllers that match any of RULES")
//FIXME: .add_option(OPTION_DAEMON_MATCH_GROUP, 0, "match-group", "RULES", "Only allow controllers that match all of RULES")
.add_newline()
.add_text("Device Options: ")
@ -400,6 +404,14 @@ CommandLineParser::parse_args(int argc, char** argv, Options* options)
opts.mode = Options::RUN_DAEMON;
break;
case OPTION_DAEMON_MATCH:
opts.set_match(opt.argument);
break;
case OPTION_DAEMON_MATCH_GROUP:
opts.set_match_group(opt.argument);
break;
case OPTION_WRITE_CONFIG:
{
opts.instant_exit = true;

View file

@ -18,6 +18,7 @@
#include "controller_config.hpp"
#include "controller_options.hpp"
#include "options.hpp"
ControllerConfig::ControllerConfig(UInput& uinput, int slot, bool extra_devices, const ControllerOptions& opts) :

View file

@ -19,18 +19,19 @@
#include "controller_config_set.hpp"
#include "log.hpp"
#include "controller_options.hpp"
#include "modifier/dpad_rotation_modifier.hpp"
#include "modifier/four_way_restrictor_modifier.hpp"
#include "modifier/square_axis_modifier.hpp"
ControllerConfigSetPtr
ControllerConfigSet::create(UInput& uinput, int slot, bool extra_devices, const Options::ControllerConfigs& opts)
ControllerConfigSet::create(UInput& uinput, int slot, bool extra_devices, const ControllerSlotOptions& opts)
{
ControllerConfigSetPtr m_config(new ControllerConfigSet);
for(Options::ControllerConfigs::const_iterator i = opts.begin();
i != opts.end(); ++i)
for(ControllerSlotOptions::Options::const_iterator i = opts.get_options().begin();
i != opts.get_options().end(); ++i)
{
const ControllerOptions& ctrl_opt = i->second;

View file

@ -33,7 +33,7 @@ class ControllerConfigSet
public:
/** Creates a ControllerConfigSet from the Options object and connects it to UInput */
static ControllerConfigSetPtr create(UInput& uinput, int slot, bool extra_devices,
const Options::ControllerConfigs& opts);
const ControllerSlotOptions& opts);
private:
static void create_modifier(const ControllerOptions& options, std::vector<ModifierPtr>* modifier);

View file

@ -0,0 +1,50 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "controller_match_rule.hpp"
ControllerMatchRule
ControllerMatchRule::match_usb_id(int vendor, int product)
{
ControllerMatchRule rule;
rule.m_type = kMatchUSBId;
rule.m_vendor = vendor;
rule.m_product = product;
return rule;
}
ControllerMatchRule
ControllerMatchRule::match_usb_path(int bus, int dev)
{
ControllerMatchRule rule;
rule.m_type = kMatchUSBPath;
rule.m_bus = bus;
rule.m_dev = dev;
return rule;
}
ControllerMatchRule
ControllerMatchRule::match_evdev_path(const std::string& path)
{
ControllerMatchRule rule;
rule.m_type = kMatchEvdevPath;
rule.m_path = path;
return rule;
}
/* EOF */

View file

@ -0,0 +1,58 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEADER_XBOXDRV_CONTROLLER_MATCH_RULE_HPP
#define HEADER_XBOXDRV_CONTROLLER_MATCH_RULE_HPP
#include <string>
class ControllerMatchRule
{
public:
enum {
kMatchEverything,
kMatchUSBId,
kMatchUSBPath,
kMatchEvdevPath
} m_type;
int m_bus;
int m_dev;
int m_vendor;
int m_product;
std::string m_path;
ControllerMatchRule() :
m_type(kMatchEverything),
m_bus(),
m_dev(),
m_vendor(),
m_product(),
m_path()
{}
static ControllerMatchRule match_usb_id(int vendor, int product);
static ControllerMatchRule match_usb_path(int bus, int dev);
static ControllerMatchRule match_evdev_path(const std::string& path);
};
#endif
/* EOF */

View file

@ -0,0 +1,39 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "controller_options.hpp"
ControllerOptions::ControllerOptions() :
uinput(),
modifier(),
buttonmap(new ButtonmapModifier),
axismap(new AxismapModifier),
deadzone(0),
deadzone_trigger(0),
square_axis(false),
four_way_restrictor(0),
dpad_rotation(0),
calibration_map(),
sensitivity_map(),
relative_axis_map(),
autofire_map()
{
}
/* EOF */

View file

@ -0,0 +1,56 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEADER_XBOXDRV_CONTROLLER_OPTIONS_HPP
#define HEADER_XBOXDRV_CONTROLLER_OPTIONS_HPP
#include <vector>
#include <map>
#include "uinput_options.hpp"
#include "modifier/axismap_modifier.hpp"
#include "modifier/buttonmap_modifier.hpp"
class ControllerOptions
{
public:
ControllerOptions();
UInputOptions uinput;
std::vector<ModifierPtr> modifier;
// everything below gets later converted into modifier
boost::shared_ptr<ButtonmapModifier> buttonmap;
boost::shared_ptr<AxismapModifier> axismap;
int deadzone;
int deadzone_trigger;
bool square_axis;
bool four_way_restrictor;
int dpad_rotation;
std::map<XboxAxis, AxisFilterPtr> calibration_map;
std::map<XboxAxis, AxisFilterPtr> sensitivity_map;
std::map<XboxAxis, AxisFilterPtr> relative_axis_map;
std::map<XboxButton, ButtonFilterPtr> autofire_map;
};
#endif
/* EOF */

View file

@ -0,0 +1,69 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "controller_slot_options.hpp"
#include <stdexcept>
#include "raise_exception.hpp"
ControllerSlotOptions::ControllerSlotOptions() :
m_options(),
m_match_rules()
{
}
ControllerOptions&
ControllerSlotOptions::get_options(int num)
{
return m_options[num];
}
const ControllerOptions&
ControllerSlotOptions::get_options(int num) const
{
std::map<int, ControllerOptions>::const_iterator it = m_options.find(num);
if (it == m_options.end())
{
raise_exception(std::runtime_error, "illegal option: " << num);
}
else
{
return it->second;
}
}
void
ControllerSlotOptions::add_match_rule(const ControllerMatchRule& rule)
{
m_match_rules.push_back(rule);
}
const std::vector<ControllerMatchRule>&
ControllerSlotOptions::get_match_rules() const
{
return m_match_rules;
}
const std::map<int, ControllerOptions>&
ControllerSlotOptions::get_options() const
{
return m_options;
}
/* EOF */

View file

@ -0,0 +1,51 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEADER_XBOXDRV_CONTROLLER_SLOT_OPTIONS_HPP
#define HEADER_XBOXDRV_CONTROLLER_SLOT_OPTIONS_HPP
#include <map>
#include <vector>
#include "controller_options.hpp"
#include "controller_match_rule.hpp"
class ControllerSlotOptions
{
public:
typedef std::map<int, ControllerOptions> Options;
public:
ControllerSlotOptions();
void add_match_rule(const ControllerMatchRule& rule);
ControllerOptions& get_options(int num);
const ControllerOptions& get_options(int num) const;
const std::vector<ControllerMatchRule>& get_match_rules() const;
const std::map<int, ControllerOptions>& get_options() const;
private:
std::map<int, ControllerOptions> m_options;
std::vector<ControllerMatchRule> m_match_rules;
};
#endif
/* EOF */

View file

@ -22,8 +22,29 @@
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <stdexcept>
#include "raise_exception.hpp"
int hexstr2int(const std::string& str)
{
unsigned int value = 0;
if (sscanf(str.c_str(), "%x", &value) == 1)
{
return value;
}
else if (sscanf(str.c_str(), "0x%x", &value) == 1)
{
return value;
}
else
{
raise_exception(std::runtime_error, "couldn't convert '" << str << "' to int");
}
}
std::string raw2str(uint8_t* data, int len)
{

View file

@ -21,6 +21,8 @@
#include <boost/function.hpp>
int hexstr2int(const std::string& str);
std::string raw2str(uint8_t* buffer, int len);
std::string to_lower(const std::string &str);
bool is_number(const std::string& str);

View file

@ -18,26 +18,14 @@
#include "options.hpp"
#include <boost/tokenizer.hpp>
#include <boost/bind.hpp>
#include "helper.hpp"
#include "raise_exception.hpp"
Options* g_options;
ControllerOptions::ControllerOptions() :
uinput(),
modifier(),
buttonmap(new ButtonmapModifier),
axismap(new AxismapModifier),
deadzone(0),
deadzone_trigger(0),
square_axis(false),
four_way_restrictor(0),
dpad_rotation(0),
calibration_map(),
sensitivity_map(),
relative_axis_map(),
autofire_map()
{
}
Options::Options() :
mode(RUN_DEFAULT),
verbose(false),
@ -84,16 +72,16 @@ Options::Options() :
extra_devices(true)
{
// create the entry if not already available
controller_slots[controller_slot][config_slot];
controller_slots[controller_slot].get_options(config_slot);
}
Options::ControllerConfigs&
ControllerSlotOptions&
Options::get_controller_slot()
{
return controller_slots[controller_slot];
}
const Options::ControllerConfigs&
const ControllerSlotOptions&
Options::get_controller_slot() const
{
ControllerSlots::const_iterator it = controller_slots.find(controller_slot);
@ -110,7 +98,7 @@ Options::get_controller_slot() const
ControllerOptions&
Options::get_controller_options()
{
return controller_slots[controller_slot][config_slot];
return controller_slots[controller_slot].get_options(config_slot);
}
const ControllerOptions&
@ -123,8 +111,8 @@ Options::get_controller_options() const
}
else
{
ControllerConfigs::const_iterator cfg = it->second.find(config_slot);
if (cfg == it->second.end())
ControllerSlotOptions::Options::const_iterator cfg = it->second.get_options().find(config_slot);
if (cfg == it->second.get_options().end())
{
assert(!"shouldn't happen either");
}
@ -142,7 +130,7 @@ Options::next_controller()
config_slot = 0;
// create the entry if not already available
controller_slots[controller_slot][config_slot];
controller_slots[controller_slot].get_options(config_slot);
}
void
@ -157,7 +145,7 @@ Options::next_config()
}
// create the entry if not already available
controller_slots[controller_slot][config_slot];
controller_slots[controller_slot].get_options(config_slot);
}
void
@ -211,4 +199,67 @@ Options::set_mimic_xpad()
get_controller_options().uinput.mimic_xpad();
}
void
Options::add_match(const std::string& lhs, const std::string& rhs)
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer tokens(rhs, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
std::vector<std::string> args(tokens.begin(), tokens.end());
if (lhs == "usbid")
{
if (args.size() != 2)
{
raise_exception(std::runtime_error, "usbid requires VENDOR:PRODUCT argument");
}
else
{
int vendor = hexstr2int(args[0]);
int product = hexstr2int(args[1]);
get_controller_slot().add_match_rule(ControllerMatchRule::match_usb_id(vendor, product));
}
}
else if (lhs == "usbpath")
{
if (args.size() != 2)
{
raise_exception(std::runtime_error, "usbpath requires BUS:DEV argument");
}
else
{
int bus = boost::lexical_cast<int>(args[0]);
int dev = boost::lexical_cast<int>(args[1]);
get_controller_slot().add_match_rule(ControllerMatchRule::match_usb_path(bus, dev));
}
}
else if (lhs == "evdev")
{
if (args.size() != 1)
{
raise_exception(std::runtime_error, "evdev rule requires PATH argument");
}
else
{
get_controller_slot().add_match_rule(ControllerMatchRule::match_evdev_path(args[0]));
}
}
else
{
raise_exception(std::runtime_error, "'" << lhs << "' not a valid match rule name");
}
}
void
Options::set_match(const std::string& str)
{
process_name_value_string(str, boost::bind(&Options::add_match, this, _1, _2));
}
void
Options::set_match_group(const std::string& str)
{
// FIXME: not implied
assert(!"not implemented");
}
/* EOF */

View file

@ -23,37 +23,12 @@
#include <map>
#include <vector>
#include "controller_options.hpp"
#include "controller_slot_options.hpp"
#include "evdev_absmap.hpp"
#include "uinput_options.hpp"
#include "xpad_device.hpp"
#include "modifier/axismap_modifier.hpp"
#include "modifier/buttonmap_modifier.hpp"
class ControllerOptions
{
public:
ControllerOptions();
UInputOptions uinput;
std::vector<ModifierPtr> modifier;
// everything below gets later converted into modifier
boost::shared_ptr<ButtonmapModifier> buttonmap;
boost::shared_ptr<AxismapModifier> axismap;
int deadzone;
int deadzone_trigger;
bool square_axis;
bool four_way_restrictor;
int dpad_rotation;
std::map<XboxAxis, AxisFilterPtr> calibration_map;
std::map<XboxAxis, AxisFilterPtr> sensitivity_map;
std::map<XboxAxis, AxisFilterPtr> relative_axis_map;
std::map<XboxButton, ButtonFilterPtr> autofire_map;
};
class Options
{
public:
@ -111,8 +86,7 @@ public:
std::map<int, XboxButton> evdev_keymap;
// controller options
typedef std::map<int, ControllerOptions> ControllerConfigs;
typedef std::map<int, ControllerConfigs> ControllerSlots;
typedef std::map<int, ControllerSlotOptions> ControllerSlots;
ControllerSlots controller_slots;
// chatpad options
@ -146,8 +120,8 @@ public:
public:
Options();
ControllerConfigs& get_controller_slot();
const ControllerConfigs& get_controller_slot() const;
ControllerSlotOptions& get_controller_slot();
const ControllerSlotOptions& get_controller_slot() const;
/** Returns the currently active configuration */
ControllerOptions& get_controller_options();
@ -165,6 +139,10 @@ public:
void set_dpad_only();
void set_force_feedback();
void set_mimic_xpad();
void add_match(const std::string& lhs, const std::string& rhs);
void set_match(const std::string& str);
void set_match_group(const std::string& str);
};
extern Options* g_options;

View file

@ -214,7 +214,8 @@ XboxdrvDaemon::run_real(const Options& opts)
log_info << "creating slot: " << slot_count << std::endl;
m_controller_slots.push_back(ControllerSlot(ControllerConfigSet::create(*uinput, slot_count,
opts.extra_devices,
controller->second)));
controller->second),
controller->second.get_match_rules()));
slot_count += 1;
}

View file

@ -24,6 +24,7 @@
#include <vector>
#include "controller_config_set.hpp"
#include "controller_match_rule.hpp"
class Options;
class UInput;
@ -39,21 +40,26 @@ private:
struct ControllerSlot
{
ControllerConfigSetPtr config;
std::vector<ControllerMatchRule> match;
XboxdrvThread* thread;
ControllerSlot() :
config(),
match(),
thread(0)
{}
ControllerSlot(ControllerConfigSetPtr config_,
std::vector<ControllerMatchRule> match_,
XboxdrvThread* thread_ = 0) :
config(config_),
match(match_),
thread(thread_)
{}
ControllerSlot(const ControllerSlot& rhs) :
config(rhs.config),
match(rhs.match),
thread(rhs.thread)
{}
@ -62,6 +68,7 @@ private:
if (&rhs != this)
{
config = rhs.config;
match = rhs.match;
thread = rhs.thread;
}
return *this;