From: eric_tian Date: Wed, 14 Nov 2007 07:08:55 +0000 (+0000) Subject: add UsbMouseSimulateTouchPad driver to verify the correction of dispatching AbsoluteP... X-Git-Tag: edk2-stable201903~21765 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=8ae0b360f5463e666cf5b1c93b7693ac7ad9a312;p=mirror_edk2.git add UsbMouseSimulateTouchPad driver to verify the correction of dispatching AbsolutePointer event of consplitter git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4297 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/ComponentName.c b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/ComponentName.c new file mode 100644 index 0000000000..0c5f88d43b --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/ComponentName.c @@ -0,0 +1,377 @@ +/** @file + +Copyright (c) 2004 - 2007, 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: + + UsbMouseSimulateTouchPadComponentName.c + +Abstract: + + +**/ + +#include "UsbMouseSimulateTouchPad.h" +#include + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbMouseSimulateTouchPadComponentName = { + UsbMouseSimulateTouchPadComponentNameGetDriverName, + UsbMouseSimulateTouchPadComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseSimulateTouchPadComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbMouseSimulateTouchPadComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbMouseSimulateTouchPadComponentNameGetControllerName, + "en" +}; + + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbMouseSimulateTouchPadDriverNameTable[] = { + { "eng;en", L"Usb Mouse Simulate TouchPad Driver" }, + { NULL , NULL } +}; + + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mUsbMouseSimulateTouchPadDriverNameTable, + DriverName, + (BOOLEAN)(This == &gUsbMouseSimulateTouchPadComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol; + EFI_USB_IO_PROTOCOL *UsbIoProtocol; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIoProtocol, + gUsbMouseSimulateTouchPadDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + gUsbMouseSimulateTouchPadDriverBinding.DriverBindingHandle, + ControllerHandle + ); + + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + // + // Get the device context + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointerProtocol, + gUsbMouseSimulateTouchPadDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + UsbMouseSimulateTouchPadDev = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + UsbMouseSimulateTouchPadDev->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gUsbMouseSimulateTouchPadComponentName) + ); + +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseAbsolutePointerDxe.msa b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseAbsolutePointerDxe.msa new file mode 100644 index 0000000000..fad0d09787 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseAbsolutePointerDxe.msa @@ -0,0 +1,73 @@ + + + UsbMouseSimulateTouchPadDxe + DXE_DRIVER + 4EA43463-747C-46eb-97FB-B0E5C5F05306 + 1.0 + Component name for module UsbMouseSimulateTouchPad + FIX ME! + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + UsbMouseSimulateTouchPadDxe + + + + ReportStatusCodeLib + + + BaseMemoryLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + MemoryAllocationLib + + + + UsbMouseSimulateTouchPad.h + mousehid.c + UsbMouseSimulateTouchPad.c + ComponentName.c + mousehid.h + + + + + + + + gEfiAbsolutePointerProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiUsbIoProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + USBMouseSimulateTouchPadDriverBindingEntryPoint + + + \ No newline at end of file diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.c b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.c new file mode 100644 index 0000000000..4412881d5c --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.c @@ -0,0 +1,1025 @@ +/** @file + +Copyright (c) 2004 - 2007, 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: + + UsbMouseSimulateTouchPad.c + + Abstract: + + +**/ + +#include "UsbMouseSimulateTouchPad.h" + +#include +#include + +#include "mousehid.h" + +// +// Prototypes +// Driver model protocol interface +// +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +EFI_GUID gEfiUsbMouseSimulateTouchPadDriverGuid = { + 0xa579f729, 0xa71d, 0x4b45, { 0xbe, 0xd7, 0xd, 0xb0, 0xa8, 0x7c, 0x3e, 0x8d } +}; + +EFI_DRIVER_BINDING_PROTOCOL gUsbMouseSimulateTouchPadDriverBinding = { + USBMouseSimulateTouchPadDriverBindingSupported, + USBMouseSimulateTouchPadDriverBindingStart, + USBMouseSimulateTouchPadDriverBindingStop, + 0x1, + NULL, + NULL +}; + +// +// helper functions +// +STATIC +BOOLEAN +IsUsbMouseSimulateTouchPad ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ); + +STATIC +EFI_STATUS +InitializeUsbMouseSimulateTouchPadDevice ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev + ); + +STATIC +VOID +EFIAPI +UsbMouseSimulateTouchPadWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Mouse interrupt handler +// +STATIC +EFI_STATUS +EFIAPI +OnMouseSimulateTouchPadInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ); + +// +// Mouse simulate TouchPad, Using AbsolutePointer Protocol +// +STATIC +EFI_STATUS +EFIAPI +GetMouseSimulateTouchPadState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + OUT EFI_ABSOLUTE_POINTER_STATE *MouseSimulateTouchPadState + ); + +STATIC +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +// +// Driver start here +// +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + Entry point for EFI drivers. + + Arguments: + ImageHandle - EFI_HANDLE + SystemTable - EFI_SYSTEM_TABLE + Returns: + EFI_SUCCESS + others + +--*/ +{ + return EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gUsbMouseSimulateTouchPadDriverBinding, + ImageHandle, + &gUsbMouseSimulateTouchPadComponentName, + &gUsbMouseSimulateTouchPadComponentName2 + ); +} + + +/** + Test to see if this driver supports ControllerHandle. Any ControllerHandle + that has UsbHcProtocol installed will be supported. + + @param This Protocol instance pointer. + @param Controller Handle of device to test + @param RemainingDevicePath Not used + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_UNSUPPORTED This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS OpenStatus; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_STATUS Status; + + OpenStatus = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) { + return EFI_UNSUPPORTED; + } + + if (OpenStatus == EFI_ALREADY_STARTED) { + return EFI_ALREADY_STARTED; + } + + // + // Use the USB I/O protocol interface to see the Controller is + // the Mouse controller that can be managed by this driver. + // + Status = EFI_SUCCESS; + if (!IsUsbMouseSimulateTouchPad (UsbIo)) { + Status = EFI_UNSUPPORTED; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + + +/** + Starting the Usb Bus Driver + + @param This Protocol instance pointer. + @param Controller Handle of device to test + @param RemainingDevicePath Not used + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_UNSUPPORTED This driver does not support this device. + @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error + EFI_OUT_OF_RESOURCES- Can't allocate memory + resources + @retval EFI_ALREADY_STARTED Thios driver has been started + +**/ +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc; + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice; + UINT8 EndpointNumber; + UINT8 Index; + UINT8 EndpointAddr; + UINT8 PollingInterval; + UINT8 PacketSize; + + UsbMouseSimulateTouchPadDevice = NULL; + Status = EFI_SUCCESS; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + UsbMouseSimulateTouchPadDevice = AllocateZeroPool (sizeof (USB_MOUSE_SIMULATE_TOUCHPAD_DEV)); + if (UsbMouseSimulateTouchPadDevice == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + UsbMouseSimulateTouchPadDevice->UsbIo = UsbIo; + + UsbMouseSimulateTouchPadDevice->Signature = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_SIGNATURE; + + UsbMouseSimulateTouchPadDevice->InterfaceDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR)); + if (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + EndpointDesc = AllocatePool (sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)); + if (EndpointDesc == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Get the Device Path Protocol on Controller's handle + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &UsbMouseSimulateTouchPadDevice->DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + // + // Get interface & endpoint descriptor + // + UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + UsbMouseSimulateTouchPadDevice->InterfaceDescriptor + ); + + EndpointNumber = UsbMouseSimulateTouchPadDevice->InterfaceDescriptor->NumEndpoints; + + for (Index = 0; Index < EndpointNumber; Index++) { + UsbIo->UsbGetEndpointDescriptor ( + UsbIo, + Index, + EndpointDesc + ); + + if ((EndpointDesc->Attributes & 0x03) == 0x03) { + + // + // We only care interrupt endpoint here + // + UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor = EndpointDesc; + } + } + + if (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor == NULL) { + // + // No interrupt endpoint, then error + // + Status = EFI_UNSUPPORTED; + goto ErrorExit; + } + + Status = InitializeUsbMouseSimulateTouchPadDevice (UsbMouseSimulateTouchPadDevice); + if (EFI_ERROR (Status)) { + MouseSimulateTouchPadReportStatusCode ( + UsbMouseSimulateTouchPadDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInterfaceError) + ); + + goto ErrorExit; + } + + UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.GetState = GetMouseSimulateTouchPadState; + UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.Reset = UsbMouseSimulateTouchPadReset; + UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.Mode = &UsbMouseSimulateTouchPadDevice->AbsolutePointerMode; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + UsbMouseSimulateTouchPadWaitForInput, + UsbMouseSimulateTouchPadDevice, + &((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput) + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = gBS->InstallProtocolInterface ( + &Controller, + &gEfiAbsolutePointerProtocolGuid, + EFI_NATIVE_INTERFACE, + &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto ErrorExit; + } + + // + // After Enabling Async Interrupt Transfer on this mouse Device + // we will be able to get key data from it. Thus this is deemed as + // the enable action of the mouse + // + + MouseSimulateTouchPadReportStatusCode ( + UsbMouseSimulateTouchPadDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseEnable) + ); + + // + // submit async interrupt transfer + // + EndpointAddr = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress; + PollingInterval = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->Interval; + PacketSize = (UINT8) (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->MaxPacketSize); + + Status = UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + EndpointAddr, + TRUE, + PollingInterval, + PacketSize, + OnMouseSimulateTouchPadInterruptComplete, + UsbMouseSimulateTouchPadDevice + ); + + if (!EFI_ERROR (Status)) { + + UsbMouseSimulateTouchPadDevice->ControllerNameTable = NULL; + AddUnicodeString2 ( + "eng", + gUsbMouseSimulateTouchPadComponentName.SupportedLanguages, + &UsbMouseSimulateTouchPadDevice->ControllerNameTable, + L"Generic Usb Mouse Simulate TouchPad", + TRUE + ); + AddUnicodeString2 ( + "en", + gUsbMouseSimulateTouchPadComponentName2.SupportedLanguages, + &UsbMouseSimulateTouchPadDevice->ControllerNameTable, + L"Generic Usb Mouse Simulate TouchPad2", + FALSE + ); + + return EFI_SUCCESS; + } + + // + // If submit error, uninstall that interface + // + Status = EFI_DEVICE_ERROR; + + gBS->UninstallProtocolInterface ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol + ); + +ErrorExit: + DEBUG ((EFI_D_ERROR, __FUNCTION__ " driver start fail\n")); + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + if (UsbMouseSimulateTouchPadDevice != NULL) { + if (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor != NULL) { + gBS->FreePool (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor); + } + + if (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor != NULL) { + gBS->FreePool (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor); + } + + if ((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput != NULL) { + gBS->CloseEvent ((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput); + } + + gBS->FreePool (UsbMouseSimulateTouchPadDevice); + UsbMouseSimulateTouchPadDevice = NULL; + } + } + + return Status; +} + + +/** + Stop this driver on ControllerHandle. Support stoping any child handles + created by this driver. + + @param This Protocol instance pointer. + @param Controller Handle of device to stop driver on + @param NumberOfChildren Number of Children in the ChildHandleBuffer + @param ChildHandleBuffer List of handles for the children we need to stop. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return others + +**/ +EFI_STATUS +EFIAPI +USBMouseSimulateTouchPadDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol; + EFI_USB_IO_PROTOCOL *UsbIo; + + // + // Get our context back. + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointerProtocol, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + UsbMouseSimulateTouchPadDevice = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol); + + gBS->CloseProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + UsbIo = UsbMouseSimulateTouchPadDevice->UsbIo; + + // + // Uninstall the Asyn Interrupt Transfer from this device + // will disable the mouse data input from this device + // + MouseSimulateTouchPadReportStatusCode ( + UsbMouseSimulateTouchPadDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseDisable) + ); + + // + // Delete Mouse Async Interrupt Transfer + // + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->Interval, + 0, + NULL, + NULL + ); + + gBS->CloseEvent (UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.WaitForInput); + + if (UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent); + UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent = 0; + } + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->FreePool (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor); + gBS->FreePool (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor); + + if (UsbMouseSimulateTouchPadDevice->ControllerNameTable) { + FreeUnicodeStringTable (UsbMouseSimulateTouchPadDevice->ControllerNameTable); + } + + gBS->FreePool (UsbMouseSimulateTouchPadDevice); + + return EFI_SUCCESS; + +} + + +/** + Tell if a Usb Controller is a mouse + + @param UsbIo Protocol instance pointer. + + @retval TRUE It is a mouse + @retval FALSE It is not a mouse + +**/ +BOOLEAN +IsUsbMouseSimulateTouchPad ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ) +{ + EFI_STATUS Status; + EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + + // + // Get the Default interface descriptor, now we only + // suppose it is interface 1 + // + Status = UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + &InterfaceDescriptor + ); + + if (EFI_ERROR (Status)) { + return FALSE; + } + + if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) && + (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) && + (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE) + ) { + + return TRUE; + } + + return FALSE; +} + + +/** + Initialize the Usb Mouse Simulate TouchPad Device. + + @param UsbMouseSimulateTouchPadDev Device instance to be initialized + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Init error. EFI_OUT_OF_RESOURCES- Can't allocate + memory + +**/ +STATIC +EFI_STATUS +InitializeUsbMouseSimulateTouchPadDevice ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev + ) +{ + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 Protocol; + EFI_STATUS Status; + EFI_USB_HID_DESCRIPTOR MouseHidDesc; + UINT8 *ReportDesc; + + UsbIo = UsbMouseSimulateTouchPadDev->UsbIo; + + // + // Get HID descriptor + // + Status = UsbGetHidDescriptor ( + UsbIo, + UsbMouseSimulateTouchPadDev->InterfaceDescriptor->InterfaceNumber, + &MouseHidDesc + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get Report descriptor + // + if (MouseHidDesc.HidClassDesc[0].DescriptorType != 0x22) { + return EFI_UNSUPPORTED; + } + + ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength); + if (ReportDesc == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = UsbGetReportDescriptor ( + UsbIo, + UsbMouseSimulateTouchPadDev->InterfaceDescriptor->InterfaceNumber, + MouseHidDesc.HidClassDesc[0].DescriptorLength, + ReportDesc + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + // + // Parse report descriptor + // + Status = ParseMouseReportDescriptor ( + UsbMouseSimulateTouchPadDev, + ReportDesc, + MouseHidDesc.HidClassDesc[0].DescriptorLength + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxX = 1024; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxY = 1024; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxZ = 0; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinX = 0; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinY = 0; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinZ = 0; + UsbMouseSimulateTouchPadDev->AbsolutePointerMode.Attributes = 0x3; + + // + // Here we just assume interface 0 is the mouse interface + // + UsbGetProtocolRequest ( + UsbIo, + 0, + &Protocol + ); + + if (Protocol != BOOT_PROTOCOL) { + Status = UsbSetProtocolRequest ( + UsbIo, + 0, + BOOT_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return EFI_DEVICE_ERROR; + } + } + + // + // Set indefinite Idle rate for USB Mouse + // + UsbSetIdleRequest ( + UsbIo, + 0, + 0, + 0 + ); + + gBS->FreePool (ReportDesc); + + if (UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent); + UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent = 0; + } + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + USBMouseSimulateTouchPadRecoveryHandler, + UsbMouseSimulateTouchPadDev, + &UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent + ); + + return EFI_SUCCESS; +} + + +/** + It is called whenever there is data received from async interrupt + transfer. + + @param Data Data received. + @param DataLength Length of Data + @param Context Passed in context + @param Result Async Interrupt Transfer result + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + +**/ +STATIC +EFI_STATUS +EFIAPI +OnMouseSimulateTouchPadInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ) +{ + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 EndpointAddr; + UINT32 UsbResult; + + UsbMouseSimulateTouchPadDevice = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context; + UsbIo = UsbMouseSimulateTouchPadDevice->UsbIo; + + if (Result != EFI_USB_NOERROR) { + // + // Some errors happen during the process + // + MouseSimulateTouchPadReportStatusCode ( + UsbMouseSimulateTouchPadDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInputError) + ); + + if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) { + EndpointAddr = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress; + + UsbClearEndpointHalt ( + UsbIo, + EndpointAddr, + &UsbResult + ); + } + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + 0, + 0, + NULL, + NULL + ); + + gBS->SetTimer ( + UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent, + TimerRelative, + EFI_USB_INTERRUPT_DELAY + ); + return EFI_DEVICE_ERROR; + } + + if (DataLength == 0 || Data == NULL) { + return EFI_SUCCESS; + } + + // + //Check mouse Data + // + UsbMouseSimulateTouchPadDevice->AbsolutePointerStateChanged = TRUE; + UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentX += *((INT8 *) Data + 1); + UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentY += *((INT8 *) Data + 2); + if (DataLength > 3) { + UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentZ += *((INT8 *) Data + 3); + } + UsbMouseSimulateTouchPadDevice->AbsolutePointerState.ActiveButtons = *(UINT8 *)Data & 0x3; + + return EFI_SUCCESS; +} + +/** + Get the mouse state, see ABSOLUTE POINTER PROTOCOL. + + @param This Protocol instance pointer. + @param MouseState Current mouse state + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_NOT_READY + +**/ +STATIC +EFI_STATUS +EFIAPI +GetMouseSimulateTouchPadState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + OUT EFI_ABSOLUTE_POINTER_STATE *MouseSimulateTouchPadState + ) +{ + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *MouseSimulateTouchPadDev; + + if (MouseSimulateTouchPadState == NULL) { + return EFI_DEVICE_ERROR; + } + + MouseSimulateTouchPadDev = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (This); + + if (!MouseSimulateTouchPadDev->AbsolutePointerStateChanged) { + return EFI_NOT_READY; + } + + CopyMem ( + MouseSimulateTouchPadState, + &MouseSimulateTouchPadDev->AbsolutePointerState, + sizeof (EFI_ABSOLUTE_POINTER_STATE) + ); + + // + // Clear previous move state + // + MouseSimulateTouchPadDev->AbsolutePointerState.CurrentX = 0; + MouseSimulateTouchPadDev->AbsolutePointerState.CurrentY = 0; + MouseSimulateTouchPadDev->AbsolutePointerState.CurrentZ = 0; + MouseSimulateTouchPadDev->AbsolutePointerState.ActiveButtons = 0; + + MouseSimulateTouchPadDev->AbsolutePointerStateChanged = FALSE; + + return EFI_SUCCESS; +} + + +/** + Reset the mouse device, see ABSOLUTE POINTER PROTOCOL. + + @param This Protocol instance pointer. + @param ExtendedVerification Ignored here/ + + @return EFI_SUCCESS + +**/ +STATIC +EFI_STATUS +EFIAPI +UsbMouseSimulateTouchPadReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice; + + UsbMouseSimulateTouchPadDevice = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (This); + + MouseSimulateTouchPadReportStatusCode ( + UsbMouseSimulateTouchPadDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseReset) + ); + + ZeroMem ( + &UsbMouseSimulateTouchPadDevice->AbsolutePointerState, + sizeof (EFI_ABSOLUTE_POINTER_STATE) + ); + UsbMouseSimulateTouchPadDevice->AbsolutePointerStateChanged = FALSE; + + return EFI_SUCCESS; +} + +/** + Event notification function for ABSOLUTE_POINTER.WaitForInput event + Signal the event if there is input from mouse + + @param Event Wait Event + @param Context Passed parameter to event handler + VOID + +**/ +STATIC +VOID +EFIAPI +UsbMouseSimulateTouchPadWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev; + + UsbMouseSimulateTouchPadDev = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context; + + // + // Someone is waiting on the mouse event, if there's + // input from mouse, signal the event + // + if (UsbMouseSimulateTouchPadDev->AbsolutePointerStateChanged) { + gBS->SignalEvent (Event); + } +} + +/** + Timer handler for Delayed Recovery timer. + + @param Event The Delayed Recovery event. + @param Context Points to the USB_KB_DEV instance. + + +**/ +VOID +EFIAPI +USBMouseSimulateTouchPadRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbMouseSimulateTouchPadDev = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context; + + UsbIo = UsbMouseSimulateTouchPadDev->UsbIo; + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->EndpointAddress, + TRUE, + UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->Interval, + UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->MaxPacketSize, + OnMouseSimulateTouchPadInterruptComplete, + UsbMouseSimulateTouchPadDev + ); +} + + +/** + Report Status Code in Usb Bot Driver + + @param DevicePath Use this to get Device Path + @param CodeType Status Code Type + @param CodeValue Status Code Value + + @return None + +**/ +VOID +MouseSimulateTouchPadReportStatusCode ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value + ) +{ + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + CodeType, + Value, + DevicePath + ); +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.h b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.h new file mode 100644 index 0000000000..65a87f1d2e --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.h @@ -0,0 +1,106 @@ +/** @file + +Copyright (c) 2004 - 2007, 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: + + UsbMouseSimulateTouchPad.h + + Abstract: + + +**/ + +#ifndef _USB_MOUSE_SIMULATE_TOUCHPAD_H +#define _USB_MOUSE_SIMULATE_TOUCHPAD_H + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CLASS_HID 3 +#define SUBCLASS_BOOT 1 +#define PROTOCOL_MOUSE 2 + +#define BOOT_PROTOCOL 0 +#define REPORT_PROTOCOL 1 + +#define USB_MOUSE_SIMULATE_TOUCHPAD_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'm', 's', 't') + +typedef struct { + BOOLEAN ButtonDetected; + UINT8 ButtonMinIndex; + UINT8 ButtonMaxIndex; + UINT8 Reserved; +} PRIVATE_DATA; + +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_EVENT DelayedRecoveryEvent; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor; + EFI_USB_ENDPOINT_DESCRIPTOR *IntEndpointDescriptor; + UINT8 NumberOfButtons; + INT32 XLogicMax; + INT32 XLogicMin; + INT32 YLogicMax; + INT32 YLogicMin; + + EFI_ABSOLUTE_POINTER_PROTOCOL AbsolutePointerProtocol; + EFI_ABSOLUTE_POINTER_STATE AbsolutePointerState; + EFI_ABSOLUTE_POINTER_MODE AbsolutePointerMode; + BOOLEAN AbsolutePointerStateChanged; + + PRIVATE_DATA PrivateData; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} USB_MOUSE_SIMULATE_TOUCHPAD_DEV; + +#define USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL(a) \ + CR(a, USB_MOUSE_SIMULATE_TOUCHPAD_DEV, AbsolutePointerProtocol, USB_MOUSE_SIMULATE_TOUCHPAD_DEV_SIGNATURE) + +VOID +EFIAPI +USBMouseSimulateTouchPadRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gUsbMouseSimulateTouchPadDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUsbMouseSimulateTouchPadComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseSimulateTouchPadComponentName2; +extern EFI_GUID gEfiUsbMouseSimulateTouchPadDriverGuid; + +VOID +MouseSimulateTouchPadReportStatusCode ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value + ); + +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPadDxe.inf b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPadDxe.inf new file mode 100644 index 0000000000..a1e98d6da2 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPadDxe.inf @@ -0,0 +1,67 @@ +#/** @file +# Component name for module UsbMouseSimulateTouchPad +# +# FIX ME! +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UsbMouseSimulateTouchPadDxe + FILE_GUID = 4EA43463-747C-46eb-97FB-B0E5C5F05306 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = USBMouseSimulateTouchPadDriverBindingEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + mousehid.h + ComponentName.c + UsbMouseSimulateTouchPad.c + mousehid.c + UsbMouseSimulateTouchPad.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + BaseMemoryLib + ReportStatusCodeLib + PcdLib + UsbLib + +[Protocols] + gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiAbsolutePointerProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseInterfaceError + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseEnable + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseDisable + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseInputError + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseReset + + diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.c b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.c new file mode 100644 index 0000000000..735a59e6a5 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.c @@ -0,0 +1,362 @@ +/** @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 UsbMouseSimulateTouchPad USB_MOUSE_SIMULATE_TOUCHPAD_DEV + @param LocalItem Local Item + + +**/ +STATIC +VOID +ParseLocalItem ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + 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 (UsbMouseSimulateTouchPad->PrivateData.ButtonDetected) { + UsbMouseSimulateTouchPad->PrivateData.ButtonMinIndex = (UINT8) Data; + } + + return ; + + case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: + { + if (UsbMouseSimulateTouchPad->PrivateData.ButtonDetected) { + UsbMouseSimulateTouchPad->PrivateData.ButtonMaxIndex = (UINT8) Data; + } + + return ; + } + } +} + +STATIC +VOID +ParseGlobalItem ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + 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 + // + UsbMouseSimulateTouchPad->PrivateData.ButtonDetected = TRUE; + return ; + } + break; + } + + } +} + + + +/** + Parse Main Item + + @param UsbMouseSimulateTouchPad USB_MOUSE_SIMULATE_TOUCHPAD_DEV + @param MainItem HID_ITEM to parse + + @return VOID + +**/ +STATIC +VOID +ParseMainItem ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + IN HID_ITEM *MainItem + ) +{ + // + // we don't care any main items, just skip + // + return ; +} + + +/** + Parse Hid Item + + @param UsbMouseSimulateTouchPad USB_MOUSE_SIMULATE_TOUCHPAD_DEV + @param HidItem HidItem to parse + + @return VOID + +**/ +STATIC +VOID +ParseHidItem ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + IN HID_ITEM *HidItem + ) +{ + switch (HidItem->Type) { + + case HID_ITEM_TYPE_MAIN: + // + // For Main Item, parse main item + // + ParseMainItem (UsbMouseSimulateTouchPad, HidItem); + break; + + case HID_ITEM_TYPE_GLOBAL: + // + // For global Item, parse global item + // + ParseGlobalItem (UsbMouseSimulateTouchPad, HidItem); + break; + + case HID_ITEM_TYPE_LOCAL: + // + // For Local Item, parse local item + // + ParseLocalItem (UsbMouseSimulateTouchPad, 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_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + 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 (UsbMouseSimulateTouchPad, &HidItem); + + ptr = GetNextItem (ptr, DescriptorEnd, &HidItem); + } + + UsbMouseSimulateTouchPad->NumberOfButtons = (UINT8) (UsbMouseSimulateTouchPad->PrivateData.ButtonMaxIndex - UsbMouseSimulateTouchPad->PrivateData.ButtonMinIndex + 1); + UsbMouseSimulateTouchPad->XLogicMax = UsbMouseSimulateTouchPad->YLogicMax = 1023; + UsbMouseSimulateTouchPad->XLogicMin = UsbMouseSimulateTouchPad->YLogicMin = -1023; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.h b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.h new file mode 100644 index 0000000000..4a1fadea93 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/mousehid.h @@ -0,0 +1,85 @@ +/** @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.h + +Abstract: + + +**/ + +#ifndef __MOUSE_HID_H +#define __MOUSE_HID_H + +#include "UsbMouseSimulateTouchPad.h" + +// +// HID Item general structure +// +typedef struct _hid_item { + UINT16 Format; + UINT8 Size; + UINT8 Type; + UINT8 Tag; + union { + UINT8 U8; + UINT16 U16; + UINT32 U32; + INT8 I8; + INT16 I16; + INT32 I32; + UINT8 *LongData; + } Data; +} HID_ITEM; + +typedef struct { + UINT16 UsagePage; + INT32 LogicMin; + INT32 LogicMax; + INT32 PhysicalMin; + INT32 PhysicalMax; + UINT16 UnitExp; + UINT16 UINT; + UINT16 ReportId; + UINT16 ReportSize; + UINT16 ReportCount; +} HID_GLOBAL; + +typedef struct { + UINT16 Usage[16]; /* usage array */ + UINT16 UsageIndex; + UINT16 UsageMin; +} HID_LOCAL; + +typedef struct { + UINT16 Type; + UINT16 Usage; +} HID_COLLECTION; + +typedef struct { + HID_GLOBAL Global; + HID_GLOBAL GlobalStack[8]; + UINT32 GlobalStackPtr; + HID_LOCAL Local; + HID_COLLECTION CollectionStack[8]; + UINT32 CollectionStackPtr; +} HID_PARSER; + +EFI_STATUS +ParseMouseReportDescriptor ( + IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPad, + IN UINT8 *ReportDescriptor, + IN UINTN ReportSize + ); + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index fa2fa94ab9..4b8d282a6e 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -300,6 +300,7 @@ MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf + MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPadDxe.inf MdeModulePkg/Universal/Variable/Pei/VariablePei.inf MdeModulePkg/Universal/Variable/Application/VariableInfo.inf diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ComponentName.c b/MdeModulePkg/Universal/Console/ConSplitterDxe/ComponentName.c index 35c1273c50..b13a859785 100644 --- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ComponentName.c @@ -56,6 +56,23 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gConSplitterSimplePoi "en" }; +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gConSplitterAbsolutePointerComponentName = { + ConSplitterComponentNameGetDriverName, + ConSplitterAbsolutePointerComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gConSplitterAbsolutePointerComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) ConSplitterComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) ConSplitterAbsolutePointerComponentNameGetControllerName, + "en" +}; // // EFI Component Name Protocol @@ -128,6 +145,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mConSplitterSimplePointer } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mConSplitterAbsolutePointerControllerNameTable[] = { + { + "eng;en", + (CHAR16 *)L"Primary Absolute Pointer Device" + }, + { + NULL, + NULL + } +}; + GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mConSplitterConOutControllerNameTable[] = { { "eng;en", @@ -422,6 +450,91 @@ ConSplitterSimplePointerComponentNameGetControllerName ( ); } +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + Language - A pointer to RFC3066 language identifier. + This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + ControllerName - A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language + specified by Language from the point of view of the + driver specified by This. + + Returns: + EFI_SUCCESS - The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + EFI_STATUS Status; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; + // + // here ChildHandle is not an Optional parameter. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointer, + NULL, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + +return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mConSplitterAbsolutePointerControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gConSplitterAbsolutePointerComponentName) + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c index f100d04688..39e67c8f42 100644 --- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c +++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c @@ -76,6 +76,27 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = { (EFI_SIMPLE_POINTER_PROTOCOL **) NULL, 0, + { + ConSplitterAbsolutePointerReset, + ConSplitterAbsolutePointerGetState, + (EFI_EVENT) NULL, + (EFI_ABSOLUTE_POINTER_MODE *) NULL + }, + + { + 0, //AbsoluteMinX + 0, //AbsoluteMinY + 0, //AbsoluteMinZ + 0x10000, //AbsoluteMaxX + 0x10000, //AbsoluteMaxY + 0x10000, //AbsoluteMaxZ + 0 //Attributes + }, + 0, + (EFI_ABSOLUTE_POINTER_PROTOCOL **) NULL, + 0, + FALSE, + FALSE, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -240,6 +261,18 @@ EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = { NULL }; +// +// Driver binding instance for Absolute Pointer protocol +// +EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding = { + ConSplitterAbsolutePointerDriverBindingSupported, + ConSplitterAbsolutePointerDriverBindingStart, + ConSplitterAbsolutePointerDriverBindingStop, + 0xa, + NULL, + NULL +}; + EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding = { ConSplitterConOutDriverBindingSupported, ConSplitterConOutDriverBindingStart, @@ -300,6 +333,16 @@ InitializeConSplitter( ); ASSERT_EFI_ERROR (Status); + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gConSplitterAbsolutePointerDriverBinding, + NULL, + &gConSplitterAbsolutePointerComponentName, + &gConSplitterAbsolutePointerComponentName2 + ); + ASSERT_EFI_ERROR (Status); + Status = EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, @@ -386,6 +429,8 @@ Returns: &mConIn.TextInEx, &gEfiSimplePointerProtocolGuid, &mConIn.SimplePointer, + &gEfiAbsolutePointerProtocolGuid, + &mConIn.AbsolutePointer, &gEfiPrimaryConsoleInDeviceGuid, NULL, NULL @@ -554,6 +599,28 @@ Returns: InitializeListHead (&ConInPrivate->NotifyList); + // + // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols + // + ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode; + + Status = ConSplitterGrowBuffer ( + sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *), + &ConInPrivate->AbsolutePointerListCount, + (VOID **) &ConInPrivate->AbsolutePointerList + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + ConSplitterAbsolutePointerWaitForInput, + ConInPrivate, + &ConInPrivate->AbsolutePointer.WaitForInput + ); + ASSERT_EFI_ERROR (Status); ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode; @@ -787,6 +854,36 @@ Returns: ); } +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + Absolute Pointer Supported Check + +Arguments: + This - Pointer to protocol. + ControllerHandle - Controller handle. + RemainingDevicePath - Remaining device path. + +Returns: + + EFI_STATUS + +--*/ +{ + return ConSplitterSupported ( + This, + ControllerHandle, + &gEfiAbsolutePointerProtocolGuid + ); +} + EFI_STATUS EFIAPI ConSplitterConOutDriverBindingSupported ( @@ -1021,6 +1118,49 @@ Returns: return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer); } +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + Start ConSplitter on ControllerHandle, and create the virtual + agrogated console device on first call Start for a ConIn handle. + +Arguments: + This - Pointer to protocol. + ControllerHandle - Controller handle. + RemainingDevicePath - Remaining device path. + +Returns: + + EFI_ERROR if a AbsolutePointer protocol is not started. + +--*/ +{ + EFI_STATUS Status; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; + + Status = ConSplitterStart ( + This, + ControllerHandle, + mConIn.VirtualHandle, + &gEfiAbsolutePointerProtocolGuid, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointer + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return ConSplitterAbsolutePointerAddDevice (&mConIn, AbsolutePointer); +} + EFI_STATUS EFIAPI ConSplitterConOutDriverBindingStart ( @@ -1341,6 +1481,51 @@ Returns: return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer); } +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + +Arguments: + (Standard DriverBinding Protocol Stop() function) + +Returns: + + None + +--*/ +{ + EFI_STATUS Status; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; + + if (NumberOfChildren == 0) { + return EFI_SUCCESS; + } + + Status = ConSplitterStop ( + This, + ControllerHandle, + mConIn.VirtualHandle, + &gEfiAbsolutePointerProtocolGuid, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointer + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Delete this console input device's data structures. + // + return ConSplitterAbsolutePointerDeleteDevice (&mConIn, AbsolutePointer); +} + EFI_STATUS EFIAPI ConSplitterConOutDriverBindingStop ( @@ -1729,6 +1914,83 @@ Returns: return EFI_NOT_FOUND; } +EFI_STATUS +ConSplitterAbsolutePointerAddDevice ( + IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, + IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + EFI_OUT_OF_RESOURCES + EFI_SUCCESS + +--*/ +{ + EFI_STATUS Status; + + // + // If the Absolute Pointer List is full, enlarge it by calling growbuffer(). + // + if (Private->CurrentNumberOfAbsolutePointers >= Private->AbsolutePointerListCount) { + Status = ConSplitterGrowBuffer ( + sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *), + &Private->AbsolutePointerListCount, + (VOID **) &Private->AbsolutePointerList + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + } + // + // Add the new text-in device data structure into the Text In List. + // + Private->AbsolutePointerList[Private->CurrentNumberOfAbsolutePointers] = AbsolutePointer; + Private->CurrentNumberOfAbsolutePointers++; + return EFI_SUCCESS; +} + +EFI_STATUS +ConSplitterAbsolutePointerDeleteDevice ( + IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, + IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +{ + UINTN Index; + // + // Remove the specified text-in device data structure from the Text In List, + // and rearrange the remaining data structures in the Text In List. + // + for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) { + if (Private->AbsolutePointerList[Index] == AbsolutePointer) { + for (Index = Index; Index < Private->CurrentNumberOfAbsolutePointers - 1; Index++) { + Private->AbsolutePointerList[Index] = Private->AbsolutePointerList[Index + 1]; + } + + Private->CurrentNumberOfAbsolutePointers--; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + STATIC EFI_STATUS ConSplitterGrowMapTable ( @@ -3325,8 +3587,6 @@ ConSplitterTextInUnregisterKeyNotify ( } - - EFI_STATUS EFIAPI ConSplitterSimplePointerReset ( @@ -3552,6 +3812,198 @@ Returns: } } +// +// Absolute Pointer Protocol functions +// + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Resets the pointer device hardware. + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + EFI_DEVICE_ERROR - The device is not functioning correctly and could + not be reset. + +--*/ +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + TEXT_IN_SPLITTER_PRIVATE_DATA *Private; + UINTN Index; + + Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This); + + Private->AbsoluteInputEventSignalState = FALSE; + + if (Private->CurrentNumberOfAbsolutePointers == 0) { + return EFI_SUCCESS; + } + // + // return the worst status met + // + for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfAbsolutePointers; Index++) { + Status = Private->AbsolutePointerList[Index]->Reset ( + Private->AbsolutePointerList[Index], + ExtendedVerification + ); + if (EFI_ERROR (Status)) { + ReturnStatus = Status; + } + } + + return ReturnStatus; +} + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerGetState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN OUT EFI_ABSOLUTE_POINTER_STATE *State + ) +/*++ + + Routine Description: + Retrieves the current state of a pointer device. + + Arguments: + This - Protocol instance pointer. + State - A pointer to the state information on the pointer device. + + Returns: + EFI_SUCCESS - The state of the pointer device was returned in State.. + EFI_NOT_READY - The state of the pointer device has not changed since the last call to + GetState(). + EFI_DEVICE_ERROR - A device error occurred while attempting to retrieve the pointer + device's current state. +--*/ +{ + TEXT_IN_SPLITTER_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + UINTN Index; + EFI_ABSOLUTE_POINTER_STATE CurrentState; + + + Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This); + if (Private->PasswordEnabled) { + // + // If StdIn Locked return not ready + // + return EFI_NOT_READY; + } + + Private->AbsoluteInputEventSignalState = FALSE; + + State->CurrentX = 0; + State->CurrentY = 0; + State->CurrentZ = 0; + State->ActiveButtons = 0; + + // + // if no physical pointer device exists, return EFI_NOT_READY; + // if any physical pointer device has changed state, + // return the state and EFI_SUCCESS. + // + ReturnStatus = EFI_NOT_READY; + for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) { + + Status = Private->AbsolutePointerList[Index]->GetState ( + Private->AbsolutePointerList[Index], + &CurrentState + ); + if (!EFI_ERROR (Status)) { + if (ReturnStatus == EFI_NOT_READY) { + ReturnStatus = EFI_SUCCESS; + } + + State->ActiveButtons = CurrentState.ActiveButtons; + + if (!(Private->AbsolutePointerMode.AbsoluteMinX == 0 && Private->AbsolutePointerMode.AbsoluteMaxX == 0)) { + State->CurrentX = CurrentState.CurrentX; + } + if (!(Private->AbsolutePointerMode.AbsoluteMinY == 0 && Private->AbsolutePointerMode.AbsoluteMaxY == 0)) { + State->CurrentY = CurrentState.CurrentY; + } + if (!(Private->AbsolutePointerMode.AbsoluteMinZ == 0 && Private->AbsolutePointerMode.AbsoluteMaxZ == 0)) { + State->CurrentZ = CurrentState.CurrentZ; + } + + } else if (Status == EFI_DEVICE_ERROR) { + ReturnStatus = EFI_DEVICE_ERROR; + } + } + + return ReturnStatus; +} + +VOID +EFIAPI +ConSplitterAbsolutePointerWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + This event agregates all the events of the pointer devices in the splitter. + If the ConIn is password locked then return. + If any events of physical pointer devices are signaled, signal the pointer + splitter event. This will cause the calling code to call + ConSplitterAbsolutePointerGetState (). + +Arguments: + Event - The Event assoicated with callback. + Context - Context registered when Event was created. + +Returns: + None + +--*/ +{ + EFI_STATUS Status; + TEXT_IN_SPLITTER_PRIVATE_DATA *Private; + UINTN Index; + + Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context; + if (Private->PasswordEnabled) { + // + // If StdIn Locked return not ready + // + return ; + } + + // + // if AbsoluteInputEventSignalState is flagged before, + // and not cleared by Reset() or GetState(), signal it + // + if (Private->AbsoluteInputEventSignalState) { + gBS->SignalEvent (Event); + return ; + } + // + // if any physical console input device has key input, signal the event. + // + for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) { + Status = gBS->CheckEvent (Private->AbsolutePointerList[Index]->WaitForInput); + if (!EFI_ERROR (Status)) { + gBS->SignalEvent (Event); + Private->AbsoluteInputEventSignalState = TRUE; + } + } +} + EFI_STATUS EFIAPI ConSplitterTextOutReset ( diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h index 4a71bb6294..40bafdf6d2 100644 --- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h +++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h @@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include #include @@ -47,6 +48,8 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterConInComponentName2; extern EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterSimplePointerComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterSimplePointerComponentName2; +extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterAbsolutePointerComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterAbsolutePointerComponentName2; extern EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterConOutComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterConOutComponentName2; @@ -89,6 +92,7 @@ typedef struct _TEXT_IN_EX_SPLITTER_NOTIFY { EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn; LIST_ENTRY NotifyEntry; } TEXT_IN_EX_SPLITTER_NOTIFY; + typedef struct { UINT64 Signature; EFI_HANDLE VirtualHandle; @@ -111,6 +115,13 @@ typedef struct { EFI_SIMPLE_POINTER_PROTOCOL **PointerList; UINTN PointerListCount; + EFI_ABSOLUTE_POINTER_PROTOCOL AbsolutePointer; + EFI_ABSOLUTE_POINTER_MODE AbsolutePointerMode; + UINTN CurrentNumberOfAbsolutePointers; + EFI_ABSOLUTE_POINTER_PROTOCOL **AbsolutePointerList; + UINTN AbsolutePointerListCount; + BOOLEAN AbsoluteInputEventSignalState; + BOOLEAN PasswordEnabled; CHAR16 Password[MAX_STD_IN_PASSWORD]; UINTN PwdIndex; @@ -368,6 +379,111 @@ ConSplitterStdErrDriverBindingStop ( ) ; +// +// Driver binding functions +// + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +EFI_STATUS +ConSplitterAbsolutePointerAddDevice ( + IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, + IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer + ) +; + +EFI_STATUS +ConSplitterAbsolutePointerDeleteDevice ( + IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, + IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer + ) +; + +// +// Absolute Pointer protocol interfaces +// + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Resets the pointer device hardware. + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + EFI_DEVICE_ERROR - The device is not functioning correctly and could + not be reset. + +--*/ +; + +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerGetState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN OUT EFI_ABSOLUTE_POINTER_STATE *State + ) +/*++ + + Routine Description: + Retrieves the current state of a pointer device. + + Arguments: + This - Protocol instance pointer. + State - A pointer to the state information on the pointer device. + + Returns: + EFI_SUCCESS - The state of the pointer device was returned in State.. + EFI_NOT_READY - The state of the pointer device has not changed since the last call to + GetState(). + EFI_DEVICE_ERROR - A device error occurred while attempting to retrieve the pointer + device's current state. +--*/ +; + +VOID +EFIAPI +ConSplitterAbsolutePointerWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -573,6 +689,16 @@ ConSplitterSimplePointerComponentNameGetControllerName ( OUT CHAR16 **ControllerName ); +EFI_STATUS +EFIAPI +ConSplitterAbsolutePointerComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +; /** Retrieves a Unicode string that is the user readable name of the controller diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf index 9a781a5a65..8201f2ce4f 100644 --- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf @@ -77,6 +77,7 @@ gEfiSimpleTextOutProtocolGuid # PROTOCOL ALWAYS_PRODUCED gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_PRODUCED gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiAbsolutePointerProtocolGuid # PROTOCOL ALWAYS_PRODUCED [FeaturePcd.common] gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport diff --git a/MdePkg/Include/Protocol/AbsolutePointer.h b/MdePkg/Include/Protocol/AbsolutePointer.h index 9748c3b6d0..3043391f9c 100644 --- a/MdePkg/Include/Protocol/AbsolutePointer.h +++ b/MdePkg/Include/Protocol/AbsolutePointer.h @@ -113,8 +113,8 @@ typedef struct { typedef EFI_STATUS (EFIAPI *EFI_ABSOLUTE_POINTER_RESET) ( - IN CONST EFI_ABSOLUTE_POINTER_PROTOCOL *This, - IN CONST BOOLEAN ExtendedVerification + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification ); @@ -204,7 +204,7 @@ typedef struct { typedef EFI_STATUS (EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE) ( - IN CONST EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, IN OUT EFI_ABSOLUTE_POINTER_STATE *State );