summaryrefslogtreecommitdiff
path: root/src/kernel/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/window.c')
-rw-r--r--src/kernel/window.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/src/kernel/window.c b/src/kernel/window.c
index 078a194..ac03fc9 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -12,6 +12,9 @@
#define BACKGROUND(x, y) ((x / 16 + y / 16) % 2 ? 0x14 : 0x07)
+#define BORDER_LIGHT 0x1c
+#define BORDER_DARK 0x08
+
static struct window {
const volatile void *pixel_buffer_pma;
uint16_t width;
@@ -33,27 +36,65 @@ static struct window {
static struct window *bottom_window = 0;
static struct window *top_window = 0;
-static inline void set_pix(uint16_t x, uint16_t y, uint8_t value) {
- if ((x < 320) && (y < 200))
- *(uint8_t *)(0xa0000 + y * 320 + x) = value;
+#define SCREEN_HEIGHT 200
+#define SCREEN_WIDTH 320
+#define VGA_MEMORY ((uint8_t *)0xa0000)
+
+static inline void draw_hz_line(uint16_t y, uint16_t xs, uint16_t xm, uint8_t color) {
+ if (y >= SCREEN_HEIGHT)
+ return;
+ if (xs >= SCREEN_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;
+}
+
+static inline void draw_vt_line(uint16_t x, uint16_t ys, uint16_t ym, uint8_t color) {
+ if (x >= SCREEN_WIDTH)
+ return;
+ if (ys >= SCREEN_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;
}
static void paint_and_above(const struct window *w) {
switch_to_kernel_cr3();
- for (const struct window *i = w; i; i = i->above)
- for (uint16_t y = 0; y < i->height; ++y)
- for (uint16_t x = 0; x < i->width; ++x) {
+ 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;
+
+ 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)
- set_pix(x + i->xpos, y + i->ypos, pixel);
+ VGA_MEMORY[(y + i->ypos) * SCREEN_WIDTH + x + i->xpos] = pixel;
}
+
+ 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);
+ }
switch_to_task_cr3();
}
void paint_bg() {
- for (uint16_t y = 0; y < 200; ++y)
- for (uint16_t x = 0; x < 320; ++x)
- set_pix(x, y, BACKGROUND(x, y));
+ 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);
}
static void paint_all() {
@@ -79,6 +120,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;
struct window_action *const ab = allocate_kernel_pages(ACTION_BUFFER_PAGES);
w->action_buffer = ab;
@@ -100,7 +143,6 @@ got_window:
}
static void del_no_paint(struct window *w) {
-//logf(LOG_INFO, "-- deleting window 0x%h", w);
if (w == top_window)
top_window = w->below;
if (w == bottom_window)
@@ -110,7 +152,6 @@ static void del_no_paint(struct window *w) {
if (w->above)
w->above->below = w->below;
-//logf(LOG_INFO, " -- action buffer was 0x%h", w->action_buffer);
free_pages(w->action_buffer, ACTION_BUFFER_PAGES);
w->pixel_buffer_pma = 0;
}
@@ -121,18 +162,14 @@ void del_window(struct window *w) {
}
void delete_any_windows_from(struct task_state *tstate) {
-//logf(LOG_INFO, "-- deleting windows from 0x%h", tstate);
bool need_to_paint = false;
for (struct window *w = windows; w < windows + MAX_WINDOWS; ++w)
if (w->pixel_buffer_pma && (w->from_task == tstate)) {
- //logf(LOG_INFO, " -- found match at 0x%h", w);
del_no_paint(w);
need_to_paint = true;
}
- if (need_to_paint) {
- //logf(LOG_INFO, "-- trying to paint after deleting windows");
+ if (need_to_paint)
paint_all();
- }
}
void resize_window(struct window *w, uint16_t width, uint16_t height, const void *pixel_buffer) {