1/*++ @file
2
3Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
4Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14**/
15
16#include "Gop.h"
17
18
19BOOLEAN
20GopPrivateIsKeyRegistered (
21  IN EFI_KEY_DATA  *RegsiteredData,
22  IN EFI_KEY_DATA  *InputData
23  )
24/*++
25
26Routine Description:
27
28Arguments:
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
35Returns:
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
65VOID
66EFIAPI
67GopPrivateMakeCallbackFunction (
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
94VOID
95EFIAPI
96GopPrivateBreakCallbackFunction (
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**/
120EFI_STATUS
121EFIAPI
122EmuGopSimpleTextInReset (
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**/
169EFI_STATUS
170EFIAPI
171EmuGopSimpleTextInReadKeyStroke (
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**/
218VOID
219EFIAPI
220EmuGopSimpleTextInWaitForKey (
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**/
283EFI_STATUS
284EFIAPI
285EmuGopSimpleTextInExResetEx (
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**/
357EFI_STATUS
358EFIAPI
359EmuGopSimpleTextInExReadKeyStrokeEx (
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**/
434EFI_STATUS
435EFIAPI
436EmuGopSimpleTextInExSetState (
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**/
472VOID
473EFIAPI
474EmuGopRegisterKeyCallback (
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**/
511EFI_STATUS
512EFIAPI
513EmuGopSimpleTextInExRegisterKeyNotify (
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**/
596EFI_STATUS
597EFIAPI
598EmuGopSimpleTextInExUnregisterKeyNotify (
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**/
668EFI_STATUS
669EmuGopInitializeSimpleTextInForWindow (
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**/
741EFI_STATUS
742EFIAPI
743EmuGopSimplePointerReset (
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**/
790EFI_STATUS
791EFIAPI
792EmuGopSimplePointerGetState (
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**/
828VOID
829EFIAPI
830EmuGopSimplePointerWaitForInput (
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**/
871EFI_STATUS
872EmuGopInitializeSimplePointerForWindow (
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