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

📄 keyboard.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
    UsbKeyboardDevice->LastKeyCodeArray[i] = CurKeyCodeBuffer[i];
  }
  
  //
  // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
  // and judge whether it will invoke reset event.
  //
  SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;
  i = UsbKeyboardDevice->KeyboardBuffer.bHead;
  while(i != SavedTail) {
    RemoveKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),&UsbKey);
    
    switch(UsbKey.KeyCode) {
      case 0xe0:
      case 0xe4:
        if(UsbKey.Down) {
          UsbKeyboardDevice->CtrlOn = 1;
        } else {
          UsbKeyboardDevice->CtrlOn = 0;
        }
        break;
      
      case 0xe2:
      case 0xe6:
        if(UsbKey.Down) {
          UsbKeyboardDevice->AltOn = 1;
        } else {
          UsbKeyboardDevice->AltOn = 0;
        }
        break;
      
      case 0x4c:      // Del Key Code
      case 0x63:
        if(UsbKey.Down) {
          if(UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
            gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);         
          } 
        }
        break;
        
      default:
        break;
    }
    
    //
    // insert the key back to the buffer. 
    // so the key sequence will not be destroyed.
    //
    InsertKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),
                  UsbKey.KeyCode,
                  UsbKey.Down
                  );
    i = UsbKeyboardDevice->KeyboardBuffer.bHead;
     
  }
  
  //
  // If have new key pressed, update the RepeatKey value, and set the
  // timer to repeate delay timer
  //
  if(NewRepeatKey != 0) {    
    //
    // sets trigger time to "Repeat Delay Time",
    // to trigger the repeat timer when the key is hold long
    // enough time.
    //
    gBS->SetTimer(UsbKeyboardDevice->RepeatTimer, 
                  TimerRelative, 
                  USBKBD_REPEAT_DELAY
                  );
    UsbKeyboardDevice->RepeatKey = NewRepeatKey;
  } 

  return EFI_SUCCESS;
}   


EFI_STATUS
USBParseKey(
  IN OUT  USB_KB_DEV  *UsbKeyboardDevice,
  OUT     UINT8       *KeyChar
  )
/*++
  
  Routine Description:
    Retrieves a key character after parsing the raw data in keyboard buffer.
    
  Arguments:
    UsbKeyboardDevice:    The USB_KB_DEV instance.
    KeyChar:              Points to the Key character after key parsing.
    
  Returns:
  
--*/  
{
  USB_KEY   UsbKey;
  
  *KeyChar = 0;
  
  while (!IsUSBKeyboardBufferEmpty(UsbKeyboardDevice->KeyboardBuffer)) {
    //
    // pops one raw data off.
    //
    RemoveKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),&UsbKey);
    
    if (!UsbKey.Down) {
      switch(UsbKey.KeyCode) {
        case 0xe0:  // fall through
        case 0xe4:
          UsbKeyboardDevice->CtrlOn = 0;
          break;
      
        case 0xe1:  // fall through
        case 0xe5:
          UsbKeyboardDevice->ShiftOn = 0;
          break;
        
        case 0xe2:  // fall through
        case 0xe6:
          UsbKeyboardDevice->AltOn = 0;
          break;
        
        default:          
          break;
      }
      
      continue;
    }
    
    //
    // Analyzes key pressing situation
    //  
    switch (UsbKey.KeyCode) {
      case 0xe0:  // fall through
      case 0xe4:
        UsbKeyboardDevice->CtrlOn = 1;
        continue;
        break;
      
      case 0xe1:  // fall through
      case 0xe5:
        UsbKeyboardDevice->ShiftOn = 1;
        continue;
        break;
        
      case 0xe2:  // fall through
      case 0xe6:
        UsbKeyboardDevice->AltOn = 1;
        continue;
        break;
        
      case 0xe3:  // fall through
      case 0xe7:
        continue;       
        break;
        
      case 0x53:
        UsbKeyboardDevice->NumLockOn ^= 1;
        SetKeyLED(UsbKeyboardDevice);
        continue;
        break;
        
      case 0x39:
        UsbKeyboardDevice->CapsOn ^= 1;        
        SetKeyLED(UsbKeyboardDevice);
        continue;
        break;
        
      //
      // F11,F12,PrintScreen,ScrollLock,Pause,Application,Power
      // keys are not valid EFI key
      //  
      case 0x44:  // fall through
      case 0x45:  // fall through
      case 0x46:  // fall through
      case 0x47:  // fall through
      case 0x48:  // fall through
      case 0x65:  // fall through
      case 0x66: 
        continue;
        break;
          
      default:
        break;
    }
    
    //
    // When encountered Del Key...
    //
    if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {
      if(UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
        gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); 
      }
    }
    
    *KeyChar = UsbKey.KeyCode;
    return EFI_SUCCESS;   
  }
  
  return EFI_NOT_READY;
    
}


