keyboard.cpp

来自「Jazmyn is a 32-bit, protected mode, mult」· C++ 代码 · 共 319 行

CPP
319
字号
/*
 * Copyright (C) 2004, Thejesh AP. All rights reserved.
 */

#include <sys\types.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <mm\new.h>
#include <mm\heap.h>
#include <jazmyn\desc.h>
#include <mm\memory.h>
#include <fs\file_sys.h>
#include <jazmyn\process.h>
#include <jazmyn\handlers.h>
#include <fs\devmgr.h>
#include <drivers\keyboard.h>
#include <drivers\console.h>

extern void (*handlers[16])();
extern  device_manager  _dev_mgr;
extern process *fg_proc;
extern process *curr_proc;

#define NIL     -1
#define ESC     27
#define CTRL    29
#define SHFT    42
#define ALT     56
#define CAPS    58
#define F1      59
#define F2      60
#define F3      61
#define F4      62
#define F5      63
#define F6      64
#define F7      65
#define F8      66
#define F9      67
#define F10     68
#define NUM     69
#define SCRL    70
#define HOME    71
#define UP      72
#define PGUP    73
#define LEFT    75
#define FIVE    76
#define RGHT    77
#define END     79
#define DOWN    80
#define PGDN    81
#define INS     82
#define DEL     83
#define F11     87
#define F12     88
#define WIN     91
#define RTCK    93
#define POWR    94
#define SLEP    95      
#define WAKE    99  


#define REVERT_NUM _keyboard_obj.num_lock = _keyboard_obj.num_lock?OFF:ON
#define REVERT_CAPS _keyboard_obj.caps_lock = _keyboard_obj.caps_lock?OFF:ON
#define REVERT_SCRL _keyboard_obj.num_lock = _keyboard_obj.scroll_lock?OFF:ON


char ascii[]=  {/* 0      1     2     3     4     5     6     7     8     9*/

		   NIL,  ESC,  '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',
		  '9',   '0',  '-',  '=', '\b', '\t',  'q',  'w',  'e',  'r',
		  't',   'y',  'u',  'i',  'o',  'p',  '[',  ']', '\n',  CTRL,
                  'a',   's',  'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
                  '\'',   '`', SHFT, '\\', 'z',  'x',  'c',  'v',  'b',  'n',
		  'm',   ',',  '.',  '/',  SHFT, '*',  ALT,  ' ', CAPS,   F1,
		   F2,    F3,   F4,   F5,   F6,   F7,   F8,   F9,  F10,  NUM,
		   SCRL,HOME,   UP,  PGUP, '-', LEFT, FIVE, RGHT,  '+',  END,
		   DOWN, PGDN,  INS,   DEL,  NIL,  NIL,  NIL,  F11,  F12,  NIL,
		   NIL,   WIN,  WIN, RTCK, POWR, SLEP,  NIL,  NIL,  NIL, WAKE
	       };

char shifted[]= {/*0      1     2     3     4     5     6     7     8     9*/

                  NIL,   ESC,  '!',  '@',   '#',  '$',  '%',  '^',  '&',  '*',
		  '(',   ')',  '_',  '+', '\b', '\t',  'Q',  'W',  'E',  'R',
		  'T',   'Y',  'U',  'I',  'O',  'P',  '{',  '}', '\n',  CTRL,
		  'A',   'S',  'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
		  '"',   '~',  SHFT, '|',  'Z',  'X',  'C',  'V',  'B',  'N',
		  'M',   '<',  '>',  '?', SHFT,  NIL,  ALT,  ' ', CAPS,  F1 ,
		   F2,    F3,   F4,   F5,   F6,   F7,   F8,   F9,  F10,  NUM,
		  SCRL, HOME,   UP,  PGUP, '-', LEFT, FIVE, RGHT,  '+',  END,
		  DOWN, PGDN,  INS,   DEL, NIL,  NIL,  NIL,  F11,  F12,  NIL,
		  NIL,   WIN,  WIN,  RTCK, POWR,SLEP,  NIL,  NIL,  NIL,  WAKE
	 };
    
keyboard::keyboard(char* name): driver(name)
{
	shift = alt = ctrl = RELEASED;
	caps_lock = num_lock = scroll_lock = OFF;
	int err;
        if((err = _dev_mgr.register_driver(1,this->name,0,keyboard_main))<0)
	{
		cout<<"register_driver ERROR : "<<this->name<<" "<<err<<endl;
		return;
	}
        if((err = set_handler(IRQ1,keyboard_handler))<0)
	{
		cout<<"set_handler ERROR : "<<this->name<<" "<<err<<endl;
		return;
	}
        enable_irq(IRQ1);
        cout<<"Keyboard driver succesfully registered          [name] = "<<this->name<<endl;
        keyhit = 0;
        for(int i=0;i<MAX_KB_REQ;i++)
        {
                kbr_arr[i].proc = NULL;
        }
}

keyboard::~keyboard()
{
	int err;
        if((err = _dev_mgr.deregister_driver(this->name))<0)
	{
		cout<<"deregister driver ERROR : "<<this->name<<" "<<err<<endl;
		return;
	}
}

char keyboard::get_num_lock_keys(int scan)
{
	if(shift)
	return shifted[scan];
	switch(scan)
	{
		case 71:return '7';
		case 72:return '8';
		case 73:return '9';
		case 74:return '-';
		case 75:return '4';
		case 76:return '5';
		case 77:return '6';
		case 78:return '+';
		case 79:return '1';
		case 80:return '2';
		case 81:return '3';
		case 82:return '0';
		case 83:return '.';
                default:return ascii[scan];
	}
}

