git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			396 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			396 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| Copyright (c) 2006, Intel Corporation                                                         
 | |
| All rights reserved. This program and the accompanying materials                          
 | |
| are licensed and made available under the terms and conditions of the BSD License         
 | |
| which accompanies this distribution.  The full text of the license may be found at        
 | |
| http://opensource.org/licenses/bsd-license.php                                            
 | |
|                                                                                           
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | |
| 
 | |
| Module Name:
 | |
| 
 | |
|   Mousehid.c
 | |
| 
 | |
| Abstract:
 | |
|   Parse mouse hid descriptor
 | |
| 
 | |
| --*/
 | |
| 
 | |
| #include "usbmouse.h"
 | |
| #include "mousehid.h"
 | |
| 
 | |
| //
 | |
| // Get an item from report descriptor
 | |
| //
 | |
| STATIC
 | |
| UINT8 *
 | |
| GetNextItem (
 | |
|   IN  UINT8    *StartPos,
 | |
|   IN  UINT8    *EndPos,
 | |
|   OUT HID_ITEM *HidItem
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Get Next Item
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   StartPos  - Start Position
 | |
|   EndPos    - End Position
 | |
|   HidItem   - HidItem to return
 | |
| 
 | |
| Returns:
 | |
|   Position
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   UINT8 Temp;
 | |
| 
 | |
|   if ((EndPos - StartPos) <= 0) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Temp = *StartPos;
 | |
|   StartPos++;
 | |
|   //
 | |
|   // bit 2,3
 | |
|   //
 | |
|   HidItem->Type = (UINT8) ((Temp >> 2) & 0x03);
 | |
|   //
 | |
|   // bit 4-7
 | |
|   //
 | |
|   HidItem->Tag = (UINT8) ((Temp >> 4) & 0x0F);
 | |
| 
 | |
|   if (HidItem->Tag == HID_ITEM_TAG_LONG) {
 | |
|     //
 | |
|     // Long Items are not supported by HID rev1.0,
 | |
|     // although we try to parse it.
 | |
|     //
 | |
|     HidItem->Format = HID_ITEM_FORMAT_LONG;
 | |
| 
 | |
|     if ((EndPos - StartPos) >= 2) {
 | |
|       HidItem->Size = *StartPos++;
 | |
|       HidItem->Tag  = *StartPos++;
 | |
| 
 | |
|       if ((EndPos - StartPos) >= HidItem->Size) {
 | |
|         HidItem->Data.LongData = StartPos;
 | |
|         StartPos += HidItem->Size;
 | |
|         return StartPos;
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     HidItem->Format = HID_ITEM_FORMAT_SHORT;
 | |
|     //
 | |
|     // bit 0, 1
 | |
|     //
 | |
|     HidItem->Size   = (UINT8) (Temp & 0x03);
 | |
|     switch (HidItem->Size) {
 | |
| 
 | |
|     case 0:
 | |
|       //
 | |
|       // No data
 | |
|       //
 | |
|       return StartPos;
 | |
| 
 | |
|     case 1:
 | |
|       //
 | |
|       // One byte data
 | |
|       //
 | |
|       if ((EndPos - StartPos) >= 1) {
 | |
|         HidItem->Data.U8 = *StartPos++;
 | |
|         return StartPos;
 | |
|       }
 | |
| 
 | |
|     case 2:
 | |
|       //
 | |
|       // Two byte data
 | |
|       //
 | |
|       if ((EndPos - StartPos) >= 2) {
 | |
|         CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16));
 | |
|         StartPos += 2;
 | |
|         return StartPos;
 | |
|       }
 | |
| 
 | |
|     case 3:
 | |
|       //
 | |
|       // 4 byte data, adjust size
 | |
|       //
 | |
|       HidItem->Size++;
 | |
|       if ((EndPos - StartPos) >= 4) {
 | |
|         CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32));
 | |
|         StartPos += 4;
 | |
|         return StartPos;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| UINT32
 | |
| GetItemData (
 | |
|   IN  HID_ITEM *HidItem
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Get Item Data
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   HidItem - HID_ITEM
 | |
| 
 | |
| Returns:
 | |
|   HidItem Data
 | |
|   
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   //
 | |
|   // Get Data from HID_ITEM structure
 | |
|   //
 | |
|   switch (HidItem->Size) {
 | |
| 
 | |
|   case 1:
 | |
|     return HidItem->Data.U8;
 | |
| 
 | |
|   case 2:
 | |
|     return HidItem->Data.U16;
 | |
| 
 | |
|   case 4:
 | |
|     return HidItem->Data.U32;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| ParseLocalItem (
 | |
|   IN  USB_MOUSE_DEV   *UsbMouse,
 | |
|   IN  HID_ITEM        *LocalItem
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Parse Local Item
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   UsbMouse  - USB_MOUSE_DEV
 | |
|   LocalItem - Local Item
 | |
| 
 | |
| Returns:
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   UINT32  Data;
 | |
| 
 | |
|   if (LocalItem->Size == 0) {
 | |
|     //
 | |
|     // No expected data for local item
 | |
|     //
 | |
|     return ;
 | |
|   }
 | |
| 
 | |
|   Data = GetItemData (LocalItem);
 | |
| 
 | |
|   switch (LocalItem->Tag) {
 | |
| 
 | |
|   case HID_LOCAL_ITEM_TAG_DELIMITER:
 | |
|     //
 | |
|     // we don't support delimiter here
 | |
|     //
 | |
|     return ;
 | |
| 
 | |
|   case HID_LOCAL_ITEM_TAG_USAGE:
 | |
|     return ;
 | |
| 
 | |
|   case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
 | |
|     if (UsbMouse->PrivateData.ButtonDetected) {
 | |
|       UsbMouse->PrivateData.ButtonMinIndex = (UINT8) Data;
 | |
|     }
 | |
| 
 | |
|     return ;
 | |
| 
 | |
|   case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
 | |
|     {
 | |
|       if (UsbMouse->PrivateData.ButtonDetected) {
 | |
|         UsbMouse->PrivateData.ButtonMaxIndex = (UINT8) Data;
 | |
|       }
 | |
| 
 | |
|       return ;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| ParseGlobalItem (
 | |
|   IN  USB_MOUSE_DEV   *UsbMouse,
 | |
|   IN  HID_ITEM        *GlobalItem
 | |
|   )
 | |
| {
 | |
|   UINT8 UsagePage;
 | |
| 
 | |
|   switch (GlobalItem->Tag) {
 | |
|   case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
 | |
|     {
 | |
|       UsagePage = (UINT8) GetItemData (GlobalItem);
 | |
| 
 | |
|       //
 | |
|       // We only care Button Page here
 | |
|       //
 | |
|       if (UsagePage == 0x09) {
 | |
|         //
 | |
|         // Button Page
 | |
|         //
 | |
|         UsbMouse->PrivateData.ButtonDetected = TRUE;
 | |
|         return ;
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| ParseMainItem (
 | |
|   IN  USB_MOUSE_DEV   *UsbMouse,
 | |
|   IN  HID_ITEM        *MainItem
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Parse Main Item
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   UsbMouse  - TODO: add argument description
 | |
|   MainItem  - HID_ITEM to parse
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   VOID
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   //
 | |
|   // we don't care any main items, just skip
 | |
|   //
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| ParseHidItem (
 | |
|   IN  USB_MOUSE_DEV   *UsbMouse,
 | |
|   IN  HID_ITEM        *HidItem
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Parse Hid Item
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   UsbMouse  - USB_MOUSE_DEV
 | |
|   HidItem   - HidItem to parse
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   VOID
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   switch (HidItem->Type) {
 | |
| 
 | |
|   case HID_ITEM_TYPE_MAIN:
 | |
|     //
 | |
|     // For Main Item, parse main item
 | |
|     //
 | |
|     ParseMainItem (UsbMouse, HidItem);
 | |
|     break;
 | |
| 
 | |
|   case HID_ITEM_TYPE_GLOBAL:
 | |
|     //
 | |
|     // For global Item, parse global item
 | |
|     //
 | |
|     ParseGlobalItem (UsbMouse, HidItem);
 | |
|     break;
 | |
| 
 | |
|   case HID_ITEM_TYPE_LOCAL:
 | |
|     //
 | |
|     // For Local Item, parse local item
 | |
|     //
 | |
|     ParseLocalItem (UsbMouse, HidItem);
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| //
 | |
| // A simple parse just read some field we are interested in
 | |
| //
 | |
| EFI_STATUS
 | |
| ParseMouseReportDescriptor (
 | |
|   IN  USB_MOUSE_DEV   *UsbMouse,
 | |
|   IN  UINT8           *ReportDescriptor,
 | |
|   IN  UINTN           ReportSize
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Parse Mouse Report Descriptor
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   UsbMouse          - USB_MOUSE_DEV
 | |
|   ReportDescriptor  - Report descriptor to parse
 | |
|   ReportSize        - Report descriptor size
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   EFI_DEVICE_ERROR - Report descriptor error
 | |
|   EFI_SUCCESS      - Success
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   UINT8     *DescriptorEnd;
 | |
|   UINT8     *ptr;
 | |
|   HID_ITEM  HidItem;
 | |
| 
 | |
|   DescriptorEnd = ReportDescriptor + ReportSize;
 | |
| 
 | |
|   ptr           = GetNextItem (ReportDescriptor, DescriptorEnd, &HidItem);
 | |
| 
 | |
|   while (ptr != NULL) {
 | |
|     if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {
 | |
|       //
 | |
|       // Long Format Item is not supported at current HID revision
 | |
|       //
 | |
|       return EFI_DEVICE_ERROR;
 | |
|     }
 | |
| 
 | |
|     ParseHidItem (UsbMouse, &HidItem);
 | |
| 
 | |
|     ptr = GetNextItem (ptr, DescriptorEnd, &HidItem);
 | |
|   }
 | |
| 
 | |
|   UsbMouse->NumberOfButtons                 = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);
 | |
|   UsbMouse->XLogicMax                       = UsbMouse->YLogicMax = 127;
 | |
|   UsbMouse->XLogicMin                       = UsbMouse->YLogicMin = -127;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |