This commit is contained in:
Paul Healy 2015-11-15 14:09:43 +00:00
commit d278f9bcb8
10 changed files with 350 additions and 84 deletions

View File

@ -1 +1,2 @@
SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c21c", MODE="0666"

View File

@ -1,16 +1,27 @@
FLAGS=$(CXXFLAGS) -DBOOST_LOG_DYN_LINK -std=c++0x
LIBS=-lusb-1.0 -lboost_log -lboost_log_setup-mt -lboost_thread -lboost_system-mt -lpthread
all: g13d pbm2lpbm
g13d: g13.h g13.cc
g++ -o g13d -std=c++0x g13.cc -lusb-1.0
g13d: g13.o g13map.o g13logging.o
$(CXX) $(FLAGS) -o $@ $^ $(LIBS) $(LDFLAGS)
g13.o: g13.cc g13.h g13logging.h g13map.h logo.h
g13map.o: g13map.cc g13map.h
g13logging.o: g13logging.cc g13logging.h
%.o: %.cc
$(CXX) $(FLAGS) -c $(FLAGS) -o $@ $<
pbm2lpbm: pbm2lpbm.c
g++ -o pbm2lpbm pbm2lpbm.c
$(CXX) $(FLAGS) -o pbm2lpbm pbm2lpbm.c $(LDFLAGS)
package:
rm -Rf g13-userspace
mkdir g13-userspace
cp g13.cc g13.h logo.h Makefile pbm2lpbm.c g13-userspace
cp *.cc *.h Makefile g13-userspace
tar cjf g13-userspace.tbz2 g13-userspace
rm -Rf g13-userspace
clean:
rm -f g13 pbm2lpbm
rm -f g13d *.o pbm2lpbm

View File

@ -12,13 +12,13 @@ If you want to run the daemon as user, put the file 91-g13.rules into /etc/udev/
Connect your device, then run ./g13, it should automatically find your device.
If you see output like
```
Known keys on G13:
BD DOWN G1 G10 G11 G12 G13 G14 G15 G16 G17 G18 G19 G2 G20 G21 G22 G3 G4 G5 G6 G7 G8 G9 L1 L2 L3 L4 LEFT LIGHT LIGHT_STATE M1 M2 M3 MR TOP STICK_LEFT STICK_RIGHT STICK_UP STICK_DOWN
Known keys to map to:
KEY_0 KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9 KEY_A KEY_APOSTROPHE KEY_B KEY_BACKSLASH KEY_BACKSPACE KEY_C KEY_CAPSLOCK KEY_COMMA KEY_D KEY_DOT KEY_DOWN KEY_E KEY_ENTER KEY_EQUAL KEY_ESC KEY_F KEY_F1 KEY_F10 KEY_F2 KEY_F3 KEY_F4 KEY_F5 KEY_F6 KEY_F7 KEY_F8 KEY_F9 KEY_G KEY_GRAVE KEY_H KEY_I KEY_J KEY_K KEY_KP0 KEY_KP1 KEY_KP2 KEY_KP3 KEY_KP4 KEY_KP5 KEY_KP6 KEY_KP7 KEY_KP8 KEY_KP9 KEY_KPASTERISK KEY_KPDOT KEY_KPMINUS KEY_KPPLUS KEY_L KEY_LEFT KEY_LEFTALT KEY_LEFTBRACE KEY_LEFTCTRL KEY_LEFTSHIFT KEY_M KEY_MINUS KEY_N KEY_NUMLOCK KEY_O KEY_P KEY_Q KEY_R KEY_RIGHT KEY_RIGHTBRACE KEY_RIGHTSHIFT KEY_S KEY_SCROLLLOCK KEY_SEMICOLON KEY_SLASH KEY_SPACE KEY_T KEY_TAB KEY_U KEY_UP KEY_V KEY_W KEY_X KEY_Y KEY_Z
Found 1 G13s
```
that is good. This also shows you which name the keys on the G13 have, and what keys you can bind them to.
** Commands
@ -38,6 +38,17 @@ would set M1, M3 and MR, and unset M2).
This binds a key. The possible values of <keyname> are shown upon startup (e.g. G1), same for <binding> (e.g. KEY_LEFTSHIFT).
A single G13 key press can be mapped to multiple key events using this syntax:
```
bind G1 KEY_LEFTCTRL KEY_F
bind G2 KEY_LEFTSHIFT KEY_G
bind G3 KEY_LEFTALT KEY_H
bind G4 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_I
bind G5 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_LEFTALT KEY_J
bind G6 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_LEFTALT KEY_K # this is a comment
```
This is useful in the case of modifiers.
*** Stick mode
The stick can be used as an absolute input device or can send key events. Right now there is no command for this, you need to edit the source (file g13.cc, around line 622, this->stick_mode = STICK_KEYS, change to this->stick_mode = STICK_ABSOLUTE).

