mirror of
https://github.com/jtgans/g13gui.git
synced 2025-06-20 08:23:50 -04:00
g13d: Rework and cleanup namespaces and files
This is the first half of some major rework of the g13d codebase to make things a bit more manageable. This splits out a great deal of stuff from helper.h into separate translation units, and also breaks out a great deal of the g13.h header into separate translation units as well. Doing this saves in compilation time as we make changes to the system, and also helps to clean up a whole bunch of leaking symbols.
This commit is contained in:
parent
efe01fb850
commit
ae6cf5084a
@ -11,14 +11,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")
|
||||
|
||||
add_executable(pbm2lpbm pbm2lpbm.cc)
|
||||
add_executable(g13d
|
||||
device.cc
|
||||
g13.cc
|
||||
g13_fonts.cc
|
||||
g13_keys.cc
|
||||
g13_lcd.cc
|
||||
g13_log.cc
|
||||
g13_main.cc
|
||||
g13_stick.cc
|
||||
helper.cc
|
||||
manager.cc
|
||||
)
|
||||
|
||||
target_compile_definitions(g13d PRIVATE BOOST_LOG_DYN_LINK=1)
|
||||
|
111
g13d/action.h
Normal file
111
g13d/action.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef ACTION_H
|
||||
#define ACTION_H
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "g13.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_Device;
|
||||
class G13_Manager;
|
||||
|
||||
/*! holds potential actions which can be bound to G13 activity
|
||||
*
|
||||
*/
|
||||
class G13_Action {
|
||||
public:
|
||||
G13_Action(G13_Device &keypad) : _keypad(keypad) {}
|
||||
virtual ~G13_Action();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down) = 0;
|
||||
virtual void dump(std::ostream &) const = 0;
|
||||
|
||||
void act(bool is_down) { act(keypad(), is_down); }
|
||||
|
||||
G13_Device &keypad() { return _keypad; }
|
||||
const G13_Device &keypad() const { return _keypad; }
|
||||
|
||||
G13_Manager &manager();
|
||||
const G13_Manager &manager() const;
|
||||
|
||||
private:
|
||||
G13_Device &_keypad;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send one or more keystrokes
|
||||
*/
|
||||
class G13_Action_Keys : public G13_Action {
|
||||
public:
|
||||
G13_Action_Keys(G13_Device &keypad, const std::string &keys);
|
||||
virtual ~G13_Action_Keys();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::vector<LINUX_KEY_VALUE> _keys;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send a string to the output pipe
|
||||
*/
|
||||
class G13_Action_PipeOut : public G13_Action {
|
||||
public:
|
||||
G13_Action_PipeOut(G13_Device &keypad, const std::string &out);
|
||||
virtual ~G13_Action_PipeOut();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::string _out;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send a command to the g13
|
||||
*/
|
||||
class G13_Action_Command : public G13_Action {
|
||||
public:
|
||||
G13_Action_Command(G13_Device &keypad, const std::string &cmd);
|
||||
virtual ~G13_Action_Command();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::string _cmd;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<G13_Action> G13_ActionPtr;
|
||||
|
||||
template <class PARENT_T> class G13_Actionable {
|
||||
public:
|
||||
G13_Actionable(PARENT_T &parent_arg, const std::string &name)
|
||||
: _name(name), _parent_ptr(&parent_arg) {
|
||||
}
|
||||
|
||||
virtual ~G13_Actionable() {
|
||||
_parent_ptr = 0;
|
||||
}
|
||||
|
||||
G13_ActionPtr action() const { return _action; }
|
||||
const std::string &name() const { return _name; }
|
||||
PARENT_T &parent() { return *_parent_ptr; }
|
||||
const PARENT_T &parent() const { return *_parent_ptr; }
|
||||
G13_Manager &manager() { return _parent_ptr->manager(); }
|
||||
const G13_Manager &manager() const { return _parent_ptr->manager(); }
|
||||
|
||||
virtual void set_action(const G13_ActionPtr &action) { _action = action; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
G13_ActionPtr _action;
|
||||
|
||||
private:
|
||||
PARENT_T *_parent_ptr;
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // ACTION_H
|
51
g13d/bounds.h
Normal file
51
g13d/bounds.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BOUNDS_H
|
||||
#define BOUNDS_H
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "coord.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
template <class T> class Bounds {
|
||||
public:
|
||||
Bounds(const Coord<T> &_tl, const Coord<T> &_br)
|
||||
: tl(_tl), br(_br) {
|
||||
}
|
||||
|
||||
Bounds(T x1, T y1, T x2, T y2) : tl(x1, y1), br(x2, y2) {
|
||||
}
|
||||
|
||||
bool contains(const Coord<T> &pos) const {
|
||||
return tl.x <= pos.x && tl.y <= pos.y && pos.x <= br.x && pos.y <= br.y;
|
||||
}
|
||||
|
||||
void expand(const Coord<T> &pos) {
|
||||
if (pos.x < tl.x)
|
||||
tl.x = pos.x;
|
||||
if (pos.y < tl.y)
|
||||
tl.y = pos.y;
|
||||
if (pos.x > br.x)
|
||||
br.x = pos.x;
|
||||
if (pos.y > br.y)
|
||||
br.y = pos.y;
|
||||
}
|
||||
|
||||
Coord<T> tl;
|
||||
Coord<T> br;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::ostream &operator<<(std::ostream &o, const Bounds<T> &b) {
|
||||
o << "{ "
|
||||
<< b.tl.x << " x " << b.tl.y
|
||||
<< " / "
|
||||
<< b.br.x << " x " << b.br.y
|
||||
<< " }";
|
||||
|
||||
return o;
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // BOUNDS_H
|
28
g13d/coord.h
Normal file
28
g13d/coord.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef COORD_H
|
||||
#define COORD_H
|
||||
|
||||
namespace G13 {
|
||||
|
||||
template <class T> class Coord {
|
||||
public:
|
||||
Coord()
|
||||
: x(), y() {
|
||||
}
|
||||
|
||||
Coord(T _x, T _y)
|
||||
: x(_x), y(_y) {
|
||||
}
|
||||
|
||||
T x;
|
||||
T y;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::ostream &operator<<(std::ostream &o, const Coord<T> &c) {
|
||||
o << "{ " << c.x << " x " << c.y << " }";
|
||||
return o;
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // COORD_H
|
60
g13d/device.cc
Normal file
60
g13d/device.cc
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
|
||||
#include "device.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
void G13_Device::send_event(int type, int code, int val) {
|
||||
memset(&_event, 0, sizeof(_event));
|
||||
gettimeofday(&_event.time, 0);
|
||||
_event.type = type;
|
||||
_event.code = code;
|
||||
_event.value = val;
|
||||
|
||||
// TODO(jtgans): Make this actually verify it writes all bytes
|
||||
auto result = write(_uinput_fid, &_event, sizeof(_event));
|
||||
if (result < 0) {
|
||||
G13_LOG(error, "Unable to send event: " << strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::write_output_pipe(const std::string &out) {
|
||||
// TODO(jtgans): Make this actually verify it writes all bytes
|
||||
auto result = write(_output_pipe_fid, out.c_str(), out.size());
|
||||
if (result < 0) {
|
||||
G13_LOG(error, "Unable to write to output pipe: " << strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::set_mode_leds(int leds) {
|
||||
unsigned char usb_data[] = {5, 0, 0, 0, 0};
|
||||
usb_data[1] = leds;
|
||||
int r = libusb_control_transfer(
|
||||
handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 9, 0x305,
|
||||
0, usb_data, 5, 1000);
|
||||
|
||||
if (r != 5) {
|
||||
G13_LOG(error, "Problem sending data");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::set_key_color(int red, int green, int blue) {
|
||||
int error;
|
||||
unsigned char usb_data[] = {5, 0, 0, 0, 0};
|
||||
usb_data[1] = red;
|
||||
usb_data[2] = green;
|
||||
usb_data[3] = blue;
|
||||
|
||||
error = libusb_control_transfer(
|
||||
handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 9, 0x307,
|
||||
0, usb_data, 5, 1000);
|
||||
if (error != 5) {
|
||||
G13_LOG(error, "Problem sending data");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace G13
|
117
g13d/device.h
Normal file
117
g13d/device.h
Normal file
@ -0,0 +1,117 @@
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "stick.h"
|
||||
#include "font.h"
|
||||
#include "profile.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_Manager;
|
||||
|
||||
class G13_Device {
|
||||
public:
|
||||
G13_Device(G13_Manager &manager, libusb_device_handle *handle, int id);
|
||||
|
||||
G13_Manager &manager() { return _manager; }
|
||||
const G13_Manager &manager() const { return _manager; }
|
||||
|
||||
G13_LCD &lcd() { return _lcd; }
|
||||
const G13_LCD &lcd() const { return _lcd; }
|
||||
G13_Stick &stick() { return _stick; }
|
||||
const G13_Stick &stick() const { return _stick; }
|
||||
|
||||
FontPtr switch_to_font(const std::string &name);
|
||||
void switch_to_profile(const std::string &name);
|
||||
ProfilePtr profile(const std::string &name);
|
||||
|
||||
void dump(std::ostream &, int detail = 0);
|
||||
void command(char const *str);
|
||||
|
||||
void read_commands();
|
||||
void read_config_file(const std::string &filename);
|
||||
|
||||
int read_keys();
|
||||
void parse_joystick(unsigned char *buf);
|
||||
|
||||
G13_ActionPtr make_action(const std::string &);
|
||||
|
||||
void set_key_color(int red, int green, int blue);
|
||||
void set_mode_leds(int leds);
|
||||
|
||||
void send_event(int type, int code, int val);
|
||||
void write_output_pipe(const std::string &out);
|
||||
|
||||
void write_lcd(unsigned char *data, size_t size);
|
||||
|
||||
bool is_set(int key);
|
||||
bool update(int key, bool v);
|
||||
|
||||
// used by G13_Manager
|
||||
void cleanup();
|
||||
void register_context(libusb_context *ctx);
|
||||
void write_lcd_file(const std::string &filename);
|
||||
|
||||
G13_Font ¤t_font() { return *_current_font; }
|
||||
G13_Profile ¤t_profile() { return *_current_profile; }
|
||||
|
||||
int id_within_manager() const { return _id_within_manager; }
|
||||
|
||||
typedef std::function<void(const char *)> COMMAND_FUNCTION;
|
||||
typedef std::map<std::string, COMMAND_FUNCTION> CommandFunctionTable;
|
||||
|
||||
protected:
|
||||
void _init_fonts();
|
||||
void init_lcd();
|
||||
void _init_commands();
|
||||
|
||||
// typedef void (COMMAND_FUNCTION)( G13_Device*, const char *, const char * );
|
||||
CommandFunctionTable _command_table;
|
||||
|
||||
struct timeval _event_time;
|
||||
struct input_event _event;
|
||||
|
||||
int _id_within_manager;
|
||||
libusb_device_handle *handle;
|
||||
libusb_context *ctx;
|
||||
|
||||
int _uinput_fid;
|
||||
|
||||
int _input_pipe_fid;
|
||||
std::string _input_pipe_name;
|
||||
int _output_pipe_fid;
|
||||
std::string _output_pipe_name;
|
||||
|
||||
std::map<std::string, FontPtr> _fonts;
|
||||
FontPtr _current_font;
|
||||
std::map<std::string, ProfilePtr> _profiles;
|
||||
ProfilePtr _current_profile;
|
||||
|
||||
G13_Manager &_manager;
|
||||
G13_LCD _lcd;
|
||||
G13_Stick _stick;
|
||||
|
||||
bool keys[G13_NUM_KEYS];
|
||||
};
|
||||
|
||||
inline bool G13_Device::is_set(int key) {
|
||||
return keys[key];
|
||||
}
|
||||
|
||||
inline bool G13_Device::update(int key, bool v) {
|
||||
bool old = keys[key];
|
||||
keys[key] = v;
|
||||
return old != v;
|
||||
}
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // DEVICE_H
|
38
g13d/find_or_throw.h
Normal file
38
g13d/find_or_throw.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef FIND_OR_THROW_H
|
||||
#define FIND_OR_THROW_H
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class NotFoundException : public std::exception {
|
||||
public:
|
||||
const char *what() throw();
|
||||
};
|
||||
|
||||
template<class K_T, class V_T>
|
||||
inline const V_T &find_or_throw(const std::map<K_T, V_T> &m,
|
||||
const K_T &target) {
|
||||
auto i = m.find(target);
|
||||
|
||||
if (i == m.end()) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
return i->second;
|
||||
};
|
||||
|
||||
template<class K_T, class V_T>
|
||||
inline V_T &find_or_throw(std::map<K_T, V_T> &m, const K_T &target) {
|
||||
auto i = m.find(target);
|
||||
|
||||
if (i == m.end()) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
return i->second;
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // FIND_OR_THROW_H
|
51
g13d/font.h
Normal file
51
g13d/font.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef FONT_H
|
||||
#define FONT_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_FontChar {
|
||||
public:
|
||||
static const int CHAR_BUF_SIZE = 8;
|
||||
enum FONT_FLAGS { FF_ROTATE = 0x01 };
|
||||
|
||||
G13_FontChar() {
|
||||
memset(bits_regular, 0, CHAR_BUF_SIZE);
|
||||
memset(bits_inverted, 0, CHAR_BUF_SIZE);
|
||||
}
|
||||
|
||||
void set_character(unsigned char *data, int width, unsigned flags);
|
||||
unsigned char bits_regular[CHAR_BUF_SIZE];
|
||||
unsigned char bits_inverted[CHAR_BUF_SIZE];
|
||||
};
|
||||
|
||||
class G13_Font {
|
||||
public:
|
||||
G13_Font();
|
||||
G13_Font(const std::string &name, unsigned int width = 8);
|
||||
|
||||
void set_character(unsigned int c, unsigned char *data);
|
||||
|
||||
template<class ARRAY_T, class FLAGST>
|
||||
void install_font(ARRAY_T &data, FLAGST flags, int first = 0);
|
||||
|
||||
const std::string &name() const { return _name; }
|
||||
unsigned int width() const { return _width; }
|
||||
|
||||
const G13_FontChar &char_data(unsigned int x) { return _chars[x]; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
unsigned int _width;
|
||||
|
||||
G13_FontChar _chars[256];
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<G13_Font> FontPtr;
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // FONT_H
|
202
g13d/g13.cc
202
g13d/g13.cc
@ -1,129 +1,39 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <linux/uinput.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "device.h"
|
||||
#include "g13.h"
|
||||
#include "logo.h"
|
||||
#include <fstream>
|
||||
|
||||
#if 0
|
||||
#include <boost/log/attributes.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/expressions/formatters/stream.hpp>
|
||||
#include <boost/log/sources/severity_feature.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
// *************************************************************************
|
||||
#include "manager.h"
|
||||
#include "repr.h"
|
||||
#include "find_or_throw.h"
|
||||
|
||||
#define CONTROL_DIR std::string("/tmp/")
|
||||
|
||||
namespace G13 {
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
void G13_Device::send_event(int type, int code, int val) {
|
||||
memset(&_event, 0, sizeof(_event));
|
||||
gettimeofday(&_event.time, 0);
|
||||
_event.type = type;
|
||||
_event.code = code;
|
||||
_event.value = val;
|
||||
|
||||
// TODO(jtgans): Make this actually verify it writes all bytes
|
||||
auto result = write(_uinput_fid, &_event, sizeof(_event));
|
||||
if (result < 0) {
|
||||
G13_LOG(error, "Unable to send event: " << strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::write_output_pipe(const std::string &out) {
|
||||
// TODO(jtgans): Make this actually verify it writes all bytes
|
||||
auto result = write(_output_pipe_fid, out.c_str(), out.size());
|
||||
if (result < 0) {
|
||||
G13_LOG(error, "Unable to write to output pipe: " << strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::set_mode_leds(int leds) {
|
||||
unsigned char usb_data[] = {5, 0, 0, 0, 0};
|
||||
usb_data[1] = leds;
|
||||
int r = libusb_control_transfer(
|
||||
handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 9, 0x305,
|
||||
0, usb_data, 5, 1000);
|
||||
|
||||
if (r != 5) {
|
||||
G13_LOG(error, "Problem sending data");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Device::set_key_color(int red, int green, int blue) {
|
||||
int error;
|
||||
unsigned char usb_data[] = {5, 0, 0, 0, 0};
|
||||
usb_data[1] = red;
|
||||
usb_data[2] = green;
|
||||
usb_data[3] = blue;
|
||||
|
||||
error = libusb_control_transfer(
|
||||
handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 9, 0x307,
|
||||
0, usb_data, 5, 1000);
|
||||
if (error != 5) {
|
||||
G13_LOG(error, "Problem sending data");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
void G13_Manager::discover_g13s(libusb_device **devs, ssize_t count,
|
||||
vector<G13_Device *> &g13s) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
libusb_device_descriptor desc;
|
||||
int r = libusb_get_device_descriptor(devs[i], &desc);
|
||||
if (r < 0) {
|
||||
G13_LOG(error, "Failed to get device descriptor");
|
||||
return;
|
||||
}
|
||||
if (desc.idVendor == G13_VENDOR_ID && desc.idProduct == G13_PRODUCT_ID) {
|
||||
libusb_device_handle *handle;
|
||||
int r = libusb_open(devs[i], &handle);
|
||||
if (r != 0) {
|
||||
G13_LOG(error, "Error opening G13 device");
|
||||
return;
|
||||
}
|
||||
if (libusb_kernel_driver_active(handle, 0) == 1)
|
||||
if (libusb_detach_kernel_driver(handle, 0) == 0)
|
||||
G13_LOG(info, "Kernel driver detached");
|
||||
|
||||
r = libusb_claim_interface(handle, 0);
|
||||
if (r < 0) {
|
||||
G13_LOG(error, "Cannot Claim Interface");
|
||||
return;
|
||||
}
|
||||
g13s.push_back(new G13_Device(*this, handle, g13s.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
int g13_create_fifo(const char *fifo_name) {
|
||||
|
||||
// mkfifo(g13->fifo_name(), 0777); - didn't work
|
||||
mkfifo(fifo_name, 0666);
|
||||
chmod(fifo_name, 0777);
|
||||
|
||||
chmod(fifo_name, 0660);
|
||||
return open(fifo_name, O_RDWR | O_NONBLOCK);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
int g13_create_uinput(G13_Device *g13) {
|
||||
int g13_create_uinput(void) {
|
||||
struct uinput_user_dev uinp;
|
||||
const char *dev_uinput_fname =
|
||||
access("/dev/input/uinput", F_OK) == 0
|
||||
@ -197,7 +107,7 @@ void G13_Device::register_context(libusb_context *_ctx) {
|
||||
|
||||
write_lcd(g13_logo, sizeof(g13_logo));
|
||||
|
||||
_uinput_fid = g13_create_uinput(this);
|
||||
_uinput_fid = g13_create_uinput();
|
||||
|
||||
_input_pipe_name = _manager.make_pipe_name(this, true);
|
||||
_input_pipe_fid = g13_create_fifo(_input_pipe_name.c_str());
|
||||
@ -238,7 +148,6 @@ static std::string describe_libusb_error_code(int code) {
|
||||
return BOOST_PP_STRINGIZE(elem);
|
||||
|
||||
switch (code) {
|
||||
|
||||
BOOST_PP_SEQ_FOR_EACH(
|
||||
TEST_libusb_error, _,
|
||||
(SUCCESS)(ERROR_IO)(ERROR_INVALID_PARAM)(ERROR_ACCESS)(ERROR_NO_DEVICE)(
|
||||
@ -468,15 +377,17 @@ G13_ActionPtr G13_Device::make_action(const std::string &action) {
|
||||
// *************************************************************************
|
||||
|
||||
void G13_Device::dump(std::ostream &o, int detail) {
|
||||
o << "G13 id=" << id_within_manager() << endl;
|
||||
o << " input_pipe_name=" << repr(_input_pipe_name) << endl;
|
||||
o << " output_pipe_name=" << repr(_output_pipe_name) << endl;
|
||||
o << " current_profile=" << _current_profile->name() << endl;
|
||||
o << " current_font=" << _current_font->name() << std::endl;
|
||||
o << "G13 id=" << id_within_manager() << std::endl
|
||||
<< " input_pipe_name=" << repr(_input_pipe_name) << std::endl
|
||||
<< " output_pipe_name=" << repr(_output_pipe_name) << std::endl
|
||||
<< " current_profile=" << _current_profile->name() << std::endl
|
||||
<< " current_font=" << _current_font->name() << std::endl;
|
||||
|
||||
if (detail > 0) {
|
||||
o << "STICK" << std::endl;
|
||||
|
||||
stick().dump(o);
|
||||
|
||||
if (detail == 1) {
|
||||
_current_profile->dump(o);
|
||||
} else {
|
||||
@ -513,11 +424,24 @@ struct command_adder {
|
||||
BOOST_PP_STRINGIZE(name)); \
|
||||
BOOST_PP_CAT(add_, name) += [this](const char *remainder)
|
||||
|
||||
inline const char *advance_ws(const char* &source, std::string &dest) {
|
||||
const char *space = source ? strchr(source, ' ') : 0;
|
||||
|
||||
if (space) {
|
||||
dest = std::string(source, space - source);
|
||||
source = space + 1;
|
||||
} else {
|
||||
dest = source;
|
||||
source = 0;
|
||||
}
|
||||
|
||||
return source;
|
||||
};
|
||||
|
||||
void G13_Device::_init_commands() {
|
||||
|
||||
using Helper::advance_ws;
|
||||
|
||||
G13_DEVICE_COMMAND(out) { lcd().write_string(remainder); }
|
||||
G13_DEVICE_COMMAND(out) {
|
||||
lcd().write_string(remainder);
|
||||
}
|
||||
|
||||
G13_DEVICE_COMMAND(pos) {
|
||||
int row, col;
|
||||
@ -548,7 +472,6 @@ void G13_Device::_init_commands() {
|
||||
}
|
||||
|
||||
G13_DEVICE_COMMAND(profile) { switch_to_profile(remainder); }
|
||||
|
||||
G13_DEVICE_COMMAND(font) { switch_to_font(remainder); }
|
||||
G13_DEVICE_COMMAND(mod) { set_mode_leds(atoi(remainder)); }
|
||||
G13_DEVICE_COMMAND(textmode) { lcd().text_mode = atoi(remainder); }
|
||||
@ -562,15 +485,15 @@ void G13_Device::_init_commands() {
|
||||
}
|
||||
}
|
||||
|
||||
G13_DEVICE_COMMAND(stickmode) {
|
||||
|
||||
std::string mode = remainder;
|
||||
#define STICKMODE_TEST(r, data, elem) \
|
||||
if (mode == BOOST_PP_STRINGIZE(elem)) { \
|
||||
_stick.set_mode(BOOST_PP_CAT(STICK_, elem)); \
|
||||
return; \
|
||||
} else
|
||||
|
||||
G13_DEVICE_COMMAND(stickmode) {
|
||||
std::string mode = remainder;
|
||||
|
||||
BOOST_PP_SEQ_FOR_EACH(
|
||||
STICKMODE_TEST, _,
|
||||
(ABSOLUTE)(RELATIVE)(KEYS)(CALCENTER)(CALBOUNDS)(CALNORTH)) {
|
||||
@ -594,9 +517,11 @@ void G13_Device::_init_commands() {
|
||||
zone->set_action(make_action(remainder));
|
||||
} else if (operation == "bounds") {
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
if (sscanf(remainder, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2) != 4) {
|
||||
throw G13_CommandException("bad bounds format");
|
||||
}
|
||||
|
||||
zone->set_bounds(G13_ZoneBounds(x1, y1, x2, y2));
|
||||
} else if (operation == "del") {
|
||||
_stick.remove_zone(*zone);
|
||||
@ -626,22 +551,20 @@ void G13_Device::_init_commands() {
|
||||
manager().set_log_level(level);
|
||||
}
|
||||
|
||||
G13_DEVICE_COMMAND(refresh) { lcd().image_send(); }
|
||||
G13_DEVICE_COMMAND(refresh) {
|
||||
lcd().image_send();
|
||||
}
|
||||
|
||||
G13_DEVICE_COMMAND(clear) {
|
||||
lcd().image_clear();
|
||||
lcd().image_send();
|
||||
}
|
||||
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
void G13_Device::command(char const *str) {
|
||||
const char *remainder = str;
|
||||
|
||||
try {
|
||||
using Helper::advance_ws;
|
||||
|
||||
std::string cmd;
|
||||
advance_ws(remainder, cmd);
|
||||
|
||||
@ -649,15 +572,19 @@ void G13_Device::command(char const *str) {
|
||||
if (i == _command_table.end()) {
|
||||
RETURN_FAIL("unknown command : " << cmd)
|
||||
}
|
||||
|
||||
COMMAND_FUNCTION f = i->second;
|
||||
f(remainder);
|
||||
|
||||
return;
|
||||
} catch (const std::exception &ex) {
|
||||
RETURN_FAIL("command failed : " << ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
G13_Manager::G13_Manager() : devs(0), ctx(0) {}
|
||||
G13_Manager::G13_Manager()
|
||||
: devs(0), ctx(0) {
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
@ -671,6 +598,7 @@ std::string G13_Manager::string_config_value(const std::string &name) const {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Manager::set_string_config_value(const std::string &name,
|
||||
const std::string &value) {
|
||||
G13_LOG(info, "set_string_config_value " << name << " = " << repr(value));
|
||||
@ -707,7 +635,6 @@ std::string G13_Manager::make_pipe_name(G13_Device *d, bool is_input) {
|
||||
}
|
||||
|
||||
int G13_Manager::run() {
|
||||
|
||||
init_keynames();
|
||||
display_keys();
|
||||
|
||||
@ -769,4 +696,5 @@ int G13_Manager::run() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace G13
|
||||
|
489
g13d/g13.h
489
g13d/g13.h
@ -1,22 +1,9 @@
|
||||
#ifndef __G13_H__
|
||||
#define __G13_H__
|
||||
|
||||
#include "helper.h"
|
||||
#ifndef G13_H
|
||||
#define G13_H
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
#include <linux/uinput.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// *************************************************************************
|
||||
#include <string>
|
||||
|
||||
namespace G13 {
|
||||
|
||||
@ -54,20 +41,6 @@ const LINUX_KEY_VALUE BAD_KEY_VALUE = -1;
|
||||
|
||||
typedef int G13_KEY_INDEX;
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
using Helper::find_or_throw;
|
||||
using Helper::repr;
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
class G13_Action;
|
||||
class G13_Stick;
|
||||
class G13_LCD;
|
||||
class G13_Profile;
|
||||
class G13_Device;
|
||||
class G13_Manager;
|
||||
|
||||
class G13_CommandException : public std::exception {
|
||||
public:
|
||||
G13_CommandException(const std::string &reason) : _reason(reason) {}
|
||||
@ -77,462 +50,6 @@ public:
|
||||
std::string _reason;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
/*! holds potential actions which can be bound to G13 activity
|
||||
*
|
||||
*/
|
||||
class G13_Action {
|
||||
public:
|
||||
G13_Action(G13_Device &keypad) : _keypad(keypad) {}
|
||||
virtual ~G13_Action();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down) = 0;
|
||||
virtual void dump(std::ostream &) const = 0;
|
||||
|
||||
void act(bool is_down) { act(keypad(), is_down); }
|
||||
|
||||
G13_Device &keypad() { return _keypad; }
|
||||
const G13_Device &keypad() const { return _keypad; }
|
||||
|
||||
G13_Manager &manager();
|
||||
const G13_Manager &manager() const;
|
||||
|
||||
private:
|
||||
G13_Device &_keypad;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send one or more keystrokes
|
||||
*/
|
||||
class G13_Action_Keys : public G13_Action {
|
||||
public:
|
||||
G13_Action_Keys(G13_Device &keypad, const std::string &keys);
|
||||
virtual ~G13_Action_Keys();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::vector<LINUX_KEY_VALUE> _keys;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send a string to the output pipe
|
||||
*/
|
||||
class G13_Action_PipeOut : public G13_Action {
|
||||
public:
|
||||
G13_Action_PipeOut(G13_Device &keypad, const std::string &out);
|
||||
virtual ~G13_Action_PipeOut();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::string _out;
|
||||
};
|
||||
|
||||
/*!
|
||||
* action to send a command to the g13
|
||||
*/
|
||||
class G13_Action_Command : public G13_Action {
|
||||
public:
|
||||
G13_Action_Command(G13_Device &keypad, const std::string &cmd);
|
||||
virtual ~G13_Action_Command();
|
||||
|
||||
virtual void act(G13_Device &, bool is_down);
|
||||
virtual void dump(std::ostream &) const;
|
||||
|
||||
std::string _cmd;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<G13_Action> G13_ActionPtr;
|
||||
|
||||
// *************************************************************************
|
||||
template <class PARENT_T> class G13_Actionable {
|
||||
public:
|
||||
G13_Actionable(PARENT_T &parent_arg, const std::string &name)
|
||||
: _name(name), _parent_ptr(&parent_arg) {}
|
||||
virtual ~G13_Actionable() { _parent_ptr = 0; }
|
||||
|
||||
G13_ActionPtr action() const { return _action; }
|
||||
const std::string &name() const { return _name; }
|
||||
PARENT_T &parent() { return *_parent_ptr; }
|
||||
const PARENT_T &parent() const { return *_parent_ptr; }
|
||||
G13_Manager &manager() { return _parent_ptr->manager(); }
|
||||
const G13_Manager &manager() const { return _parent_ptr->manager(); }
|
||||
|
||||
virtual void set_action(const G13_ActionPtr &action) { _action = action; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
G13_ActionPtr _action;
|
||||
|
||||
private:
|
||||
PARENT_T *_parent_ptr;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
/*! manages the bindings for a G13 key
|
||||
*
|
||||
*/
|
||||
class G13_Key : public G13_Actionable<G13_Profile> {
|
||||
public:
|
||||
void dump(std::ostream &o) const;
|
||||
G13_KEY_INDEX index() const { return _index.index; }
|
||||
|
||||
void parse_key(unsigned char *byte, G13_Device *g13);
|
||||
|
||||
protected:
|
||||
struct KeyIndex {
|
||||
KeyIndex(int key) : index(key), offset(key / 8), mask(1 << (key % 8)) {}
|
||||
|
||||
int index;
|
||||
unsigned char offset;
|
||||
unsigned char mask;
|
||||
};
|
||||
|
||||
// G13_Profile is the only class able to instantiate G13_Keys
|
||||
friend class G13_Profile;
|
||||
|
||||
G13_Key(G13_Profile &mode, const std::string &name, int index)
|
||||
: G13_Actionable<G13_Profile>(mode, name), _index(index),
|
||||
_should_parse(true) {}
|
||||
|
||||
G13_Key(G13_Profile &mode, const G13_Key &key)
|
||||
: G13_Actionable<G13_Profile>(mode, key.name()), _index(key._index),
|
||||
_should_parse(key._should_parse) {
|
||||
set_action(key.action());
|
||||
}
|
||||
|
||||
KeyIndex _index;
|
||||
bool _should_parse;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Represents a set of configured key mappings
|
||||
*
|
||||
* This allows a keypad to have multiple configured
|
||||
* profiles and switch between them easily
|
||||
*/
|
||||
class G13_Profile {
|
||||
public:
|
||||
G13_Profile(G13_Device &keypad, const std::string &name_arg)
|
||||
: _keypad(keypad), _name(name_arg) {
|
||||
_init_keys();
|
||||
}
|
||||
G13_Profile(const G13_Profile &other, const std::string &name_arg)
|
||||
: _keypad(other._keypad), _name(name_arg), _keys(other._keys) {}
|
||||
|
||||
// search key by G13 keyname
|
||||
G13_Key *find_key(const std::string &keyname);
|
||||
|
||||
void dump(std::ostream &o) const;
|
||||
|
||||
void parse_keys(unsigned char *buf);
|
||||
const std::string &name() const { return _name; }
|
||||
|
||||
const G13_Manager &manager() const;
|
||||
|
||||
protected:
|
||||
G13_Device &_keypad;
|
||||
std::string _name;
|
||||
std::vector<G13_Key> _keys;
|
||||
|
||||
void _init_keys();
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<G13_Profile> ProfilePtr;
|
||||
|
||||
class G13_FontChar {
|
||||
public:
|
||||
static const int CHAR_BUF_SIZE = 8;
|
||||
enum FONT_FLAGS { FF_ROTATE = 0x01 };
|
||||
|
||||
G13_FontChar() {
|
||||
memset(bits_regular, 0, CHAR_BUF_SIZE);
|
||||
memset(bits_inverted, 0, CHAR_BUF_SIZE);
|
||||
}
|
||||
void set_character(unsigned char *data, int width, unsigned flags);
|
||||
unsigned char bits_regular[CHAR_BUF_SIZE];
|
||||
unsigned char bits_inverted[CHAR_BUF_SIZE];
|
||||
};
|
||||
|
||||
class G13_Font {
|
||||
public:
|
||||
G13_Font();
|
||||
G13_Font(const std::string &name, unsigned int width = 8);
|
||||
|
||||
void set_character(unsigned int c, unsigned char *data);
|
||||
|
||||
template <class ARRAY_T, class FLAGST>
|
||||
void install_font(ARRAY_T &data, FLAGST flags, int first = 0);
|
||||
|
||||
const std::string &name() const { return _name; }
|
||||
unsigned int width() const { return _width; }
|
||||
|
||||
const G13_FontChar &char_data(unsigned int x) { return _chars[x]; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
unsigned int _width;
|
||||
|
||||
G13_FontChar _chars[256];
|
||||
|
||||
// unsigned char font_basic[256][8];
|
||||
// unsigned char font_inverted[256][8];
|
||||
};
|
||||
typedef boost::shared_ptr<G13_Font> FontPtr;
|
||||
|
||||
class G13_LCD {
|
||||
public:
|
||||
G13_LCD(G13_Device &keypad);
|
||||
|
||||
G13_Device &_keypad;
|
||||
unsigned char image_buf[G13_LCD_BUF_SIZE + 8];
|
||||
unsigned cursor_row;
|
||||
unsigned cursor_col;
|
||||
int text_mode;
|
||||
|
||||
void image(unsigned char *data, int size);
|
||||
void image_send() { image(image_buf, G13_LCD_BUF_SIZE); }
|
||||
|
||||
void image_test(int x, int y);
|
||||
void image_clear() { memset(image_buf, 0, G13_LCD_BUF_SIZE); }
|
||||
|
||||
unsigned image_byte_offset(unsigned row, unsigned col) {
|
||||
return col + (row / 8) * G13_LCD_BYTES_PER_ROW * 8;
|
||||
}
|
||||
|
||||
void image_setpixel(unsigned row, unsigned col);
|
||||
void image_clearpixel(unsigned row, unsigned col);
|
||||
|
||||
void write_char(char c, int row = -1, int col = -1);
|
||||
void write_string(const char *str);
|
||||
void write_pos(int row, int col);
|
||||
};
|
||||
using Helper::repr;
|
||||
|
||||
typedef Helper::Coord<int> G13_StickCoord;
|
||||
typedef Helper::Bounds<int> G13_StickBounds;
|
||||
typedef Helper::Coord<double> G13_ZoneCoord;
|
||||
typedef Helper::Bounds<double> G13_ZoneBounds;
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
class G13_StickZone : public G13_Actionable<G13_Stick> {
|
||||
public:
|
||||
G13_StickZone(G13_Stick &, const std::string &name, const G13_ZoneBounds &,
|
||||
G13_ActionPtr = 0);
|
||||
|
||||
bool operator==(const G13_StickZone &other) const {
|
||||
return _name == other._name;
|
||||
}
|
||||
|
||||
void dump(std::ostream &) const;
|
||||
|
||||
void parse_key(unsigned char *byte, G13_Device *g13);
|
||||
void test(const G13_ZoneCoord &loc);
|
||||
void set_bounds(const G13_ZoneBounds &bounds) { _bounds = bounds; }
|
||||
|
||||
protected:
|
||||
bool _active;
|
||||
G13_ZoneBounds _bounds;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<G13_StickZone> G13_StickZonePtr;
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
class G13_Stick {
|
||||
public:
|
||||
G13_Stick(G13_Device &keypad);
|
||||
|
||||
void parse_joystick(unsigned char *buf);
|
||||
|
||||
void set_mode(stick_mode_t);
|
||||
G13_StickZone *zone(const std::string &, bool create = false);
|
||||
void remove_zone(const G13_StickZone &zone);
|
||||
|
||||
const std::vector<G13_StickZone> &zones() const { return _zones; }
|
||||
|
||||
void dump(std::ostream &) const;
|
||||
|
||||
protected:
|
||||
void _recalc_calibrated();
|
||||
|
||||
G13_Device &_keypad;
|
||||
std::vector<G13_StickZone> _zones;
|
||||
|
||||
G13_StickBounds _bounds;
|
||||
G13_StickCoord _center_pos;
|
||||
G13_StickCoord _north_pos;
|
||||
|
||||
G13_StickCoord _current_pos;
|
||||
|
||||
stick_mode_t _stick_mode;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
class G13_Device {
|
||||
public:
|
||||
G13_Device(G13_Manager &manager, libusb_device_handle *handle, int id);
|
||||
|
||||
G13_Manager &manager() { return _manager; }
|
||||
const G13_Manager &manager() const { return _manager; }
|
||||
|
||||
G13_LCD &lcd() { return _lcd; }
|
||||
const G13_LCD &lcd() const { return _lcd; }
|
||||
G13_Stick &stick() { return _stick; }
|
||||
const G13_Stick &stick() const { return _stick; }
|
||||
|
||||
FontPtr switch_to_font(const std::string &name);
|
||||
void switch_to_profile(const std::string &name);
|
||||
ProfilePtr profile(const std::string &name);
|
||||
|
||||
void dump(std::ostream &, int detail = 0);
|
||||
void command(char const *str);
|
||||
|
||||
void read_commands();
|
||||
void read_config_file(const std::string &filename);
|
||||
|
||||
int read_keys();
|
||||
void parse_joystick(unsigned char *buf);
|
||||
|
||||
G13_ActionPtr make_action(const std::string &);
|
||||
|
||||
void set_key_color(int red, int green, int blue);
|
||||
void set_mode_leds(int leds);
|
||||
|
||||
void send_event(int type, int code, int val);
|
||||
void write_output_pipe(const std::string &out);
|
||||
|
||||
void write_lcd(unsigned char *data, size_t size);
|
||||
|
||||
bool is_set(int key);
|
||||
bool update(int key, bool v);
|
||||
|
||||
// used by G13_Manager
|
||||
void cleanup();
|
||||
void register_context(libusb_context *ctx);
|
||||
void write_lcd_file(const std::string &filename);
|
||||
|
||||
G13_Font ¤t_font() { return *_current_font; }
|
||||
G13_Profile ¤t_profile() { return *_current_profile; }
|
||||
|
||||
int id_within_manager() const { return _id_within_manager; }
|
||||
|
||||
typedef boost::function<void(const char *)> COMMAND_FUNCTION;
|
||||
typedef std::map<std::string, COMMAND_FUNCTION> CommandFunctionTable;
|
||||
|
||||
protected:
|
||||
void _init_fonts();
|
||||
void init_lcd();
|
||||
void _init_commands();
|
||||
|
||||
// typedef void (COMMAND_FUNCTION)( G13_Device*, const char *, const char * );
|
||||
CommandFunctionTable _command_table;
|
||||
|
||||
struct timeval _event_time;
|
||||
struct input_event _event;
|
||||
|
||||
int _id_within_manager;
|
||||
libusb_device_handle *handle;
|
||||
libusb_context *ctx;
|
||||
|
||||
int _uinput_fid;
|
||||
|
||||
int _input_pipe_fid;
|
||||
std::string _input_pipe_name;
|
||||
int _output_pipe_fid;
|
||||
std::string _output_pipe_name;
|
||||
|
||||
std::map<std::string, FontPtr> _fonts;
|
||||
FontPtr _current_font;
|
||||
std::map<std::string, ProfilePtr> _profiles;
|
||||
ProfilePtr _current_profile;
|
||||
|
||||
G13_Manager &_manager;
|
||||
G13_LCD _lcd;
|
||||
G13_Stick _stick;
|
||||
|
||||
bool keys[G13_NUM_KEYS];
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
/*!
|
||||
* top level class, holds what would otherwise be in global variables
|
||||
*/
|
||||
|
||||
class G13_Manager {
|
||||
public:
|
||||
G13_Manager();
|
||||
|
||||
G13_KEY_INDEX find_g13_key_value(const std::string &keyname) const;
|
||||
std::string find_g13_key_name(G13_KEY_INDEX) const;
|
||||
|
||||
LINUX_KEY_VALUE find_input_key_value(const std::string &keyname) const;
|
||||
std::string find_input_key_name(LINUX_KEY_VALUE) const;
|
||||
|
||||
void set_logo(const std::string &fn) { logo_filename = fn; }
|
||||
int run();
|
||||
|
||||
std::string string_config_value(const std::string &name) const;
|
||||
void set_string_config_value(const std::string &name, const std::string &val);
|
||||
|
||||
std::string make_pipe_name(G13_Device *d, bool is_input);
|
||||
|
||||
void set_log_level(::boost::log::trivial::severity_level lvl);
|
||||
void set_log_level(const std::string &);
|
||||
|
||||
protected:
|
||||
void init_keynames();
|
||||
void display_keys();
|
||||
void discover_g13s(libusb_device **devs, ssize_t count,
|
||||
std::vector<G13_Device *> &g13s);
|
||||
void cleanup();
|
||||
|
||||
std::string logo_filename;
|
||||
libusb_device **devs;
|
||||
|
||||
libusb_context *ctx;
|
||||
std::vector<G13_Device *> g13s;
|
||||
|
||||
std::map<G13_KEY_INDEX, std::string> g13_key_to_name;
|
||||
std::map<std::string, G13_KEY_INDEX> g13_name_to_key;
|
||||
std::map<LINUX_KEY_VALUE, std::string> input_key_to_name;
|
||||
std::map<std::string, LINUX_KEY_VALUE> input_name_to_key;
|
||||
|
||||
std::map<std::string, std::string> _string_config_values;
|
||||
|
||||
static bool running;
|
||||
static void set_stop(int);
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
// inlines
|
||||
|
||||
inline G13_Manager &G13_Action::manager() { return _keypad.manager(); }
|
||||
|
||||
inline const G13_Manager &G13_Action::manager() const {
|
||||
return _keypad.manager();
|
||||
}
|
||||
|
||||
inline bool G13_Device::is_set(int key) { return keys[key]; }
|
||||
|
||||
inline bool G13_Device::update(int key, bool v) {
|
||||
bool old = keys[key];
|
||||
keys[key] = v;
|
||||
return old != v;
|
||||
}
|
||||
|
||||
inline const G13_Manager &G13_Profile::manager() const {
|
||||
return _keypad.manager();
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // __G13_H__
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "g13.h"
|
||||
#include "device.h"
|
||||
#include "font.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -1,9 +1,15 @@
|
||||
/* This file contains code for managing keys an profiles
|
||||
*
|
||||
*/
|
||||
#include "g13.h"
|
||||
|
||||
using namespace std;
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "profile.h"
|
||||
#include "manager.h"
|
||||
#include "repr.h"
|
||||
#include "find_or_throw.h"
|
||||
#include "helper.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
|
@ -18,9 +18,11 @@
|
||||
A0.01 A1.01 A2.01 ...
|
||||
*/
|
||||
|
||||
#include "g13.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
#include "lcd.h"
|
||||
#include "device.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
@ -51,16 +53,16 @@ void G13_Device::write_lcd(unsigned char *data, size_t size) {
|
||||
<< error << ", " << bytes_written << " bytes written");
|
||||
}
|
||||
|
||||
void G13_Device::write_lcd_file(const string &filename) {
|
||||
filebuf *pbuf;
|
||||
ifstream filestr;
|
||||
void G13_Device::write_lcd_file(const std::string &filename) {
|
||||
std::filebuf *pbuf;
|
||||
std::ifstream filestr;
|
||||
size_t size;
|
||||
|
||||
filestr.open(filename.c_str());
|
||||
pbuf = filestr.rdbuf();
|
||||
|
||||
size = pbuf->pubseekoff(0, ios::end, ios::in);
|
||||
pbuf->pubseekpos(0, ios::in);
|
||||
size = pbuf->pubseekoff(0, std::ios::end, std::ios::in);
|
||||
pbuf->pubseekpos(0, std::ios::in);
|
||||
|
||||
char buffer[size];
|
||||
|
||||
|
@ -1,35 +1,30 @@
|
||||
#include "g13.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#if 0
|
||||
#include <boost/log/attributes.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/expressions/formatters/stream.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#endif
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "g13.h"
|
||||
#include "manager.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace G13;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
extern "C" {
|
||||
|
||||
G13_Manager manager;
|
||||
int main(int argc, char *argv[]) {
|
||||
G13::G13_Manager manager;
|
||||
manager.set_log_level("info");
|
||||
|
||||
// Declare the supported options.
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()("help", "produce help message");
|
||||
std::vector<std::string> sopt_names;
|
||||
|
||||
auto add_string_option = [&sopt_names, &desc](const char *name,
|
||||
const char *description) {
|
||||
desc.add_options()(name, po::value<std::string>(), description);
|
||||
sopt_names.push_back(name);
|
||||
};
|
||||
|
||||
add_string_option("logo", "set logo from file");
|
||||
add_string_option("config", "load config commands from file");
|
||||
add_string_option("pipe_in", "specify name for input pipe");
|
||||
@ -46,8 +41,8 @@ int main(int argc, char *argv[]) {
|
||||
po::notify(vm);
|
||||
|
||||
if (vm.count("help")) {
|
||||
cout << argv[0] << " : user space G13 driver" << endl;
|
||||
cout << desc << "\n";
|
||||
std::cout << argv[0] << " : user space G13 driver" << std::endl
|
||||
<< desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -66,4 +61,8 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
manager.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
/* This file contains code for managing keys and profiles
|
||||
*
|
||||
*/
|
||||
#include "g13.h"
|
||||
|
||||
using namespace std;
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "device.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
@ -67,21 +71,23 @@ void G13_Stick::set_mode(stick_mode_t m) {
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Stick::_recalc_calibrated() {}
|
||||
void G13_Stick::_recalc_calibrated() {
|
||||
}
|
||||
|
||||
void G13_Stick::remove_zone(const G13_StickZone &zone) {
|
||||
G13_StickZone target(zone);
|
||||
_zones.erase(std::remove(_zones.begin(), _zones.end(), target), _zones.end());
|
||||
}
|
||||
|
||||
void G13_Stick::dump(std::ostream &out) const {
|
||||
BOOST_FOREACH (const G13_StickZone &zone, _zones) {
|
||||
zone.dump(out);
|
||||
out << endl;
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G13_StickZone::dump(std::ostream &out) const {
|
||||
out << " " << setw(20) << name() << " " << _bounds << " ";
|
||||
out << " " << std::setw(20) << name() << " " << _bounds << " ";
|
||||
if (action()) {
|
||||
action()->dump(out);
|
||||
} else {
|
||||
|
@ -26,11 +26,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "helper.h"
|
||||
#include "repr.h"
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
namespace Helper {
|
||||
namespace G13 {
|
||||
|
||||
void string_repr_out::write_on(std::ostream &o) const {
|
||||
|
||||
|
110
g13d/helper.h
110
g13d/helper.h
@ -51,115 +51,13 @@
|
||||
|
||||
namespace Helper {
|
||||
|
||||
struct string_repr_out {
|
||||
string_repr_out(const std::string &str) : s(str) {}
|
||||
void write_on(std::ostream &) const;
|
||||
|
||||
std::string s;
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &o, const string_repr_out &sro) {
|
||||
sro.write_on(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <class T> inline const T &repr(const T &v) { return v; }
|
||||
|
||||
inline string_repr_out repr(const char *s) { return string_repr_out(s); }
|
||||
inline string_repr_out repr(const std::string &s) { return string_repr_out(s); }
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
class NotFoundException : public std::exception {
|
||||
public:
|
||||
const char *what() throw();
|
||||
};
|
||||
|
||||
template <class KEY_T, class VAL_T>
|
||||
inline const VAL_T &find_or_throw(const std::map<KEY_T, VAL_T> &m,
|
||||
const KEY_T &target) {
|
||||
auto i = m.find(target);
|
||||
if (i == m.end()) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
return i->second;
|
||||
};
|
||||
|
||||
template <class KEY_T, class VAL_T>
|
||||
inline VAL_T &find_or_throw(std::map<KEY_T, VAL_T> &m, const KEY_T &target) {
|
||||
auto i = m.find(target);
|
||||
if (i == m.end()) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
return i->second;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
template <class T> class Coord {
|
||||
public:
|
||||
Coord() : x(), y() {}
|
||||
Coord(T _x, T _y) : x(_x), y(_y) {}
|
||||
T x;
|
||||
T y;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::ostream &operator<<(std::ostream &o, const Coord<T> &c) {
|
||||
o << "{ " << c.x << " x " << c.y << " }";
|
||||
return o;
|
||||
};
|
||||
|
||||
template <class T> class Bounds {
|
||||
public:
|
||||
typedef Coord<T> CT;
|
||||
Bounds(const CT &_tl, const CT &_br) : tl(_tl), br(_br) {}
|
||||
Bounds(T x1, T y1, T x2, T y2) : tl(x1, y1), br(x2, y2) {}
|
||||
|
||||
bool contains(const CT &pos) const {
|
||||
return tl.x <= pos.x && tl.y <= pos.y && pos.x <= br.x && pos.y <= br.y;
|
||||
}
|
||||
|
||||
void expand(const CT &pos) {
|
||||
if (pos.x < tl.x)
|
||||
tl.x = pos.x;
|
||||
if (pos.y < tl.y)
|
||||
tl.y = pos.y;
|
||||
if (pos.x > br.x)
|
||||
br.x = pos.x;
|
||||
if (pos.y > br.y)
|
||||
br.y = pos.y;
|
||||
}
|
||||
CT tl;
|
||||
CT br;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::ostream &operator<<(std::ostream &o, const Bounds<T> &b) {
|
||||
o << "{ " << b.tl.x << " x " << b.tl.y << " / " << b.br.x << " x " << b.br.y
|
||||
<< " }";
|
||||
return o;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
typedef const char *CCP;
|
||||
inline const char *advance_ws(CCP &source, std::string &dest) {
|
||||
const char *space = source ? strchr(source, ' ') : 0;
|
||||
if (space) {
|
||||
dest = std::string(source, space - source);
|
||||
source = space + 1;
|
||||
} else {
|
||||
dest = source;
|
||||
source = 0;
|
||||
}
|
||||
return source;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
template <class MAP_T> struct _map_keys_out {
|
||||
_map_keys_out(const MAP_T &c, const std::string &s) : container(c), sep(s) {}
|
||||
_map_keys_out(const MAP_T &c, const std::string &s)
|
||||
: container(c), sep(s) {
|
||||
}
|
||||
|
||||
const MAP_T &container;
|
||||
std::string sep;
|
||||
};
|
||||
|
42
g13d/lcd.h
Normal file
42
g13d/lcd.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef LCD_H
|
||||
#define LCD_H
|
||||
|
||||
#include "g13.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_Device;
|
||||
|
||||
class G13_LCD {
|
||||
public:
|
||||
G13_LCD(G13_Device &keypad);
|
||||
|
||||
G13_Device &_keypad;
|
||||
unsigned char image_buf[G13_LCD_BUF_SIZE + 8];
|
||||
unsigned cursor_row;
|
||||
unsigned cursor_col;
|
||||
int text_mode;
|
||||
|
||||
void image(unsigned char *data, int size);
|
||||
void image_send() { image(image_buf, G13_LCD_BUF_SIZE); }
|
||||
|
||||
void image_test(int x, int y);
|
||||
void image_clear() { memset(image_buf, 0, G13_LCD_BUF_SIZE); }
|
||||
|
||||
unsigned image_byte_offset(unsigned row, unsigned col) {
|
||||
return col + (row / 8) * G13_LCD_BYTES_PER_ROW * 8;
|
||||
}
|
||||
|
||||
void image_setpixel(unsigned row, unsigned col);
|
||||
void image_clearpixel(unsigned row, unsigned col);
|
||||
|
||||
void write_char(char c, int row = -1, int col = -1);
|
||||
void write_string(const char *str);
|
||||
void write_pos(int row, int col);
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // LCD_H
|
@ -1,6 +1,3 @@
|
||||
#include "g13.h"
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/log/attributes.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
@ -12,10 +9,44 @@
|
||||
#include <boost/log/utility/setup.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
|
||||
using namespace std;
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "device.h"
|
||||
#include "manager.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
void G13_Manager::discover_g13s(libusb_device **devs, ssize_t count,
|
||||
std::vector<G13_Device *> &g13s) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
libusb_device_descriptor desc;
|
||||
int r = libusb_get_device_descriptor(devs[i], &desc);
|
||||
if (r < 0) {
|
||||
G13_LOG(error, "Failed to get device descriptor");
|
||||
return;
|
||||
}
|
||||
if (desc.idVendor == G13_VENDOR_ID && desc.idProduct == G13_PRODUCT_ID) {
|
||||
libusb_device_handle *handle;
|
||||
int r = libusb_open(devs[i], &handle);
|
||||
if (r != 0) {
|
||||
G13_LOG(error, "Error opening G13 device");
|
||||
return;
|
||||
}
|
||||
if (libusb_kernel_driver_active(handle, 0) == 1)
|
||||
if (libusb_detach_kernel_driver(handle, 0) == 0)
|
||||
G13_LOG(info, "Kernel driver detached");
|
||||
|
||||
r = libusb_claim_interface(handle, 0);
|
||||
if (r < 0) {
|
||||
G13_LOG(error, "Cannot Claim Interface");
|
||||
return;
|
||||
}
|
||||
g13s.push_back(new G13_Device(*this, handle, g13s.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G13_Manager::set_log_level(::boost::log::trivial::severity_level lvl) {
|
||||
boost::log::core::get()->set_filter(::boost::log::trivial::severity >= lvl);
|
||||
G13_OUT("set log level to " << lvl);
|
||||
@ -38,5 +69,4 @@ void G13_Manager::set_log_level(const std::string &level) {
|
||||
|
||||
G13_LOG(error, "unknown log level" << level);
|
||||
}
|
||||
|
||||
} // namespace G13
|
79
g13d/manager.h
Normal file
79
g13d/manager.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef MANAGER_H
|
||||
#define MANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "action.h"
|
||||
#include "device.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
/*!
|
||||
* top level class, holds what would otherwise be in global variables
|
||||
*/
|
||||
class G13_Manager {
|
||||
public:
|
||||
G13_Manager();
|
||||
|
||||
G13_KEY_INDEX find_g13_key_value(const std::string &keyname) const;
|
||||
std::string find_g13_key_name(G13_KEY_INDEX) const;
|
||||
|
||||
LINUX_KEY_VALUE find_input_key_value(const std::string &keyname) const;
|
||||
std::string find_input_key_name(LINUX_KEY_VALUE) const;
|
||||
|
||||
void set_logo(const std::string &fn) { logo_filename = fn; }
|
||||
int run();
|
||||
|
||||
std::string string_config_value(const std::string &name) const;
|
||||
void set_string_config_value(const std::string &name, const std::string &val);
|
||||
|
||||
std::string make_pipe_name(G13_Device *d, bool is_input);
|
||||
|
||||
void set_log_level(::boost::log::trivial::severity_level lvl);
|
||||
void set_log_level(const std::string &);
|
||||
|
||||
protected:
|
||||
void init_keynames();
|
||||
void display_keys();
|
||||
void discover_g13s(libusb_device **devs, ssize_t count,
|
||||
std::vector<G13_Device *> &g13s);
|
||||
void cleanup();
|
||||
|
||||
std::string logo_filename;
|
||||
libusb_device **devs;
|
||||
|
||||
libusb_context *ctx;
|
||||
std::vector<G13_Device *> g13s;
|
||||
|
||||
std::map<G13_KEY_INDEX, std::string> g13_key_to_name;
|
||||
std::map<std::string, G13_KEY_INDEX> g13_name_to_key;
|
||||
std::map<LINUX_KEY_VALUE, std::string> input_key_to_name;
|
||||
std::map<std::string, LINUX_KEY_VALUE> input_name_to_key;
|
||||
|
||||
std::map<std::string, std::string> _string_config_values;
|
||||
|
||||
static bool running;
|
||||
static void set_stop(int);
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
// inlines
|
||||
|
||||
inline G13_Manager &G13_Action::manager() {
|
||||
return _keypad.manager();
|
||||
}
|
||||
|
||||
inline const G13_Manager &G13_Action::manager() const {
|
||||
return _keypad.manager();
|
||||
}
|
||||
|
||||
inline const G13_Manager &G13_Profile::manager() const {
|
||||
return _keypad.manager();
|
||||
}
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // MANAGER_H
|
91
g13d/profile.h
Normal file
91
g13d/profile.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
#include "action.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_Device;
|
||||
class G13_Key;
|
||||
class G13_Profile;
|
||||
|
||||
/*! manages the bindings for a G13 key
|
||||
*
|
||||
*/
|
||||
class G13_Key : public G13_Actionable<G13_Profile> {
|
||||
public:
|
||||
void dump(std::ostream &o) const;
|
||||
G13_KEY_INDEX index() const { return _index.index; }
|
||||
|
||||
void parse_key(unsigned char *byte, G13_Device *g13);
|
||||
|
||||
protected:
|
||||
struct KeyIndex {
|
||||
KeyIndex(int key) : index(key), offset(key / 8), mask(1 << (key % 8)) {}
|
||||
|
||||
int index;
|
||||
unsigned char offset;
|
||||
unsigned char mask;
|
||||
};
|
||||
|
||||
// G13_Profile is the only class able to instantiate G13_Keys
|
||||
friend class G13_Profile;
|
||||
|
||||
G13_Key(G13_Profile &mode, const std::string &name, int index)
|
||||
: G13_Actionable<G13_Profile>(mode, name), _index(index),
|
||||
_should_parse(true) {
|
||||
}
|
||||
|
||||
G13_Key(G13_Profile &mode, const G13_Key &key)
|
||||
: G13_Actionable<G13_Profile>(mode, key.name()), _index(key._index),
|
||||
_should_parse(key._should_parse) {
|
||||
set_action(key.action());
|
||||
}
|
||||
|
||||
KeyIndex _index;
|
||||
bool _should_parse;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Represents a set of configured key mappings
|
||||
*
|
||||
* This allows a keypad to have multiple configured
|
||||
* profiles and switch between them easily
|
||||
*/
|
||||
class G13_Profile {
|
||||
public:
|
||||
G13_Profile(G13_Device &keypad, const std::string &name_arg)
|
||||
: _keypad(keypad), _name(name_arg) {
|
||||
_init_keys();
|
||||
}
|
||||
|
||||
G13_Profile(const G13_Profile &other, const std::string &name_arg)
|
||||
: _keypad(other._keypad), _name(name_arg), _keys(other._keys) {
|
||||
}
|
||||
|
||||
// search key by G13 keyname
|
||||
G13_Key *find_key(const std::string &keyname);
|
||||
|
||||
void dump(std::ostream &o) const;
|
||||
|
||||
void parse_keys(unsigned char *buf);
|
||||
const std::string &name() const { return _name; }
|
||||
|
||||
const G13_Manager &manager() const;
|
||||
|
||||
protected:
|
||||
G13_Device &_keypad;
|
||||
std::string _name;
|
||||
std::vector<G13_Key> _keys;
|
||||
|
||||
void _init_keys();
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<G13_Profile> ProfilePtr;
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // PROFILE_H
|
35
g13d/repr.h
Normal file
35
g13d/repr.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef REPR_H
|
||||
#define REPR_H
|
||||
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
namespace G13 {
|
||||
|
||||
struct string_repr_out {
|
||||
string_repr_out(const std::string &str) : s(str) {}
|
||||
void write_on(std::ostream &) const;
|
||||
|
||||
std::string s;
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &o, const string_repr_out &sro) {
|
||||
sro.write_on(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <class T> inline const T &repr(const T &v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
inline string_repr_out repr(const char *s) {
|
||||
return string_repr_out(s);
|
||||
}
|
||||
|
||||
inline string_repr_out repr(const std::string &s) {
|
||||
return string_repr_out(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // REPR_H
|
70
g13d/stick.h
Normal file
70
g13d/stick.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef STICK_H
|
||||
#define STICK_H
|
||||
|
||||
#include "coord.h"
|
||||
#include "bounds.h"
|
||||
#include "action.h"
|
||||
|
||||
namespace G13 {
|
||||
|
||||
class G13_Stick;
|
||||
|
||||
typedef Coord<int> G13_StickCoord;
|
||||
typedef Bounds<int> G13_StickBounds;
|
||||
typedef Coord<double> G13_ZoneCoord;
|
||||
typedef Bounds<double> G13_ZoneBounds;
|
||||
|
||||
class G13_StickZone : public G13_Actionable<G13_Stick> {
|
||||
public:
|
||||
G13_StickZone(G13_Stick &, const std::string &name, const G13_ZoneBounds &,
|
||||
G13_ActionPtr = 0);
|
||||
|
||||
bool operator==(const G13_StickZone &other) const {
|
||||
return _name == other._name;
|
||||
}
|
||||
|
||||
void dump(std::ostream &) const;
|
||||
|
||||
void parse_key(unsigned char *byte, G13_Device *g13);
|
||||
void test(const G13_ZoneCoord &loc);
|
||||
void set_bounds(const G13_ZoneBounds &bounds) { _bounds = bounds; }
|
||||
|
||||
protected:
|
||||
bool _active;
|
||||
G13_ZoneBounds _bounds;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<G13_StickZone> G13_StickZonePtr;
|
||||
|
||||
class G13_Stick {
|
||||
public:
|
||||
G13_Stick(G13_Device &keypad);
|
||||
|
||||
void parse_joystick(unsigned char *buf);
|
||||
|
||||
void set_mode(stick_mode_t);
|
||||
G13_StickZone *zone(const std::string &, bool create = false);
|
||||
void remove_zone(const G13_StickZone &zone);
|
||||
|
||||
const std::vector<G13_StickZone> &zones() const { return _zones; }
|
||||
|
||||
void dump(std::ostream &) const;
|
||||
|
||||
protected:
|
||||
void _recalc_calibrated();
|
||||
|
||||
G13_Device &_keypad;
|
||||
std::vector<G13_StickZone> _zones;
|
||||
|
||||
G13_StickBounds _bounds;
|
||||
G13_StickCoord _center_pos;
|
||||
G13_StickCoord _north_pos;
|
||||
|
||||
G13_StickCoord _current_pos;
|
||||
|
||||
stick_mode_t _stick_mode;
|
||||
};
|
||||
|
||||
} // namespace G13
|
||||
|
||||
#endif // STICK_H
|
Loading…
Reference in New Issue
Block a user