summaryrefslogtreecommitdiff
path: root/src/kernel/window.c
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-18 11:56:08 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-18 11:56:08 -0500
commit00cc8736f10098dedf6b856b9ad8bd0094211263 (patch)
tree4cd252a614b26cb3dcf4a20c142feeffbb4c3c2a /src/kernel/window.c
parent9d8ce7688f051fc5cd9e917faf3b1e49a3e620ab (diff)
downloadportland-os-00cc8736f10098dedf6b856b9ad8bd0094211263.tar.gz
vbe support, truecolor window manager pixbufs
Diffstat (limited to 'src/kernel/window.c')
-rw-r--r--src/kernel/window.c126
1 files changed, 73 insertions, 53 deletions
diff --git a/src/kernel/window.c b/src/kernel/window.c
index 74273fb..10c573f 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -7,18 +7,21 @@
#include "pmap.h"
#include "elf.h"
#include "log.h"
+#include "vbe.h"
#define MAX_WINDOWS 64
#define ACTION_BUFFER_PAGES 1
#define AB_END(buf) (buf + (ACTION_BUFFER_PAGES * 4096) / sizeof(struct window_action))
-#define BACKGROUND(x, y) ((x / 16 + y / 16) % 2 ? 0x14 : 0x07)
+#define GSC(x, y) (x / 4 + y / 4 >= 256 ? 255 : x / 4 + y / 4)
+#define BACKGROUND(x, y) ((struct pixel){.r = GSC(x / 2, y / 3), .g = GSC(x, y), .b = GSC(x, y / 2)})
-#define BORDER_LIGHT 0x1c
-#define BORDER_DARK 0x08
+#define BORDER_COLOR ((struct pixel){.r = 0x11, .g = 0x11, .b = 0x11})
+
+#define MOVE_BY 5
static struct window {
- const volatile void *pixel_buffer_pma;
+ const volatile struct pixel *pixel_buffer_pma;
uint16_t width;
uint16_t height;
@@ -38,65 +41,74 @@ static struct window {
static struct window *bottom_window = 0;
static struct window *top_window = 0;
-#define SCREEN_HEIGHT 200
-#define SCREEN_WIDTH 320
-#define VGA_MEMORY ((uint8_t *)0xa0000)
+uint32_t pix_clear_mask;
+
+static inline void put_pix(uint16_t y, uint16_t x, struct pixel px) {
+ uint32_t *const fbp = VBE_MODE_INFO->frame_buf + y * VBE_MODE_INFO->pitch + x * VBE_MODE_INFO->bpp / 8;
+//logf(LOG_INFO, "-- fbp = 0x%h", fbp);
+//logf(LOG_INFO, "-- *fbp -> 0x%h", *fbp);
+ *fbp &= pix_clear_mask;
+ *fbp |= (px.r >> (8 - VBE_MODE_INFO->red_len)) << VBE_MODE_INFO->red_off;
+ *fbp |= (px.g >> (8 - VBE_MODE_INFO->green_len)) << VBE_MODE_INFO->green_off;
+ *fbp |= (px.b >> (8 - VBE_MODE_INFO->blue_len)) << VBE_MODE_INFO->blue_off;
+//logf(LOG_INFO, "-- *fbp <- 0x%h", *fbp);
+}
-static inline void draw_hz_line(uint16_t y, uint16_t xs, uint16_t xm, uint8_t color) {
- if (y >= SCREEN_HEIGHT)
+static inline void draw_hz_line(uint16_t y, uint16_t xs, uint16_t xm, struct pixel color) {
+ if (y >= VBE_MODE_INFO->height)
return;
- if (xs >= SCREEN_WIDTH)
+ if (xs >= VBE_MODE_INFO->width)
xs = 0;
- if (xm > SCREEN_WIDTH)
- xm = SCREEN_WIDTH;
- uint8_t *const line_start = VGA_MEMORY + y * SCREEN_WIDTH;
- for (uint8_t *p = line_start + xs; p < line_start + xm; ++p)
- *p = color;
+ if (xm > VBE_MODE_INFO->width)
+ xm = VBE_MODE_INFO->width;
+ for (uint16_t x = xs; x < xm; ++x)
+ put_pix(y, x, color);
}
-static inline void draw_vt_line(uint16_t x, uint16_t ys, uint16_t ym, uint8_t color) {
- if (x >= SCREEN_WIDTH)
+static inline void draw_vt_line(uint16_t x, uint16_t ys, uint16_t ym, struct pixel color) {
+ if (x >= VBE_MODE_INFO->width)
return;
- if (ys >= SCREEN_HEIGHT)
+ if (ys >= VBE_MODE_INFO->height)
ys = 0;
- if (ym > SCREEN_HEIGHT)
- ym = SCREEN_HEIGHT;
- uint8_t *const line_start = VGA_MEMORY + x;
- for (uint8_t *p = line_start + ys * SCREEN_WIDTH; p < line_start + ym * SCREEN_WIDTH; p += SCREEN_WIDTH)
- *p = color;
+ if (ym > VBE_MODE_INFO->height)
+ ym = VBE_MODE_INFO->height;
+ for (uint16_t y = ys; y < ym; ++y)
+ put_pix(y, x, color);
}
static void paint_and_above(const struct window *w) {
switch_to_kernel_cr3();
for (const struct window *i = w; i; i = i->above) {
- const uint16_t ys = i->ypos < SCREEN_HEIGHT ? 0 : -i->ypos;
- const uint16_t xs = i->xpos < SCREEN_WIDTH ? 0 : -i->xpos;
- const uint16_t ym = i->ypos + i->height <= SCREEN_HEIGHT ? i->height : SCREEN_HEIGHT - i->ypos;
- const uint16_t xm = i->xpos + i->width <= SCREEN_WIDTH ? i->width : SCREEN_WIDTH - i->xpos;
+ const uint16_t ys = i->ypos < VBE_MODE_INFO->height ? 0 : -i->ypos;
+ const uint16_t xs = i->xpos < VBE_MODE_INFO->width ? 0 : -i->xpos;
+ const uint16_t ym = ((i->ypos + i->height) & 0xffff) <= VBE_MODE_INFO->height ? i->height : VBE_MODE_INFO->height - i->ypos;
+ const uint16_t xm = ((i->xpos + i->width) & 0xffff) <= VBE_MODE_INFO->width ? i->width : VBE_MODE_INFO->width - i->xpos;
- for (uint16_t y = ys; y < ym; ++y)
- for (uint16_t x = xs; x < xm; ++x) {
- const uint8_t pixel = ((uint8_t *)i->pixel_buffer_pma)[y * i->width + x];
- if (pixel)
- VGA_MEMORY[(y + i->ypos) * SCREEN_WIDTH + x + i->xpos] = pixel;
- }
+ //logf(LOG_INFO, "y: %n .. %n", ys, ym - 1);
+ //logf(LOG_INFO, "x: %n .. %n", xs, xm - 1);
- draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, BORDER_LIGHT);
- draw_vt_line(i->xpos - 2, i->ypos - 1, i->ypos + i->height + 2, BORDER_LIGHT);
- draw_hz_line(i->ypos - 1, i->xpos - 1, i->xpos + i->width + 2, BORDER_DARK);
- draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height + 2, BORDER_DARK);
- draw_hz_line(i->ypos + i->height, i->xpos, i->xpos + i->width + 1, BORDER_LIGHT);
- draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, BORDER_LIGHT);
- draw_hz_line(i->ypos + i->height + 1, i->xpos, i->xpos + i->width + 2, BORDER_DARK);
- draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height + 1, BORDER_DARK);
+ for (uint16_t y = ys; y < ym; ++y)
+ for (uint16_t x = xs; x < xm; ++x)
+ put_pix(y + i->ypos, x + i->xpos, i->pixel_buffer_pma[y * i->width + x]);
+
+ draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos - 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos + i->height, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos + i->height + 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_vt_line(i->xpos - 2, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height, BORDER_COLOR);
}
switch_to_task_cr3();
}
static void paint_bg() {
- for (uint16_t y = 0; y < SCREEN_HEIGHT; ++y)
- for (uint16_t x = 0; x < SCREEN_WIDTH; ++x)
- VGA_MEMORY[y * SCREEN_WIDTH + x] = BACKGROUND(x, y);
+ switch_to_kernel_cr3();
+ for (uint16_t y = 0; y < VBE_MODE_INFO->height; ++y)
+ for (uint16_t x = 0; x < VBE_MODE_INFO->width; ++x)
+ put_pix(y, x, BACKGROUND(x, y));
+ switch_to_task_cr3();
}
static void paint_all() {
@@ -104,7 +116,7 @@ static void paint_all() {
paint_and_above(bottom_window);
}
-struct window *new_window(uint16_t width, uint16_t height, const void *pixel_buffer) {
+struct window *new_window(uint16_t width, uint16_t height, const struct pixel *pixel_buffer) {
if (!pixel_buffer) {
logf(LOG_WARN, "Refusing to create window with null pixel buffer for task %s.", active_task->name);
return 0;
@@ -122,8 +134,8 @@ got_window:
w->pixel_buffer_pma = vma_to_pma(active_task->page_directory, pixel_buffer);
w->width = width;
w->height = height;
- w->xpos = 10;
- w->ypos = 10;
+ w->xpos = (VBE_MODE_INFO->width / 2) - (width / 2);
+ w->ypos = (VBE_MODE_INFO->height / 2) - (height / 2);
struct window_action *const ab = allocate_kernel_pages(ACTION_BUFFER_PAGES);
w->action_buffer = ab;
@@ -174,7 +186,7 @@ void delete_any_windows_from(struct task_state *tstate) {
paint_all();
}
-void resize_window(struct window *w, uint16_t width, uint16_t height, const void *pixel_buffer) {
+void resize_window(struct window *w, uint16_t width, uint16_t height, const struct pixel *pixel_buffer) {
const bool smaller = (width < w->width) || (height < w->height);
w->width = width;
@@ -187,7 +199,7 @@ void resize_window(struct window *w, uint16_t width, uint16_t height, const void
paint_and_above(w);
}
-void reassign_pixel_buffer(struct window *w, const void *pixel_buffer) {
+void reassign_pixel_buffer(struct window *w, const struct pixel *pixel_buffer) {
w->pixel_buffer_pma = vma_to_pma(active_task->page_directory, pixel_buffer);
}
@@ -259,6 +271,14 @@ static char *run_command;
static char *run_command_pass = "";
void init_win() {
+ #define MASK(offset, length) ((~((1 << offset) - 1)) - (offset + length == 32 ? 0 : (~((1 << (offset + length)) - 1))))
+ pix_clear_mask = ~(
+ MASK(VBE_MODE_INFO->red_off, VBE_MODE_INFO->red_len) |
+ MASK(VBE_MODE_INFO->green_off, VBE_MODE_INFO->green_len) |
+ MASK(VBE_MODE_INFO->blue_off, VBE_MODE_INFO->blue_len) |
+ MASK(VBE_MODE_INFO->alpha_off, VBE_MODE_INFO->alpha_len)
+ );
+
paint_bg();
const file_id_t fid = drives->get_file(drives, RUN_COMMAND_FILE);
@@ -323,25 +343,25 @@ void on_action(struct window_action packet) {
break;
case WM_MOVE_LEFT:
if (top_window) {
- --top_window->xpos;
+ top_window->xpos -= MOVE_BY;
paint_all();
}
break;
case WM_MOVE_RIGHT:
if (top_window) {
- ++top_window->xpos;
+ top_window->xpos += MOVE_BY;
paint_all();
}
break;
case WM_MOVE_UP:
if (top_window) {
- --top_window->ypos;
+ top_window->ypos -= MOVE_BY;
paint_all();
}
break;
case WM_MOVE_DOWN:
if (top_window) {
- ++top_window->ypos;
+ top_window->ypos += MOVE_BY;
paint_all();
}
break;