diff --git a/91-g13.rules b/91-g13.rules index 7926d4e..b4cbb0f 100644 --- a/91-g13.rules +++ b/91-g13.rules @@ -1 +1,2 @@ -SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c21c", MODE="0666" \ No newline at end of file +SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c21c", MODE="0666" + diff --git a/Makefile b/Makefile index ee53160..9e46229 100644 --- a/Makefile +++ b/Makefile @@ -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 \ No newline at end of file +clean: + rm -f g13d *.o pbm2lpbm diff --git a/README.org b/README.org index f4f5adb..a05fd06 100644 --- a/README.org +++ b/README.org @@ -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 are shown upon startup (e.g. G1), same for (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). @@ -50,4 +61,4 @@ Use pbm2lpbm to convert a pbm image to the correct format, then just cat that in The pbm file must be 160x43 pixels. * License -This code is placed in the public domain. Do with it whatever you want. \ No newline at end of file +This code is placed in the public domain. Do with it whatever you want. diff --git a/g13.cc b/g13.cc index d428bce..d2135f5 100644 --- a/g13.cc +++ b/g13.cc @@ -1,9 +1,12 @@ #include #include #include +#include +#include #include #include #include +#include #include #include #include "logo.h" @@ -16,6 +19,7 @@ #include #include #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& keys = g13->keymap->mapping(key); + + for (std::list::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 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 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 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(buf); std::vector 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 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 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_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) { - std::cout << item.first << " "; + BOOST_LOG_TRIVIAL(info) << " " << item.first; } - std::cout << std::endl; - } + int main(int argc, char *argv[]) { + std::unique_ptr 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 << ">"; } } diff --git a/g13.h b/g13.h index 4eb7b5a..9e4e1ad 100644 --- a/g13.h +++ b/g13.h @@ -1,5 +1,6 @@ #include #include +#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]; diff --git a/g13logging.cc b/g13logging.cc new file mode 100644 index 0000000..5f7607e --- /dev/null +++ b/g13logging.cc @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +} + +g13map::~g13map() +{ + BOOST_LOG_TRIVIAL(debug) << "g13map dtor"; +} + +bool +g13map::bind(const int g13key, const char* cmd, + const std::map& lut) +{ + assert(g13key>=0); + assert(g13key tok; + + boost::split(tok, cmd, boost::is_any_of(" ")); + + for (int i=2; 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& +g13map::mapping(const int g13key) const +{ + if ((g13key>=0) && (g13key +#include +#include +#include + +/** 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& lut); + + // return the current mapping for the G13 key g13key as a list of one or + // more keys + virtual const std::list& 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 > m_bind; + + // a list to return when the mapping has not been set for a key + // (contains KEY_A) + std::list m_keya; + + // disabled + g13map(); + +}; + +#endif // _g13map_ diff --git a/modifiertest.bind b/modifiertest.bind new file mode 100644 index 0000000..0a2006c --- /dev/null +++ b/modifiertest.bind @@ -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