diff options
author | Anton Kling <anton@kling.gg> | 2023-10-22 19:50:38 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-22 19:50:38 +0200 |
commit | 4e09bca9e34c226b6d7e34b4fa11248405fd988e (patch) | |
tree | 80f156b7940d9d19971395f335530170c69516c7 /userland/windowserver |
Move everything into a new repo.
Diffstat (limited to 'userland/windowserver')
-rw-r--r-- | userland/windowserver/Makefile | 16 | ||||
-rw-r--r-- | userland/windowserver/draw.c | 80 | ||||
-rw-r--r-- | userland/windowserver/draw.h | 13 | ||||
-rw-r--r-- | userland/windowserver/font.h | 133 | ||||
-rw-r--r-- | userland/windowserver/ws.c | 375 | ||||
-rw-r--r-- | userland/windowserver/ws.h | 30 |
6 files changed, 647 insertions, 0 deletions
diff --git a/userland/windowserver/Makefile b/userland/windowserver/Makefile new file mode 100644 index 0000000..f67bd66 --- /dev/null +++ b/userland/windowserver/Makefile @@ -0,0 +1,16 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O2 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -fsanitize=shift,signed-integer-overflow,bounds +BIN=ws +LIB=-L../json -ljson -L../json/hashmap -lhashmap -L../libc -lc -lgcc +INC=-I../json/ -I../libgui/ +all: $(BIN) +OBJ=ws.o draw.o + +%.o: %.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +clean: + rm $(OBJ) ws + +$(BIN): $(OBJ) + $(CC) -o $(BIN) -ffreestanding -nostdlib $(CFLAGS) $(OBJ) $(LIB) diff --git a/userland/windowserver/draw.c b/userland/windowserver/draw.c new file mode 100644 index 0000000..caa16a2 --- /dev/null +++ b/userland/windowserver/draw.c @@ -0,0 +1,80 @@ +#include "draw.h" +#include <string.h> + +#define BPP 4 + +#define place_pixel(_p, _w, _h) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_w) + (WIDTH * BPP * (_h))) = _p; } + +#define place_pixel_pos(_p, _pos) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_pos)) = _p; } + +int mx; +int my; + +void update_display(DISPLAY *disp) { + for (int i = 0; i < 20; i++) { + place_pixel(0xFFFFFFFF, mx + i, my + i); + place_pixel(0xFFFFFFFF, mx, my + i / 2); + place_pixel(0xFFFFFFFF, mx + i / 2, my); + } + for (int i = 0; i < disp->size; i++) + disp->true_buffer[i] = disp->back_buffer[i]; + // memcpy(disp->true_buffer, disp->back_buffer, disp->size); +} + +void draw_wallpaper(DISPLAY *disp) { + for (int i = 0; i < disp->size / BPP; i++) { + place_pixel_pos(0xFF00FF, i); + } +} + +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y) { + mx = mouse_x; + my = mouse_y; + update_full_display(disp, mouse_x, mouse_y); +} + +void draw_window(DISPLAY *disp, const WINDOW *w) { + int x, y; + uint8_t border_size = disp->border_size; + const int px = w->x + border_size; + const int py = w->y; + const int sx = w->sx; + const int sy = w->sy; + x = px; + y = py; + for (int i = 0; i < sy; i++) { + if((i+py)*WIDTH + px > HEIGHT*WIDTH) + break; + uint32_t *ptr = disp->back_buffer + BPP * ((i + py) * WIDTH) + px * BPP; + if(i*sx > HEIGHT*WIDTH) + break; + uint32_t *bm = &w->bitmap_ptr[i * sx]; + // ((uint8_t *)w->bitmap_ptr) + BPP * ((i + py) * WIDTH) + px * BPP; + for (int j = 0; j < sx; j++) { + ptr[j] = bm[j]; + } + } +} + +void update_active_window(DISPLAY *disp) { + for (int i = 0; i < 100; i++) { + if (!disp->clients[i]) + continue; + if (!disp->clients[i]->w) + continue; + draw_window(disp, disp->clients[i]->w); + } +} + +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y) { + draw_wallpaper(disp); /* + for (int i = 0; i < 100; i++) { + if (!disp->windows[i]) + continue; + draw_window(disp, disp->windows[i]); + }*/ + update_active_window(disp); + update_display(disp); +} diff --git a/userland/windowserver/draw.h b/userland/windowserver/draw.h new file mode 100644 index 0000000..bf9ff4f --- /dev/null +++ b/userland/windowserver/draw.h @@ -0,0 +1,13 @@ +#ifndef DRAW_H +#define DRAW_H +#include "ws.h" + +#define WIDTH 0x500 +#define HEIGHT 0x320 + +void draw_wallpaper(DISPLAY *disp); +void draw_window(DISPLAY *disp, const WINDOW *w); +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y); +void update_active_window(DISPLAY *disp); +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y); +#endif diff --git a/userland/windowserver/font.h b/userland/windowserver/font.h new file mode 100644 index 0000000..ad63e41 --- /dev/null +++ b/userland/windowserver/font.h @@ -0,0 +1,133 @@ +#ifndef FONT_H +#define FONT_H +char font8x8_basic[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; +#endif diff --git a/userland/windowserver/ws.c b/userland/windowserver/ws.c new file mode 100644 index 0000000..e4f1a9e --- /dev/null +++ b/userland/windowserver/ws.c @@ -0,0 +1,375 @@ +#include <fcntl.h> +#include <poll.h> +#include <stddef.h> +#include <stdint.h> +//#include <sys/mman.h> +#include "draw.h" +#include "font.h" +#include "ws.h" +#include <assert.h> +#include <socket.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#define WINDOW_SERVER_SOCKET "/windowserver" + +CLIENT *clients[100]; +CLIENT *active_client; + +int mouse_x = 0; +int mouse_y = 0; + +// void *true_display; +// void *buffer_display; +// uint64_t display_size; +// int border_size; +// uint8_t border_color; +DISPLAY main_display; + +struct pollfd *fds; +uint64_t num_fds; + +uint64_t socket_fd_poll; +uint64_t keyboard_fd_poll; +uint64_t mouse_fd_poll; + +// Taken from drivers/keyboard.c +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +int create_socket(void) { + struct sockaddr_un address; + int fd = socket(AF_UNIX, 0, 0); + address.sun_family = AF_UNIX; + size_t str_len = strlen(WINDOW_SERVER_SOCKET); + address.sun_path = malloc(str_len + 1); + memcpy(address.sun_path, WINDOW_SERVER_SOCKET, str_len); + address.sun_path[str_len] = 0; + + bind(fd, (struct sockaddr *)(&address), sizeof(address)); + // for(;;); + /*free(address.sun_path);*/ + return fd; +} + +void setup_display(DISPLAY *disp, const char *path, uint64_t size) { + disp->wallpaper_color = 0x3; + disp->size = size; + disp->vga_fd = open(path, O_RDWR, 0); + if (-1 == disp->vga_fd) { + perror("open"); + for (;;) + ; + } + disp->true_buffer = mmap(NULL, size, 0, 0, disp->vga_fd, 0); + disp->back_buffer = malloc(size + 0x1000); + disp->clients = clients; +} + +void setup(void) { + setup_display(&main_display, "/dev/vbe", 0xBB8000); + draw_wallpaper(&main_display); + update_display(&main_display); + + main_display.border_size = 1; + main_display.border_color = 0xF; + active_client = NULL; + for (int i = 0; i < 100; i++) { + clients[i] = NULL; + } + + num_fds = 100; + fds = malloc(sizeof(struct pollfd[num_fds])); + memset(fds, 0, sizeof(struct pollfd[num_fds])); + for (size_t i = 0; i < num_fds; i++) + fds[i].fd = -1; + // Create socket + int socket_fd = create_socket(); + assert(socket_fd >= 0); + socket_fd_poll = 0; + fds[socket_fd_poll].fd = socket_fd; + fds[socket_fd_poll].events = POLLIN; + fds[socket_fd_poll].revents = 0; + int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK, 0); + assert(keyboard_fd >= 0); + keyboard_fd_poll = 1; + fds[keyboard_fd_poll].fd = keyboard_fd; + fds[keyboard_fd_poll].events = POLLIN; + fds[keyboard_fd_poll].revents = 0; + int mouse_fd = open("/dev/mouse", O_RDONLY, 0); + assert(mouse_fd >= 0); + mouse_fd_poll = 2; + fds[mouse_fd_poll].fd = mouse_fd; + fds[mouse_fd_poll].events = POLLIN; + fds[mouse_fd_poll].revents = 0; +} + +void reset_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) + fds[i].revents = 0; +} + +void add_fd(int fd) { + int i; + for (i = 0; i < num_fds; i++) + if (-1 == fds[i].fd) + break; + + fds[i].fd = fd; + fds[i].events = POLLIN | POLLHUP; + // fds[i].events = POLLIN; + fds[i].revents = 0; +} + +void add_client(int fd) { + int client_socket = accept(fd, NULL, NULL); + add_fd(client_socket); + int i; + for (i = 0; i < 100; i++) + if (!clients[i]) + break; + printf("adding client: %d\n", i); + CLIENT *c = clients[i] = malloc(sizeof(CLIENT)); + c->fd = client_socket; + active_client = c; + printf("clients[0]: %x\n", clients[0]); +} + +#define CLIENT_EVENT_CREATESCREEN 0 +#define CLIENT_EVENT_UPDATESCREEN 1 + +void add_window(CLIENT *c, int fd, int x, int y, int sx, int sy) { + WINDOW *w = malloc(sizeof(WINDOW)); + w->bitmap_fd = fd; + w->bitmap_ptr = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, fd, 0); + w->x = x; + w->y = y; + w->sx = sx; + w->sy = sy; + c->w = w; +} + +typedef struct { + uint16_t px; + uint16_t py; + uint16_t sx; + uint16_t sy; + uint8_t name_len; +} WS_EVENT_CREATE; + +void parse_client_event(CLIENT *c) { + uint8_t event_type; + if (0 == read(c->fd, &event_type, sizeof(uint8_t))) { + printf("empty\n"); + return; + } + if (0 == event_type) { + update_full_display(&main_display, mouse_x, mouse_y); + return; + } + if (1 == event_type) { + WS_EVENT_CREATE e; + for (; 0 == read(c->fd, &e, sizeof(e));) + ; + uint8_t bitmap_name[e.name_len + 1]; + read(c->fd, bitmap_name, e.name_len); + bitmap_name[e.name_len] = '\0'; + int bitmap_fd = shm_open(bitmap_name, O_RDWR, O_CREAT); + add_window(c, bitmap_fd, e.px, e.py, e.sx, e.sy); + update_full_display(&main_display, mouse_x, mouse_y); + } +} + +typedef struct { + int type; + struct KEY_EVENT ev; +} WS_EVENT; + +void send_to_client(struct KEY_EVENT ev) { + WS_EVENT e = { + .type = 0, + .ev = ev, + }; + write(active_client->fd, &e, sizeof(e)); +} + +void clamp_screen_position(int *x, int *y) { + if (0 > *x) { + *x = 0; + } + if (0 > *y) { + *y = 0; + } + if (WIDTH < *x) { + *x = WIDTH; + } + if (HEIGHT < *y) { + *y = HEIGHT; + } +} + +int windowserver_key_events(struct KEY_EVENT ev, int *redraw) { + if (!(ev.mode & (1 << 1))) + return 0; + if (!active_client) + return 0; + int x = 0; + int y = 0; + switch (ev.c) { + case 'l': + x++; + break; + case 'h': + x--; + break; + case 'k': + y--; + break; + case 'j': + y++; + break; + } + if (x || y) { + active_client->w->x += x; + active_client->w->y += y; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + *redraw = 1; + return 1; + } + return 0; +} + +struct mouse_event { + uint8_t buttons; + uint8_t x; + uint8_t y; +}; + +void update_mouse(void) { + draw_mouse(&main_display, mouse_x, mouse_y); + return; +} + +void parse_mouse_event(int fd) { + int16_t xc = 0; + int16_t yc = 0; + int middle_button = 0; + for (;;) { + struct mouse_event e[100]; + int rc = read(fd, e, sizeof(e)); + if (rc <= 0) + break; + + 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); + int16_t x = e[i].x; + int16_t y = e[i].y; + if (xs) + x |= 0xFF00; + if (ys) + y |= 0xFF00; + xc += *(int16_t *)&x; + yc += *(int16_t *)&y; + } + } + mouse_x += xc; + mouse_y -= yc; + if (mouse_x < 0) + mouse_x = 0; + if (mouse_y < 0) + mouse_y = 0; + if (middle_button) { + active_client->w->x += xc; + active_client->w->y -= yc; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + } + update_mouse(); +} + +void parse_keyboard_event(int fd) { + if (!active_client) { + return; + } + struct KEY_EVENT ev[250]; + int redraw = 0; + for (;;) { + int rc; + if (0 > (rc = read(fd, &ev[0], sizeof(ev)))) + break; + int n = rc / sizeof(ev[0]); + for (int i = 0; i < n; i++) { + if (windowserver_key_events(ev[i], &redraw)) + continue; + send_to_client(ev[i]); + } + } + if (redraw) + update_full_display(&main_display, mouse_x, mouse_y); +} + +CLIENT *get_client(int fd) { + for (int i = 0; i < 100; i++) { + if (!clients[i]) + continue; + if (clients[i]->fd == fd) + return clients[i]; + } + return NULL; +} + +void kill_client(CLIENT *c) { + c->w = NULL; + update_full_display(&main_display, mouse_x, mouse_y); + active_client = clients[0]; +} + +void parse_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) { + if (!fds[i].revents) + continue; + if (-1 == fds[i].fd) + continue; + if (socket_fd_poll == i && fds[i].revents & POLLIN) { + add_client(fds[i].fd); + continue; + } else if (keyboard_fd_poll == i) { + parse_keyboard_event(fds[i].fd); + continue; + } else if (mouse_fd_poll == i) { + parse_mouse_event(fds[i].fd); + continue; + } + CLIENT *c = get_client(fds[i].fd); + assert(c); + if (fds[i].revents & POLLHUP) { + kill_client(c); + fds[i].fd = -1; + } else { + parse_client_event(c); + } + } +} + +void run(void) { + for (;;) { + poll(fds, num_fds, 0); + parse_revents(fds, num_fds); + reset_revents(fds, num_fds); + } +} + +int main(void) { + open("/dev/serial", O_WRITE, 0); + open("/dev/serial", O_WRITE, 0); + setup(); + run(); + return 0; +} diff --git a/userland/windowserver/ws.h b/userland/windowserver/ws.h new file mode 100644 index 0000000..c4daf7b --- /dev/null +++ b/userland/windowserver/ws.h @@ -0,0 +1,30 @@ +#ifndef WS_H +#define WS_H +#include <stddef.h> +#include <stdint.h> + +typedef struct { + int bitmap_fd; + uint32_t *bitmap_ptr; + int x; + int y; + int sx; + int sy; +} WINDOW; + +typedef struct { + int fd; + WINDOW *w; +} CLIENT; + +typedef struct { + int vga_fd; + uint8_t *back_buffer; + uint8_t *true_buffer; + size_t size; + uint8_t border_size; + uint8_t border_color; + uint8_t wallpaper_color; + CLIENT **clients; +} DISPLAY; +#endif |