g13d: More symbol relocations and cleanups

Lots of cross-translation unit messes in here cleaned up finally. This should be
the last change necessary to clean up these refs between translation units.
This commit is contained in:
June Tate-Gans 2021-04-25 17:09:19 -05:00
parent 95b137f3db
commit a05dcb04c8
9 changed files with 267 additions and 279 deletions

View File

@ -14,10 +14,10 @@ add_executable(g13d
action.cc
device.cc
font.cc
g13_keys.cc
g13_lcd.cc
g13_main.cc
g13_stick.cc
profile.cc
lcd.cc
main.cc
stick.cc
helper.cc
manager.cc
)

View File

@ -546,4 +546,55 @@ void G13_Device::command(char const *str) {
}
}
void G13_Device::init_lcd() {
int error = libusb_control_transfer(handle, 0, 9, 1, 0, 0, 0, 1000);
if (error) {
G13_LOG(error, "Error when initializing lcd endpoint");
}
}
void G13_Device::write_lcd(unsigned char *data, size_t size) {
init_lcd();
if (size != G13_LCD_BUFFER_SIZE) {
G13_LOG(error, "Invalid LCD data size " << size << ", should be "
<< G13_LCD_BUFFER_SIZE);
return;
}
unsigned char buffer[G13_LCD_BUFFER_SIZE + 32];
memset(buffer, 0, G13_LCD_BUFFER_SIZE + 32);
buffer[0] = 0x03;
memcpy(buffer + 32, data, G13_LCD_BUFFER_SIZE);
int bytes_written;
int error = libusb_interrupt_transfer(
handle, LIBUSB_ENDPOINT_OUT | G13_LCD_ENDPOINT, buffer,
G13_LCD_BUFFER_SIZE + 32, &bytes_written, 1000);
if (error)
G13_LOG(error, "Error when transferring image: "
<< error << ", " << bytes_written << " bytes written");
}
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, std::ios::end, std::ios::in);
pbuf->pubseekpos(0, std::ios::in);
char buffer[size];
pbuf->sgetn(buffer, size);
filestr.close();
write_lcd((unsigned char *)buffer, size);
}
void G13_Device::parse_joystick(unsigned char *buf) {
_stick.parse_joystick(buf);
}
} // namespace G13

View File