EFI_STATUS
USBKeyCodeToEFIScanCode(
  IN  USB_KB_DEV      *UsbKeyboardDevice, 
  IN  UINT8           KeyChar,
  OUT EFI_INPUT_KEY   *Key
  )
/*++
  
  Routine Description:
    Converts USB Keyboard code to EFI Scan Code.
    
  Arguments:  
    UsbKeyboardDevice:    The USB_KB_DEV instance.
    KeyChar:              Indicates the key code that will be interpreted.    
    Key:                  A pointer to a buffer that is filled in with 
                          the keystroke information for the key that 
                          was pressed.
  Returns:
  
--*/
{
  UINT8     Index;
  
  if (!USBKBD_VALID_KEYCODE(KeyChar)) {
    return EFI_NOT_READY;
  }
  
  //
  // valid USB Key Code starts from 4
  //
  Index = (UINT8)(KeyChar - 4);
  
  if (Index >= USB_KEYCODE_MAX_MAKE){
    return EFI_NOT_READY;
  }    
  
  Key->ScanCode = KeyConvertionTable[Index][0];
  
  if (UsbKeyboardDevice->ShiftOn) {
    
    Key->UnicodeChar = KeyConvertionTable[Index][2];
  
  } else {
    
    Key->UnicodeChar = KeyConvertionTable[Index][1];
  }
  
  if (UsbKeyboardDevice->CapsOn) {
    
    if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
    
      Key->UnicodeChar = KeyConvertionTable[Index][2];
    
    } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
    
      Key->UnicodeChar = KeyConvertionTable[Index][1];
    
    }
  }
  
  if (KeyChar >= 0x59 && KeyChar <=0x63 && Key->ScanCode != SCAN_NULL) {
    
    if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {
    
      Key->ScanCode = SCAN_NULL;
    
    } else {
      
      Key->UnicodeChar = 0x00;
    }
  }
  
  if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
    return EFI_NOT_READY;
  }
  
  return EFI_SUCCESS;    
  
}


EFI_STATUS
InitUSBKeyBuffer(
  IN OUT  USB_KB_BUFFER   *KeyboardBuffer
  )
/*++
  
  Routine Description:
    Resets USB Keyboard Buffer.
    
  Arguments:
    KeyboardBuffer:   Points to the USB Keyboard Buffer.
    
  Returns:
  
--*/  
{
  EfiZeroMem(KeyboardBuffer,sizeof(USB_KB_BUFFER));
  
  KeyboardBuffer->bHead = KeyboardBuffer->bTail;
  
  return EFI_SUCCESS;
}

BOOLEAN
IsUSBKeyboardBufferEmpty(
  IN  USB_KB_BUFFER   KeyboardBuffer
  )
/*++
  
  Routine Description:
    Check whether USB Keyboard buffer is empty.
    
  Arguments:
    KeyboardBuffer:   USB Keyboard Buffer.
    
  Returns:
  
--*/
{
  //
  // meet FIFO empty condition
  //
  return (BOOLEAN)(KeyboardBuffer.bHead == KeyboardBuffer.bTail);
}


BOOLEAN
IsUSBKeyboardBufferFull(
  IN  USB_KB_BUFFER   KeyboardBuffer
  )
/*++
  
  Routine Description:
    Check whether USB Keyboard buffer is full.
    
  Arguments:
    KeyboardBuffer:   USB Keyboard Buffer.
    
  Returns:
  
--*/
{
  return (BOOLEAN)(((KeyboardBuffer.bTail + 1) % (MAX_KEY_ALLOWED + 1)) == 
                                                        KeyboardBuffer.bHead);
}


