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