⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse.c

📁 是经典的UNIX的部分源代码
💻 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 + -