1/*++ @file 2 3Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> 4Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR> 5This program and the accompanying materials 6are licensed and made available under the terms and conditions of the BSD License 7which accompanies this distribution. The full text of the license may be found at 8http://opensource.org/licenses/bsd-license.php 9 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 14**/ 15 16#include "Gop.h" 17 18 19BOOLEAN 20GopPrivateIsKeyRegistered ( 21 IN EFI_KEY_DATA *RegsiteredData, 22 IN EFI_KEY_DATA *InputData 23 ) 24/*++ 25 26Routine Description: 27 28Arguments: 29 30 RegsiteredData - A pointer to a buffer that is filled in with the keystroke 31 state data for the key that was registered. 32 InputData - A pointer to a buffer that is filled in with the keystroke 33 state data for the key that was pressed. 34 35Returns: 36 TRUE - Key be pressed matches a registered key. 37 FLASE - Match failed. 38 39**/ 40{ 41 ASSERT (RegsiteredData != NULL && InputData != NULL); 42 43 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || 44 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { 45 return FALSE; 46 } 47 48 // 49 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. 50 // 51 if (RegsiteredData->KeyState.KeyShiftState != 0 && 52 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) { 53 return FALSE; 54 } 55 if (RegsiteredData->KeyState.KeyToggleState != 0 && 56 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) { 57 return FALSE; 58 } 59 60 return TRUE; 61 62} 63 64 65VOID 66EFIAPI 67GopPrivateMakeCallbackFunction ( 68 IN VOID *Context, 69 IN EFI_KEY_DATA *KeyData 70 ) 71{ 72 LIST_ENTRY *Link; 73 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; 74 GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context; 75 76 KeyMapMake (KeyData); 77 78 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { 79 CurrentNotify = CR ( 80 Link, 81 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, 82 NotifyEntry, 83 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE 84 ); 85 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { 86 // We could be called at a high TPL so signal an event to call the registered function 87 // at a lower TPL. 88 gBS->SignalEvent (CurrentNotify->Event); 89 } 90 } 91} 92 93 94VOID 95EFIAPI 96GopPrivateBreakCallbackFunction ( 97 IN VOID *Context, 98 IN EFI_KEY_DATA *KeyData 99 ) 100{ 101 KeyMapBreak (KeyData); 102} 103 104 105 106// 107// Simple Text In implementation. 108// 109 110/** 111 Reset the input device and optionally run diagnostics 112 113 @param This Protocol instance pointer. 114 @param ExtendedVerification Driver may perform diagnostics on reset. 115 116 @retval EFI_SUCCESS The device was reset. 117 @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. 118 119**/ 120EFI_STATUS 121EFIAPI 122EmuGopSimpleTextInReset ( 123 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, 124 IN BOOLEAN ExtendedVerification 125 ) 126{ 127 GOP_PRIVATE_DATA *Private; 128 EFI_KEY_DATA KeyData; 129 EFI_TPL OldTpl; 130 131 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); 132 if (Private->EmuGraphicsWindow == NULL) { 133 return EFI_SUCCESS; 134 } 135 136 // 137 // Enter critical section 138 // 139 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 140 141 // 142 // A reset is draining the Queue 143 // 144 while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) 145 ; 146 147 // 148 // Leave critical section and return 149 // 150 gBS->RestoreTPL (OldTpl); 151 return EFI_SUCCESS; 152} 153 154 155/** 156 Reads the next keystroke from the input device. The WaitForKey Event can 157 be used to test for existence of a keystroke via WaitForEvent () call. 158 159 @param This Protocol instance pointer. 160 @param Key A pointer to a buffer that is filled in with the keystroke 161 information for the key that was pressed. 162 163 @retval EFI_SUCCESS The keystroke information was returned. 164 @retval EFI_NOT_READY There was no keystroke data available. 165 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to 166 hardware errors. 167 168**/ 169EFI_STATUS 170EFIAPI 171EmuGopSimpleTextInReadKeyStroke ( 172 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, 173 OUT EFI_INPUT_KEY *Key 174 ) 175{ 176 GOP_PRIVATE_DATA *Private; 177 EFI_STATUS Status; 178 EFI_TPL OldTpl; 179 EFI_KEY_DATA KeyData; 180 181 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); 182 if (Private->EmuGraphicsWindow == NULL) { 183 return EFI_NOT_READY; 184 } 185 186 // 187 // Enter critical section 188 // 189 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 190 191 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData); 192 if (!EFI_ERROR (Status)) { 193 if ((KeyData.Key.ScanCode == 0) && (KeyData.Key.UnicodeChar == 0)) { 194 // Modifier key was pressed 195 Status = EFI_NOT_READY; 196 } else { 197 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); 198 } 199 } 200 201 // 202 // Leave critical section and return 203 // 204 gBS->RestoreTPL (OldTpl); 205 206 return Status; 207} 208 209 210 211/** 212 SimpleTextIn and SimpleTextInEx Notify Wait Event 213 214 @param Event Event whose notification function is being invoked. 215 @param Context Pointer to GOP_PRIVATE_DATA. 216 217**/ 218VOID 219EFIAPI 220EmuGopSimpleTextInWaitForKey ( 221 IN EFI_EVENT Event, 222 IN VOID *Context 223 ) 224{ 225 GOP_PRIVATE_DATA *Private; 226 EFI_STATUS Status; 227 EFI_TPL OldTpl; 228 229 Private = (GOP_PRIVATE_DATA *) Context; 230 if (Private->EmuGraphicsWindow == NULL) { 231 return; 232 } 233 234 // 235 // Enter critical section 236 // 237 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 238 239 Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow); 240 if (!EFI_ERROR (Status)) { 241 // 242 // If a there is a key in the queue signal our event. 243 // 244 gBS->SignalEvent (Event); 245 } 246 // 247 // Leave critical section and return 248 // 249 gBS->RestoreTPL (OldTpl); 250} 251 252 253// 254// Simple Text Input Ex protocol functions 255// 256 257 258/** 259 The Reset() function resets the input device hardware. As part 260 of initialization process, the firmware/device will make a quick 261 but reasonable attempt to verify that the device is functioning. 262 If the ExtendedVerification flag is TRUE the firmware may take 263 an extended amount of time to verify the device is operating on 264 reset. Otherwise the reset operation is to occur as quickly as 265 possible. The hardware verification process is not defined by 266 this specification and is left up to the platform firmware or 267 driver to implement. 268 269 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. 270 271 @param ExtendedVerification Indicates that the driver may 272 perform a more exhaustive 273 verification operation of the 274 device during reset. 275 276 277 @retval EFI_SUCCESS The device was reset. 278 279 @retval EFI_DEVICE_ERROR The device is not functioning 280 correctly and could not be reset. 281 282**/ 283EFI_STATUS 284EFIAPI 285EmuGopSimpleTextInExResetEx ( 286 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 287 IN BOOLEAN ExtendedVerification 288 ) 289/*++ 290 291 Routine Description: 292 Reset the input device and optionaly run diagnostics 293 294 Arguments: 295 This - Protocol instance pointer. 296 ExtendedVerification - Driver may perform diagnostics on reset. 297 298 Returns: 299 EFI_SUCCESS - The device was reset. 300 301**/ 302{ 303 return EFI_SUCCESS; 304} 305 306 307 308/** 309 The function reads the next keystroke from the input device. If 310 there is no pending keystroke the function returns 311 EFI_NOT_READY. If there is a pending keystroke, then 312 KeyData.Key.ScanCode is the EFI scan code defined in Error! 313 Reference source not found. The KeyData.Key.UnicodeChar is the 314 actual printable character or is zero if the key does not 315 represent a printable character (control key, function key, 316 etc.). The KeyData.KeyState is shift state for the character 317 reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode . 318 When interpreting the data from this function, it should be 319 noted that if a class of printable characters that are 320 normally adjusted by shift modifiers (e.g. Shift Key + "f" 321 key) would be presented solely as a KeyData.Key.UnicodeChar 322 without the associated shift state. So in the previous example 323 of a Shift Key + "f" key being pressed, the only pertinent 324 data returned would be KeyData.Key.UnicodeChar with the value 325 of "F". This of course would not typically be the case for 326 non-printable characters such as the pressing of the Right 327 Shift Key + F10 key since the corresponding returned data 328 would be reflected both in the KeyData.KeyState.KeyShiftState 329 and KeyData.Key.ScanCode values. UEFI drivers which implement 330 the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return 331 KeyData.Key and KeyData.KeyState values. These drivers must 332 always return the most current state of 333 KeyData.KeyState.KeyShiftState and 334 KeyData.KeyState.KeyToggleState. It should also be noted that 335 certain input devices may not be able to produce shift or toggle 336 state information, and in those cases the high order bit in the 337 respective Toggle and Shift state fields should not be active. 338 339 340 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. 341 342 @param KeyData A pointer to a buffer that is filled in with 343 the keystroke state data for the key that was 344 pressed. 345 346 347 @retval EFI_SUCCESS The keystroke information was 348 returned. 349 350 @retval EFI_NOT_READY There was no keystroke data available. 351 EFI_DEVICE_ERROR The keystroke 352 information was not returned due to 353 hardware errors. 354 355 356**/ 357EFI_STATUS 358EFIAPI 359EmuGopSimpleTextInExReadKeyStrokeEx ( 360 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 361 OUT EFI_KEY_DATA *KeyData 362 ) 363/*++ 364 365 Routine Description: 366 Reads the next keystroke from the input device. The WaitForKey Event can 367 be used to test for existance of a keystroke via WaitForEvent () call. 368 369 Arguments: 370 This - Protocol instance pointer. 371 KeyData - A pointer to a buffer that is filled in with the keystroke 372 state data for the key that was pressed. 373 374 Returns: 375 EFI_SUCCESS - The keystroke information was returned. 376 EFI_NOT_READY - There was no keystroke data availiable. 377 EFI_DEVICE_ERROR - The keystroke information was not returned due to 378 hardware errors. 379 EFI_INVALID_PARAMETER - KeyData is NULL. 380 381**/ 382{ 383 EFI_STATUS Status; 384 GOP_PRIVATE_DATA *Private; 385 EFI_TPL OldTpl; 386 387 388 if (KeyData == NULL) { 389 return EFI_INVALID_PARAMETER; 390 } 391 392 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); 393 if (Private->EmuGraphicsWindow == NULL) { 394 return EFI_NOT_READY; 395 } 396 397 // 398 // Enter critical section 399 // 400 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 401 402 Status = Private->EmuGraphicsWindow->GetKey(Private->EmuGraphicsWindow, KeyData); 403 404 // 405 // Leave critical section and return 406 // 407 gBS->RestoreTPL (OldTpl); 408 409 return Status; 410} 411 412 413 414/** 415 The SetState() function allows the input device hardware to 416 have state settings adjusted. 417 418 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. 419 420 @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to 421 set the state for the input device. 422 423 424 @retval EFI_SUCCESS The device state was set appropriately. 425 426 @retval EFI_DEVICE_ERROR The device is not functioning 427 correctly and could not have the 428 setting adjusted. 429 430 @retval EFI_UNSUPPORTED The device does not support the 431 ability to have its state set. 432 433**/ 434EFI_STATUS 435EFIAPI 436EmuGopSimpleTextInExSetState ( 437 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 438 IN EFI_KEY_TOGGLE_STATE *KeyToggleState 439 ) 440{ 441 GOP_PRIVATE_DATA *Private; 442 EFI_STATUS Status; 443 EFI_TPL OldTpl; 444 445 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); 446 if (Private->EmuGraphicsWindow == NULL) { 447 return EFI_NOT_READY; 448 } 449 450 // 451 // Enter critical section 452 // 453 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 454 455 Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState); 456 // 457 // Leave critical section and return 458 // 459 gBS->RestoreTPL (OldTpl); 460 461 return Status; 462} 463 464 465/** 466 SimpleTextIn and SimpleTextInEx Notify Wait Event 467 468 @param Event Event whose notification function is being invoked. 469 @param Context Pointer to GOP_PRIVATE_DATA. 470 471**/ 472VOID 473EFIAPI 474EmuGopRegisterKeyCallback ( 475 IN EFI_EVENT Event, 476 IN VOID *Context 477 ) 478{ 479 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context; 480 481 ExNotify->KeyNotificationFn (&ExNotify->KeyData); 482} 483 484 485 486/** 487 The RegisterKeystrokeNotify() function registers a function 488 which will be called when a specified keystroke will occur. 489 490 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. 491 492 @param KeyData A pointer to a buffer that is filled in with 493 the keystroke information for the key that was 494 pressed. 495 496 @param KeyNotificationFunction Points to the function to be 497 called when the key sequence 498 is typed specified by KeyData. 499 500 501 @param NotifyHandle Points to the unique handle assigned to 502 the registered notification. 503 504 @retval EFI_SUCCESS The device state was set 505 appropriately. 506 507 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary 508 data structures. 509 510**/ 511EFI_STATUS 512EFIAPI 513EmuGopSimpleTextInExRegisterKeyNotify ( 514 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 515 IN EFI_KEY_DATA *KeyData, 516 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, 517 OUT EFI_HANDLE *NotifyHandle 518 ) 519{ 520 EFI_STATUS Status; 521 GOP_PRIVATE_DATA *Private; 522 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; 523 LIST_ENTRY *Link; 524 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; 525 526 if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) { 527 return EFI_INVALID_PARAMETER; 528 } 529 530 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); 531 532 // 533 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. 534 // 535 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { 536 CurrentNotify = CR ( 537 Link, 538 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, 539 NotifyEntry, 540 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE 541 ); 542 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { 543 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { 544 *NotifyHandle = CurrentNotify->NotifyHandle; 545 return EFI_SUCCESS; 546 } 547 } 548 } 549 550 // 551 // Allocate resource to save the notification function 552 // 553 NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY)); 554 if (NewNotify == NULL) { 555 return EFI_OUT_OF_RESOURCES; 556 } 557 558 NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; 559 NewNotify->KeyNotificationFn = KeyNotificationFunction; 560 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; 561 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); 562 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry); 563 564 Status = gBS->CreateEvent ( 565 EVT_NOTIFY_SIGNAL, 566 TPL_NOTIFY, 567 EmuGopRegisterKeyCallback, 568 NewNotify, 569 &NewNotify->Event 570 ); 571 ASSERT_EFI_ERROR (Status); 572 573 574 *NotifyHandle = NewNotify->NotifyHandle; 575 576 return EFI_SUCCESS; 577 578} 579 580 581/** 582 The UnregisterKeystrokeNotify() function removes the 583 notification which was previously registered. 584 585 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. 586 587 @param NotificationHandle The handle of the notification 588 function being unregistered. 589 590 @retval EFI_SUCCESS The device state was set appropriately. 591 592 @retval EFI_INVALID_PARAMETER The NotificationHandle is 593 invalid. 594 595**/ 596EFI_STATUS 597EFIAPI 598EmuGopSimpleTextInExUnregisterKeyNotify ( 599 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 600 IN EFI_HANDLE NotificationHandle 601 ) 602/*++ 603 604 Routine Description: 605 Remove a registered notification function from a particular keystroke. 606 607 Arguments: 608 This - Protocol instance pointer. 609 NotificationHandle - The handle of the notification function being unregistered. 610 611 Returns: 612 EFI_SUCCESS - The notification function was unregistered successfully. 613 EFI_INVALID_PARAMETER - The NotificationHandle is invalid. 614 615**/ 616{ 617 GOP_PRIVATE_DATA *Private; 618 LIST_ENTRY *Link; 619 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; 620 621 if (NotificationHandle == NULL) { 622 return EFI_INVALID_PARAMETER; 623 } 624 625 if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) { 626 return EFI_INVALID_PARAMETER; 627 } 628 629 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); 630 631 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { 632 CurrentNotify = CR ( 633 Link, 634 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, 635 NotifyEntry, 636 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE 637 ); 638 if (CurrentNotify->NotifyHandle == NotificationHandle) { 639 // 640 // Remove the notification function from NotifyList and free resources 641 // 642 RemoveEntryList (&CurrentNotify->NotifyEntry); 643 644 gBS->CloseEvent (CurrentNotify->Event); 645 646 gBS->FreePool (CurrentNotify); 647 return EFI_SUCCESS; 648 } 649 } 650 651 // 652 // Can not find the specified Notification Handle 653 // 654 return EFI_INVALID_PARAMETER; 655} 656 657 658 659/** 660 Initialize SimplelTextIn and SimpleTextInEx protocols in the Private 661 context structure. 662 663 @param Private Context structure to fill in. 664 665 @return EFI_SUCCESS Initialization was a success 666 667**/ 668EFI_STATUS 669EmuGopInitializeSimpleTextInForWindow ( 670 IN GOP_PRIVATE_DATA *Private 671 ) 672{ 673 EFI_STATUS Status; 674 675 // 676 // Initialize Simple Text In protoocol 677 // 678 Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset; 679 Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke; 680 681 Status = gBS->CreateEvent ( 682 EVT_NOTIFY_WAIT, 683 TPL_NOTIFY, 684 EmuGopSimpleTextInWaitForKey, 685 Private, 686 &Private->SimpleTextIn.WaitForKey 687 ); 688 ASSERT_EFI_ERROR (Status); 689 690 691 // 692 // Initialize Simple Text In Ex 693 // 694 695 Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx; 696 Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx; 697 Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState; 698 Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify; 699 Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify; 700 701 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE); 702 703 InitializeListHead (&Private->NotifyList); 704 705 Status = gBS->CreateEvent ( 706 EVT_NOTIFY_WAIT, 707 TPL_NOTIFY, 708 EmuGopSimpleTextInWaitForKey, 709 Private, 710 &Private->SimpleTextInEx.WaitForKeyEx 711 ); 712 ASSERT_EFI_ERROR (Status); 713 714 715 return Status; 716} 717 718 719 720 721 722 723 724// 725// Simple Pointer implementation. 726// 727 728 729/** 730 Resets the pointer device hardware. 731 732 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL 733 instance. 734 @param ExtendedVerification Indicates that the driver may perform a more exhaustive 735 verification operation of the device during reset. 736 737 @retval EFI_SUCCESS The device was reset. 738 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. 739 740**/ 741EFI_STATUS 742EFIAPI 743EmuGopSimplePointerReset ( 744 IN EFI_SIMPLE_POINTER_PROTOCOL *This, 745 IN BOOLEAN ExtendedVerification 746 ) 747{ 748 GOP_PRIVATE_DATA *Private; 749 EFI_SIMPLE_POINTER_STATE State; 750 EFI_TPL OldTpl; 751 752 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); 753 if (Private->EmuGraphicsWindow == NULL) { 754 return EFI_SUCCESS; 755 } 756 757 // 758 // Enter critical section 759 // 760 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 761 762 // 763 // A reset is draining the Queue 764 // 765 while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) 766 ; 767 768 // 769 // Leave critical section and return 770 // 771 gBS->RestoreTPL (OldTpl); 772 return EFI_SUCCESS; 773} 774 775 776/** 777 Retrieves the current state of a pointer device. 778 779 @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL 780 instance. 781 @param State A pointer to the state information on the pointer device. 782 783 @retval EFI_SUCCESS The state of the pointer device was returned in State. 784 @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to 785 GetState(). 786 @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's 787 current state. 788 789**/ 790EFI_STATUS 791EFIAPI 792EmuGopSimplePointerGetState ( 793 IN EFI_SIMPLE_POINTER_PROTOCOL *This, 794 IN OUT EFI_SIMPLE_POINTER_STATE *State 795 ) 796{ 797 GOP_PRIVATE_DATA *Private; 798 EFI_STATUS Status; 799 EFI_TPL OldTpl; 800 801 Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); 802 if (Private->EmuGraphicsWindow == NULL) { 803 return EFI_NOT_READY; 804 } 805 806 // 807 // Enter critical section 808 // 809 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 810 811 Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State); 812 // 813 // Leave critical section and return 814 // 815 gBS->RestoreTPL (OldTpl); 816 817 return Status; 818} 819 820 821/** 822 SimplePointer Notify Wait Event 823 824 @param Event Event whose notification function is being invoked. 825 @param Context Pointer to GOP_PRIVATE_DATA. 826 827**/ 828VOID 829EFIAPI 830EmuGopSimplePointerWaitForInput ( 831 IN EFI_EVENT Event, 832 IN VOID *Context 833 ) 834{ 835 GOP_PRIVATE_DATA *Private; 836 EFI_STATUS Status; 837 EFI_TPL OldTpl; 838 839 Private = (GOP_PRIVATE_DATA *) Context; 840 if (Private->EmuGraphicsWindow == NULL) { 841 return; 842 } 843 844 // 845 // Enter critical section 846 // 847 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 848 849 Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow); 850 if (!EFI_ERROR (Status)) { 851 // 852 // If the pointer state has changed, signal our event. 853 // 854 gBS->SignalEvent (Event); 855 } 856 // 857 // Leave critical section and return 858 // 859 gBS->RestoreTPL (OldTpl); 860} 861 862 863/** 864 SimplePointer constructor 865 866 @param Private Context structure to fill in. 867 868 @retval EFI_SUCCESS Constructor had success 869 870**/ 871EFI_STATUS 872EmuGopInitializeSimplePointerForWindow ( 873 IN GOP_PRIVATE_DATA *Private 874 ) 875{ 876 EFI_STATUS Status; 877 878 // 879 // Initialize Simple Pointer protoocol 880 // 881 Private->PointerMode.ResolutionX = 1; 882 Private->PointerMode.ResolutionY = 1; 883 Private->PointerMode.ResolutionZ = 1; 884 Private->PointerMode.LeftButton = TRUE; 885 Private->PointerMode.RightButton = TRUE; 886 887 Private->SimplePointer.Reset = EmuGopSimplePointerReset; 888 Private->SimplePointer.GetState = EmuGopSimplePointerGetState; 889 Private->SimplePointer.Mode = &Private->PointerMode; 890 891 Status = gBS->CreateEvent ( 892 EVT_NOTIFY_WAIT, 893 TPL_NOTIFY, 894 EmuGopSimplePointerWaitForInput, 895 Private, 896 &Private->SimplePointer.WaitForInput 897 ); 898 899 return Status; 900} 901