--- /dev/null
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <msp/graphics/window_private.h>
+#include "keyboard.h"
+#include "keys_private.h"
+
+namespace Msp {
+namespace Input {
+
+std::string Keyboard::get_button_name(unsigned btn) const
+{
+ if(btn==0)
+ return "None";
+
+ const char *str = XKeysymToString(key_to_sys(btn));
+ if(!str)
+ return Device::get_button_name(btn);
+ return str;
+}
+
+void Keyboard::input_event(const Graphics::Window::Event &event)
+{
+ switch(event.xevent.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ {
+ KeySym keysym = XLookupKeysym(const_cast<XKeyEvent *>(&event.xevent.xkey), 0);
+ if(keysym!=NoSymbol)
+ if(unsigned key = key_from_sys(keysym))
+ set_button_state(key, event.xevent.type==KeyPress, true);
+ if(event.xevent.type==KeyPress)
+ {
+ char ch;
+ if(XLookupString(const_cast<XKeyEvent *>(&event.xevent.xkey), &ch, 1, 0, 0))
+ // XLookupString always returns Latin-1
+ signal_character.emit(static_cast<unsigned char>(ch));
+ }
+ }
+ break;
+ }
+}
+
+} // namespace Input
+} // namespace Msp