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.c131
1 files changed, 96 insertions, 35 deletions
diff --git a/src/kernel/window.c b/src/kernel/window.c
index e7cf30d..bc36578 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -71,6 +71,49 @@ static void load_mode_params() {
);
}
+static inline void blit_pixel(uint32_t *into, struct pixel from) {
+ *into &= pix_clear_mask;
+ *into |= (from.r >> (8 - VBE_MODE_INFO->red_len)) << VBE_MODE_INFO->red_off;
+ *into |= (from.g >> (8 - VBE_MODE_INFO->green_len)) << VBE_MODE_INFO->green_off;
+ *into |= (from.b >> (8 - VBE_MODE_INFO->blue_len)) << VBE_MODE_INFO->blue_off;
+}
+
+static uint16_t mouse_y;
+static uint16_t mouse_x;
+
+#define MOUSE_WIDTH 8
+#define MOUSE_HEIGHT 8
+
+#define B {.r = 0, .g = 0, .b = 0, .pad = 0}
+#define W {.r = 255, .g = 255, .b = 255, .pad = 0}
+#define T {.pad = 1}
+
+static const struct pixel mouse_image[] = {
+ W, W, W, W, W, W, T, T,
+ W, B, B, B, W, T, T, T,
+ W, B, B, B, W, W, T, T,
+ W, B, B, B, B, W, W, T,
+ W, W, W, B, B, B, W, T,
+ W, T, W, W, B, B, B, W,
+ T, T, T, W, W, B, W, W,
+ T, T, T, T, W, W, W, T
+};
+
+static void blit_mouse() {
+ uint16_t y_max = mouse_y + MOUSE_HEIGHT > VBE_MODE_INFO->height ? VBE_MODE_INFO->height - mouse_y : MOUSE_HEIGHT;
+ uint16_t x_max = mouse_x + MOUSE_WIDTH > VBE_MODE_INFO->width ? VBE_MODE_INFO->width - mouse_x : MOUSE_WIDTH;
+ void *row = VBE_MODE_INFO->frame_buf + mouse_y * VBE_MODE_INFO->pitch + mouse_x * (VBE_MODE_INFO->bpp / 8);
+ for (uint16_t y = 0; y < y_max; ++y) {
+ uint32_t *out_pix = row;
+ for (uint16_t x = 0; x < x_max; ++x) {
+ if (!mouse_image[y * MOUSE_WIDTH + x].pad)
+ blit_pixel(out_pix, mouse_image[y * MOUSE_WIDTH + x]);
+ out_pix = (uint32_t *)((void *)out_pix + VBE_MODE_INFO->bpp / 8);
+ }
+ row += VBE_MODE_INFO->pitch;
+ }
+}
+
static void blit(uint16_t x_min, uint16_t x_max, uint16_t y_min, uint16_t y_max) {
void *row = VBE_MODE_INFO->frame_buf + y_min * VBE_MODE_INFO->pitch + x_min * (VBE_MODE_INFO->bpp / 8);
const struct super_pixel *from_row = buffer + y_min * VBE_MODE_INFO->width + x_min;
@@ -78,16 +121,17 @@ static void blit(uint16_t x_min, uint16_t x_max, uint16_t y_min, uint16_t y_max)
uint32_t *out_pix = row;
const struct super_pixel *from = from_row;
for (uint16_t x = x_min; x < x_max; ++x) {
- *out_pix &= pix_clear_mask;
- *out_pix |= (from->p.r >> (8 - VBE_MODE_INFO->red_len)) << VBE_MODE_INFO->red_off;
- *out_pix |= (from->p.g >> (8 - VBE_MODE_INFO->green_len)) << VBE_MODE_INFO->green_off;
- *out_pix |= (from->p.b >> (8 - VBE_MODE_INFO->blue_len)) << VBE_MODE_INFO->blue_off;
+ blit_pixel(out_pix, from->p);
out_pix = (uint32_t *)((void *)out_pix + VBE_MODE_INFO->bpp / 8);
++from;
}
row += VBE_MODE_INFO->pitch;
from_row += VBE_MODE_INFO->width;
}
+
+ if ((y_min < mouse_y) && (y_max > mouse_y) &&
+ (x_min < mouse_x) && (x_max > mouse_x))
+ blit_mouse();
}
#define POWER_OFF_MESSAGE_PITCH 45
@@ -343,8 +387,6 @@ static void send_action(struct window *w, struct window_action packet) {
#define RUN_COMMAND_FILE "sys/winspace.rc"
enum wm_action {
- WM_SHUFFLE_UP,
- WM_SHUFFLE_DOWN,
WM_MOVE_LEFT,
WM_MOVE_RIGHT,
WM_MOVE_UP,
@@ -355,8 +397,6 @@ enum wm_action {
};
static struct key_packet keybinds[] = {
- {.key_id = KEY_PAGE_DOWN, .modifiers = WINS},
- {.key_id = KEY_PAGE_UP, .modifiers = WINS},
{.key_id = KEY_LEFT_ARROW, .modifiers = WINS},
{.key_id = KEY_RIGHT_ARROW, .modifiers = WINS},
{.key_id = KEY_UP_ARROW, .modifiers = WINS},
@@ -393,6 +433,10 @@ void init_win() {
paint_bg();
blit(0, VBE_MODE_INFO->width, 0, VBE_MODE_INFO->height);
+ mouse_x = (VBE_MODE_INFO->width - MOUSE_WIDTH) / 2;
+ mouse_y = (VBE_MODE_INFO->height - MOUSE_HEIGHT) / 2;
+ blit_mouse();
+
const file_id_t fid = drives->get_file(drives, RUN_COMMAND_FILE);
if (!fid)
PANIC("Couldn't open " RUN_COMMAND_FILE ".");
@@ -425,34 +469,7 @@ void on_action(struct window_action packet) {
for (uint8_t i = 0; i < N_WM_ACTIONS; ++i)
if (fuzzy_key_match(keybinds[i], packet.as_key)) {
switch_to_kernel_cr3();
- struct window *old_top, *old_bottom;
switch (i) {
- case WM_SHUFFLE_UP:
- if (!top_window || !top_window->below)
- break;
- old_top = top_window;
- old_bottom = bottom_window;
- top_window = old_top->below;
- top_window->above = 0;
- old_top->below = 0;
- old_top->above = old_bottom;
- old_bottom->below = old_top;
- bottom_window = old_top;
- paint_and_above(bottom_window->above);
- break;
- case WM_SHUFFLE_DOWN:
- if (!top_window || !top_window->below)
- break;
- old_top = top_window;
- old_bottom = bottom_window;
- bottom_window = old_bottom->above;
- bottom_window->below = 0;
- old_bottom->above = 0;
- old_bottom->below = old_top;
- old_top->above = old_bottom;
- top_window = old_bottom;
- paint_and_above(top_window);
- break;
case WM_MOVE_LEFT:
if (top_window) {
top_window->xpos -= MOVE_BY;
@@ -487,4 +504,48 @@ void on_action(struct window_action packet) {
if (top_window)
send_action(top_window, packet);
+}
+
+void move_mouse_by(int16_t y, int16_t x) {
+//logf(LOG_INFO, "old mouse coords: (%d, %d)", mouse_x, mouse_y);
+ switch_to_kernel_cr3();
+ blit(mouse_x, mouse_x + MOUSE_WIDTH > VBE_MODE_INFO->width ? VBE_MODE_INFO->width : mouse_x + MOUSE_WIDTH,
+ mouse_y, mouse_y + MOUSE_HEIGHT > VBE_MODE_INFO->height ? VBE_MODE_INFO->height : mouse_y + MOUSE_HEIGHT);
+ mouse_y = (-y > mouse_y) ? 0 : (y + mouse_y + MOUSE_HEIGHT > VBE_MODE_INFO->height) ? VBE_MODE_INFO->height - MOUSE_HEIGHT : y + mouse_y;
+ mouse_x = (-x > mouse_x) ? 0 : (x + mouse_x + MOUSE_WIDTH > VBE_MODE_INFO->width) ? VBE_MODE_INFO->width - MOUSE_WIDTH : x + mouse_x;
+ blit_mouse();
+ switch_to_task_cr3();
+//logf(LOG_INFO, "new mouse coords: (%d, %d)", mouse_x, mouse_y);
+}
+
+static void focus(struct window *w) {
+ send_action(top_window, (struct window_action){.action_type = FOCUS_LEAVE});
+
+ if (w->below)
+ w->below->above = w->above;
+ else
+ bottom_window = w->above;
+ w->above->below = w->below;
+ w->above = 0;
+ w->below = top_window;
+ top_window->above = w;
+ top_window = w;
+
+ send_action(w, (struct window_action){.action_type = FOCUS_ENTER});
+}
+
+void mouse_button(enum mouse_button which, bool up) {
+ if (!top_window)
+ return;
+
+ struct window *const clicked_on = buffer[mouse_y * VBE_MODE_INFO->width + mouse_x].from_window;
+ if (!clicked_on)
+ return;
+
+ if (clicked_on != top_window) {
+ focus(clicked_on);
+ paint_and_above(clicked_on);
+ }
+
+ send_action(clicked_on, (struct window_action){.action_type = up ? MOUSE_UP : MOUSE_DOWN, .as_mouse = {.y = mouse_y - clicked_on->ypos, .x = mouse_x - clicked_on->xpos, .which = which}});
} \ No newline at end of file