📄 mouse.c
字号:
#include "interrupt.h"
#include "vesa.h"
#include "io.h"
#include "message.h"
#include "kernel.h"
#include "mouse.h"
/*****************************************************
* 下面是声明 *
*****************************************************/
void mouse_asm_handle_for_mouse_interrupt() ;
void mouse_handle_for_mouse_interrupt() ;
void mouse_enable_mouse() ;
static void *mouse_get_mouse_picture_addr( enum mouse_type_enum mouse_type ) ;
/*****************************************************
* 下面是定义 *
*****************************************************/
static const int MOUSE_MOUSE_INTERRUPT_NUMBER = 0x2c ;
static const int MOUSE_MOUSE_INTERRUPT_IRQ_NUMBER = 12 ;
static const unsigned short mouse_old_picture[ 32 * 32 ] ;
int ttmp = 0 ;
/*****************************************************
* 下面是函数的实现 *
*****************************************************/
void *mouse_get_mouse_picture_addr( enum mouse_type_enum mouse_type )
{
switch( mouse_type ){
case MOUSE_NORMAL_MOUSE :
return ( void * )0x40000 ;
case MOUSE_OVER_MOUSE :
return ( void * )0x41000 ;
case MOUSE_DOWN_MOUSE :
return ( void * )0x42000 ;
}
}
// mouse 初始化函数
void mouse_init()
{
// 许可 mouse
mouse_enable_mouse() ;
// 安装中断处理函数
interrupt_install_handle_for_interrupt( MOUSE_MOUSE_INTERRUPT_NUMBER , mouse_asm_handle_for_mouse_interrupt ) ;
// 设置中断屏幕字
interrupt_set_interrupt_mask_word( MOUSE_MOUSE_INTERRUPT_IRQ_NUMBER , 1 ) ;
}
// mouse 中断处理函数
void mouse_handle_for_mouse_interrupt()
{
static int x_position = 444 ;
static int y_position = 300 ;
static int count = 0 ;
static int x_sign = 0 ;
static int y_sign = 0 ;
static struct message_message_struct message ;
char ch = io_read_from_io_port( 0x60 ) ;
switch( ++count ){
case 1 :
// 收到的是第一字节
// 检测按键信息
message.dose_left_button_down = ch & 0x1 ;
message.dose_right_button_down = ch & 0x2 ;
x_sign = ch & 0x10 ? 0xffffff00 : 0 ;
y_sign = ch & 0x20 ? 0xffffff00 : 0 ;
break ;
case 2 :
// 收到的是第二字节,即 x 的位移量
x_position += ( x_sign | ch ) ;
break ;
case 3 :
// 收到的是第三字节,即 y 的位移量
y_position += -( y_sign | ch ) ;
// 把消息发送给内核
message.message_type = MESSAGE_MOUSE_MESSAGE ;
message.x_position = x_position ;
message.y_position = y_position ;
message_put_message( &kernel_message_queue , message ) ;
count = 0 ;
break ;
}
}
// 许可 mouse
void mouse_enable_mouse()
{
// 对 8042 键盘控制芯片进行编程
// 允许 mouse 接口
io_write_to_io_port( 0x64 , 0xa8 ) ;
// 通知 8042 下个字节的发向 0x60 的数据将发给 mouse
io_write_to_io_port( 0x64 , 0xd4 ) ;
// 允许 mouse 发数据
io_write_to_io_port( 0x60 , 0xf4 ) ;
// 通知 8042,下个字节的发向 0x60 的数据应放向 8042 的命令寄存器
io_write_to_io_port( 0x64 , 0x60 ) ;
// 许可键盘及 mouse 接口及中断
io_write_to_io_port( 0x60 , 0x47 ) ;
}
/* 显示 mouse */
void mouse_show_mouse( int x , int y , enum mouse_type_enum mouse_type )
{
// 先保存 mouse 显示区的那副图
mouse_save_picture( x , y ) ;
// 再画出 mouse
void *mouse_picture_addr = mouse_get_mouse_picture_addr( mouse_type ) ;
vesa_show_bmp_picture( x , y , mouse_picture_addr , ( unsigned short )0xffffffff , 1 ) ;
}
/* 移动 mouse 函数 */
void mouse_move_mouse( int x1 , int y1 , int x2 , int y2 , enum mouse_type_enum mouse_type )
{
// 先恢复以前 mouse 所在的显示区的那副图
mouse_restore_picture( x1 , y1 ) ;
// 再显示 mouse
mouse_show_mouse( x2 , y2 , mouse_type ) ;
}
/* 保存指定位置的图片 */
void mouse_save_picture( int x , int y )
{
// mouse 的大小固定为 32 * 32
vesa_copy_picture_from_screen( x , y , ( unsigned short * )mouse_old_picture , 32 , 32 ) ;
}
/* 恢复指定位置的图片 */
void mouse_restore_picture( int x , int y )
{
vesa_copy_picture_to_screen( x , y , ( unsigned short * )mouse_old_picture , 32 , 32 ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -