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