]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
Fix warnings generated by gcc for ia32 builds:
[mirror_edk2.git] / Nt32Pkg / WinNtGopDxe / WinNtGopInput.c
1 /** @file
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 WinNtGopInput.c
15
16 Abstract:
17
18 This file produces the Simple Text In for an Gop window.
19
20 This stuff is linked at the hip to the Window, since the window
21 processing is done in a thread kicked off in WinNtGopImplementation.c
22
23 Since the window information is processed in an other thread we need
24 a keyboard Queue to pass data about. The Simple Text In code just
25 takes data off the Queue. The WinProc message loop takes keyboard input
26 and places it in the Queue.
27
28
29 **/
30
31
32 #include "WinNtGop.h"
33
34
35 /**
36 TODO: Add function description
37
38 @param Private TODO: add argument description
39
40 @retval EFI_SUCCESS TODO: Add description for return value
41
42 **/
43 EFI_STATUS
44 GopPrivateCreateQ (
45 IN GOP_PRIVATE_DATA *Private
46 )
47 {
48 Private->WinNtThunk->InitializeCriticalSection (&Private->QCriticalSection);
49
50 Private->Queue.Front = 0;
51 Private->Queue.Rear = MAX_Q - 1;
52 Private->Queue.Count = 0;
53 return EFI_SUCCESS;
54 }
55
56
57 /**
58 TODO: Add function description
59
60 @param Private TODO: add argument description
61
62 @retval EFI_SUCCESS TODO: Add description for return value
63
64 **/
65 EFI_STATUS
66 GopPrivateDestroyQ (
67 IN GOP_PRIVATE_DATA *Private
68 )
69 {
70 Private->Queue.Count = 0;
71 Private->WinNtThunk->DeleteCriticalSection (&Private->QCriticalSection);
72 return EFI_SUCCESS;
73 }
74
75
76 /**
77 TODO: Add function description
78
79 @param Private TODO: add argument description
80 @param Key TODO: add argument description
81
82 @retval EFI_NOT_READY TODO: Add description for return value
83 @retval EFI_SUCCESS TODO: Add description for return value
84
85 **/
86 EFI_STATUS
87 GopPrivateAddQ (
88 IN GOP_PRIVATE_DATA *Private,
89 IN EFI_INPUT_KEY Key
90 )
91 {
92 Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);
93
94 if (Private->Queue.Count == MAX_Q) {
95 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
96 return EFI_NOT_READY;
97 }
98
99 Private->Queue.Rear = (Private->Queue.Rear + 1) % MAX_Q;
100 Private->Queue.Q[Private->Queue.Rear] = Key;
101 Private->Queue.Count++;
102
103 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
104 return EFI_SUCCESS;
105 }
106
107
108 /**
109 TODO: Add function description
110
111 @param Private TODO: add argument description
112 @param Key TODO: add argument description
113
114 @retval EFI_NOT_READY TODO: Add description for return value
115 @retval EFI_SUCCESS TODO: Add description for return value
116
117 **/
118 EFI_STATUS
119 GopPrivateDeleteQ (
120 IN GOP_PRIVATE_DATA *Private,
121 OUT EFI_INPUT_KEY *Key
122 )
123 {
124 Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);
125
126 if (Private->Queue.Count == 0) {
127 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
128 return EFI_NOT_READY;
129 }
130
131 *Key = Private->Queue.Q[Private->Queue.Front];
132 Private->Queue.Front = (Private->Queue.Front + 1) % MAX_Q;
133 Private->Queue.Count--;
134
135 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
136 return EFI_SUCCESS;
137 }
138
139
140 /**
141 TODO: Add function description
142
143 @param Private TODO: add argument description
144
145 @retval EFI_NOT_READY TODO: Add description for return value
146 @retval EFI_SUCCESS TODO: Add description for return value
147
148 **/
149 EFI_STATUS
150 GopPrivateCheckQ (
151 IN GOP_PRIVATE_DATA *Private
152 )
153 {
154 if (Private->Queue.Count == 0) {
155 return EFI_NOT_READY;
156 }
157
158 return EFI_SUCCESS;
159 }
160
161 STATIC
162 BOOLEAN
163 GopPrivateIsKeyRegistered (
164 IN EFI_KEY_DATA *RegsiteredData,
165 IN EFI_KEY_DATA *InputData
166 )
167 /*++
168
169 Routine Description:
170
171 Arguments:
172
173 RegsiteredData - A pointer to a buffer that is filled in with the keystroke
174 state data for the key that was registered.
175 InputData - A pointer to a buffer that is filled in with the keystroke
176 state data for the key that was pressed.
177
178 Returns:
179 TRUE - Key be pressed matches a registered key.
180 FLASE - Match failed.
181
182 --*/
183 {
184 ASSERT (RegsiteredData != NULL && InputData != NULL);
185
186 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
187 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
188 return FALSE;
189 }
190
191 //
192 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
193 //
194 if (RegsiteredData->KeyState.KeyShiftState != 0 &&
195 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
196 return FALSE;
197 }
198 if (RegsiteredData->KeyState.KeyToggleState != 0 &&
199 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
200 return FALSE;
201 }
202
203 return TRUE;
204
205 }
206
207
208 STATIC
209 VOID
210 GopPrivateInvokeRegisteredFunction (
211 IN GOP_PRIVATE_DATA *Private,
212 IN EFI_KEY_DATA *KeyData
213 )
214 /*++
215
216 Routine Description:
217
218 This function updates the status light of NumLock, ScrollLock and CapsLock.
219
220 Arguments:
221
222 Private - The private structure of WinNt Gop device.
223 KeyData - A pointer to a buffer that is filled in with the keystroke
224 state data for the key that was pressed.
225
226 Returns:
227
228 EFI_SUCCESS - The status light is updated successfully.
229
230 --*/
231 {
232 LIST_ENTRY *Link;
233 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
234
235 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
236 CurrentNotify = CR (
237 Link,
238 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
239 NotifyEntry,
240 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
241 );
242 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
243 CurrentNotify->KeyNotificationFn (KeyData);
244 }
245 }
246 }
247
248 STATIC
249 EFI_STATUS
250 GopPrivateUpdateStatusLight (
251 IN GOP_PRIVATE_DATA *Private
252 )
253 /*++
254
255 Routine Description:
256
257 This function updates the status light of NumLock, ScrollLock and CapsLock.
258
259 Arguments:
260
261 Private - The private structure of WinNt console In/Out.
262
263 Returns:
264
265 EFI_SUCCESS - The status light is updated successfully.
266
267 --*/
268 {
269 //
270 // BUGBUG:Only SendInput/keybd_event function can toggle
271 // NumLock, CapsLock and ScrollLock keys.
272 // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.
273 // Thus, return immediately without operation.
274 //
275 return EFI_SUCCESS;
276
277 }
278
279
280 STATIC
281 EFI_STATUS
282 GopPrivateResetWorker (
283 IN GOP_PRIVATE_DATA *Private
284 )
285 /*++
286
287 Routine Description:
288
289 This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().
290
291 Arguments:
292
293 Private - WinNT GOP private structure
294
295 Returns:
296
297 EFI_SUCCESS - Reset successfully
298
299 --*/
300 {
301 EFI_INPUT_KEY Key;
302 EFI_TPL OldTpl;
303
304 //
305 // Enter critical section
306 //
307 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
308
309 //
310 // A reset is draining the Queue
311 //
312 while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)
313 ;
314
315 Private->LeftShift = FALSE;
316 Private->RightShift = FALSE;
317 Private->LeftAlt = FALSE;
318 Private->RightAlt = FALSE;
319 Private->LeftCtrl = FALSE;
320 Private->RightCtrl = FALSE;
321 Private->LeftLogo = FALSE;
322 Private->RightLogo = FALSE;
323 Private->Menu = FALSE;
324 Private->SysReq = FALSE;
325
326 Private->CapsLock = FALSE;
327 Private->NumLock = FALSE;
328 Private->ScrollLock = FALSE;
329
330 Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
331 Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
332
333 //
334 // Leave critical section and return
335 //
336 gBS->RestoreTPL (OldTpl);
337
338 return EFI_SUCCESS;
339 }
340
341 STATIC
342 EFI_STATUS
343 GopPrivateReadKeyStrokeWorker (
344 IN GOP_PRIVATE_DATA *Private,
345 OUT EFI_KEY_DATA *KeyData
346 )
347 /*++
348
349 Routine Description:
350 Reads the next keystroke from the input device. The WaitForKey Event can
351 be used to test for existance of a keystroke via WaitForEvent () call.
352
353 Arguments:
354 Private - The private structure of WinNt Gop device.
355 KeyData - A pointer to a buffer that is filled in with the keystroke
356 state data for the key that was pressed.
357
358 Returns:
359 EFI_SUCCESS - The keystroke information was returned.
360 EFI_NOT_READY - There was no keystroke data availiable.
361 EFI_DEVICE_ERROR - The keystroke information was not returned due to
362 hardware errors.
363 EFI_INVALID_PARAMETER - KeyData is NULL.
364
365 --*/
366 {
367 EFI_STATUS Status;
368 EFI_TPL OldTpl;
369
370 if (KeyData == NULL) {
371 return EFI_INVALID_PARAMETER;
372 }
373
374 //
375 // Enter critical section
376 //
377 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
378
379 Status = GopPrivateCheckQ (Private);
380 if (!EFI_ERROR (Status)) {
381 //
382 // If a Key press exists try and read it.
383 //
384 Status = GopPrivateDeleteQ (Private, &KeyData->Key);
385 if (!EFI_ERROR (Status)) {
386 //
387 // Record Key shift state and toggle state
388 //
389 if (Private->LeftCtrl) {
390 Private->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
391 }
392 if (Private->RightCtrl) {
393 Private->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
394 }
395 if (Private->LeftAlt) {
396 Private->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
397 }
398 if (Private->RightAlt) {
399 Private->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
400 }
401 if (Private->LeftShift) {
402 Private->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
403 }
404 if (Private->RightShift) {
405 Private->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
406 }
407 if (Private->LeftLogo) {
408 Private->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
409 }
410 if (Private->RightLogo) {
411 Private->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
412 }
413 if (Private->Menu) {
414 Private->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
415 }
416 if (Private->SysReq) {
417 Private->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
418 }
419 if (Private->CapsLock) {
420 Private->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
421 }
422 if (Private->NumLock) {
423 Private->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
424 }
425 if (Private->ScrollLock) {
426 Private->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
427 }
428
429 KeyData->KeyState.KeyShiftState = Private->KeyState.KeyShiftState;
430 KeyData->KeyState.KeyToggleState = Private->KeyState.KeyToggleState;
431
432 Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
433 Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
434
435 //
436 // Leave critical section and return
437 //
438 gBS->RestoreTPL (OldTpl);
439
440 GopPrivateInvokeRegisteredFunction (Private, KeyData);
441
442 return EFI_SUCCESS;
443 }
444 }
445
446 //
447 // Leave critical section and return
448 //
449 gBS->RestoreTPL (OldTpl);
450
451 return Status;
452
453 }
454
455
456 //
457 // Simple Text In implementation.
458 //
459
460
461 /**
462 TODO: Add function description
463
464 @param This TODO: add argument description
465 @param ExtendedVerification TODO: add argument description
466
467 @retval EFI_SUCCESS TODO: Add description for return value
468
469 **/
470 EFI_STATUS
471 EFIAPI
472 WinNtGopSimpleTextInReset (
473 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
474 IN BOOLEAN ExtendedVerification
475 )
476 {
477 GOP_PRIVATE_DATA *Private;
478
479 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
480
481 return GopPrivateResetWorker (Private);
482 }
483
484
485 /**
486 TODO: Add function description
487
488 @param This TODO: add argument description
489 @param Key TODO: add argument description
490
491 @return TODO: add return values
492
493 **/
494 STATIC
495 EFI_STATUS
496 EFIAPI
497 WinNtGopSimpleTextInReadKeyStroke (
498 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
499 OUT EFI_INPUT_KEY *Key
500 )
501 {
502 GOP_PRIVATE_DATA *Private;
503 EFI_STATUS Status;
504 EFI_KEY_DATA KeyData;
505
506 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
507
508 Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);
509 if (EFI_ERROR (Status)) {
510 return Status;
511 }
512
513 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
514
515 return EFI_SUCCESS;
516 }
517
518
519 /**
520 TODO: Add function description
521
522 @param Event TODO: add argument description
523 @param Context TODO: add argument description
524
525 @return TODO: add return values
526
527 **/
528 STATIC
529 VOID
530 EFIAPI
531 WinNtGopSimpleTextInWaitForKey (
532 IN EFI_EVENT Event,
533 IN VOID *Context
534 )
535 {
536 GOP_PRIVATE_DATA *Private;
537 EFI_STATUS Status;
538 EFI_TPL OldTpl;
539
540 Private = (GOP_PRIVATE_DATA *) Context;
541
542 //
543 // Enter critical section
544 //
545 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
546
547 Status = GopPrivateCheckQ (Private);
548 if (!EFI_ERROR (Status)) {
549 //
550 // If a there is a key in the queue signal our event.
551 //
552 gBS->SignalEvent (Event);
553 } else {
554 //
555 // We need to sleep or NT will schedule this thread with such high
556 // priority that WinProc thread will never run and we will not see
557 // keyboard input. This Sleep makes the syste run 10x faster, so don't
558 // remove it.
559 //
560 Private->WinNtThunk->Sleep (1);
561 }
562
563 //
564 // Leave critical section and return
565 //
566 gBS->RestoreTPL (OldTpl);
567 }
568
569 //
570 // Simple Text Input Ex protocol functions
571 //
572
573 STATIC
574 EFI_STATUS
575 EFIAPI
576 WinNtGopSimpleTextInExResetEx (
577 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
578 IN BOOLEAN ExtendedVerification
579 )
580 /*++
581
582 Routine Description:
583 Reset the input device and optionaly run diagnostics
584
585 Arguments:
586 This - Protocol instance pointer.
587 ExtendedVerification - Driver may perform diagnostics on reset.
588
589 Returns:
590 EFI_SUCCESS - The device was reset.
591
592 --*/
593 {
594 GOP_PRIVATE_DATA *Private;
595
596 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
597
598 return GopPrivateResetWorker (Private);
599 }
600
601 STATIC
602 EFI_STATUS
603 EFIAPI
604 WinNtGopSimpleTextInExReadKeyStrokeEx (
605 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
606 OUT EFI_KEY_DATA *KeyData
607 )
608 /*++
609
610 Routine Description:
611 Reads the next keystroke from the input device. The WaitForKey Event can
612 be used to test for existance of a keystroke via WaitForEvent () call.
613
614 Arguments:
615 This - Protocol instance pointer.
616 KeyData - A pointer to a buffer that is filled in with the keystroke
617 state data for the key that was pressed.
618
619 Returns:
620 EFI_SUCCESS - The keystroke information was returned.
621 EFI_NOT_READY - There was no keystroke data availiable.
622 EFI_DEVICE_ERROR - The keystroke information was not returned due to
623 hardware errors.
624 EFI_INVALID_PARAMETER - KeyData is NULL.
625
626 --*/
627 {
628 GOP_PRIVATE_DATA *Private;
629
630 if (KeyData == NULL) {
631 return EFI_INVALID_PARAMETER;
632 }
633
634 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
635
636 return GopPrivateReadKeyStrokeWorker (Private, KeyData);
637
638 }
639
640 EFI_STATUS
641 EFIAPI
642 WinNtGopSimpleTextInExSetState (
643 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
644 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
645 )
646 /*++
647
648 Routine Description:
649 Set certain state for the input device.
650
651 Arguments:
652 This - Protocol instance pointer.
653 KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
654 state for the input device.
655
656 Returns:
657 EFI_SUCCESS - The device state was set successfully.
658 EFI_DEVICE_ERROR - The device is not functioning correctly and could
659 not have the setting adjusted.
660 EFI_UNSUPPORTED - The device does not have the ability to set its state.
661 EFI_INVALID_PARAMETER - KeyToggleState is NULL.
662
663 --*/
664 {
665 EFI_STATUS Status;
666 GOP_PRIVATE_DATA *Private;
667
668 if (KeyToggleState == NULL) {
669 return EFI_INVALID_PARAMETER;
670 }
671
672 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
673
674 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
675 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
676 return EFI_UNSUPPORTED;
677 }
678
679 Private->ScrollLock = FALSE;
680 Private->NumLock = FALSE;
681 Private->CapsLock = FALSE;
682
683 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
684 Private->ScrollLock = TRUE;
685 }
686 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
687 Private->NumLock = TRUE;
688 }
689 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
690 Private->CapsLock = TRUE;
691 }
692
693 Status = GopPrivateUpdateStatusLight (Private);
694 if (EFI_ERROR (Status)) {
695 return EFI_DEVICE_ERROR;
696 }
697
698 Private->KeyState.KeyToggleState = *KeyToggleState;
699 return EFI_SUCCESS;
700
701 }
702
703 EFI_STATUS
704 EFIAPI
705 WinNtGopSimpleTextInExRegisterKeyNotify (
706 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
707 IN EFI_KEY_DATA *KeyData,
708 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
709 OUT EFI_HANDLE *NotifyHandle
710 )
711 /*++
712
713 Routine Description:
714 Register a notification function for a particular keystroke for the input device.
715
716 Arguments:
717 This - Protocol instance pointer.
718 KeyData - A pointer to a buffer that is filled in with the keystroke
719 information data for the key that was pressed.
720 KeyNotificationFunction - Points to the function to be called when the key
721 sequence is typed specified by KeyData.
722 NotifyHandle - Points to the unique handle assigned to the registered notification.
723
724 Returns:
725 EFI_SUCCESS - The notification function was registered successfully.
726 EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
727 EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
728
729 --*/
730 {
731 EFI_STATUS Status;
732 GOP_PRIVATE_DATA *Private;
733 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
734 LIST_ENTRY *Link;
735 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;
736
737 if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {
738 return EFI_INVALID_PARAMETER;
739 }
740
741 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
742
743 //
744 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
745 //
746 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
747 CurrentNotify = CR (
748 Link,
749 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
750 NotifyEntry,
751 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
752 );
753 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
754 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
755 *NotifyHandle = CurrentNotify->NotifyHandle;
756 return EFI_SUCCESS;
757 }
758 }
759 }
760
761 //
762 // Allocate resource to save the notification function
763 //
764 NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));
765 if (NewNotify == NULL) {
766 return EFI_OUT_OF_RESOURCES;
767 }
768
769 NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
770 NewNotify->KeyNotificationFn = KeyNotificationFunction;
771 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
772 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
773
774 //
775 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
776 //
777 Status = gBS->InstallMultipleProtocolInterfaces (
778 &NewNotify->NotifyHandle,
779 &gSimpleTextInExNotifyGuid,
780 NULL,
781 NULL
782 );
783 ASSERT_EFI_ERROR (Status);
784
785 *NotifyHandle = NewNotify->NotifyHandle;
786
787 return EFI_SUCCESS;
788
789 }
790
791 EFI_STATUS
792 EFIAPI
793 WinNtGopSimpleTextInExUnregisterKeyNotify (
794 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
795 IN EFI_HANDLE NotificationHandle
796 )
797 /*++
798
799 Routine Description:
800 Remove a registered notification function from a particular keystroke.
801
802 Arguments:
803 This - Protocol instance pointer.
804 NotificationHandle - The handle of the notification function being unregistered.
805
806 Returns:
807 EFI_SUCCESS - The notification function was unregistered successfully.
808 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
809 EFI_NOT_FOUND - Can not find the matching entry in database.
810
811 --*/
812 {
813 EFI_STATUS Status;
814 GOP_PRIVATE_DATA *Private;
815 LIST_ENTRY *Link;
816 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
817
818 if (NotificationHandle == NULL) {
819 return EFI_INVALID_PARAMETER;
820 }
821
822 Status = gBS->OpenProtocol (
823 NotificationHandle,
824 &gSimpleTextInExNotifyGuid,
825 NULL,
826 NULL,
827 NULL,
828 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
829 );
830 if (EFI_ERROR (Status)) {
831 return EFI_INVALID_PARAMETER;
832 }
833
834 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
835
836 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
837 CurrentNotify = CR (
838 Link,
839 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
840 NotifyEntry,
841 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
842 );
843 if (CurrentNotify->NotifyHandle == NotificationHandle) {
844 //
845 // Remove the notification function from NotifyList and free resources
846 //
847 RemoveEntryList (&CurrentNotify->NotifyEntry);
848 Status = gBS->UninstallMultipleProtocolInterfaces (
849 CurrentNotify->NotifyHandle,
850 &gSimpleTextInExNotifyGuid,
851 NULL,
852 NULL
853 );
854 ASSERT_EFI_ERROR (Status);
855 gBS->FreePool (CurrentNotify);
856 return EFI_SUCCESS;
857 }
858 }
859
860 //
861 // Can not find the specified Notification Handle
862 //
863 return EFI_NOT_FOUND;
864 }
865
866 /**
867 TODO: Add function description
868
869 @param Private TODO: add argument description
870
871 @return TODO: add return values
872
873 **/
874 EFI_STATUS
875 WinNtGopInitializeSimpleTextInForWindow (
876 IN GOP_PRIVATE_DATA *Private
877 )
878 {
879 EFI_STATUS Status;
880
881 GopPrivateCreateQ (Private);
882
883 //
884 // Initialize Simple Text In protoocol
885 //
886 Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;
887 Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;
888
889 Status = gBS->CreateEvent (
890 EVT_NOTIFY_WAIT,
891 TPL_NOTIFY,
892 WinNtGopSimpleTextInWaitForKey,
893 Private,
894 &Private->SimpleTextIn.WaitForKey
895 );
896
897
898 Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;
899 Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;
900 Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;
901 Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;
902 Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;
903
904 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
905
906 InitializeListHead (&Private->NotifyList);
907
908 Status = gBS->CreateEvent (
909 EVT_NOTIFY_WAIT,
910 TPL_NOTIFY,
911 WinNtGopSimpleTextInWaitForKey,
912 Private,
913 &Private->SimpleTextInEx.WaitForKeyEx
914 );
915 ASSERT_EFI_ERROR (Status);
916
917
918 return Status;
919 }
920
921
922
923 /**
924 TODO: Add function description
925
926 @param Private TODO: add argument description
927
928 @retval EFI_SUCCESS TODO: Add description for return value
929
930 **/
931 EFI_STATUS
932 WinNtGopDestroySimpleTextInForWindow (
933 IN GOP_PRIVATE_DATA *Private
934 )
935 {
936 GopPrivateDestroyQ (Private);
937 return EFI_SUCCESS;
938 }