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