📄 keyboard.c~
字号:
#include "../include/toyos.h"#include"keyboard.h"
int Pos=50;
PUBLIC void KeyboardHandle()
//键盘中断处理函数,从端口中读取一个字节到扫描码缓冲区中
{ t_8 ScanCode;
ScanCode=InByte(KB_DATA);
if(ScanCodeBuffer.Count<KB_IN_BYTES)
{
*(ScanCodeBuffer.Head)=ScanCode;
ScanCodeBuffer.Head++;
if(ScanCodeBuffer.Head==ScanCodeBuffer.Buffer+KB_IN_BYTES)
{
ScanCodeBuffer.Head=ScanCodeBuffer.Buffer;
}
}
ScanCodeBuffer.Count++;
}
PUBLIC void InitKeyboard()
//键盘初始化函数。
{
//初始化扫描码缓冲区
ScanCodeBuffer.Count=0;
ScanCodeBuffer.Head=ScanCodeBuffer.Tail=ScanCodeBuffer.Buffer; caps_lock = 0;
num_lock = 1;
scroll_lock = 0;
SetLeds();
// EnableIrq(0);
}
PUBLIC t_8 GetByteFromScanCode()
//从扫描码缓冲区中读取一个字节
{
t_8 ScanCode;
// DisableIrq(1);//关中断
while(ScanCodeBuffer.Count<=0){}
// asm cli
ScanCode= *(ScanCodeBuffer.Tail);
ScanCodeBuffer.Tail++;
if(ScanCodeBuffer.Tail==ScanCodeBuffer.Buffer+KB_IN_BYTES)
{
ScanCodeBuffer.Tail=ScanCodeBuffer.Buffer;
}
ScanCodeBuffer.Count--;
// asm sti // EnableIrq(1);//开中断
return ScanCode;
}
PUBLIC void ReadScanCode(TTY *pTTY)
//解析扫描码函数
{ // return ;
t_8 ScanCode;
char OutPut[2]={0,0};
t_bool IsMakeCode;//是MakeCode还是BreakCode
t_32 Key=0;
t_32 *KeyRow;
if(ScanCodeBuffer.Count>0)
{
CodeWithE0=FALSE;
ScanCode= GetByteFromScanCode();
//处理Pausebreak键
if(ScanCode==0xE1)
{
int i;
t_8 PausebreakScanCode[]={0xE1,0x1D,0x45,0xE1,0x9D,0xC5};
t_bool IsPausebreak=TRUE;
for(i=1;i<6;i++)
{
if(GetByteFromScanCode()!=PausebreakScanCode[i])
{
IsPausebreak=FALSE;
break;
}
}
if (IsPausebreak) {
Key = PAUSEBREAK;
}
}//处理PRINTSCREEN键
else if(ScanCode==0xE0)
{ CodeWithE0=TRUE;
ScanCode=GetByteFromScanCode();
//PRINTSCREEN键按下
if(ScanCode==0x2A)
{ CodeWithE0=FALSE;
if(GetByteFromScanCode()==0xE0)
{ CodeWithE0=TRUE;
if(GetByteFromScanCode()==0x37)
{
Key=PRINTSCREEN;
IsMakeCode=TRUE;
}
}
}
//PRINTSCREEN键弹开
if(ScanCode==0xB7)
{ CodeWithE0=FALSE;
if(GetByteFromScanCode()==0xE0) { CodeWithE0=FALSE;
if(GetByteFromScanCode()==0xAA)
{
Key=PRINTSCREEN;
IsMakeCode=FALSE;
} }
}
//非以上特殊按键
/*if(Key==0)
CodeWithE0=TRUE;*/
}
if (Key!=PAUSEBREAK&&Key!=PRINTSCREEN)
{
//GetByteFromScanCode();
IsMakeCode=(ScanCode&FLAG_BREAK?FALSE:TRUE);//判断 是MakeCode还是BreakCode
KeyRow=&KeyMap[(ScanCode&0x7F)*MAP_COULMN];//将KeyMap得响应行赋给KeyRow
Column=0; t_bool caps = LeftShift||RightShift; if (caps_lock) {
if ((KeyRow[0] >= 'a') && (KeyRow[0] <= 'z')){
caps = !caps;
}
}
if (caps) {
Column = 1;
}
if(CodeWithE0)
{
Column=2;
}
Key=KeyRow[Column];
switch(Key)
{
case SHIFT_L:
LeftShift=IsMakeCode;
break;
case SHIFT_R:
RightShift=IsMakeCode;
break;
case CTRL_L:
LeftCtrl=IsMakeCode;
break;
case CTRL_R:
RightCtrl=IsMakeCode;
break;
case ALT_L:
LeftAlt=IsMakeCode;
break;
case ALT_R:
RightAlt=IsMakeCode;
break; case CAPS_LOCK:
if (IsMakeCode) {
caps_lock = !caps_lock;
SetLeds();
}
break;
case NUM_LOCK:
if (IsMakeCode) {
num_lock = !num_lock;
SetLeds();
}
break;
case SCROLL_LOCK:
if (IsMakeCode) {
scroll_lock = !scroll_lock;
SetLeds();
}
break;
default:
break;
}
//如果是MakeCode则置相应位
/*if(IsMakeCode)
{
Key|=LeftShift ? FLAG_SHIFT_L:0;
Key|=RightShift ? FLAG_SHIFT_R:0;
Key|=LeftCtrl ? FLAG_CTRL_L:0;
Key|=RightCtrl ? FLAG_CTRL_R:0;
Key|=LeftAlt ? FLAG_ALT_L:0;
Key|=RightAlt ? FLAG_ALT_R:0;
InProcess(pTTY,Key);
}*/
} if(IsMakeCode){ /* 忽略 Break Code */
t_bool pad = FALSE;
/* 首先处理小键盘 */
if ((Key >= PAD_SLASH) && (Key <= PAD_9)) {
pad = TRUE;
switch(Key) { /* '/', '*', '-', '+', and 'Enter' in num pad */
case PAD_SLASH:
Key = '/';
break;
case PAD_STAR:
Key = '*';
break;
case PAD_MINUS:
Key = '-';
break;
case PAD_PLUS:
Key = '+';
break;
case PAD_ENTER:
Key = ENTER;
break;
default: /* keys whose value depends on the NumLock */
if (num_lock) { /* '0' ~ '9' and '.' in num pad */
if ((Key >= PAD_0) && (Key <= PAD_9)) {
Key = Key - PAD_0 + '0';
}
else if (Key == PAD_DOT) {
Key = '.';
}
}
else{
switch(Key) {
case PAD_HOME:
Key = HOME;
break;
case PAD_END:
Key = END;
break;
case PAD_PAGEUP:
Key = PAGEUP;
break;
case PAD_PAGEDOWN:
Key = PAGEDOWN;
break;
case PAD_INS:
Key = INSERT;
break;
case PAD_UP:
Key = UP;
break;
case PAD_DOWN:
Key = DOWN;
break;
case PAD_LEFT:
Key = LEFT;
break;
case PAD_RIGHT:
Key = RIGHT;
break;
case PAD_DOT:
Key = DELETE;
break;
default:
break;
}
}
break;
}
}
Key |= LeftShift ? FLAG_SHIFT_L : 0;
Key |= RightShift ? FLAG_SHIFT_R : 0;
Key |= LeftCtrl ? FLAG_CTRL_L : 0;
Key |= RightCtrl ? FLAG_CTRL_R : 0;
Key |= LeftAlt ? FLAG_ALT_L : 0;
Key |= RightAlt ? FLAG_ALT_R : 0;
Key |= pad ? FLAG_PAD : 0;
InProcess(pTTY,Key);
}
}
}
PRIVATE void SetCursor(unsigned int Position)
{
LockIrq();
OutByte(CRTC_ADDR_REG,START_CURSOR_H );
OutByte(CRTC_DATA_REG,(t_8)((Position>>8)&0xFF));
OutByte(CRTC_ADDR_REG,START_CURSOR_L );
OutByte(CRTC_DATA_REG,(t_8)(Position&0xFF));
UnLock();
}
PRIVATE void SetVideoStartAddr(t_32 addr)
{
LockIrq();
OutByte(CRTC_ADDR_REG,START_ADDR_H);
OutByte(CRTC_DATA_REG,(t_8)((addr>>8)&0xFF));
OutByte(CRTC_ADDR_REG,START_ADDR_L);
OutByte(CRTC_DATA_REG,(t_8)(addr&0xFF));
UnLock();
}
PRIVATE void SelectConsole(int nr_Console)
{
if((nr_Console<0)||(nr_Console>=NR_CONSOLES))
return ;
CurrentConsole=nr_Console;
SetCursor(ConsoleTable[nr_Console].CursorPos);
SetVideoStartAddr(ConsoleTable[nr_Console].CurrentStartAddr);
}
PUBLIC void ScrollScreen(CONSOLE *pConsole,int Direction)
{
if(Direction==SCROLL_SCREEN_UP)
{
if(pConsole->CurrentStartAddr>pConsole->OriginalAddr)
pConsole->CurrentStartAddr-=SCREEN_WIDTH;
}
else if(Direction==SCROLL_SCREEN_DOWN)
{
if(pConsole->CurrentStartAddr+SCREEN_SIZE<
pConsole->OriginalAddr+pConsole->Size)
pConsole->CurrentStartAddr+=SCREEN_WIDTH;
}else
{
SetVideoStartAddr(pConsole->CurrentStartAddr);
SetCursor(pConsole->CursorPos);
}
}
PUBLIC void OutChar(CONSOLE *pConsole,char ch)
{
t_8 *p_vmem = (t_8*)(V_MEM_BASE+pConsole->CursorPos*2); /* typedef struct s_Console
{
unsigned int CurrentStartAddr;
unsigned int OriginalAddr;
unsigned int Size;
unsigned int CursorPos;
}CONSOLE;
*p_vmem++ =ch;
*p_vmem++ =DEFAULT_CHAR_COLOR;
pConsole->CursorPos++;
SetCursor(pConsole->CursorPos);*/
switch(ch) {
case '\n':
if (pConsole->CursorPos < pConsole->OriginalAddr + pConsole->Size - SCREEN_WIDTH) {
pConsole->CursorPos = pConsole->OriginalAddr + SCREEN_WIDTH * ((pConsole->CursorPos - pConsole->OriginalAddr) / SCREEN_WIDTH + 1);
}
break;
case '\b':
if (pConsole->CursorPos > pConsole->OriginalAddr) {
pConsole->CursorPos--;
*(p_vmem-2) = ' ';
*(p_vmem-1) = DEFAULT_CHAR_COLOR;
}
break;
default:
if (pConsole->CursorPos <pConsole->OriginalAddr +pConsole->Size - 1) {
*p_vmem++ = ch;
*p_vmem++ = DEFAULT_CHAR_COLOR;
pConsole->CursorPos++;
}
break;
}
SetCursor(pConsole->CursorPos);
}
PUBLIC void InProcess(TTY *pTTY,t_32 Key)
{
//对按键的处理
int RawCode=Key&MASK_RAW;
char OutPut[2]={'\0','\0'};
if(!(Key&FLAG_EXT))//过滤不可打印字符
{
/*if(pTTY->Count<TTY_IN_BYTES)
{
*(pTTY->Head)=Key;
pTTY->Head++;
if(pTTY->Head==pTTY->Buffer+TTY_IN_BYTES)
pTTY->Head=pTTY->Buffer;
pTTY->Count++;
}*/
PutKey(pTTY,Key);
}
else
{
switch(RawCode)
{ case ENTER:
PutKey(pTTY, '\n');
break;
case BACKSPACE:
PutKey(pTTY, '\b');
break;
case F5:
// if((Key&FLAG_SHIFT_L)||(Key&FLAG_SHIFT_R))
ScrollScreen(pTTY->pConsole,SCROLL_SCREEN_UP);
break;
case F6:
// if((Key&FLAG_SHIFT_L)||(Key&FLAG_SHIFT_R))
ScrollScreen(pTTY->pConsole,SCROLL_SCREEN_DOWN);
break;
case F1: //Send.Type=1;Send.Next=NULL;goto Lable;
case F2:// Send.Type=2;Send.Next=NULL;goto Lable;
case F3:
case F4:
//Lable:
if((Key&FLAG_ALT_L)||(Key&FLAG_ALT_R))
SelectConsole(RawCode-F1);
else
{
printk("Send IS");
// SendMessage( IS,&Send);
}
break;
default :
break;
}
}
}
PUBLIC void InitScreen(TTY *pTTY)
{
int v_mem_size=V_MEM_SIZE>>1;
int con_v_mem_size=v_mem_size/NR_CONSOLES;
int nr_tty=pTTY-TTYTable;
pTTY->pConsole=ConsoleTable+nr_tty;
pTTY->pConsole->OriginalAddr=nr_tty*con_v_mem_size;
pTTY->pConsole->Size=con_v_mem_size;
pTTY->pConsole->CurrentStartAddr=
pTTY->pConsole->OriginalAddr;
pTTY->pConsole->CursorPos=pTTY->pConsole->OriginalAddr;
if(nr_tty==0)
pTTY->pConsole->CursorPos=Disp_pos/2;
else
{
OutChar(pTTY->pConsole,(char)(nr_tty+'0'));
OutChar(pTTY->pConsole,'@');
}
SetCursor(pTTY->pConsole->CursorPos);
}
PRIVATE void InitTTY(TTY *pTTY)
{
pTTY->Count=0;
pTTY->Head=pTTY->Tail=pTTY->Buffer;
pTTY->pConsole=ConsoleTable+(pTTY-TTYTable);
pTTY->KeyCount=0;
pTTY->KeyHead=pTTY->KeyTail=pTTY->KeyBuffer;
InitScreen(pTTY);
}
PUBLIC t_bool IsCurrentConsole(CONSOLE *pConsole)
{
return (pConsole==&ConsoleTable[CurrentConsole]);
}
PRIVATE void TTYRead(TTY *pTTY)
{
if(IsCurrentConsole(pTTY->pConsole))
{
ReadScanCode(pTTY);
}
}
PRIVATE void TTYWrite(TTY *pTTY)
{ char ch;
if(pTTY->Count)
{
ch=*(pTTY->Tail);
pTTY->Tail++;
if(pTTY->Tail==pTTY->Buffer+TTY_IN_BYTES)
pTTY->Tail=pTTY->Buffer;
pTTY->Count--;
OutChar(pTTY->pConsole,ch);
}
}
PUBLIC void sysTTYWrite(TTY *pTTY,char *buf,int len)
{
char *p=buf;
int i=len;
while(i)
{
OutChar(pTTY->pConsole,*p++);
i--;
}
}
PUBLIC int sysWrite(char *buf,int len,int console)/* ***************************** edit by et*************************** */
{
int Console=pCurrentProc->TTYNum;
if(Console>=NR_CONSOLES)
Console--;
if(Console<0)
Console=0;
sysTTYWrite(&TTYTable[Console],buf,len);
return 0;
}
PUBLIC char sysGetChar()
{
TTY *pTTY=&TTYTable[0];
char ch;
if(pTTY->KeyCount<=0)
waitEvent(EV_KEYPRESS);
if(pTTY->KeyCount>0)
{
ch=*(pTTY->KeyTail);
pTTY->KeyTail++;
if(pTTY->KeyTail==pTTY->KeyBuffer+TTY_IN_BYTES)
pTTY->KeyTail=pTTY->KeyBuffer;
pTTY->KeyCount--;
OutChar(pTTY->pConsole,ch);
return ch;
}
return '\0';
}
/*
PUBLIC void sysSetCursor(Message *pMess)
{
int Position=pMess->POSITION;
TTYTable[0].pConsole->CursorPos=Position;
SetCursor(Position);
}
PUBLIC char sysGetChar()
{
TTY *pTTY=&TTYTable[0];
char ch;
// while(pTTY->KeyCount<=0) {}
if(pTTY->KeyCount>0)
{
ch=*(pTTY->KeyTail);
pTTY->KeyTail++;
if(pTTY->KeyTail==pTTY->KeyBuffer+TTY_IN_BYTES)
pTTY->KeyTail=pTTY->KeyBuffer;
pTTY->KeyCount--;
return ch;
}
return '\0';
}
*/
PUBLIC void initTTY()
{
TTY *pTTY;
printk("*************Init TTY****************\n");
InitKeyboard();
for(pTTY=TTY_FIRST;pTTY<TTY_END;pTTY++)
InitTTY(pTTY);
CurrentConsole=0;
pTTY=TTY_FIRST;
}
PUBLIC void keyboardHandler(int Irq)
{
TTY *pTTY;
KeyboardHandle() ;
for(pTTY=TTY_FIRST;pTTY<TTY_END;pTTY++)
{
TTYRead(pTTY);
// TTYWrite(pTTY);
}
wakeUpEvent(EV_KEYPRESS);
}
PRIVATE void SetLeds()
{
t_8 leds = (caps_lock << 2) | (num_lock << 1) | scroll_lock;
KbWait()
OutByte(KB_DATA, LED_CODE);
KbAck()
KbWait()
OutByte(KB_DATA, leds);
KbAck()
}
PRIVATE void KbWait() /* 等待 8042 的输入缓冲区空 */
{
t_8 kb_stat;
do {
kb_stat = InByte(KB_CMD);
} while (kb_stat & 0x02);
}
PRIVATE void KbAck()
{
t_8 kb_read;
do {
kb_read = InByte(KB_DATA);
} while (kb_read =! KB_ACK);
}
PRIVATE void PutKey(TTY* pTTY, t_32 Key){ if(pTTY->KeyCount<TTY_IN_BYTES)
{
*(pTTY->KeyHead)=Key;
pTTY->KeyHead++;
if(pTTY->KeyHead==pTTY->KeyBuffer+TTY_IN_BYTES)
pTTY->KeyHead=pTTY->KeyBuffer;
pTTY->KeyCount++;
} }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -