diff --git a/include/keyboard.h b/include/keyboard.h index 1d24452..11ca827 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -121,6 +121,9 @@ #define PAD_MID PAD_5 /* Middle key */ #define PAD_DEL PAD_DOT /* Del */ #endif +#define MOUSESCR_UP 0x1 +#define MOUSESCR_DOWN 0x2 + #define PS2_PORT_DATA (0x60) #define PS2_PORT_CMD (0x64) @@ -155,6 +158,16 @@ typedef struct mouse_inbuf{ u8 buf[MOUSE_IN_BYTES]; }MOUSE_INPUT; +typedef struct MouseState +{ + u8 mouse_lb; + u8 mouse_mb; + u8 mouse_rb; + signed char mouse_scroll; + int mouse_x; + int mouse_y; +} MouseState; + #endif /* _ORANGES_KEYBOARD_H_ */ diff --git a/include/minix_keymap.h b/include/minix_keymap.h index d3b36ff..99fb8df 100644 --- a/include/minix_keymap.h +++ b/include/minix_keymap.h @@ -545,6 +545,19 @@ const static struct scanmap scanmap_escaped[KBD_SCAN_CODES] = { #define ALT 0x0800 /* Alternate key */ #define HASNUM 0x4000 /* Num Lock has effect */ #define HASCAPS 0x8000 /* Caps Lock has effect */ +#define ISMOUSE 0x80000000 +#define MOUSEBTN 0x40000000 +#define MOUSEBTN_RELEASE 0x00 +#define MOUSEBTN_CLICK 0x80 +#define MOUSEBTN_L 0x1 +#define MOUSEBTN_R 0x2 +#define MOUSEBTN_M 0x4 +#define MOUSEPOS 0x20000000 +#define MOUSEPOS_XY 0x00000200 +#define MOUSEPOS_NEG 0x00000100 +#define MOUSESCR 0x10000000 +#define MOUSESCR_UP 0x1 +#define MOUSESCR_DOWN 0x2 /* The left and right versions for the actual keys in the keymap. */ #define LCTRL CTRLKEY diff --git a/include/tty.h b/include/tty.h index f15b85d..81212ce 100644 --- a/include/tty.h +++ b/include/tty.h @@ -48,20 +48,10 @@ typedef struct s_tty struct s_console *console; } TTY; -typedef struct MouseState -{ - u8 mouse_lb; - u8 mouse_mb; - u8 mouse_rb; - signed char mouse_scroll; - int mouse_x; - int mouse_y; -} MouseState; typedef struct n_tty { int driver_type; // 1-vga&kbd; 2-serial - MouseState mouse; void *input_buf; void *output_buf; } NTTY; @@ -112,11 +102,13 @@ void vga_tty_init(NTTY* tty); void vga_tty_write(NTTY* tty, char ch); void vga_tty_flush(NTTY* tty); void vga_tty_backspace(NTTY* tty); +void vga_tty_scroll(NTTY *tty, int direction); + void ps2_tty_init(NTTY* tty); -int ps2_tty_read(NTTY* tty, u8* buf, int nr); +int ps2_tty_read(NTTY* tty, char* buf, int nr); -#define CYCLE_SUB(head, tail, _max) ((head) < (tail) ? (tail)-(head) : (tail) + (_max) - (head)) +#define CYCLE_SUB(head, tail, _max) ((head) <= (tail) ? (tail)-(head) : (tail) + (_max) - (head)) #define NEXT(x, _max) (((x) + 1) % (_max)) #define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1) #define DEBUGNEW diff --git a/kernel/keyboard.c b/kernel/keyboard.c index bf5af5e..1ddad55 100644 --- a/kernel/keyboard.c +++ b/kernel/keyboard.c @@ -9,6 +9,7 @@ #include "proto.h" #include "keyboard.h" // #include "keymap.h" +#include "spinlock.h" #include "x86.h" #include "stdio.h" #include "assert.h" @@ -29,13 +30,13 @@ static int ctrl_r; /* l ctrl state */ static int caps_lock; /* Caps Lock */ static int num_lock; /* Num Lock */ static int scroll_lock; /* Scroll Lock */ -static int column; +static MouseState mouse_state; static u8 get_byte_from_kb_buf(); static void set_leds(); static void set_mouse_leds(); static void kb_wait(); -static void ps2_push(NTTY* tty, u16 key); +static void ps2_push(NTTY* tty, u32 key); static void kbd_process(unsigned char scode); // static void kb_ack(); @@ -89,6 +90,7 @@ void kb_handler(int irq){ u8 scan_code = inb(PS2_PORT_DATA); #ifdef DEBUGNEW kbd_process(scan_code); + // kprintf("shit"); #else if(kb_in.count < KB_IN_BYTES){ *(kb_in.p_head) = scan_code; @@ -101,49 +103,48 @@ void kb_handler(int irq){ #endif }; -#define TTY_FIRST (tty_table) -#define TTY_END (tty_table+NR_CONSOLES) void mouse_handler(int irq){ u8 scan_code = inb(PS2_PORT_DATA); + static int aux_state = 0; + int i; + u32 pack; + if (mouse_in.count == 0 && !(scan_code & 0x08)) + return; // resync + mouse_in.buf[mouse_in.count++] = scan_code; + if (mouse_in.count < 4) return; - mouse_in.buf[mouse_in.count]=scan_code; - if ((mouse_in.buf[0] & 0xc8) == 0x08) - mouse_in.count++; // simple trick to sync mouse data - if(mouse_in.count==4){ - // printf("0x%02x 0x%02x 0x%02x 0x%02x\n", mouse_in.buf[0], mouse_in.buf[1], mouse_in.buf[2], mouse_in.buf[3]); - TTY* p_tty; - for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++) { - if(p_tty->console==&console_table[current_console]){ - p_tty->mouse_left_button = mouse_in.buf[0]&0x01; - - u8 mid_button = mouse_in.buf[0]&0b100; - if(mid_button==0b100){ - p_tty->mouse_mid_button = 1; - }else{ - p_tty->mouse_mid_button = 0; - } - - if(p_tty->mouse_left_button){ - u8 dir_Y = mouse_in.buf[0]&0x20; - u8 dir_X = mouse_in.buf[0]&0x10; - if(dir_Y==0x20){//down - p_tty->mouse_Y -= 1; - }else{//up - p_tty->mouse_Y += 1; - } - - if(dir_X==0x10){//left - p_tty->mouse_X -= 1; - }else{//right - p_tty->mouse_X += 1; - } - } - } + mouse_in.count = 0; + for (i = 0; i < 3; i++) { + pack = ISMOUSE | MOUSEBTN; + if ((aux_state ^ mouse_in.buf[0]) & (1 << i)) { + aux_state ^= (1 << i); + pack |= !!(aux_state & (1 << i)) ? MOUSEBTN_CLICK : MOUSEBTN_RELEASE; + pack |= (1 << i); + ps2_push(&ntty_table[cur_ntty], pack); } - - mouse_in.count=0; } + pack = ISMOUSE | MOUSESCR; + if ((signed char)mouse_in.buf[3] > 0) { + // actually it is 0x1 + pack |= MOUSESCR_DOWN; + ps2_push(&ntty_table[cur_ntty], pack); + } else if ((signed char)mouse_in.buf[3] < 0) { + // actually it is 0xff + pack |= MOUSESCR_UP; + ps2_push(&ntty_table[cur_ntty], pack); + } + for (i = 0; i < 2; i++) { + pack = mouse_in.buf[1 + i]; + if (pack != 0) { + pack |= ISMOUSE | MOUSEPOS; + if (mouse_in.buf[0] & (0x10 << i)) + pack |= MOUSEPOS_NEG; + if (i == 1) pack |= MOUSEPOS_XY; + ps2_push(&ntty_table[cur_ntty], pack); + } + } + // kprintf("0x%02x 0x%02x 0x%02x 0x%02x\n", mouse_in.buf[0], mouse_in.buf[1], mouse_in.buf[2], mouse_in.buf[3]); } void init_mouse(){ @@ -182,12 +183,10 @@ void init_kb(){ shift_l = shift_r = 0; alt_l = alt_r = 0; ctrl_l = ctrl_r = 0; - caps_lock = 0; num_lock = 1; scroll_lock = 0; - column = 0; set_leds(); put_irq_handler(KEYBOARD_IRQ, kb_handler); @@ -198,6 +197,7 @@ void init_kb(){ } #ifndef DEBUGNEW +static int column; void keyboard_read(TTY* p_tty) { u8 scan_code; @@ -591,6 +591,7 @@ static void set_mouse_leds(){ outb(KB_DATA, KBC_MODE); } +static struct spinlock buflock; #define LASTKEY(x) LAST(x, TTY_IN_BYTES) #define NEXTKEY(x) NEXT(x, TTY_IN_BYTES) @@ -604,29 +605,63 @@ void ps2_tty_init(NTTY* tty) { kbd->buf = (void*)keybuf[_cnt ++]; kbd->head = kbd->tail = kbd->readable = 0; kbd->len = 0; + buflock.locked = 0; } -int ps2_tty_read(NTTY* tty, u8* buf, int nr) { +int ps2_tty_read(NTTY* tty, char* buf, int nr) { + assert(tty->input_buf); keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; + assert(kbd->buf); int i = 0; - while (kbd->readable == 0); + while(1) { + if (kbd->readable) { + disable_int(); + break; + } + } + u8* ibuf = kbd->buf; for (; i < nr && i < kbd->readable; ++ i) { - buf[i] = ((int*)kbd->buf)[kbd->head]; + *(buf+i) = *(ibuf+kbd->head); + // kprintf("read %p\n", ibuf+kbd->head); kbd->head = NEXTKEY(kbd->head); } kbd->readable -= i; kbd->len -= i; + enable_int(); return i; } void ps2_tty_flush(NTTY* tty) { - + disable_int(); + assert(tty->input_buf); + keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; + kbd->head = kbd->tail = kbd->len = kbd->readable = 0; + enable_int(); } -static void ps2_push(NTTY* tty, u16 key) { +static void ps2_push(NTTY* tty, u32 key) { // kprintf("%x\n", key); + disable_int(); + assert(tty->input_buf); keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; - if (key & EXT) { + if (key & ISMOUSE) { + if (key & MOUSESCR) { + if (key & MOUSESCR_UP) { + // kprintf("scroll up\n"); + vga_tty_scroll(tty, MOUSESCR_UP); + } else { + // kprintf("scroll down\n"); + vga_tty_scroll(tty, MOUSESCR_DOWN); + } + } + else if (key & MOUSEBTN) { + if ((key & MOUSEBTN_CLICK) && (key & MOUSEBTN_M)) { + kprintf("middle btn click %x\n", key); + vga_tty_scroll(tty, 3); + } + } + } + else if (key & EXT) { switch (key) { case F1: case F2: case F3: case F4: case F5: case F6: @@ -643,10 +678,11 @@ static void ps2_push(NTTY* tty, u16 key) { { case '\r': case '\n': // escape ENTER vga_tty_write(tty, '\n'); - ((int*)kbd->buf)[kbd->tail] = '\n'; + ((u8*)kbd->buf)[kbd->tail] = '\n'; kbd->len ++; kbd->tail = NEXTKEY(kbd->tail); kbd->readable = CYCLE_SUB(kbd->head, kbd->tail, TTY_IN_BYTES); + // kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable); break; case '\b': if (kbd->len > kbd->readable) { @@ -660,12 +696,15 @@ static void ps2_push(NTTY* tty, u16 key) { if ((key & 0xff) == 0) return; if (kbd->len == TTY_IN_BYTES - 1) return; // leave one space for ctrl ascii vga_tty_write(tty, key); - ((int*)kbd->buf)[kbd->tail] = key & 0xff; + ((u8*)kbd->buf)[kbd->tail] = key & 0xff; kbd->len ++; kbd->tail = NEXTKEY(kbd->tail); + // kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable); break; } + vga_tty_flush(tty); } + enable_int(); } //TODO: 1. 修改键盘驱动 2. 添加测试代码 3. 添加鼠标并调试滚动 \ No newline at end of file diff --git a/kernel/ktest.c b/kernel/ktest.c index 37c9ad6..97a70ef 100644 --- a/kernel/ktest.c +++ b/kernel/ktest.c @@ -127,7 +127,7 @@ void initial() do_vclose(stdout); do_vclose(stderr); - exec("orange/shell_0.bin"); + exec("orange/test.bin"); while(1); } \ No newline at end of file diff --git a/kernel/tty.c b/kernel/tty.c index 7226adf..72d7b64 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -124,7 +124,7 @@ void task_tty() // } while (1) { - vga_tty_flush(&ntty_table[cur_ntty]); + // vga_tty_flush(&ntty_table[cur_ntty]); } #else @@ -305,7 +305,7 @@ void tty_write(TTY *tty, char *buf, int len) { vga_tty_write(&ntty_table[cur_ntty], *buf++); } - // vga_tty_flush(&ntty_table[cur_ntty]); + vga_tty_flush(&ntty_table[cur_ntty]); #else while (--len >= 0) out_char(tty->console, *buf++); @@ -321,7 +321,7 @@ void tty_write(TTY *tty, char *buf, int len) int tty_read(TTY *tty, char *buf, int len) { #ifdef DEBUGNEW - return ps2_tty_read(&ntty_table[cur_ntty], (u8*)buf, len); + return ps2_tty_read(&ntty_table[cur_ntty], buf, len); #else int i = 0; if (!tty->ibuf_read_cnt) diff --git a/kernel/vga.c b/kernel/vga.c index 5edf2bb..a23275b 100644 --- a/kernel/vga.c +++ b/kernel/vga.c @@ -141,31 +141,31 @@ void vga_tty_init(NTTY* tty) { kprintf("%p 0x%x %d\n", vga->buf, ((u32 *)vga->buf)[20], vga->scr_cur_line); } -#define INDEX(row, col) ((row)*SCR_WIDTH + (col)) -#define NEXTLINE(row) (((row) + 1) % SCR_MAXLINE) -#define LASTLINE(row) (((row)-1) >= 0 ? ((row)-1) % SCR_MAXLINE : SCR_MAXLINE) +#define INDEX(row, col) ((row) * SCR_WIDTH + (col)) +#define NEXTLINE(row) NEXT(row, SCR_MAXLINE) +#define LASTLINE(row) LAST(row, SCR_MAXLINE) -static void newline(vga_buf *vgabuf) -{ - vgabuf->cur_col = 0; +static void newline(vga_buf* vga) { + u16* buf = vga->buf; + vga->cur_col = 0; // kprintf("bf %x\n", vgabuf->scr_cur_line); - vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); + vga->scr_cur_line = NEXTLINE(vga->scr_cur_line); // kprintf("af %x\n", vgabuf->scr_cur_line); - vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line); - if (vgabuf->cur_row == SCR_HEIGHT) - { + vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); + if (vga->cur_row == SCR_HEIGHT) { // auto scroll - vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); - if (vgabuf->scr_cur_line == vgabuf->head_line) - { - vgabuf->head_line = NEXTLINE(vgabuf->head_line); - // remember to fill blank the old line - u32 *ptr_buf = (u32 *)(vgabuf->buf + sizeof(u16) * vgabuf->head_line * SCR_WIDTH); - for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) - { - *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space - } + vga->scr_top_line = NEXTLINE(vga->scr_top_line); + } + if(vga->scr_cur_line == vga->head_line) { + vga->head_line = NEXTLINE(vga->head_line); + // remember to fill blank the old line + u32* ptr_buf = (u32*) (vga->buf + sizeof(u16) * vga->scr_cur_line * SCR_WIDTH); + for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) { + *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space } + // for (int i = 0; i < SCR_WIDTH; ++ i) { + // buf[INDEX(vga->scr_cur_line, i)] = BLANK; + // } } } @@ -464,23 +464,24 @@ void vga_tty_flush(NTTY* tty) { u16* buf = vga->buf; int i, cur_line; vga_set_cursor(INDEX(vga->cur_row, vga->cur_col)); - if (vga->cur_row == SCR_WIDTH - 1) - { - vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]); - } - else - { + // if (vga->cur_row == SCR_HEIGHT - 1) + // { + // vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]); + + // } + // else + // { cur_line = vga->scr_top_line; for (i = 0; i <= vga->cur_row; ++i) { vga_flush_line(&buf[INDEX(cur_line, 0)], i); cur_line = NEXTLINE(cur_line); } - for (; i < SCR_WIDTH; ++i) + for (; i < SCR_HEIGHT; ++i) { vga_flush_blankline(i); } - } + // } // kprintf("flush: row=%d, top=%d, cur=%d\n", vga->cur_row, vga->scr_top_line, vga->scr_cur_line); } @@ -488,42 +489,37 @@ void vga_tty_scroll(NTTY *tty, int direction) { vga_buf *vga = tty->output_buf; u16 *buf = vga->buf; - if (direction > 0) + if (direction == MOUSESCR_DOWN) { // down if (vga->scr_top_line == vga->scr_cur_line) return; vga->scr_top_line = NEXTLINE(vga->scr_top_line); } - else + else if (direction == MOUSESCR_UP) { if (vga->scr_top_line == vga->head_line) return; vga->scr_top_line = LASTLINE(vga->scr_top_line); } - vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line); + else { + if (CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE) >= SCR_HEIGHT) { + + vga->scr_top_line = CYCLE_SUB(SCR_HEIGHT / 2, vga->scr_cur_line, SCR_MAXLINE); + } + // kprintf("scroll to cur top-%d, cur-%d\n", vga->scr_top_line, vga->scr_cur_line); + } + vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); if (vga->cur_row >= SCR_HEIGHT) { vga_disable_cursor(); + // kprintf("disable cursor: %d\n", vga->cur_row); } else { - vga_enable_cursor(0, 15); + vga_enable_cursor(14, 15); } -} - -void vga_scroll_to_cur(NTTY *tty) -{ - vga_buf *vga = tty->output_buf; - u16 *buf = vga->buf; - // vga->scr_top_line = vga->scr_cur_line -} - -void vga_ttroll_to_cur(NTTY *tty) -{ - vga_buf *vga = tty->output_buf; - u16 *buf = vga->buf; - // vga->scr_top_line = vga->scr_cur_line + vga_tty_flush(tty); } void vga_tty_select(NTTY *tty)