#define NUM_LOCK(s)     get_num_lock_keys(s)

char keyboard::get_ascii(int scan)
{
	char ch;
	char ret;

        if (!shift)
	{
		if(!caps_lock && !num_lock)
		{
                        ch = ascii[scan];
			ret = CTRL_ALT(ch);
                }
		else if(!caps_lock && num_lock)
		{
			ret = CTRL_ALT(NUM_LOCK(scan));
		}
                else if(caps_lock && !num_lock)
		{
                        ch = ascii[scan];
			if(ch>='a' && ch<='z') ret = CTRL_ALT(shifted[scan]);
			else ret = CTRL_ALT(ch);   
		}  
		else if(caps_lock && num_lock)
		{
			ch = NUM_LOCK(scan);
			if(ch>='a' && ch<='z') ret = CTRL_ALT(shifted[scan]);
			else ret = CTRL_ALT(ch);
		}       
	}   
	else       
	{
		if(!caps_lock && !num_lock)     
		{
			ch = shifted[scan];
			ret = CTRL_ALT(ch);
		}
		else if(!caps_lock && num_lock) 
		{
                        ch = shifted[scan];
                        ret = CTRL_ALT(ch);
		}
                else if(caps_lock && !num_lock)
		{       
			ch = shifted[scan];
                        if(ch>='A' && ch<='Z') ret = CTRL_ALT(ascii[scan]);
                        else ret = CTRL_ALT(ch);
		}
		else if(caps_lock && num_lock)
		{
                        ch = shifted[scan];
                        if(ch>='A' && ch<='Z') ret = CTRL_ALT(ascii[scan]);
			else ret = CTRL_ALT(ch);
		}
	}
        return ret;
}
                                           
inline int keyboard::insert(char term,char *buf,int *fin)
{
	for(int i=0;i<MAX_KB_REQ;i++)
	if(kbr_arr[i].proc == NULL)
	{
		cli();
		kbr_arr[i].term = term;
		kbr_arr[i].buf = buf;
		kbr_arr[i].ind = 0;
		kbr_arr[i].proc = curr_proc;
                kbr_arr[i].finished = fin;
                *fin = 0;
		curr_proc->block();
		sti();
		return 0;
	}
	return -1;
}
         
int keyboard::service(char term,void *buf,int *fin)
{
        if(insert(term,(char*)buf,fin) < 0) return -1;
}

int ser=0;

void getch()
{
        while(!ser);
        ser = 0;
}
  
keyboard        _keyboard_obj("keyboard");

void keyboard_handler()
{
        int scan = inportb(0x60);
        char ch;
	if(scan == 0xe0 || scan == 0xe1) return;
	if(scan & 0x80)
	{
                ch = ascii[scan & 0x7f];
		switch(ch)
		{
                        case SHFT:_keyboard_obj.shift = RELEASED;break;
                        case CTRL:_keyboard_obj.ctrl  = RELEASED;break;
                        case ALT :_keyboard_obj.alt   = RELEASED;break;
		}
	}
	else
	{
                ch = ascii[scan];
                if(scan == SHFT) _keyboard_obj.shift = PRESSED;
                else if(scan == CTRL) _keyboard_obj.ctrl = PRESSED;
                else if(scan == ALT ) _keyboard_obj.alt = PRESSED;
                else if(scan == NUM ) REVERT_NUM;
                else if(scan == CAPS) REVERT_CAPS;
                else if(scan == SCRL) REVERT_SCRL;
                else
                {
                        ser = 1;

                        for(int i=0;i<MAX_KB_REQ;i++)
                        {
                                if(_keyboard_obj.kbr_arr[i].proc == fg_proc)
                                {
                                        char ch = _keyboard_obj.get_ascii(scan);
                                        if(ch == '\b')
                                        {
                                                if(_keyboard_obj.kbr_arr[i].ind)
                                                {
                                                        cout<<ch;
                                                        _keyboard_obj.kbr_arr[i].ind--;
                                                }
                                                return;
                                        }
                                        _keyboard_obj.kbr_arr[i].buf[_keyboard_obj.kbr_arr[i].ind] = ch;
                                        cout<<_keyboard_obj.kbr_arr[i].buf[_keyboard_obj.kbr_arr[i].ind];
                                        if(_keyboard_obj.kbr_arr[i].buf[_keyboard_obj.kbr_arr[i].ind] == _keyboard_obj.kbr_arr[i].term)
                                        {
                                                _keyboard_obj.kbr_arr[i].buf[_keyboard_obj.kbr_arr[i].ind] = '\0';
                                                *_keyboard_obj.kbr_arr[i].finished = _keyboard_obj.kbr_arr[i].ind+1;
                                                cli();
                                                _keyboard_obj.kbr_arr[i].proc->unblock();
                                                _keyboard_obj.kbr_arr[i].proc = NULL;
                                                sti();
                                                return;
                                        }
                                        _keyboard_obj.kbr_arr[i].ind++;
                                }
                        }
                }
        }
}

int keyboard_main(void* req)
{
        keyboard_req *k_req = (keyboard_req*)req;
        int *fin = new int;
        if(_keyboard_obj.service(k_req->term,k_req->buf,fin) < 0) return -1;
        while(!*fin);
	int ret = *fin;
	delete fin;
        return ret;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?