@ -1,207 +0,0 @@
/* This file contains code for managing keys an profiles
*
*/
#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 {
/*! G13_KEY_SEQ is a Boost Preprocessor sequence containing the
* G13 keys. The order is very specific, with the position of each
* item corresponding to a specific bit in the G13's USB message
* format. Do NOT remove or insert items in this list.
*/
#define G13_KEY_SEQ \
/* byte 3 */ (G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8) /* byte 4 */ \
(G9)(G10)(G11)(G12)(G13)(G14)(G15)(G16) /* byte 5 */ (G17)(G18)(G19)( \
G20)(G21)(G22)(UNDEF1)(LIGHT_STATE) /* byte 6 */ \
(BD)(L1)(L2)(L3)(L4)(M1)(M2)(M3) /* byte 7 */ (MR)(LEFT)(DOWN)(TOP)( \
UNDEF3)(LIGHT)(LIGHT2)(MISC_TOGGLE)
/*! G13_NONPARSED_KEY_SEQ is a Boost Preprocessor sequence containing the
* G13 keys that shouldn't be tested input. These aren't actually keys,
* but they are in the bitmap defined by G13_KEY_SEQ.
*/
#define G13_NONPARSED_KEY_SEQ \
(UNDEF1)(LIGHT_STATE)(UNDEF3)(LIGHT)(LIGHT2)(UNDEF3)(MISC_TOGGLE)
/*! KB_INPUT_KEY_SEQ is a Boost Preprocessor sequence containing the
* names of keyboard keys we can send through binding actions.
* These correspond to KEY_xxx value definitions in <linux/input.h>,
* i.e. ESC is KEY_ESC, 1 is KEY_1, etc.
*/
#define KB_INPUT_KEY_SEQ \
(ESC)(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)(MINUS)(EQUAL)(BACKSPACE)(TAB)(Q)(W)(E)( \
R)(T)(Y)(U)(I)(O)(P)(LEFTBRACE)(RIGHTBRACE)(ENTER)(LEFTCTRL)(RIGHTCTRL)( \
A)(S)(D)(F)(G)(H)(J)(K)(L)(SEMICOLON)(APOSTROPHE)(GRAVE)(LEFTSHIFT)( \
BACKSLASH)(Z)(X)(C)(V)(B)(N)(M)(COMMA)(DOT)(SLASH)(RIGHTSHIFT)( \
KPASTERISK)(LEFTALT)(RIGHTALT)(SPACE)(CAPSLOCK)(F1)(F2)(F3)(F4)(F5)(F6)( \
F7)(F8)(F9)(F10)(F11)(F12)(NUMLOCK)(SCROLLLOCK)(KP7)(KP8)(KP9)(KPMINUS)( \
KP4)(KP5)(KP6)(KPPLUS)(KP1)(KP2)(KP3)(KP0)(KPDOT)(LEFT)(RIGHT)(UP)( \
DOWN)(PAGEUP)(PAGEDOWN)(HOME)(END)(INSERT)(DELETE)
// *************************************************************************
void G13_Profile::_init_keys() {
int key_index = 0;
// create a G13_Key entry for every key in G13_KEY_SEQ
#define INIT_KEY(r, data, elem) \
{ \
G13_Key key(*this, BOOST_PP_STRINGIZE(elem), key_index++); \
_keys.push_back(key); \
}
BOOST_PP_SEQ_FOR_EACH(INIT_KEY, _, G13_KEY_SEQ)
assert(_keys.size() == G13_NUM_KEYS);
// now disable testing for keys in G13_NONPARSED_KEY_SEQ
#define MARK_NON_PARSED_KEY(r, data, elem) \
{ \
G13_Key *key = find_key(BOOST_PP_STRINGIZE(elem)); \
assert(key); \
key->_should_parse = false; \
}
BOOST_PP_SEQ_FOR_EACH(MARK_NON_PARSED_KEY, _, G13_NONPARSED_KEY_SEQ)
}
// *************************************************************************
void G13_Key::dump(std::ostream &o) const {
o << manager().find_g13_key_name(index()) << "(" << index() << ") : ";
if (action()) {
action()->dump(o);
} else {
o << "(no action)";
}
}
void G13_Profile::dump(std::ostream &o) const {
o << "Profile " << repr(name()) << std::endl;
BOOST_FOREACH (const G13_Key &key, _keys) {
if (key.action()) {
o << " ";
key.dump(o);
o << std::endl;
}
}
}
void G13_Profile::parse_keys(unsigned char *buf) {
buf += 3;
for (size_t i = 0; i < _keys.size(); i++) {
if (_keys[i]._should_parse) {
_keys[i].parse_key(buf, &_keypad);
}
}
}
G13_Key *G13_Profile::find_key(const std::string &keyname) {
auto key = _keypad.manager().find_g13_key_value(keyname);
// TODO(jtgans): Check this is the proper type
if (key >= 0 && key < static_cast<int>(_keys.size())) {
return &_keys[key];
}
return 0;
}
// *************************************************************************
void G13_Key::parse_key(unsigned char *byte, G13_Device *g13) {
bool key_is_down = byte[_index.offset] & _index.mask;
bool key_state_changed = g13->update(_index.index, key_is_down);
if (key_state_changed && _action) {
_action->act(*g13, key_is_down);
}
}
// *************************************************************************
void G13_Manager::init_keynames() {
int key_index = 0;
// setup maps to let us convert between strings and G13 key names
#define ADD_G13_KEY_MAPPING(r, data, elem) \
{ \
std::string name = BOOST_PP_STRINGIZE(elem); \
g13_key_to_name[key_index] = name; \
g13_name_to_key[name] = key_index; \
key_index++; \
}
BOOST_PP_SEQ_FOR_EACH(ADD_G13_KEY_MAPPING, _, G13_KEY_SEQ)
// setup maps to let us convert between strings and linux key names
#define ADD_KB_KEY_MAPPING(r, data, elem) \
{ \
std::string name = BOOST_PP_STRINGIZE(elem); \
int keyval = BOOST_PP_CAT(KEY_, elem); \
input_key_to_name[keyval] = name; \
input_name_to_key[name] = keyval; \
}
BOOST_PP_SEQ_FOR_EACH(ADD_KB_KEY_MAPPING, _, KB_INPUT_KEY_SEQ)
}
LINUX_KEY_VALUE
G13_Manager::find_g13_key_value(const std::string &keyname) const {
auto i = g13_name_to_key.find(keyname);
if (i == g13_name_to_key.end()) {
return BAD_KEY_VALUE;
}
return i->second;
}
LINUX_KEY_VALUE
G13_Manager::find_input_key_value(const std::string &keyname) const {
// if there is a KEY_ prefix, strip it off
if (!strncmp(keyname.c_str(), "KEY_", 4)) {
return find_input_key_value(keyname.c_str() + 4);
}
auto i = input_name_to_key.find(keyname);
if (i == input_name_to_key.end()) {
return BAD_KEY_VALUE;
}
return i->second;
}
std::string G13_Manager::find_input_key_name(LINUX_KEY_VALUE v) const {
try {
return find_or_throw(input_key_to_name, v);
} catch (...) {
return "(unknown linux key)";
}
}
std::string G13_Manager::find_g13_key_name(G13_KEY_INDEX v) const {
try {
return find_or_throw(g13_key_to_name, v);
} catch (...) {
return "(unknown G13 key)";
}
}
void G13_Manager::display_keys() {
G13_OUT("Known keys on G13:");
G13_OUT(Helper::map_keys_out(g13_name_to_key));
G13_OUT("Known keys to map to:");
G13_OUT(Helper::map_keys_out(input_name_to_key));
}
} // namespace G13

