#include "Xlib.h" namespace ciface { namespace Xlib { void Init(std::vector& devices, void* const hwnd) { // mouse will be added to this, Keyboard class will be turned into KeyboardMouse // single device for combined keyboard/mouse, this will allow combinations like shift+click more easily devices.push_back(new Keyboard((Display*)hwnd)); } Keyboard::Keyboard(Display* display) : m_display(display) { memset(&m_state, 0, sizeof(m_state)); m_window = DefaultRootWindow(m_display); int min_keycode, max_keycode; XDisplayKeycodes(m_display, &min_keycode, &max_keycode); // Keyboard Keys for (int i = min_keycode; i <= max_keycode; ++i) { Key *temp_key = new Key(m_display, i); if (temp_key->m_keyname.length()) inputs.push_back(temp_key); else delete temp_key; } // Mouse Buttons inputs.push_back(new Button(Button1Mask)); inputs.push_back(new Button(Button2Mask)); inputs.push_back(new Button(Button3Mask)); inputs.push_back(new Button(Button4Mask)); inputs.push_back(new Button(Button5Mask)); } Keyboard::~Keyboard() { } ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) { return ((Input*)input)->GetState(&m_state); } void Keyboard::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) { } bool Keyboard::UpdateInput() { XQueryKeymap(m_display, m_state.keyboard); int root_x, root_y, win_x, win_y; Window root, child; XQueryPointer(m_display, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &m_state.buttons); return true; } bool Keyboard::UpdateOutput() { return true; } std::string Keyboard::GetName() const { return "Keyboard"; //return "Keyboard Mouse"; // change to this later } std::string Keyboard::GetSource() const { return "Xlib"; } int Keyboard::GetId() const { return 0; } Keyboard::Key::Key(Display* const display, KeyCode keycode) : m_display(display), m_keycode(keycode) { int i = 0; KeySym keysym = 0; do { keysym = XKeycodeToKeysym(m_display, keycode, i); i++; } while (keysym == NoSymbol && i < 8); // 0x0110ffff is the top of the unicode character range according to keysymdef.h // although it is probably more than we need. if (keysym == NoSymbol || keysym > 0x0110ffff) m_keyname = std::string(); else m_keyname = std::string(XKeysymToString(keysym)); } ControlState Keyboard::Key::GetState(const State* const state) { return (state->keyboard[m_keycode/8] & (1 << (m_keycode%8))) != 0; } ControlState Keyboard::Button::GetState(const State* const state) { return ((state->buttons & m_index) > 0); } std::string Keyboard::Key::GetName() const { return m_keyname; } std::string Keyboard::Button::GetName() const { char button = '0'; switch (m_index) { case Button1Mask: button = '1'; break; case Button2Mask: button = '2'; break; case Button3Mask: button = '3'; break; case Button4Mask: button = '4'; break; case Button5Mask: button = '5'; break; } return std::string("Button ") + button; } } }