diff options
-rw-r--r-- | fs-skel/sys/startup.rc | 2 | ||||
-rw-r--r-- | src/kernel/kbd.c | 321 | ||||
-rw-r--r-- | src/kernel/kbd.h | 2 | ||||
-rw-r--r-- | src/kernel/window.c | 75 |
4 files changed, 212 insertions, 188 deletions
diff --git a/fs-skel/sys/startup.rc b/fs-skel/sys/startup.rc index 95241d0..321292d 100644 --- a/fs-skel/sys/startup.rc +++ b/fs-skel/sys/startup.rc @@ -1 +1 @@ -bin/mkpopup Welcome to Portland OS v0.0.11!\n\nPress Win+Space to open a terminal with a shell.\nClick on a window to bring it to the top of the stack.\nClick and drag on a window border to move a window.\nPress Win+PageDown to send the top window to the bottom.\nType "dirlist bin" into a shell for a list of programs.\n\nPress Escape to close this window.
\ No newline at end of file +bin/mkpopup Welcome to Portland OS v0.0.11!\n\nPress Win+Space to open a terminal with a shell.\nClick on a window to bring it to the top of the stack.\nLeft click and drag a window while holding Alt to move it.\nRight click on a window while holding Alt to send it to the bottom.\nType "dirlist bin" into a shell for a list of programs.\n\nPress Escape to close this window.
\ No newline at end of file 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 |