diff options
author | dzwdz | 2022-08-08 21:13:36 +0200 |
---|---|---|
committer | dzwdz | 2022-08-08 21:13:36 +0200 |
commit | 2f6f3ea54ad01f02e68a23345565c34eb47ad365 (patch) | |
tree | 5f5c97eca9ab1e6b61a2511d4864803f8bd11557 /src | |
parent | cb04eada02bedc5b748e01b09a899dc139c4970f (diff) |
user: drawmouse for demoing mouse/graphic support
Diffstat (limited to 'src')
-rw-r--r-- | src/user/app/drawmouse/drawmouse.c | 86 | ||||
-rw-r--r-- | src/user/app/mousedump/mousedump.c | 32 | ||||
-rw-r--r-- | src/user/lib/draw/draw.c | 34 | ||||
-rw-r--r-- | src/user/lib/draw/draw.h | 5 |
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); |