simple scroll

This commit is contained in:
catfood 2022-12-24 17:50:27 +08:00
parent 4bd7c1e46d
commit 1e07c4cff6
7 changed files with 164 additions and 111 deletions

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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. 添加鼠标并调试滚动

View File

@ -127,7 +127,7 @@ void initial()
do_vclose(stdout);
do_vclose(stderr);
exec("orange/shell_0.bin");
exec("orange/test.bin");
while(1);
}

View File

@ -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)

View File

@ -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)