View File

@ -26,52 +26,6 @@
namespace G13 {
void G13_Device::init_lcd() {
int error = libusb_control_transfer(handle, 0, 9, 1, 0, 0, 0, 1000);
if (error) {
G13_LOG(error, "Error when initializing lcd endpoint");
}
}
void G13_Device::write_lcd(unsigned char *data, size_t size) {
init_lcd();
if (size != G13_LCD_BUFFER_SIZE) {
G13_LOG(error, "Invalid LCD data size " << size << ", should be "
<< G13_LCD_BUFFER_SIZE);
return;
}
unsigned char buffer[G13_LCD_BUFFER_SIZE + 32];
memset(buffer, 0, G13_LCD_BUFFER_SIZE + 32);
buffer[0] = 0x03;
memcpy(buffer + 32, data, G13_LCD_BUFFER_SIZE);
int bytes_written;
int error = libusb_interrupt_transfer(
handle, LIBUSB_ENDPOINT_OUT | G13_LCD_ENDPOINT, buffer,
G13_LCD_BUFFER_SIZE + 32, &bytes_written, 1000);
if (error)
G13_LOG(error, "Error when transferring image: "
<< error << ", " << bytes_written << " bytes written");
}
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, std::ios::end, std::ios::in);
pbuf->pubseekpos(0, std::ios::in);
char buffer[size];
pbuf->sgetn(buffer, size);
filestr.close();
write_lcd((unsigned char *)buffer, size);
}
void G13_LCD::image(unsigned char *data, int size) {
_keypad.write_lcd(data, size);
}

View File

@ -10,10 +10,14 @@
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/foreach.hpp>
#include <fstream>
#include <vector>
#include "helper.h"
#include "device.h"
#include "manager.h"
#include "find_or_throw.h"
@ -203,4 +207,77 @@ int G13_Manager::run() {
return 0;
}
// setup maps to let us convert between strings and G13 key names
#define ADD_G13_KEY_MAPPING(r, data, elem) \
{ \
std::string name = BOOST_PP_STRINGIZE(elem); \
g13_key_to_name[key_index] = name; \
g13_name_to_key[name] = key_index; \
key_index++; \
}
// setup maps to let us convert between strings and linux key names
#define ADD_KB_KEY_MAPPING(r, data, elem) \
{ \
std::string name = BOOST_PP_STRINGIZE(elem); \
int keyval = BOOST_PP_CAT(KEY_, elem); \
input_key_to_name[keyval] = name; \
input_name_to_key[name] = keyval; \
}
void G13_Manager::init_keynames() {
int key_index = 0;
BOOST_PP_SEQ_FOR_EACH(ADD_G13_KEY_MAPPING, _, G13_KEY_SEQ);
BOOST_PP_SEQ_FOR_EACH(ADD_KB_KEY_MAPPING, _, KB_INPUT_KEY_SEQ);
}
LINUX_KEY_VALUE
G13_Manager::find_g13_key_value(const std::string &keyname) const {
auto i = g13_name_to_key.find(keyname);
if (i == g13_name_to_key.end()) {
return BAD_KEY_VALUE;
}
return i->second;
}
LINUX_KEY_VALUE
G13_Manager::find_input_key_value(const std::string &keyname) const {
// if there is a KEY_ prefix, strip it off
if (!strncmp(keyname.c_str(), "KEY_", 4)) {
return find_input_key_value(keyname.c_str() + 4);
}
auto i = input_name_to_key.find(keyname);
if (i == input_name_to_key.end()) {
return BAD_KEY_VALUE;
}
return i->second;
}
std::string G13_Manager::find_input_key_name(LINUX_KEY_VALUE v) const {
try {
return find_or_throw(input_key_to_name, v);
} catch (...) {
return "(unknown linux key)";
}
}
std::string G13_Manager::find_g13_key_name(G13_KEY_INDEX v) const {
try {
return find_or_throw(g13_key_to_name, v);
} catch (...) {
return "(unknown G13 key)";
}
}
void G13_Manager::display_keys() {
G13_OUT("Known keys on G13:");
G13_OUT(Helper::map_keys_out(g13_name_to_key));
G13_OUT("Known keys to map to:");
G13_OUT(Helper::map_keys_out(input_name_to_key));
}
} // namespace G13

