diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/window.c | 71 |
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) { |