EFI_STATUS
InsertKeyCode(
  IN OUT  USB_KB_BUFFER *KeyboardBuffer,
  IN      UINT8         Key,
  IN      UINT8         Down
  )
/*++
  
  Routine Description:
    Inserts a key code into keyboard buffer.
    
  Arguments:
    KeyboardBuffer:   Points to the USB Keyboard Buffer.
  
  Returns:
  
--*/
{
  USB_KEY         UsbKey;
  
  //
  // if keyboard buffer is full, throw the 
  // first key out of the keyboard buffer.
  //  
  if (IsUSBKeyboardBufferFull (*KeyboardBuffer)) {
    RemoveKeyCode(KeyboardBuffer,&UsbKey);
  }
    
  KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
  KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
  
  //
  // adjust the tail pointer of the FIFO keyboard buffer.
  //
  KeyboardBuffer->bTail = (UINT8)((KeyboardBuffer->bTail + 1) 
                                          % (MAX_KEY_ALLOWED + 1)) ;
  
  return EFI_SUCCESS;
}

EFI_STATUS
RemoveKeyCode(
  IN OUT  USB_KB_BUFFER *KeyboardBuffer,
  OUT     USB_KEY       *UsbKey
  )
/*++
  
  Routine Description:
    Pops a key code off from keyboard buffer.
    
  Arguments:
    KeyboardBuffer:   Points to the USB Keyboard Buffer.
    UsbKey:           Points to the buffer that contains a usb key code.
  
  Returns:
  
--*/  
{
  if (IsUSBKeyboardBufferEmpty (*KeyboardBuffer)) {
    return EFI_DEVICE_ERROR;
  }
    
  UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
  UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
  
  //
  // adjust the head pointer of the FIFO keyboard buffer.
  //
  KeyboardBuffer->bHead = (UINT8)((KeyboardBuffer->bHead + 1) % 
                                                (MAX_KEY_ALLOWED + 1)) ;
  
  return EFI_SUCCESS;
}   

EFI_STATUS
SetKeyLED(
  IN  USB_KB_DEV    *UsbKeyboardDevice
  )
/*++
  
  Routine Description:
    Sets USB Keyboard LED state.
    
  Arguments:
    UsbKeyboardDevice:    The USB_KB_DEV instance.
  
  Returns:
  
--*/  
{
  LED_MAP     Led;
  UINT8       ReportId;
  
  //
  // Set each field in Led map.
  //  
  Led.NumLock = (UINT8)UsbKeyboardDevice->NumLockOn;
  Led.CapsLock = (UINT8)UsbKeyboardDevice->CapsOn;
  Led.Resrvd = 0;    
  
  ReportId = 0;
  //
  // call Set Report Request to lighten the LED.
  //
  UsbSetReportRequest (
    UsbKeyboardDevice->UsbIo,
    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
    ReportId,
    HID_OUTPUT_REPORT,
    1,
    (CHAR8 *)&Led
    );
    
  return EFI_SUCCESS;
}   

VOID
USBKeyboardRepeatHandler(
  IN    EFI_EVENT    Event,
  IN    VOID         *Context
  )
/*++
  
  Routine Description:
    Timer handler for Repeat Key timer.
    
  Arguments:
    Event:    The Repeat Key event.
    Context:  Points to the USB_KB_DEV instance.
    
  Returns:
  
--*/    
{
  USB_KB_DEV  *UsbKeyboardDevice;
  
  UsbKeyboardDevice = (USB_KB_DEV*)Context;
  
  //
  // Do nothing when there is no repeat key.
  //
  if(UsbKeyboardDevice->RepeatKey != 0) {
    //
    // Inserts one Repeat key into keyboard buffer,
    //
    InsertKeyCode(
            &(UsbKeyboardDevice->KeyboardBuffer),
            UsbKeyboardDevice->RepeatKey,
            1
            );
    
    //
    // set repeate rate for repeat key generation.
    //
   gBS->SetTimer(UsbKeyboardDevice->RepeatTimer, 
                  TimerRelative, 
                  USBKBD_REPEAT_RATE
                  ) ; 
    
  }
}

⌨️ 快捷键说明

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