/*++ | |
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; | |
} |