#include #include #include "Xlib.h" #include "X11Display.h" #include "X11Mouse.h" namespace sp { X11Mouse::X11Mouse() : m_btn_state(0) { } void X11Mouse::init() { updateFocusedWindow(); } Vector2f X11Mouse::getPosition() const { return m_position; } Vector2f X11Mouse::getAbsPosition() const { return m_abs_position; } bool X11Mouse::isButtonDown(Mouse::Button button) const { // Only signal that a button is down // if we have focus on a window. if (!m_win) { return false; } // TODO: Button1 and 2 is defined in x11 and // therefore clashes with Mouse::Button::Button1 and 2. switch(button) { case Mouse::Button::Left : return m_btn_state & Button1Mask; case Mouse::Button::Right : return m_btn_state & Button3Mask; case Mouse::Button::Middle : return m_btn_state & Button2Mask; default : return false; } return false; } void X11Mouse::update(InputModule *input) { ::Display* disp = Xlib::getDisplay(); ::Window root, child; int rx, ry, x = 0, y = 0; updateFocusedWindow(); // Query position and button state. XQueryPointer(disp, m_win ? m_win : ::XDefaultRootWindow(disp), &root, &child, &rx, &ry, &x, &y, &m_btn_state); // Update abs position (relative to root). m_abs_position.x = rx; m_abs_position.y = ry; // Update window position. if (m_win) { m_position.x = x; m_position.y = y; } } void X11Mouse::updateFocusedWindow() { X11Display *focus = X11Display::getFocused(); m_win = focus ? (::Window) focus->getHandle() : 0; } bool X11Mouse::handleMessage(XEvent* xevent, Event& event) { if (xevent->type == MotionNotify) { event.type = Event::MouseMove; event.mouseMove.x = xevent->xmotion.x; event.mouseMove.y = xevent->xmotion.y; return true; } if (xevent->type == ButtonPress || xevent->type == ButtonRelease) { Mouse::Button trans = Mouse::Button::Unknown; switch(xevent->xbutton.button) { case Button1 : trans = Mouse::Button::Left; break; case Button2 : trans = Mouse::Button::Middle; break; case Button3 : trans = Mouse::Button::Right; break; // TODO: name clash, need to rename Mouse::Button enums. // case Button4 : trans = Mouse::Button::Button1; break; // clashes with X11's "Button1" define. // case Button5 : trans = Mouse::Button::Button2; break; // clashes with X11's "Button2" define. } if (trans != Mouse::Button::Unknown) { event.type = Event::MouseButton; event.mouseButton.pressed = xevent->type == ButtonPress; event.mouseButton.button = trans; return true; } } return false; } } // namespace sp