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