91
g13d/profile.cc Normal file
View File

@ -0,0 +1,91 @@
/* This file contains code for managing keys an profiles
*
*/
#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 {
// *************************************************************************
void G13_Key::dump(std::ostream &o) const {
o << manager().find_g13_key_name(index()) << "(" << index() << ") : ";
if (action()) {
action()->dump(o);
} else {
o << "(no action)";
}
}
void G13_Key::parse_key(unsigned char *byte, G13_Device *g13) {
bool key_is_down = byte[_index.offset] & _index.mask;
bool key_state_changed = g13->update(_index.index, key_is_down);
if (key_state_changed && _action) {
_action->act(*g13, key_is_down);
}
}
void G13_Profile::_init_keys() {
int key_index = 0;
// create a G13_Key entry for every key in G13_KEY_SEQ
#define INIT_KEY(r, data, elem) \
{ \
G13_Key key(*this, BOOST_PP_STRINGIZE(elem), key_index++); \
_keys.push_back(key); \
}
BOOST_PP_SEQ_FOR_EACH(INIT_KEY, _, G13_KEY_SEQ)
assert(_keys.size() == G13_NUM_KEYS);
// now disable testing for keys in G13_NONPARSED_KEY_SEQ
#define MARK_NON_PARSED_KEY(r, data, elem) \
{ \
G13_Key *key = find_key(BOOST_PP_STRINGIZE(elem)); \
assert(key); \
key->_should_parse = false; \
}
BOOST_PP_SEQ_FOR_EACH(MARK_NON_PARSED_KEY, _, G13_NONPARSED_KEY_SEQ)
}
void G13_Profile::dump(std::ostream &o) const {
o << "Profile " << repr(name()) << std::endl;
BOOST_FOREACH (const G13_Key &key, _keys) {
if (key.action()) {
o << " ";
key.dump(o);
o << std::endl;
}
}
}
void G13_Profile::parse_keys(unsigned char *buf) {
buf += 3;
for (size_t i = 0; i < _keys.size(); i++) {
if (_keys[i]._should_parse) {
_keys[i].parse_key(buf, &_keypad);
}
}
}
G13_Key *G13_Profile::find_key(const std::string &keyname) {
auto key = _keypad.manager().find_g13_key_value(keyname);
// TODO(jtgans): Check this is the proper type
if (key >= 0 && key < static_cast<int>(_keys.size())) {
return &_keys[key];
}
return 0;
}
} // namespace G13

View File

