summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/user')
-rw-r--r--src/user/app/drawmouse/drawmouse.c86
-rw-r--r--src/user/app/mousedump/mousedump.c32
-rw-r--r--src/user/lib/draw/draw.c34
-rw-r--r--src/user/lib/draw/draw.h5
4 files changed, 124 insertions, 33 deletions
diff --git a/src/user/app/drawmouse/drawmouse.c b/src/user/app/drawmouse/drawmouse.c
new file mode 100644
index 0000000..7e7c55b
--- /dev/null
+++ b/src/user/app/drawmouse/drawmouse.c
@@ -0,0 +1,86 @@
+#include <camellia/syscalls.h>
+#include <shared/container/ring.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <user/lib/draw/draw.h>
+
+#define MOUSE_SIZE 10
+
+#define eprintf(fmt, ...) fprintf(stderr, "drawmouse: "fmt"\n" __VA_OPT__(,) __VA_ARGS__)
+
+struct framebuf fb, lastbehind;
+struct rect dirty;
+
+static uint8_t r_buf[64];
+static ring_t r = {(void*)r_buf, sizeof r_buf, 0, 0};
+static struct {uint32_t x, y;} cursor, lastcur;
+
+
+static void draw_mouse(void) {
+ static bool drawn = false;
+ if (drawn)
+ fb_cpy(&fb, &lastbehind, lastcur.x, lastcur.y, 0, 0, MOUSE_SIZE, MOUSE_SIZE);
+ drawn = true;
+ dirty_mark(&dirty, lastcur.x, lastcur.y);
+ dirty_mark(&dirty, lastcur.x + MOUSE_SIZE, lastcur.y + MOUSE_SIZE);
+ fb_cpy(&lastbehind, &fb, 0, 0, cursor.x, cursor.y, MOUSE_SIZE, MOUSE_SIZE);
+ for (int i = 0; i < MOUSE_SIZE; i++) {
+ for (int j = 0; j < MOUSE_SIZE - i; j++) {
+ uint32_t *px = fb_pixel(&fb, cursor.x + i, cursor.y + j);
+ if (px) {
+ *px ^= 0x808080;
+ dirty_mark(&dirty, cursor.x + i, cursor.y + j);
+ }
+ }
+ }
+ lastcur = cursor;
+}
+
+
+struct packet {
+ uint8_t left : 1;
+ uint8_t right : 1;
+ uint8_t middle : 1;
+ uint8_t _useless : 5;
+ int8_t dx, dy;
+} __attribute__((packed));
+
+int main(void) {
+ char buf[64];
+ handle_t fd = _syscall_open("/kdev/ps2/mouse", 15, 0);
+ if (fd < 0) {
+ eprintf("couldn't open mouse");
+ return 1;
+ }
+
+ if (fb_setup(&fb, "/kdev/video/") < 0) {
+ eprintf("fb_setup error");
+ return 1;
+ }
+ fb_anon(&lastbehind, MOUSE_SIZE, MOUSE_SIZE);
+
+
+ for (;;) {
+ int len = _syscall_read(fd, buf, sizeof buf, 0);
+ if (len == 0) break;
+ ring_put(&r, buf, len);
+ while (ring_size(&r) >= 3) {
+ struct packet p;
+ ring_get(&r, &p, sizeof p);
+ p.dy *= -1;
+ // TODO check mouse click
+ if (-p.dx > (int)cursor.x) p.dx = -cursor.x;
+ if (-p.dy > (int)cursor.y) p.dy = -cursor.y;
+ cursor.x += p.dx;
+ cursor.y += p.dy;
+ if (cursor.x >= fb.width) cursor.x = fb.width - 1;
+ if (cursor.y >= fb.height) cursor.y = fb.height - 1;
+ draw_mouse();
+ if (p.left && p.right) return 0;
+ }
+ dirty_flush(&dirty, &fb);
+ }
+ return 0;
+}
diff --git a/src/user/app/mousedump/mousedump.c b/src/user/app/mousedump/mousedump.c
deleted file mode 100644
index 04331a3..0000000
--- a/src/user/app/mousedump/mousedump.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <camellia/syscalls.h>
-#include <unistd.h>
-#include <shared/container/ring.h>
-#include <stdio.h>
-
-static uint8_t r_buf[64];
-static ring_t r = {(void*)r_buf, sizeof r_buf, 0, 0};
-
-struct packet {
- uint8_t stuff;
- int8_t dx, dy;
-} __attribute__((packed));
-
-int main(void) {
- char buf[64];
- handle_t fd = _syscall_open("/kdev/ps2/mouse", 15, 0);
- if (fd < 0) {
- fprintf(stderr, "couldn't open mouse\n");
- exit(1);
- }
- for (;;) {
- int len = _syscall_read(fd, buf, sizeof buf, 0);
- if (len == 0) break;
- ring_put(&r, buf, len);
- while (ring_size(&r) >= 3) {
- struct packet p;
- ring_get(&r, &p, sizeof p);
- printf("%4d %4d\n", p.dx, p.dy);
- }
- }
- return 0;
-}
diff --git a/src/user/lib/draw/draw.c b/src/user/lib/draw/draw.c
index c4508da..27c1d33 100644
--- a/src/user/lib/draw/draw.c
+++ b/src/user/lib/draw/draw.c
@@ -40,11 +40,43 @@ int fb_setup(struct framebuf *fb, const char *base) {
fb->height = strtol(spec, &spec, 0);
if (*spec++ != 'x') return -EINVAL;
fb->bpp = strtol(spec, &spec, 0);
+ if (fb->bpp != 32) return -EINVAL;
+
fb->len = _syscall_getsize(fb->fd);
fb->pitch = fb->len / fb->height;
fb->b = malloc(fb->len);
- if (fb->bpp != 32) return -EINVAL;
+ _syscall_read(fb->fd, fb->b, fb->len, 0);
return 0;
}
+
+int fb_anon(struct framebuf *fb, size_t w, size_t h) {
+ fb->width = w;
+ fb->height = h;
+ fb->bpp = 32;
+ fb->pitch = fb->width * fb->bpp / 8;
+ fb->len = fb->pitch * fb->height;
+ fb->b = malloc(fb->len);
+ fb->fd = -1;
+ return 0;
+}
+
+uint32_t *fb_pixel(struct framebuf *fb, uint32_t x, uint32_t y) {
+ if (x < fb->width && y < fb->height)
+ return (void*)fb->b + fb->pitch * y + 4 * x;
+ return NULL;
+}
+
+void fb_cpy(
+ struct framebuf *dest, const struct framebuf *src,
+ size_t xd, size_t yd, size_t xs, size_t ys, size_t w, size_t h)
+{
+ for (size_t y = 0; y < h; y++) {
+ memcpy(
+ fb_pixel( dest, xd, yd + y),
+ fb_pixel((void*)src, xs, ys + y),
+ w * 4
+ );
+ }
+}
diff --git a/src/user/lib/draw/draw.h b/src/user/lib/draw/draw.h
index ba15840..98316fe 100644
--- a/src/user/lib/draw/draw.h
+++ b/src/user/lib/draw/draw.h
@@ -17,3 +17,8 @@ void dirty_mark(struct rect *d, uint32_t x, uint32_t y);
void dirty_flush(struct rect *d, struct framebuf *fb);
int fb_setup(struct framebuf *fb, const char *base);
+int fb_anon(struct framebuf *fb, size_t w, size_t h);
+uint32_t *fb_pixel(struct framebuf *fb, uint32_t x, uint32_t y);
+void fb_cpy(
+ struct framebuf *dest, const struct framebuf *src,
+ size_t xd, size_t yd, size_t xs, size_t ys, size_t w, size_t h);