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