152
g13.cc
View File

@ -1,9 +1,12 @@
#include <libusb-1.0/libusb.h>
#include <iostream>
#include <vector>
#include <cerrno>
#include <memory>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/log/trivial.hpp>
#include <iomanip>
#include <sys/stat.h>
#include "logo.h"
@ -16,6 +19,7 @@
#include <linux/uinput.h>
#include <fcntl.h>
#include "g13.h"
#include "g13logging.h"
using namespace std;
@ -74,7 +78,7 @@ void g13_set_mode_leds(libusb_device_handle *handle, int leds) {
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) {
cerr << "Problem sending data" << endl;
BOOST_LOG_TRIVIAL(error) << "Problem sending leds data";
return;
}
}
@ -87,7 +91,7 @@ void g13_set_key_color(libusb_device_handle *handle, int red, int green, int blu
error = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 9, 0x307, 0, usb_data, 5, 1000);
if(error != 5) {
cerr << "Problem sending data" << endl;
BOOST_LOG_TRIVIAL(error) << "Problem sending color data";
return;
}
}
@ -100,8 +104,18 @@ void send_event(int file, int type, int code, int val) {
event.type = type;
event.code = code;
event.value = val;
write(file, &event, sizeof(event));
const int result = write(file, &event, sizeof(event));
if (result != sizeof(event)) {
if (result == -1) {
BOOST_LOG_TRIVIAL(error) << "Problem writing uinput event: result=" << result << ", error=" << strerror(errno);
} else {
BOOST_LOG_TRIVIAL(error) << "Problem writing uinput event: result=" << result;
}
}
}
void g13_parse_joystick(unsigned char *buf, g13_keypad *g13) {
int stick_x = buf[1];
int stick_y = buf[2];
@ -142,8 +156,14 @@ void g13_parse_key(int key, unsigned char *byte, g13_keypad *g13) {
unsigned char actual_byte = byte[key / 8];
unsigned char mask = 1 << (key % 8);
if(bool value = g13->update(key, actual_byte & mask)) {
// cout << g13->mapping(key) << ": " << g13->is_set(key) << endl;
send_event(g13->uinput_file, EV_KEY, g13->mapping(key), g13->is_set(key));
const std::list<int>& keys = g13->keymap->mapping(key);
for (std::list<int>::const_iterator it = keys.begin(); it!= keys.end(); it++) {
BOOST_LOG_TRIVIAL(debug) << "parsekey:" << *it << ": " << g13->is_set(key);
send_event(g13->uinput_file, EV_KEY, *it, g13->is_set(key));
}
}
}
void g13_parse_keys(unsigned char *buf, g13_keypad *g13) {
@ -198,7 +218,7 @@ void g13_parse_keys(unsigned char *buf, g13_keypad *g13) {
void g13_init_lcd(libusb_device_handle *handle) {
int error = libusb_control_transfer(handle, 0, 9, 1, 0, null, 0, 1000);
if(error) {
cerr << "Error when initialising lcd endpoint" << endl;
BOOST_LOG_TRIVIAL(error) << "Error when initialising lcd endpoint";
}
}
void g13_deregister(g13_keypad *g13) {
@ -211,22 +231,22 @@ void discover_g13s(libusb_device **devs, ssize_t count, vector<g13_keypad*>& g13
libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(devs[i], &desc);
if(r < 0) {
cout << "Failed to get device descriptor" << endl;
BOOST_LOG_TRIVIAL(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) {
cerr << "Error opening G13 device" << endl;
BOOST_LOG_TRIVIAL(error) << "Error opening G13 device";
return;
}
if(libusb_kernel_driver_active(handle, 0) == 1)
if(libusb_detach_kernel_driver(handle, 0) == 0)
cout << "Kernel driver detached" << endl;
BOOST_LOG_TRIVIAL(info) << "Kernel driver detached";
r = libusb_claim_interface(handle, 0);
if(r < 0) {
cerr << "Cannot Claim Interface" << endl;
BOOST_LOG_TRIVIAL(error) << "Cannot Claim Interface";
return;
}
g13s.push_back(new g13_keypad(handle, g13_count++));
@ -239,7 +259,7 @@ void discover_g13s(libusb_device **devs, ssize_t count, vector<g13_keypad*>& g13
void g13_write_lcd(libusb_context *ctx, libusb_device_handle *handle, unsigned char *data, size_t size) {
g13_init_lcd(handle);
if(size != G13_LCD_BUFFER_SIZE) {
cerr << "Invalid LCD data size " << size << ", should be " << G13_LCD_BUFFER_SIZE;
BOOST_LOG_TRIVIAL(error) << "Invalid LCD data size " << size << ", should be " << G13_LCD_BUFFER_SIZE;
return;
}
unsigned char buffer[G13_LCD_BUFFER_SIZE + 32];
@ -249,7 +269,7 @@ void g13_write_lcd(libusb_context *ctx, libusb_device_handle *handle, unsigned c
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)
cerr << "Error when transfering image: " << error << ", " << bytes_written << " bytes written" << endl;
BOOST_LOG_TRIVIAL(error) << "Error when transfering image: " << error << ", " << bytes_written << " bytes written";
}
int g13_create_fifo(g13_keypad *g13) {
mkfifo(g13->fifo_name(), 0666);
@ -262,16 +282,16 @@ int g13_create_uinput(g13_keypad *g13) {
: access("/dev/uinput", F_OK)==0 ? "/dev/uinput"
: 0;
if(!dev_uinput_fname) {
cerr << "Could not find an uinput device" << endl;
BOOST_LOG_TRIVIAL(error) << "Could not find an uinput device";
return -1;
}
if(access(dev_uinput_fname, W_OK) != 0) {
cerr << dev_uinput_fname << " doesn't grant write permissions" << endl;
BOOST_LOG_TRIVIAL(error) << dev_uinput_fname << " doesn't grant write permissions";
return -1;
}
int ufile = open(dev_uinput_fname, O_WRONLY | O_NDELAY);
if(ufile <= 0) {
cerr << "Could not open uinput" << endl;
BOOST_LOG_TRIVIAL(error) << "Could not open uinput";
return -1;
}
memset(&uinp, 0, sizeof(uinp));
@ -304,12 +324,12 @@ int g13_create_uinput(g13_keypad *g13) {
int retcode = write(ufile, &uinp, sizeof(uinp));
if(retcode < 0) {
cerr << "Could not write to uinput device (" << retcode << ")" << endl;
BOOST_LOG_TRIVIAL(error) << "Could not write to uinput device (" << retcode << ")";
return -1;
}
retcode = ioctl(ufile, UI_DEV_CREATE);
if(retcode) {
cerr << "Error creating uinput device for G13" << endl;
BOOST_LOG_TRIVIAL(error) << "Error creating uinput device for G13";
return -1;
}
return ufile;
@ -366,7 +386,7 @@ int g13_read_keys(g13_keypad *g13) {
errors[LIBUSB_ERROR_NO_MEM] = "LIBUSB_ERROR_NO_MEM";
errors[LIBUSB_ERROR_NOT_SUPPORTED] = "LIBUSB_ERROR_NOT_SUPPORTED";
errors[LIBUSB_ERROR_OTHER ] = "LIBUSB_ERROR_OTHER ";
cerr << "Error while reading keys: " << error << " (" << errors[error] << ")" << endl;
BOOST_LOG_TRIVIAL(error) << "Error while reading keys: " << error << " (" << errors[error] << ")";
// cerr << "Stopping daemon" << endl;
// return -1;
}
@ -389,12 +409,13 @@ void g13_destroy_uinput(g13_keypad *g13) {
libusb_context *ctx = null;
vector<g13_keypad*> g13s;
void cleanup(int n = 0) {
// cout << "cleaning up" << endl;
void cleanup() {
BOOST_LOG_TRIVIAL(info) << "cleanup called";
for(int i = 0; i < g13s.size(); i++) {
g13_destroy_uinput(g13s[i]);
g13_destroy_fifo(g13s[i]);
g13_deregister(g13s[i]);
delete g13s[i]->keymap;
delete g13s[i];
}
libusb_exit(ctx);
@ -415,20 +436,20 @@ void g13_read_commands(g13_keypad *g13) {
unsigned char buf[1024*1024];
memset(buf, 0, 1024*1024);
ret = read(g13->fifo, buf, 1024*1024);
// std::cout << "INFO: read " << ret << " characters" << std::endl;
BOOST_LOG_TRIVIAL(debug) << "INFO: read " << ret << " characters";
if(ret == 960) { // TODO probably image, for now, don't test, just assume image
g13->image(buf, ret);
} else {
std::string buffer = reinterpret_cast<const char*>(buf);
std::vector<std::string> lines;
boost::split(lines, buffer, boost::is_any_of("\n\r"));
// std::cout << "INFO: lines: " << lines.size() << std::endl;
BOOST_LOG_TRIVIAL(debug) << "INFO: lines: " << lines.size();
BOOST_FOREACH(std::string const &cmd, lines) {
std::vector<std::string> command;
boost::split(command, cmd, boost::is_any_of("#"));
// std::cout << "INFO: command [" << command.size() << "]: " << command[0] << " (" << command[0].size() << ")" << std::endl;
BOOST_LOG_TRIVIAL(debug) << "INFO: command [" << command.size() << "]: " << command[0] << " (" << command[0].size() << ")";
if(command.size() > 0 && command[0] != std::string("")) {
cout << "command: " << command[0] << endl;
BOOST_LOG_TRIVIAL(info) << "command: " << command[0];
g13->command(command[0].c_str());
}
}
@ -578,65 +599,74 @@ void init_keynames() {
}
void display_keys() {
typedef std::map<std::string,int> mapType;
std::cout << "Known keys on G13:" << std::endl;
BOOST_LOG_TRIVIAL(info) << "Known keys on G13:";
BOOST_FOREACH(const mapType::value_type &item, name_to_key) {
std::cout << item.first << " ";
BOOST_LOG_TRIVIAL(info) << " " << item.first;
}
std::cout << "STICK_LEFT " << "STICK_RIGHT " << "STICK_UP " << "STICK_DOWN ";
std::cout << std::endl;
std::cout << "Known keys to map to:" << std::endl;
BOOST_FOREACH(const mapType::value_type &item, input_name_to_key) {
std::cout << item.first << " ";
}
std::cout << std::endl;
BOOST_LOG_TRIVIAL(info) << "STICK_LEFT " << "STICK_RIGHT " << "STICK_UP " << "STICK_DOWN";
BOOST_LOG_TRIVIAL(info) << "Known keys to map to:";
BOOST_FOREACH(const mapType::value_type &item, input_name_to_key) {
BOOST_LOG_TRIVIAL(info) << " " << item.first;
}
}
int main(int argc, char *argv[]) {
std::unique_ptr<g13logging> logger(new g13logging(argc, argv));
init_keynames();
display_keys();
g13_count = 0;
string filename;
if(argc == 2) {
if(argc >= 2) {
filename = argv[1];
cout << "Setting logo: " << filename << endl;
BOOST_LOG_TRIVIAL(info) << "Setting logo: " << filename;
}
libusb_device **devs;
ssize_t cnt;
int ret;
ret = libusb_init(&ctx);
if(ret < 0) {
cout << "Initialization error: " << ret << endl;
BOOST_LOG_TRIVIAL(error) << "Initialization error: " << ret;
return 1;
}
libusb_set_debug(ctx, 3);
cnt = libusb_get_device_list(ctx, &devs);
if(cnt < 0) {
cout << "Error while getting device list" << endl;
BOOST_LOG_TRIVIAL(error) << "Error while getting device list";
return 1;
}
discover_g13s(devs, cnt, g13s);
libusb_free_device_list(devs, 1);
cout << "Found " << g13s.size() << " G13s" << endl;
BOOST_LOG_TRIVIAL(info) << "Found " << g13s.size() << " G13s";
if(g13s.size() == 0) {
BOOST_LOG_TRIVIAL(error) << "No G13 found - exiting";
return 1;
}
for(int i = 0; i < g13s.size(); i++) {
register_g13(ctx, g13s[i]);
}
signal(SIGINT, set_stop);
if(g13s.size() > 0 && argc == 2) {
if(g13s.size() > 0 && argc >= 2) {
g13_write_lcd_file(ctx, g13s[0], filename);
}
BOOST_LOG_TRIVIAL(info) << "Entering event loop";
do {
if(g13s.size() > 0)
for(int i = 0; i < g13s.size(); i++) {
int status = g13_read_keys(g13s[i]);
g13_read_commands(g13s[i]);
if(status < 0)
running = false;
}
for(int i = 0; i < g13s.size(); i++) {
int status = g13_read_keys(g13s[i]);
g13_read_commands(g13s[i]);
if(status < 0)
running = false;
}
} while(running);
BOOST_LOG_TRIVIAL(info) << "Cleaning up";
cleanup();
BOOST_LOG_TRIVIAL(info) << "Exiting";
return 0;
}
void g13_keypad::image(unsigned char *data, int size) {
@ -654,23 +684,11 @@ g13_keypad::g13_keypad(libusb_device_handle *handle, int id) {
uinput_file = -1;
for(int i = 0; i < sizeof(keys); i++)
keys[i] = false;
for(int i = 0; i < G13_NUM_KEYS; i++)
map[i] = KEY_A;
/* map = { KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H,
KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P,
KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, 0, 0,
KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2, KEY_3, KEY_4,
KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_F1, KEY_F2 };*/
// starcraft 2
// map = { KEY_5, KEY_3, KEY_1, KEY_0, KEY_2, KEY_4, KEY_6,
// KEY_V, KEY_F, KEY_E, KEY_C, KEY_B, KEY_G, KEY_I,
// KEY_LEFTSHIFT, KEY_M, KEY_T, KEY_L, KEY_H,
// KEY_A, KEY_S, KEY_LEFTCTRL, 0, 0,
// KEY_F1, KEY_N, KEY_R, KEY_P, KEY_K, KEY_D, KEY_X, KEY_Y,
// KEY_Z, KEY_TAB, KEY_W, KEY_BACKSPACE, 0, 0, 0, 0};
}
void g13_keypad::command(char const *str) {
keymap = new g13map(G13_NUM_KEYS);
}
void g13_keypad::command(char const *str) {
int red, green, blue, mod;
char keyname[256];
char binding[256];
@ -684,7 +702,9 @@ g13_keypad::g13_keypad(libusb_device_handle *handle, int id) {
int bind = input_name_to_key[binding];
if(name_to_key.find(keyname) != name_to_key.end()) {
int key = name_to_key[keyname];
map[key] = bind;
keymap->bind(key, str, input_name_to_key);
} else if(key_name == "STICK_LEFT") {
this->stick_keys[STICK_LEFT] = bind;
} else if(key_name == "STICK_RIGHT") {
@ -694,13 +714,13 @@ g13_keypad::g13_keypad(libusb_device_handle *handle, int id) {
} else if(key_name == "STICK_DOWN") {
this->stick_keys[STICK_DOWN] = bind;
} else {
cerr << "unknown g13 key: " << keyname << endl;
BOOST_LOG_TRIVIAL(error) << "unknown g13 key: " << keyname;
}
} else {
cerr << "unknown key: " << binding << endl;
BOOST_LOG_TRIVIAL(error) << "unknown key: " << binding;
}
} else {
cerr << "unknown command: <" << str << ">" << endl;
BOOST_LOG_TRIVIAL(error) << "unknown command: <" << str << ">";
}
}

11
g13.h
View File

@ -1,5 +1,6 @@
#include <string>
#include <map>
#include "g13map.h"
#define null 0
@ -23,15 +24,9 @@ struct g13_keypad {
stick_mode_t stick_mode;
int stick_keys[4];
g13_keypad(libusb_device_handle *handle, int id);
int map[G13_NUM_KEYS];
void set_mapping(int mapping[G13_NUM_KEYS]) {
for(int i = 0; i < G13_NUM_KEYS; i++)
map[i] = mapping[i];
}
int mapping(int key) {
return map[key];
}
g13map* keymap;
bool keys[G13_NUM_KEYS];
bool is_set(int key) {
return keys[key];

77
g13logging.cc Normal file
View File

@ -0,0 +1,77 @@
#include <fstream>
#include <boost/log/attributes.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/expressions/formatters/stream.hpp>
#include <boost/log/support/date_time.hpp>
#include "g13logging.h"
namespace expr = boost::log::expressions;
static const char* param = "--log-settings=";
g13logging::g13logging(int argc, char* argv[])
{
init(argc, argv);
}
g13logging::~g13logging()
{
BOOST_LOG_TRIVIAL(debug) << "g13logging dtor";
}
void
g13logging::init()
{
boost::log::add_console_log(
std::clog,
boost::log::keywords::filter = boost::log::trivial::severity > boost::log::trivial::debug,
boost::log::keywords::format = (
expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S") << ": "
<< boost::log::trivial::severity << ", " << expr::smessage
)
);
register_attributes();
}
void
g13logging::init(const std::string& filename)
{
std::ifstream s(filename.c_str());
boost::log::init_from_stream(s);
register_attributes();
}
void
g13logging::register_attributes()
{
boost::log::add_common_attributes(); // add LineID and TimeStamp
boost::log::register_simple_formatter_factory< boost::log::trivial::severity_level, char >("Severity");
}
int
g13logging::init(int argc, char* argv[])
{
for (int i=1; i<argc; i++) {
if (std::strncmp(argv[i], param, strlen(param)) == 0) {
const std::string filename(argv[i]+strlen(param));
init(filename);
BOOST_LOG_TRIVIAL(info) << "Logging initialised from " << filename;
return 0;
}
}
init();
BOOST_LOG_TRIVIAL(info) << "Logging initialised (default configuration)";
return 0;
}

29
g13logging.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _g13logging_
#define _g13logging_ 1
class g13logging {
public:
// ctor
g13logging(int argc, char* argv[]);
// dtor
virtual ~g13logging();
protected:
// setup up either default logging or from config file
virtual int init(int argc, char* argv[]);
virtual void init();
virtual void init(const std::string& filename);
virtual void register_attributes();
private:
// disabled
g13logging();
};
#endif // _g13logging_

64
g13map.cc Normal file
View File

@ -0,0 +1,64 @@
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/log/trivial.hpp>
#include <cassert>
#include <linux/uinput.h>
#include "g13map.h"
g13map::g13map(const int g13_num_keys) :
m_bind(g13_num_keys),
m_keya(1)
{
BOOST_LOG_TRIVIAL(debug) << "g13map ctor";
m_keya.push_back(KEY_A); // from <linux/uinput.h>
}
g13map::~g13map()
{
BOOST_LOG_TRIVIAL(debug) << "g13map dtor";
}
bool
g13map::bind(const int g13key, const char* cmd,
const std::map<std::string, int>& lut)
{
assert(g13key>=0);
assert(g13key<m_bind.size());
m_bind[g13key].clear();
std::vector<std::string> tok;
boost::split(tok, cmd, boost::is_any_of(" "));
for (int i=2; i<tok.size(); i++) {
BOOST_LOG_TRIVIAL(debug) << "g13map::bind " << i << " <" << tok[i] << ">";
if (tok[i].size() < 1 || tok[i][0] == '#')
break;
else if (lut.count(tok[i])==1)
m_bind[g13key].push_back(lut.at(tok[i]));
else {
BOOST_LOG_TRIVIAL(error) << "Keyboard key not found for: " << tok[i];
return false;
}
}
return true;
}
const std::list<int>&
g13map::mapping(const int g13key) const
{
if ((g13key>=0) && (g13key<m_bind.size()))
if (m_bind[g13key].size()<1)
return m_keya;
else
return m_bind[g13key];
else {
BOOST_LOG_TRIVIAL(error) << "Bad G13 key: " << g13key;
return m_keya;
}
}

47
g13map.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef _g13map_
#define _g13map_ 1
#include <map>
#include <string>
#include <vector>
#include <list>
/** This class maps between a single key pressed on the G13 and one or
* key presses which will be generated for passing via the uinput
* interface.
*/
class g13map {
public:
// ctor: create a map capable of holding g13_num_keys number of mappings
g13map(const int g13_num_keys);
// dtor
virtual ~g13map();
// add a mapping between g13key and the to-be decoded normal keyboard
// mappings in cmd (cmd holds the full bind command line, e.g.
// 'bind G12 KEY_U') - use the look up table lut to map between the strings
// found in cmd and key numbers
virtual bool bind(const int g13key, const char* cmd,
const std::map<std::string, int>& lut);
// return the current mapping for the G13 key g13key as a list of one or
// more keys
virtual const std::list<int>& mapping(const int g13key) const;
private:
// the mapping between the G13 key and a list of one or more key codes
// for each g13key
std::vector<std::list<int> > m_bind;
// a list to return when the mapping has not been set for a key
// (contains KEY_A)
std::list<int> m_keya;
// disabled
g13map();
};
#endif // _g13map_

11
modifiertest.bind Normal file
View File

@ -0,0 +1,11 @@
bind G1 KEY_LEFTCTRL KEY_F
bind G2 KEY_LEFTSHIFT KEY_G
bind G3 KEY_LEFTALT KEY_H
bind G4 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_I
bind G5 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_LEFTALT KEY_J
bind G6 KEY_LEFTCTRL KEY_LEFTSHIFT KEY_LEFTALT KEY_K # this is a comment
bind G7 KEY_L
bind G7 KEY_M #another comment
bind G8
bind G9 FOO
bind G10 BAR #comment