]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/EmuGopDxe/GopInput.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
79e4f2a5
RN
12BOOLEAN\r
13GopPrivateIsKeyRegistered (\r
14 IN EFI_KEY_DATA *RegsiteredData,\r
15 IN EFI_KEY_DATA *InputData\r
16 )\r
a550d468 17\r
79e4f2a5
RN
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
a550d468
MK
38 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))\r
39 {\r
79e4f2a5
RN
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
a550d468
MK
46 if ((RegsiteredData->KeyState.KeyShiftState != 0) &&\r
47 (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))\r
48 {\r
79e4f2a5
RN
49 return FALSE;\r
50 }\r
a550d468
MK
51\r
52 if ((RegsiteredData->KeyState.KeyToggleState != 0) &&\r
53 (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))\r
54 {\r
79e4f2a5
RN
55 return FALSE;\r
56 }\r
57\r
58 return TRUE;\r
79e4f2a5
RN
59}\r
60\r
79e4f2a5
RN
61VOID\r
62EFIAPI\r
63GopPrivateMakeCallbackFunction (\r
a550d468
MK
64 IN VOID *Context,\r
65 IN EFI_KEY_DATA *KeyData\r
79e4f2a5
RN
66 )\r
67{\r
a550d468 68 LIST_ENTRY *Link;\r
79e4f2a5 69 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
a550d468 70 GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context;\r
79e4f2a5
RN
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
79e4f2a5
RN
89VOID\r
90EFIAPI\r
91GopPrivateBreakCallbackFunction (\r
a550d468
MK
92 IN VOID *Context,\r
93 IN EFI_KEY_DATA *KeyData\r
79e4f2a5
RN
94 )\r
95{\r
96 KeyMapBreak (KeyData);\r
97}\r
98\r
79e4f2a5
RN
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
a550d468
MK
116 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
117 IN BOOLEAN ExtendedVerification\r
79e4f2a5
RN
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
a550d468
MK
137 while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) {\r
138 }\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
164 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
165 OUT EFI_INPUT_KEY *Key\r
79e4f2a5
RN
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
a550d468 181 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 182\r
a550d468 183 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData);\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
211 IN EFI_EVENT Event,\r
212 IN VOID *Context\r
79e4f2a5
RN
213 )\r
214{\r
215 GOP_PRIVATE_DATA *Private;\r
216 EFI_STATUS Status;\r
217 EFI_TPL OldTpl;\r
218\r
a550d468 219 Private = (GOP_PRIVATE_DATA *)Context;\r
79e4f2a5
RN
220 if (Private->EmuGraphicsWindow == NULL) {\r
221 return;\r
222 }\r
223\r
224 //\r
225 // Enter critical section\r
226 //\r
a550d468 227 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 228\r
a550d468 229 Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow);\r
79e4f2a5
RN
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
a550d468 236\r
79e4f2a5
RN
237 //\r
238 // Leave critical section and return\r
239 //\r
240 gBS->RestoreTPL (OldTpl);\r
241}\r
242\r
79e4f2a5
RN
243//\r
244// Simple Text Input Ex protocol functions\r
245//\r
246\r
79e4f2a5
RN
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
a550d468 278\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
348 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
349 OUT EFI_KEY_DATA *KeyData\r
79e4f2a5 350 )\r
a550d468 351\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468 388 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 389\r
a550d468 390 Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, KeyData);\r
79e4f2a5
RN
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
79e4f2a5
RN
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
158b5587
RN
431 if (KeyToggleState == NULL) {\r
432 return EFI_INVALID_PARAMETER;\r
433 }\r
434\r
79e4f2a5
RN
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
158b5587 440 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
a550d468
MK
441 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID))\r
442 {\r
158b5587
RN
443 return EFI_UNSUPPORTED;\r
444 }\r
445\r
79e4f2a5
RN
446 //\r
447 // Enter critical section\r
448 //\r
a550d468 449 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 450\r
a550d468 451 Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState);\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
470 IN EFI_EVENT Event,\r
471 IN VOID *Context\r
79e4f2a5
RN
472 )\r
473{\r
a550d468 474 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context;\r
79e4f2a5
RN
475\r
476 ExNotify->KeyNotificationFn (&ExNotify->KeyData);\r
477}\r
478\r
79e4f2a5
RN
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
02ee79fa 510 OUT VOID **NotifyHandle\r
79e4f2a5
RN
511 )\r
512{\r
a550d468
MK
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
79e4f2a5 518\r
a550d468 519 if ((KeyData == NULL) || (KeyNotificationFunction == NULL) || (NotifyHandle == NULL)) {\r
79e4f2a5
RN
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
a550d468 546 NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY));\r
79e4f2a5
RN
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
a550d468 553 NewNotify->NotifyHandle = (EFI_HANDLE)NewNotify;\r
79e4f2a5
RN
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
79e4f2a5
RN
566 *NotifyHandle = NewNotify->NotifyHandle;\r
567\r
568 return EFI_SUCCESS;\r
79e4f2a5
RN
569}\r
570\r
79e4f2a5
RN
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
02ee79fa 590 IN VOID *NotificationHandle\r
79e4f2a5 591 )\r
a550d468 592\r
79e4f2a5
RN
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
a550d468
MK
608 GOP_PRIVATE_DATA *Private;\r
609 LIST_ENTRY *Link;\r
610 EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
79e4f2a5
RN
611\r
612 if (NotificationHandle == NULL) {\r
613 return EFI_INVALID_PARAMETER;\r
614 }\r
615\r
a550d468 616 if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468 659 IN GOP_PRIVATE_DATA *Private\r
79e4f2a5
RN
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
79e4f2a5
RN
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
79e4f2a5
RN
702 return Status;\r
703}\r
704\r
79e4f2a5
RN
705//\r
706// Simple Pointer implementation.\r
707//\r
708\r
79e4f2a5
RN
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
a550d468
MK
724 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
725 IN BOOLEAN ExtendedVerification\r
79e4f2a5
RN
726 )\r
727{\r
a550d468
MK
728 GOP_PRIVATE_DATA *Private;\r
729 EFI_SIMPLE_POINTER_STATE State;\r
730 EFI_TPL OldTpl;\r
79e4f2a5
RN
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
a550d468
MK
745 while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) {\r
746 }\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
772 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
773 IN OUT EFI_SIMPLE_POINTER_STATE *State\r
79e4f2a5
RN
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
a550d468 788 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 789\r
a550d468 790 Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State);\r
79e4f2a5
RN
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
79e4f2a5
RN
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
a550d468
MK
809 IN EFI_EVENT Event,\r
810 IN VOID *Context\r
79e4f2a5
RN
811 )\r
812{\r
813 GOP_PRIVATE_DATA *Private;\r
814 EFI_STATUS Status;\r
815 EFI_TPL OldTpl;\r
816\r
a550d468 817 Private = (GOP_PRIVATE_DATA *)Context;\r
79e4f2a5
RN
818 if (Private->EmuGraphicsWindow == NULL) {\r
819 return;\r
820 }\r
821\r
822 //\r
823 // Enter critical section\r
824 //\r
a550d468 825 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
79e4f2a5 826\r
a550d468 827 Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow);\r
79e4f2a5
RN
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
a550d468 834\r
79e4f2a5
RN
835 //\r
836 // Leave critical section and return\r
837 //\r
838 gBS->RestoreTPL (OldTpl);\r
839}\r
840\r
79e4f2a5
RN
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
a550d468 851 IN GOP_PRIVATE_DATA *Private\r
79e4f2a5
RN
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
a550d468
MK
865 Private->SimplePointer.Reset = EmuGopSimplePointerReset;\r
866 Private->SimplePointer.GetState = EmuGopSimplePointerGetState;\r
867 Private->SimplePointer.Mode = &Private->PointerMode;\r
79e4f2a5
RN
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