summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/kbd.c321
-rw-r--r--src/kernel/kbd.h2
-rw-r--r--src/kernel/window.c75
3 files changed, 211 insertions, 187 deletions
diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c
index 004706f..ce25397 100644
--- a/src/kernel/kbd.c
+++ b/src/kernel/kbd.c
@@ -125,185 +125,180 @@ void init_kbd() {
drives->free_file(drives, stf);
}
-static uint8_t last_code_byte = 0;
-
-static inline uint8_t get_next_code_byte() {
- uint8_t cb;
- do
- cb = inb(PS2_DATA);
- while (cb == last_code_byte);
- last_code_byte = cb;
- return cb;
-}
-
-static inline uint8_t get_wait() {
- for (uint32_t i = 0; i < 1000000; ++i)
+static inline uint8_t get_next_byte() {
+ while (!(inb(PS2_CMD) & PS2S_CODE_READY))
;
return inb(PS2_DATA);
}
-static enum key_modifiers_t keymods = 0;
+enum key_modifiers_t keymods = 0;
bool last_mouse_one = false;
bool last_mouse_two = false;
bool last_mouse_mid = false;
+static const char *const hextab = "0123456789abcdef";
+
enum kbd_isr_result on_kbd_isr() {
- uint8_t code;
- while ((code = inb(PS2_CMD)) & PS2S_CODE_READY) {
- if (code & PS2S_FROM_MOUSE) {
- const uint8_t first = get_wait();
- const uint8_t x = get_wait();
- const uint8_t y = get_wait();
-
- if (x || y || (first & (MFB_X_SIGN | MFB_Y_SIGN)))
- move_mouse_by((first & MFB_Y_SIGN) ? 256 - y : -y,
- (first & MFB_X_SIGN) ? x - 256 : x);
-
- const bool mouse_one = first & MFB_BUTTON_ONE;
- const bool mouse_two = first & MFB_BUTTON_TWO;
- const bool mouse_mid = first & MFB_BUTTON_MID;
-
- if (mouse_one && !last_mouse_one)
- mouse_button(LEFT, false);
- if (mouse_two && !last_mouse_two)
- mouse_button(RIGHT, false);
- if (mouse_mid && !last_mouse_mid)
- mouse_button(MIDDLE, false);
-
- if (!mouse_one && last_mouse_one)
- mouse_button(LEFT, true);
- if (!mouse_two && last_mouse_two)
- mouse_button(RIGHT, true);
- if (!mouse_mid && last_mouse_mid)
- mouse_button(MIDDLE, true);
-
- last_mouse_one = mouse_one;
- last_mouse_two = mouse_two;
- last_mouse_mid = mouse_mid;
- continue;
- }
+ if (inb(PS2_CMD) & PS2S_FROM_MOUSE) {
+ const uint8_t first = get_next_byte();
+ const uint8_t x = get_next_byte();
+ const uint8_t y = get_next_byte();
+
+ if (x || y || (first & (MFB_X_SIGN | MFB_Y_SIGN)))
+ move_mouse_by((first & MFB_Y_SIGN) ? 256 - y : -y,
+ (first & MFB_X_SIGN) ? x - 256 : x);
+
+ const bool mouse_one = first & MFB_BUTTON_ONE;
+ const bool mouse_two = first & MFB_BUTTON_TWO;
+ const bool mouse_mid = first & MFB_BUTTON_MID;
+
+ if (mouse_one && !last_mouse_one)
+ mouse_button(LEFT, false);
+ if (mouse_two && !last_mouse_two)
+ mouse_button(RIGHT, false);
+ if (mouse_mid && !last_mouse_mid)
+ mouse_button(MIDDLE, false);
+
+ if (!mouse_one && last_mouse_one)
+ mouse_button(LEFT, true);
+ if (!mouse_two && last_mouse_two)
+ mouse_button(RIGHT, true);
+ if (!mouse_mid && last_mouse_mid)
+ mouse_button(MIDDLE, true);
+
+ last_mouse_one = mouse_one;
+ last_mouse_two = mouse_two;
+ last_mouse_mid = mouse_mid;
+ return NORMAL;
+ }
- last_code_byte = 0;
- uint8_t code[256];
- uint8_t code_i = 0;
- sub_table:
- code[code_i] = get_next_code_byte();
- const uint8_t *table;
- for (uint32_t i = 0; i < n_scantabs; ++i) {
- if (scantabs[i].prefix_length != code_i)
- continue;
- for (uint8_t j = 0; j < code_i; ++j)
- if (scantabs[i].prefix[j] != code[j])
- goto next_table;
- table = scantabs[i].scantab;
- goto got_table;
- next_table:;
- }
- PANIC("Couldn't find scantable");
-
- got_table:;
- bool is_up = false;
- flipped_table:;
- uint8_t entry = table[code[code_i]];
- switch (entry) {
- case ST_ILLEGAL:
- PANIC("Illegal scancode encountered");
- case ST_SUBTABLE:
- ++code_i;
- goto sub_table;
- case ST_FLIP:
- if (is_up)
- PANIC("Recursive flip in scantable");
- table += 0x100;
- is_up = true;
- goto flipped_table;
- case ST_SKIP:
+ uint8_t code[256];
+ uint8_t code_i = 0;
+sub_table:
+ code[code_i] = get_next_byte();
+ const uint8_t *table;
+ for (uint32_t i = 0; i < n_scantabs; ++i) {
+ if (scantabs[i].prefix_length != code_i)
continue;
+ for (uint8_t j = 0; j < code_i; ++j)
+ if (scantabs[i].prefix[j] != code[j])
+ goto next_table;
+ table = scantabs[i].scantab;
+ goto got_table;
+ next_table:;
+ }
+ PANIC("Couldn't find scantable");
+
+got_table:;
+ bool is_up = false;
+flipped_table:;
+ uint8_t entry = table[code[code_i]];
+ switch (entry) {
+ char code_str[256 * 3 + 1];
+ case ST_ILLEGAL:
+ for (uint16_t i = 0; i <= code_i; ++i) {
+ code_str[i * 3] = ' ';
+ code_str[i * 3 + 1] = hextab[code[i] >> 4];
+ code_str[i * 3 + 2] = hextab[code[i] & 0xf];
}
+ code_str[(code_i + 1) * 3] = '\0';
+ logf(LOG_ERROR, "Illegal scancode encountered:%s. Ignoring.", code_str);
+ return NORMAL;
+ case ST_SUBTABLE:
+ ++code_i;
+ goto sub_table;
+ case ST_FLIP:
+ if (is_up)
+ PANIC("Recursive flip in scantable");
+ table += 0x100;
+ is_up = true;
+ goto flipped_table;
+ case ST_SKIP:
+ return NORMAL;
+ }
- switch ((enum key_id_t)entry) {
- case KEY_LEFT_SHIFT:
- if (is_up)
- keymods &= ~LSHIFT;
- else
- keymods |= LSHIFT;
- break;
- case KEY_RIGHT_SHIFT:
- if (is_up)
- keymods &= ~RSHIFT;
- else
- keymods |= RSHIFT;
- break;
- case KEY_LEFT_CONTROL:
- if (is_up)
- keymods &= ~LCTRL;
- else
- keymods |= LCTRL;
- break;
- case KEY_RIGHT_CONTROL:
- if (is_up)
- keymods &= ~RCTRL;
- else
- keymods |= RCTRL;
- break;
- case KEY_LEFT_ALT:
- if (is_up)
- keymods &= ~LALT;
- else
- keymods |= LALT;
- break;
- case KEY_RIGHT_ALT:
- if (is_up)
- keymods &= ~RALT;
- else
- keymods |= RALT;
- break;
- case KEY_LEFT_WIN:
- if (is_up)
- keymods &= ~LWIN;
- else
- keymods |= LWIN;
- break;
- case KEY_RIGHT_WIN:
- if (is_up)
- keymods &= ~RWIN;
- else
- keymods |= RWIN;
- break;
- case KEY_CAPS_LOCK:
- if (!is_up)
- keymods ^= CAPS;
- break;
- case KEY_NUM_LOCK:
- if (!is_up)
- keymods ^= NUM;
- break;
- case KEY_SCROLL_LOCK:
- if (!is_up)
- keymods ^= SCROLL;
- break;
- case KEY_INSERT:
- if (!is_up)
- keymods ^= INSERT;
- break;
- default:
- break;
- }
+ switch ((enum key_id_t)entry) {
+ case KEY_LEFT_SHIFT:
+ if (is_up)
+ keymods &= ~LSHIFT;
+ else
+ keymods |= LSHIFT;
+ break;
+ case KEY_RIGHT_SHIFT:
+ if (is_up)
+ keymods &= ~RSHIFT;
+ else
+ keymods |= RSHIFT;
+ break;
+ case KEY_LEFT_CONTROL:
+ if (is_up)
+ keymods &= ~LCTRL;
+ else
+ keymods |= LCTRL;
+ break;
+ case KEY_RIGHT_CONTROL:
+ if (is_up)
+ keymods &= ~RCTRL;
+ else
+ keymods |= RCTRL;
+ break;
+ case KEY_LEFT_ALT:
+ if (is_up)
+ keymods &= ~LALT;
+ else
+ keymods |= LALT;
+ break;
+ case KEY_RIGHT_ALT:
+ if (is_up)
+ keymods &= ~RALT;
+ else
+ keymods |= RALT;
+ break;
+ case KEY_LEFT_WIN:
+ if (is_up)
+ keymods &= ~LWIN;
+ else
+ keymods |= LWIN;
+ break;
+ case KEY_RIGHT_WIN:
+ if (is_up)
+ keymods &= ~RWIN;
+ else
+ keymods |= RWIN;
+ break;
+ case KEY_CAPS_LOCK:
+ if (!is_up)
+ keymods ^= CAPS;
+ break;
+ case KEY_NUM_LOCK:
+ if (!is_up)
+ keymods ^= NUM;
+ break;
+ case KEY_SCROLL_LOCK:
+ if (!is_up)
+ keymods ^= SCROLL;
+ break;
+ case KEY_INSERT:
+ if (!is_up)
+ keymods ^= INSERT;
+ break;
+ default:
+ break;
+ }
- if (!is_up && (entry == KEY_PAUSE) && (keymods & ALTS))
- return (keymods & SHIFTS) ? SHIFT_DUMP : DUMP;
+ if (!is_up && (entry == KEY_PAUSE) && (keymods & ALTS))
+ return (keymods & SHIFTS) ? SHIFT_DUMP : DUMP;
- if (!is_up && (entry == KEY_Q) && (keymods & WINS) && (keymods & SHIFTS))
- shutdown();
+ if (!is_up && (entry == KEY_Q) && (keymods & WINS) && (keymods & SHIFTS))
+ shutdown();
- on_action((struct window_action){
- .action_type = is_up ? KEY_UP : KEY_DOWN,
- .as_key = (struct key_packet){
- .key_id = entry,
- .modifiers = keymods
- }
- });
- }
+ on_action((struct window_action){
+ .action_type = is_up ? KEY_UP : KEY_DOWN,
+ .as_key = (struct key_packet){
+ .key_id = entry,
+ .modifiers = keymods
+ }
+ });
return NORMAL;
}
diff --git a/src/kernel/kbd.h b/src/kernel/kbd.h
index 7e03fd7..a83d759 100644
--- a/src/kernel/kbd.h
+++ b/src/kernel/kbd.h
@@ -14,4 +14,6 @@ enum kbd_isr_result {
SHIFT_DUMP
} on_kbd_isr();
+extern enum key_modifiers_t keymods;
+
#endif
diff --git a/src/kernel/window.c b/src/kernel/window.c
index d50e454..9487211 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -7,6 +7,7 @@
#include "util.h"
#include "pmap.h"
#include "elf.h"
+#include "kbd.h"
#include "log.h"
#include "vbe.h"
@@ -402,7 +403,6 @@ enum wm_action {
WM_MOVE_UP,
WM_MOVE_DOWN,
WM_RUN_COMMAND,
- WM_SEND_BOTTOM,
N_WM_ACTIONS
};
@@ -412,8 +412,7 @@ static struct key_packet keybinds[] = {
{.key_id = KEY_RIGHT_ARROW, .modifiers = WINS},
{.key_id = KEY_UP_ARROW, .modifiers = WINS},
{.key_id = KEY_DOWN_ARROW, .modifiers = WINS},
- {.key_id = KEY_SPACE, .modifiers = WINS},
- {.key_id = KEY_PAGE_DOWN, .modifiers = WINS}
+ {.key_id = KEY_SPACE, .modifiers = WINS}
};
static inline bool fuzzy_key_match(struct key_packet t, struct key_packet a) {
@@ -510,18 +509,6 @@ void on_action(struct window_action packet) {
if (!try_elf_run(drives, run_command, run_command_pass, 0))
logf(LOG_ERROR, "Couldn't run program listed in " RUN_COMMAND_FILE ".");
break;
- case WM_SEND_BOTTOM:
- if (top_window && (top_window != bottom_window)) {
- struct window *const top = top_window;
- struct window *const bot = bottom_window;
- top->above = bot;
- bot->below = top;
- top_window = top->below;
- bottom_window = top;
- top_window->above = 0;
- bottom_window->below = 0;
- paint_and_above(bot);
- }
}
switch_to_task_cr3();
return;
@@ -572,6 +559,32 @@ static void focus(struct window *w) {
send_action(w, (struct window_action){.action_type = FOCUS_ENTER});
}
+static void send_bottom(struct window *w) {
+ if (w == bottom_window)
+ return;
+ if (w == top_window) {
+ send_action(w, (struct window_action){.action_type = FOCUS_LEAVE});
+ top_window = w->below;
+ top_window->above = 0;
+ w->above = bottom_window;
+ w->below = 0;
+ bottom_window->below = w;
+ bottom_window = w;
+ send_action(top_window, (struct window_action){.action_type = FOCUS_ENTER});
+ }
+ else {
+ w->above->below = w->below;
+ w->below->above = w->above;
+ bottom_window->below = w;
+ w->above = bottom_window;
+ w->below = 0;
+ bottom_window = w;
+ }
+ paint_and_above(w->above);
+}
+
+bool skip_up_right = false;
+
void mouse_button(enum mouse_button which, bool up) {
if (!top_window)
return;
@@ -580,19 +593,33 @@ void mouse_button(enum mouse_button which, bool up) {
if (!clicked_on)
return;
- if ((mouse_y >= clicked_on->ypos) && (mouse_y < clicked_on->ypos + clicked_on->height) &&
- (mouse_x >= clicked_on->xpos) && (mouse_x < clicked_on->xpos + clicked_on->width)) {
+ if ((mouse_y < clicked_on->ypos) || (mouse_y >= clicked_on->ypos + clicked_on->height) ||
+ (mouse_x < clicked_on->xpos) || (mouse_x >= clicked_on->xpos + clicked_on->width))
+ //TODO: resizing
+ return;
+
+ if (up && being_moved && (which == LEFT))
+ being_moved = 0;
+
+ else if (!up && !being_moved && (keymods & ALTS) && (which == LEFT)) {
+ being_moved = clicked_on;
+ winpos_rel_y = clicked_on->ypos - mouse_y;
+ winpos_rel_x = clicked_on->xpos - mouse_x;
+ }
+
+ else if (!up && (keymods & ALTS) && (which == RIGHT)) {
+ send_bottom(clicked_on);
+ skip_up_right = true;
+ }
+
+ else if (up && skip_up_right && (which == RIGHT))
+ skip_up_right = false;
+
+ else {
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}});
}
- else if (!up && !being_moved) {
- being_moved = clicked_on;
- winpos_rel_y = clicked_on->ypos - mouse_y;
- winpos_rel_x = clicked_on->xpos - mouse_x;
- }
- else if (up)
- being_moved = 0;
} \ No newline at end of file