@ -6,6 +6,40 @@
#include "action.h"
/*! G13_KEY_SEQ is a Boost Preprocessor sequence containing the
* G13 keys. The order is very specific, with the position of each
* item corresponding to a specific bit in the G13's USB message
* format. Do NOT remove or insert items in this list.
*/
#define G13_KEY_SEQ \
/* byte 3 */ (G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8) /* byte 4 */ \
(G9)(G10)(G11)(G12)(G13)(G14)(G15)(G16) /* byte 5 */ (G17)(G18)(G19)( \
G20)(G21)(G22)(UNDEF1)(LIGHT_STATE) /* byte 6 */ \
(BD)(L1)(L2)(L3)(L4)(M1)(M2)(M3) /* byte 7 */ (MR)(LEFT)(DOWN)(TOP)( \
UNDEF3)(LIGHT)(LIGHT2)(MISC_TOGGLE)
/*! G13_NONPARSED_KEY_SEQ is a Boost Preprocessor sequence containing the
* G13 keys that shouldn't be tested input. These aren't actually keys,
* but they are in the bitmap defined by G13_KEY_SEQ.
*/
#define G13_NONPARSED_KEY_SEQ \
(UNDEF1)(LIGHT_STATE)(UNDEF3)(LIGHT)(LIGHT2)(UNDEF3)(MISC_TOGGLE)
/*! KB_INPUT_KEY_SEQ is a Boost Preprocessor sequence containing the
* names of keyboard keys we can send through binding actions.
* These correspond to KEY_xxx value definitions in <linux/input.h>,
* i.e. ESC is KEY_ESC, 1 is KEY_1, etc.
*/
#define KB_INPUT_KEY_SEQ \
(ESC)(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)(MINUS)(EQUAL)(BACKSPACE)(TAB)(Q)(W)(E)( \
R)(T)(Y)(U)(I)(O)(P)(LEFTBRACE)(RIGHTBRACE)(ENTER)(LEFTCTRL)(RIGHTCTRL)( \
A)(S)(D)(F)(G)(H)(J)(K)(L)(SEMICOLON)(APOSTROPHE)(GRAVE)(LEFTSHIFT)( \
BACKSLASH)(Z)(X)(C)(V)(B)(N)(M)(COMMA)(DOT)(SLASH)(RIGHTSHIFT)( \
KPASTERISK)(LEFTALT)(RIGHTALT)(SPACE)(CAPSLOCK)(F1)(F2)(F3)(F4)(F5)(F6)( \
F7)(F8)(F9)(F10)(F11)(F12)(NUMLOCK)(SCROLLLOCK)(KP7)(KP8)(KP9)(KPMINUS)( \
KP4)(KP5)(KP6)(KPPLUS)(KP1)(KP2)(KP3)(KP0)(KPDOT)(LEFT)(RIGHT)(UP)( \
DOWN)(PAGEUP)(PAGEDOWN)(HOME)(END)(INSERT)(DELETE)
namespace G13 {
class G13_Device;

View File

@ -11,12 +11,6 @@
namespace G13 {
// *************************************************************************
void G13_Device::parse_joystick(unsigned char *buf) {
_stick.parse_joystick(buf);
}
G13_Stick::G13_Stick(G13_Device &keypad)
: _keypad(keypad), _bounds(0, 0, 255, 255), _center_pos(127, 127),
_north_pos(127, 0) {
@ -38,17 +32,18 @@ G13_Stick::G13_Stick(G13_Device &keypad)
}
G13_StickZone *G13_Stick::zone(const std::string &name, bool create) {
BOOST_FOREACH (G13_StickZone &zone, _zones) {
if (zone.name() == name) {
return &zone;
}
}
if (create) {
_zones.push_back(
G13_StickZone(*this, name, G13_ZoneBounds(0.0, 0.0, 0.0, 0.0)));
return zone(name);
}
return 0;
}
@ -88,6 +83,7 @@ void G13_Stick::dump(std::ostream &out) const {
void G13_StickZone::dump(std::ostream &out) const {
out << " " << std::setw(20) << name() << " " << _bounds << " ";
if (action()) {
action()->dump(out);
} else {
@ -96,17 +92,14 @@ void G13_StickZone::dump(std::ostream &out) const {
}
void G13_StickZone::test(const G13_ZoneCoord &loc) {
if (!_action)
return;
if (!_action) return;
bool prior_active = _active;
_active = _bounds.contains(loc);
if (!_active) {
if (prior_active) {
// cout << "exit stick zone " << _name << std::endl;
_action->act(false);
}
if ((!_active) && prior_active) {
_action->act(false);
} else {
// cout << "in stick zone " << _name << std::endl;
_action->act(true);
}
}
@ -118,7 +111,6 @@ G13_StickZone::G13_StickZone(G13_Stick &stick, const std::string &name,
}
void G13_Stick::parse_joystick(unsigned char *buf) {
_current_pos.x = buf[1];
_current_pos.y = buf[2];
@ -150,6 +142,7 @@ void G13_Stick::parse_joystick(unsigned char *buf) {
dx /= (_bounds.br.x - _center_pos.x) * 2;
dx = 1.0 - dx;
}
double dy = 0.5;
if (_current_pos.y <= _center_pos.y) {
dy = _current_pos.y - _bounds.tl.y;
@ -162,19 +155,14 @@ void G13_Stick::parse_joystick(unsigned char *buf) {
G13_LOG(trace, "x=" << _current_pos.x << " y=" << _current_pos.y
<< " dx=" << dx << " dy=" << dy);
G13_ZoneCoord jpos(dx, dy);
if (_stick_mode == STICK_ABSOLUTE) {
_keypad.send_event(EV_ABS, ABS_X, _current_pos.x);
_keypad.send_event(EV_ABS, ABS_Y, _current_pos.y);
} else if (_stick_mode == STICK_KEYS) {
BOOST_FOREACH (G13_StickZone &zone, _zones) { zone.test(jpos); }
return;
} else {
/* send_event(g13->uinput_file, EV_REL, REL_X, stick_x/16 - 8);
send_event(g13->uinput_file, EV_REL, REL_Y, stick_y/16 - 8);*/
}
}