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