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