]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
add check for invalid handle.
[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 BOOLEAN
162 GopPrivateIsKeyRegistered (
163 IN EFI_KEY_DATA *RegsiteredData,
164 IN EFI_KEY_DATA *InputData
165 )
166 /*++
167
168 Routine Description:
169
170 Arguments:
171
172 RegsiteredData - A pointer to a buffer that is filled in with the keystroke
173 state data for the key that was registered.
174 InputData - A pointer to a buffer that is filled in with the keystroke
175 state data for the key that was pressed.
176
177 Returns:
178 TRUE - Key be pressed matches a registered key.
179 FLASE - Match failed.
180
181 --*/
182 {
183 ASSERT (RegsiteredData != NULL && InputData != NULL);
184
185 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
186 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
187 return FALSE;
188 }
189
190 //
191 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
192 //
193 if (RegsiteredData->KeyState.KeyShiftState != 0 &&
194 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
195 return FALSE;
196 }
197 if (RegsiteredData->KeyState.KeyToggleState != 0 &&
198 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
199 return FALSE;
200 }
201
202 return TRUE;
203
204 }
205
206
207 VOID
208 GopPrivateInvokeRegisteredFunction (
209 IN GOP_PRIVATE_DATA *Private,
210 IN EFI_KEY_DATA *KeyData
211 )
212 /*++
213
214 Routine Description:
215
216 This function updates the status light of NumLock, ScrollLock and CapsLock.
217
218 Arguments:
219
220 Private - The private structure of WinNt Gop device.
221 KeyData - A pointer to a buffer that is filled in with the keystroke
222 state data for the key that was pressed.
223
224 Returns:
225
226 EFI_SUCCESS - The status light is updated successfully.
227
228 --*/
229 {
230 LIST_ENTRY *Link;
231 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
232
233 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
234 CurrentNotify = CR (
235 Link,
236 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
237 NotifyEntry,
238 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
239 );
240 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
241 CurrentNotify->KeyNotificationFn (KeyData);
242 }
243 }
244 }
245
246 EFI_STATUS
247 GopPrivateUpdateStatusLight (
248 IN GOP_PRIVATE_DATA *Private
249 )
250 /*++
251
252 Routine Description:
253
254 This function updates the status light of NumLock, ScrollLock and CapsLock.
255
256 Arguments:
257
258 Private - The private structure of WinNt console In/Out.
259
260 Returns:
261
262 EFI_SUCCESS - The status light is updated successfully.
263
264 --*/
265 {
266 //
267 // BUGBUG:Only SendInput/keybd_event function can toggle
268 // NumLock, CapsLock and ScrollLock keys.
269 // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.
270 // Thus, return immediately without operation.
271 //
272 return EFI_SUCCESS;
273
274 }
275
276
277 EFI_STATUS
278 GopPrivateResetWorker (
279 IN GOP_PRIVATE_DATA *Private
280 )
281 /*++
282
283 Routine Description:
284
285 This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().
286
287 Arguments:
288
289 Private - WinNT GOP private structure
290
291 Returns:
292
293 EFI_SUCCESS - Reset successfully
294
295 --*/
296 {
297 EFI_INPUT_KEY Key;
298 EFI_TPL OldTpl;
299
300 //
301 // Enter critical section
302 //
303 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
304
305 //
306 // A reset is draining the Queue
307 //
308 while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)
309 ;
310
311 Private->LeftShift = FALSE;
312 Private->RightShift = FALSE;
313 Private->LeftAlt = FALSE;
314 Private->RightAlt = FALSE;
315 Private->LeftCtrl = FALSE;
316 Private->RightCtrl = FALSE;
317 Private->LeftLogo = FALSE;
318 Private->RightLogo = FALSE;
319 Private->Menu = FALSE;
320 Private->SysReq = FALSE;
321
322 Private->CapsLock = FALSE;
323 Private->NumLock = FALSE;
324 Private->ScrollLock = FALSE;
325
326 Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
327 Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
328
329 //
330 // Leave critical section and return
331 //
332 gBS->RestoreTPL (OldTpl);
333
334 return EFI_SUCCESS;
335 }
336
337 EFI_STATUS
338 GopPrivateReadKeyStrokeWorker (
339 IN GOP_PRIVATE_DATA *Private,
340 OUT EFI_KEY_DATA *KeyData
341 )
342 /*++
343
344 Routine Description:
345 Reads the next keystroke from the input device. The WaitForKey Event can
346 be used to test for existance of a keystroke via WaitForEvent () call.
347
348 Arguments:
349 Private - The private structure of WinNt Gop device.
350 KeyData - A pointer to a buffer that is filled in with the keystroke
351 state data for the key that was pressed.
352
353 Returns:
354 EFI_SUCCESS - The keystroke information was returned.
355 EFI_NOT_READY - There was no keystroke data availiable.
356 EFI_DEVICE_ERROR - The keystroke information was not returned due to
357 hardware errors.
358 EFI_INVALID_PARAMETER - KeyData is NULL.
359
360 --*/
361 {
362 EFI_STATUS Status;
363 EFI_TPL OldTpl;
364
365 if (KeyData == NULL) {
366 return EFI_INVALID_PARAMETER;
367 }
368
369 //
370 // Enter critical section
371 //
372 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
373
374 Status = GopPrivateCheckQ (Private);
375 if (!EFI_ERROR (Status)) {
376 //
377 // If a Key press exists try and read it.
378 //
379 Status = GopPrivateDeleteQ (Private, &KeyData->Key);
380 if (!EFI_ERROR (Status)) {
381 //
382 // Record Key shift state and toggle state
383 //
384 if (Private->LeftCtrl) {
385 Private->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
386 }
387 if (Private->RightCtrl) {
388 Private->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
389 }
390 if (Private->LeftAlt) {
391 Private->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
392 }
393 if (Private->RightAlt) {
394 Private->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
395 }
396 if (Private->LeftShift) {
397 Private->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
398 }
399 if (Private->RightShift) {
400 Private->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
401 }
402 if (Private->LeftLogo) {
403 Private->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
404 }
405 if (Private->RightLogo) {
406 Private->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
407 }
408 if (Private->Menu) {
409 Private->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
410 }
411 if (Private->SysReq) {
412 Private->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
413 }
414 if (Private->CapsLock) {
415 Private->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
416 }
417 if (Private->NumLock) {
418 Private->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
419 }
420 if (Private->ScrollLock) {
421 Private->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
422 }
423
424 KeyData->KeyState.KeyShiftState = Private->KeyState.KeyShiftState;
425 KeyData->KeyState.KeyToggleState = Private->KeyState.KeyToggleState;
426
427 Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
428 Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
429
430 //
431 // Leave critical section and return
432 //
433 gBS->RestoreTPL (OldTpl);
434
435 GopPrivateInvokeRegisteredFunction (Private, KeyData);
436
437 return EFI_SUCCESS;
438 }
439 }
440
441 //
442 // Leave critical section and return
443 //
444 gBS->RestoreTPL (OldTpl);
445
446 return Status;
447
448 }
449
450
451 //
452 // Simple Text In implementation.
453 //
454
455
456 /**
457 TODO: Add function description
458
459 @param This TODO: add argument description
460 @param ExtendedVerification TODO: add argument description
461
462 @retval EFI_SUCCESS TODO: Add description for return value
463
464 **/
465 EFI_STATUS
466 EFIAPI
467 WinNtGopSimpleTextInReset (
468 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
469 IN BOOLEAN ExtendedVerification
470 )
471 {
472 GOP_PRIVATE_DATA *Private;
473
474 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
475
476 return GopPrivateResetWorker (Private);
477 }
478
479
480 /**
481 TODO: Add function description
482
483 @param This TODO: add argument description
484 @param Key TODO: add argument description
485
486 @return TODO: add return values
487
488 **/
489 EFI_STATUS
490 EFIAPI
491 WinNtGopSimpleTextInReadKeyStroke (
492 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
493 OUT EFI_INPUT_KEY *Key
494 )
495 {
496 GOP_PRIVATE_DATA *Private;
497 EFI_STATUS Status;
498 EFI_KEY_DATA KeyData;
499
500 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
501
502 Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);
503 if (EFI_ERROR (Status)) {
504 return Status;
505 }
506
507 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
508
509 return EFI_SUCCESS;
510 }
511
512
513 /**
514 TODO: Add function description
515
516 @param Event TODO: add argument description
517 @param Context TODO: add argument description
518
519 @return TODO: add return values
520
521 **/
522 VOID
523 EFIAPI
524 WinNtGopSimpleTextInWaitForKey (
525 IN EFI_EVENT Event,
526 IN VOID *Context
527 )
528 {
529 GOP_PRIVATE_DATA *Private;
530 EFI_STATUS Status;
531 EFI_TPL OldTpl;
532
533 Private = (GOP_PRIVATE_DATA *) Context;
534
535 //
536 // Enter critical section
537 //
538 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
539
540 Status = GopPrivateCheckQ (Private);
541 if (!EFI_ERROR (Status)) {
542 //
543 // If a there is a key in the queue signal our event.
544 //
545 gBS->SignalEvent (Event);
546 } else {
547 //
548 // We need to sleep or NT will schedule this thread with such high
549 // priority that WinProc thread will never run and we will not see
550 // keyboard input. This Sleep makes the syste run 10x faster, so don't
551 // remove it.
552 //
553 Private->WinNtThunk->Sleep (1);
554 }
555
556 //
557 // Leave critical section and return
558 //
559 gBS->RestoreTPL (OldTpl);
560 }
561
562 //
563 // Simple Text Input Ex protocol functions
564 //
565
566 EFI_STATUS
567 EFIAPI
568 WinNtGopSimpleTextInExResetEx (
569 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
570 IN BOOLEAN ExtendedVerification
571 )
572 /*++
573
574 Routine Description:
575 Reset the input device and optionaly run diagnostics
576
577 Arguments:
578 This - Protocol instance pointer.
579 ExtendedVerification - Driver may perform diagnostics on reset.
580
581 Returns:
582 EFI_SUCCESS - The device was reset.
583
584 --*/
585 {
586 GOP_PRIVATE_DATA *Private;
587
588 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
589
590 return GopPrivateResetWorker (Private);
591 }
592
593 EFI_STATUS
594 EFIAPI
595 WinNtGopSimpleTextInExReadKeyStrokeEx (
596 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
597 OUT EFI_KEY_DATA *KeyData
598 )
599 /*++
600
601 Routine Description:
602 Reads the next keystroke from the input device. The WaitForKey Event can
603 be used to test for existance of a keystroke via WaitForEvent () call.
604
605 Arguments:
606 This - Protocol instance pointer.
607 KeyData - A pointer to a buffer that is filled in with the keystroke
608 state data for the key that was pressed.
609
610 Returns:
611 EFI_SUCCESS - The keystroke information was returned.
612 EFI_NOT_READY - There was no keystroke data availiable.
613 EFI_DEVICE_ERROR - The keystroke information was not returned due to
614 hardware errors.
615 EFI_INVALID_PARAMETER - KeyData is NULL.
616
617 --*/
618 {
619 GOP_PRIVATE_DATA *Private;
620
621 if (KeyData == NULL) {
622 return EFI_INVALID_PARAMETER;
623 }
624
625 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
626
627 return GopPrivateReadKeyStrokeWorker (Private, KeyData);
628
629 }
630
631 EFI_STATUS
632 EFIAPI
633 WinNtGopSimpleTextInExSetState (
634 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
635 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
636 )
637 /*++
638
639 Routine Description:
640 Set certain state for the input device.
641
642 Arguments:
643 This - Protocol instance pointer.
644 KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
645 state for the input device.
646
647 Returns:
648 EFI_SUCCESS - The device state was set successfully.
649 EFI_DEVICE_ERROR - The device is not functioning correctly and could
650 not have the setting adjusted.
651 EFI_UNSUPPORTED - The device does not have the ability to set its state.
652 EFI_INVALID_PARAMETER - KeyToggleState is NULL.
653
654 --*/
655 {
656 EFI_STATUS Status;
657 GOP_PRIVATE_DATA *Private;
658
659 if (KeyToggleState == NULL) {
660 return EFI_INVALID_PARAMETER;
661 }
662
663 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
664
665 if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
666 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
667 return EFI_UNSUPPORTED;
668 }
669
670 Private->ScrollLock = FALSE;
671 Private->NumLock = FALSE;
672 Private->CapsLock = FALSE;
673
674 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
675 Private->ScrollLock = TRUE;
676 }
677 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
678 Private->NumLock = TRUE;
679 }
680 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
681 Private->CapsLock = TRUE;
682 }
683
684 Status = GopPrivateUpdateStatusLight (Private);
685 if (EFI_ERROR (Status)) {
686 return EFI_DEVICE_ERROR;
687 }
688
689 Private->KeyState.KeyToggleState = *KeyToggleState;
690 return EFI_SUCCESS;
691
692 }
693
694 EFI_STATUS
695 EFIAPI
696 WinNtGopSimpleTextInExRegisterKeyNotify (
697 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
698 IN EFI_KEY_DATA *KeyData,
699 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
700 OUT EFI_HANDLE *NotifyHandle
701 )
702 /*++
703
704 Routine Description:
705 Register a notification function for a particular keystroke for the input device.
706
707 Arguments:
708 This - Protocol instance pointer.
709 KeyData - A pointer to a buffer that is filled in with the keystroke
710 information data for the key that was pressed.
711 KeyNotificationFunction - Points to the function to be called when the key
712 sequence is typed specified by KeyData.
713 NotifyHandle - Points to the unique handle assigned to the registered notification.
714
715 Returns:
716 EFI_SUCCESS - The notification function was registered successfully.
717 EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
718 EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
719
720 --*/
721 {
722 GOP_PRIVATE_DATA *Private;
723 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
724 LIST_ENTRY *Link;
725 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;
726
727 if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {
728 return EFI_INVALID_PARAMETER;
729 }
730
731 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
732
733 //
734 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
735 //
736 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
737 CurrentNotify = CR (
738 Link,
739 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
740 NotifyEntry,
741 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
742 );
743 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
744 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
745 *NotifyHandle = CurrentNotify->NotifyHandle;
746 return EFI_SUCCESS;
747 }
748 }
749 }
750
751 //
752 // Allocate resource to save the notification function
753 //
754 NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));
755 if (NewNotify == NULL) {
756 return EFI_OUT_OF_RESOURCES;
757 }
758
759 NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
760 NewNotify->KeyNotificationFn = KeyNotificationFunction;
761 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;
762 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
763 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
764
765 *NotifyHandle = NewNotify->NotifyHandle;
766
767 return EFI_SUCCESS;
768
769 }
770
771 EFI_STATUS
772 EFIAPI
773 WinNtGopSimpleTextInExUnregisterKeyNotify (
774 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
775 IN EFI_HANDLE NotificationHandle
776 )
777 /*++
778
779 Routine Description:
780 Remove a registered notification function from a particular keystroke.
781
782 Arguments:
783 This - Protocol instance pointer.
784 NotificationHandle - The handle of the notification function being unregistered.
785
786 Returns:
787 EFI_SUCCESS - The notification function was unregistered successfully.
788 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
789 EFI_NOT_FOUND - Can not find the matching entry in database.
790
791 --*/
792 {
793 GOP_PRIVATE_DATA *Private;
794 LIST_ENTRY *Link;
795 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
796
797 if (NotificationHandle == NULL) {
798 return EFI_INVALID_PARAMETER;
799 }
800
801 if (((WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {
802 return EFI_INVALID_PARAMETER;
803 }
804
805 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
806
807 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
808 CurrentNotify = CR (
809 Link,
810 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
811 NotifyEntry,
812 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
813 );
814 if (CurrentNotify->NotifyHandle == NotificationHandle) {
815 //
816 // Remove the notification function from NotifyList and free resources
817 //
818 RemoveEntryList (&CurrentNotify->NotifyEntry);
819
820 gBS->FreePool (CurrentNotify);
821 return EFI_SUCCESS;
822 }
823 }
824
825 //
826 // Can not find the specified Notification Handle
827 //
828 return EFI_NOT_FOUND;
829 }
830
831 /**
832 TODO: Add function description
833
834 @param Private TODO: add argument description
835
836 @return TODO: add return values
837
838 **/
839 EFI_STATUS
840 WinNtGopInitializeSimpleTextInForWindow (
841 IN GOP_PRIVATE_DATA *Private
842 )
843 {
844 EFI_STATUS Status;
845
846 GopPrivateCreateQ (Private);
847
848 //
849 // Initialize Simple Text In protoocol
850 //
851 Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;
852 Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;
853
854 Status = gBS->CreateEvent (
855 EVT_NOTIFY_WAIT,
856 TPL_NOTIFY,
857 WinNtGopSimpleTextInWaitForKey,
858 Private,
859 &Private->SimpleTextIn.WaitForKey
860 );
861
862
863 Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;
864 Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;
865 Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;
866 Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;
867 Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;
868
869 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
870
871 InitializeListHead (&Private->NotifyList);
872
873 Status = gBS->CreateEvent (
874 EVT_NOTIFY_WAIT,
875 TPL_NOTIFY,
876 WinNtGopSimpleTextInWaitForKey,
877 Private,
878 &Private->SimpleTextInEx.WaitForKeyEx
879 );
880 ASSERT_EFI_ERROR (Status);
881
882
883 return Status;
884 }
885
886
887
888 /**
889 TODO: Add function description
890
891 @param Private TODO: add argument description
892
893 @retval EFI_SUCCESS TODO: Add description for return value
894
895 **/
896 EFI_STATUS
897 WinNtGopDestroySimpleTextInForWindow (
898 IN GOP_PRIVATE_DATA *Private
899 )
900 {
901 GopPrivateDestroyQ (Private);
902 return EFI_SUCCESS;
903 }