1
0
Fork 0
spectre/source/Platform/Unix/X11Mouse.cpp
Henrik Hautakoski 090646b61a Platform/Unix: Rename X11SharedDisplay to Xlib, and remove Display member variable from all classes.
We now initialize/destroy the display in Xlib::init/shutdown that is called in UnixApplication::init/shutdown and
therefore is valid through the whole lifetime. So no need for classes to keep references.
2020-12-26 15:37:56 +01:00

118 lines
2.5 KiB
C++

#include <Spectre/System/Event.h>
#include <Spectre/System/Log.h>
#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