GopInput.c 25 KB

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