summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/drivers/mouse.c101
-rw-r--r--userland/windowserver/ws.c52
2 files changed, 114 insertions, 39 deletions
diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c
index 0eb6df6..47133b8 100644
--- a/kernel/drivers/mouse.c
+++ b/kernel/drivers/mouse.c
@@ -5,29 +5,69 @@
#include <fs/fifo.h>
#include <fs/vfs.h>
#include <interrupts.h>
+#include <math.h>
#include <typedefs.h>
u8 mouse_cycle = 0;
u8 mouse_u8[3];
-u8 mouse_x = 0;
-u8 mouse_y = 0;
-vfs_inode_t *mouse_inode;
+int mouse_x = 0;
+int mouse_y = 0;
+
+u8 mouse_left_button = 0;
+u8 mouse_middle_button = 0;
+u8 mouse_right_button = 0;
+
+vfs_inode_t *mouse_inode = NULL;
struct mouse_event {
u8 buttons;
- u8 x;
- u8 y;
+ int x;
+ int y;
+};
+
+struct mouse_event previous_event = {
+ .buttons = 0,
+ .x = 0,
+ .y = 0,
};
int fs_mouse_has_data(vfs_inode_t *inode) {
+ if (mouse_x != previous_event.x || mouse_y != previous_event.y) {
+ return 1;
+ }
+
const struct ringbuffer *rb = inode->internal_object;
return !ringbuffer_isempty(rb);
}
int fs_mouse_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
+ mouse_middle_button = mouse_u8[0] & (1 << 2);
+ mouse_right_button = mouse_u8[0] & (1 << 1);
+ mouse_left_button = mouse_u8[0] & (1 << 0);
+
struct ringbuffer *rb = fd->inode->internal_object;
u32 rc = ringbuffer_read(rb, buffer, len);
if (0 == rc && len > 0) {
+ if (mouse_x != previous_event.x || mouse_y != previous_event.y) {
+ int read_len = min(len, sizeof(struct mouse_event));
+
+ struct mouse_event e;
+ e.x = mouse_x;
+ e.y = mouse_y;
+ e.buttons = 0;
+ if (mouse_middle_button) {
+ e.buttons |= (1 << 2);
+ }
+ if (mouse_right_button) {
+ e.buttons |= (1 << 1);
+ }
+ if (mouse_left_button) {
+ e.buttons |= (1 << 0);
+ }
+ memcpy(buffer, &e, read_len);
+ previous_event = e;
+ return read_len;
+ }
return -EAGAIN;
}
return rc;
@@ -56,19 +96,60 @@ void int_mouse(reg_t *r) {
mouse_u8[1] = inb(0x60);
mouse_cycle++;
break;
- case 2:
+ case 2: {
mouse_u8[2] = inb(0x60);
- mouse_x = mouse_u8[1];
- mouse_y = mouse_u8[2];
+ int16_t x = mouse_u8[1];
+ int16_t y = mouse_u8[2];
+ uint8_t xs = mouse_u8[0] & (1 << 4);
+ uint8_t ys = mouse_u8[0] & (1 << 5);
+ if (xs)
+ x |= 0xFF00;
+ if (ys)
+ y |= 0xFF00;
+
+ mouse_x += x;
+ mouse_y -= y;
+
+ if (mouse_x < 0)
+ mouse_x = 0;
+ if (mouse_y < 0)
+ mouse_y = 0;
+
+ mouse_middle_button = mouse_u8[0] & (1 << 2);
+ mouse_right_button = mouse_u8[0] & (1 << 1);
+ mouse_left_button = mouse_u8[0] & (1 << 0);
+
mouse_cycle = 0;
+
+ // If there is a change in the mouse buttons that event should be written.
+ // The mouse movements will be generated upon request. This avoids
+ // filling the ringbuffer with a ton of small mouse movements.
+
+ int button_change = 0;
+ if (mouse_middle_button != (previous_event.buttons & (1 << 2))) {
+ button_change = 1;
+ } else if (mouse_right_button != (previous_event.buttons & (1 << 1))) {
+ button_change = 1;
+ } else if (mouse_left_button != (previous_event.buttons & (1 << 0))) {
+ button_change = 1;
+ }
+
+ if (!button_change) {
+ break;
+ }
+
struct mouse_event e;
e.buttons = mouse_u8[0];
e.x = mouse_x;
e.y = mouse_y;
- struct ringbuffer *rb = mouse_inode->internal_object;
- ringbuffer_write(rb, (u8 *)&e, sizeof(e));
+ previous_event = e;
+ if (mouse_inode) {
+ struct ringbuffer *rb = mouse_inode->internal_object;
+ ringbuffer_write(rb, (u8 *)&e, sizeof(e));
+ }
break;
}
+ }
EOI(0xC);
}
diff --git a/userland/windowserver/ws.c b/userland/windowserver/ws.c
index b177358..7a1b7d6 100644
--- a/userland/windowserver/ws.c
+++ b/userland/windowserver/ws.c
@@ -5,13 +5,13 @@
#include <fcntl.h>
#include <math.h>
#include <poll.h>
-#include <sys/socket.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/socket.h>
#include <unistd.h>
#define WINDOW_SERVER_SOCKET "/windowserver"
@@ -347,8 +347,8 @@ int windowserver_key_events(struct KEY_EVENT ev, int *redraw) {
struct mouse_event {
uint8_t buttons;
- uint8_t x;
- uint8_t y;
+ int x;
+ int y;
};
void send_resize(WINDOW *w, int x, int y) {
@@ -360,42 +360,36 @@ void send_resize(WINDOW *w, int x, int y) {
}
void parse_mouse_event(int fd) {
- int16_t xc = 0;
- int16_t yc = 0;
+ int xc = 0;
+ int yc = 0;
int middle_button = 0;
int right_button = 0;
int left_button = 0;
- struct mouse_event e[100];
- for (;;) {
- int rc = read(fd, e, sizeof(e));
- if (rc <= 0)
- break;
+ struct mouse_event e;
+ int rc = read(fd, &e, sizeof(e));
+ if (rc <= 0)
+ return;
- int n = rc / sizeof(e[0]);
- for (int i = 0; i < n; i++) {
- uint8_t xs = e[i].buttons & (1 << 4);
- uint8_t ys = e[i].buttons & (1 << 5);
- middle_button = e[i].buttons & (1 << 2);
- right_button = e[i].buttons & (1 << 1);
- left_button = e[i].buttons & (1 << 0);
- int16_t x = e[i].x;
- int16_t y = e[i].y;
- if (xs)
- x |= 0xFF00;
- if (ys)
- y |= 0xFF00;
- xc += x;
- yc += y;
- }
- }
- mouse_x += xc;
- mouse_y -= yc;
+ uint8_t xs = e.buttons & (1 << 4);
+ uint8_t ys = e.buttons & (1 << 5);
+ middle_button = e.buttons & (1 << 2);
+ right_button = e.buttons & (1 << 1);
+ left_button = e.buttons & (1 << 0);
+
+ xc = -mouse_x;
+ yc = mouse_y;
+
+ mouse_x = e.x;
+ mouse_y = e.y;
if (mouse_x < 0) {
mouse_x = 0;
}
if (mouse_y < 0) {
mouse_y = 0;
}
+
+ xc += mouse_x;
+ yc -= mouse_y;
if (mouse_left_down && !left_button) {
mouse_left_up = 1;
} else {