| /** @file | |
| Copyright (c) 2004, 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 "mousehid.h" | |
| // | |
| // Get an item from report descriptor | |
| // | |
| /** | |
| Get Next Item | |
| @param StartPos Start Position | |
| @param EndPos End Position | |
| @param HidItem HidItem to return | |
| @return Position | |
| **/ | |
| STATIC | |
| UINT8 * | |
| GetNextItem ( | |
| IN UINT8 *StartPos, | |
| IN UINT8 *EndPos, | |
| OUT HID_ITEM *HidItem | |
| ) | |
| { | |
| 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; | |
| } | |
| /** | |
| Get Item Data | |
| @param HidItem HID_ITEM | |
| @return HidItem Data | |
| **/ | |
| STATIC | |
| UINT32 | |
| GetItemData ( | |
| IN HID_ITEM *HidItem | |
| ) | |
| { | |
| // | |
| // 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; | |
| } | |
| /** | |
| Parse Local Item | |
| @param UsbMouse USB_MOUSE_DEV | |
| @param LocalItem Local Item | |
| **/ | |
| STATIC | |
| VOID | |
| ParseLocalItem ( | |
| IN USB_MOUSE_DEV *UsbMouse, | |
| IN HID_ITEM *LocalItem | |
| ) | |
| { | |
| 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; | |
| } | |
| } | |
| } | |
| /** | |
| Parse Main Item | |
| @param UsbMouse TODO: add argument description | |
| @param MainItem HID_ITEM to parse | |
| @return VOID | |
| **/ | |
| STATIC | |
| VOID | |
| ParseMainItem ( | |
| IN USB_MOUSE_DEV *UsbMouse, | |
| IN HID_ITEM *MainItem | |
| ) | |
| { | |
| // | |
| // we don't care any main items, just skip | |
| // | |
| return ; | |
| } | |
| /** | |
| Parse Hid Item | |
| @param UsbMouse USB_MOUSE_DEV | |
| @param HidItem HidItem to parse | |
| @return VOID | |
| **/ | |
| STATIC | |
| VOID | |
| ParseHidItem ( | |
| IN USB_MOUSE_DEV *UsbMouse, | |
| IN HID_ITEM *HidItem | |
| ) | |
| { | |
| 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 | |
| // | |
| /** | |
| Parse Mouse Report Descriptor | |
| @param UsbMouse USB_MOUSE_DEV | |
| @param ReportDescriptor Report descriptor to parse | |
| @param ReportSize Report descriptor size | |
| @retval EFI_DEVICE_ERROR Report descriptor error | |
| @retval EFI_SUCCESS Success | |
| **/ | |
| EFI_STATUS | |
| ParseMouseReportDescriptor ( | |
| IN USB_MOUSE_DEV *UsbMouse, | |
| IN UINT8 *ReportDescriptor, | |
| IN UINTN ReportSize | |
| ) | |
| { | |
| 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; | |
| } |