mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:07:36 +00:00
WindowServer: Preliminary absolute mouse positioning support
This commit is contained in:
parent
0334656e45
commit
e94484d208
3 changed files with 34 additions and 21 deletions
|
@ -89,11 +89,9 @@ WSEventLoop::~WSEventLoop()
|
||||||
void WSEventLoop::drain_mouse()
|
void WSEventLoop::drain_mouse()
|
||||||
{
|
{
|
||||||
auto& screen = WSScreen::the();
|
auto& screen = WSScreen::the();
|
||||||
unsigned prev_buttons = screen.mouse_button_state();
|
MousePacket state;
|
||||||
int dx = 0;
|
state.buttons = screen.mouse_button_state();
|
||||||
int dy = 0;
|
unsigned buttons = state.buttons;
|
||||||
int dz = 0;
|
|
||||||
unsigned buttons = prev_buttons;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
MousePacket packet;
|
MousePacket packet;
|
||||||
ssize_t nread = read(m_mouse_fd, &packet, sizeof(MousePacket));
|
ssize_t nread = read(m_mouse_fd, &packet, sizeof(MousePacket));
|
||||||
|
@ -102,19 +100,26 @@ void WSEventLoop::drain_mouse()
|
||||||
ASSERT(nread == sizeof(packet));
|
ASSERT(nread == sizeof(packet));
|
||||||
buttons = packet.buttons;
|
buttons = packet.buttons;
|
||||||
|
|
||||||
dx += packet.dx;
|
if (packet.is_relative) {
|
||||||
dy += -packet.dy;
|
state.x += packet.x;
|
||||||
dz += packet.dz;
|
state.y -= packet.y;
|
||||||
if (buttons != prev_buttons) {
|
state.z += packet.z;
|
||||||
screen.on_receive_mouse_data(dx, dy, dz, buttons);
|
} else {
|
||||||
dx = 0;
|
state.x = packet.x;
|
||||||
dy = 0;
|
state.y = packet.y;
|
||||||
dz = 0;
|
state.z += packet.z;
|
||||||
prev_buttons = buttons;
|
}
|
||||||
|
|
||||||
|
if (buttons != state.buttons) {
|
||||||
|
state.buttons = buttons;
|
||||||
|
screen.on_receive_mouse_data(state);
|
||||||
|
state.x = 0;
|
||||||
|
state.y = 0;
|
||||||
|
state.z = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dx || dy || dz)
|
if (state.is_relative && (state.x || state.y || state.z))
|
||||||
screen.on_receive_mouse_data(dx, dy, dz, buttons);
|
screen.on_receive_mouse_data(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSEventLoop::drain_keyboard()
|
void WSEventLoop::drain_keyboard()
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "WSEventLoop.h"
|
#include "WSEventLoop.h"
|
||||||
#include "WSWindowManager.h"
|
#include "WSWindowManager.h"
|
||||||
#include <Kernel/FB.h>
|
#include <Kernel/FB.h>
|
||||||
|
#include <Kernel/MousePacket.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -101,11 +102,16 @@ void WSScreen::set_buffer(int index)
|
||||||
ASSERT(rc == 0);
|
ASSERT(rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSScreen::on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons)
|
void WSScreen::on_receive_mouse_data(const MousePacket& packet)
|
||||||
{
|
{
|
||||||
auto prev_location = m_cursor_location;
|
auto prev_location = m_cursor_location;
|
||||||
m_cursor_location.move_by(dx, dy);
|
if (packet.is_relative)
|
||||||
|
m_cursor_location.move_by(packet.x, packet.y);
|
||||||
|
else
|
||||||
|
m_cursor_location = { packet.x * m_width / 0xffff, packet.y * m_height / 0xffff };
|
||||||
m_cursor_location.constrain(rect());
|
m_cursor_location.constrain(rect());
|
||||||
|
|
||||||
|
unsigned buttons = packet.buttons;
|
||||||
unsigned prev_buttons = m_mouse_button_state;
|
unsigned prev_buttons = m_mouse_button_state;
|
||||||
m_mouse_button_state = buttons;
|
m_mouse_button_state = buttons;
|
||||||
unsigned changed_buttons = prev_buttons ^ buttons;
|
unsigned changed_buttons = prev_buttons ^ buttons;
|
||||||
|
@ -123,8 +129,8 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons)
|
||||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dz) {
|
if (packet.z) {
|
||||||
auto message = make<WSMouseEvent>(WSEvent::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, dz);
|
auto message = make<WSMouseEvent>(WSEvent::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, packet.z);
|
||||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include <LibDraw/Rect.h>
|
#include <LibDraw/Rect.h>
|
||||||
#include <LibDraw/Size.h>
|
#include <LibDraw/Size.h>
|
||||||
|
|
||||||
|
struct MousePacket;
|
||||||
|
|
||||||
class WSScreen {
|
class WSScreen {
|
||||||
public:
|
public:
|
||||||
WSScreen(unsigned width, unsigned height);
|
WSScreen(unsigned width, unsigned height);
|
||||||
|
@ -53,7 +55,7 @@ public:
|
||||||
Point cursor_location() const { return m_cursor_location; }
|
Point cursor_location() const { return m_cursor_location; }
|
||||||
unsigned mouse_button_state() const { return m_mouse_button_state; }
|
unsigned mouse_button_state() const { return m_mouse_button_state; }
|
||||||
|
|
||||||
void on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons);
|
void on_receive_mouse_data(const MousePacket&);
|
||||||
void on_receive_keyboard_data(KeyEvent);
|
void on_receive_keyboard_data(KeyEvent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue