]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
Update the copyright notice format
[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
62cf113f 722 GOP_PRIVATE_DATA *Private;\r
723 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
724 LIST_ENTRY *Link;\r
725 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; \r
726\r
6c295504 727 if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {\r
62cf113f 728 return EFI_INVALID_PARAMETER;\r
6c295504 729 }\r
62cf113f 730\r
731 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
732\r
733 //\r
734 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
735 //\r
736 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
737 CurrentNotify = CR (\r
738 Link, \r
739 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
740 NotifyEntry, \r
741 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
742 );\r
743 if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
744 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
745 *NotifyHandle = CurrentNotify->NotifyHandle;\r
746 return EFI_SUCCESS;\r
747 }\r
748 }\r
749 } \r
750 \r
751 //\r
752 // Allocate resource to save the notification function\r
753 // \r
754 NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));\r
755 if (NewNotify == NULL) {\r
756 return EFI_OUT_OF_RESOURCES;\r
757 }\r
758\r
759 NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; \r
760 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
7fc80d44 761 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
62cf113f 762 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
763 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
764\r
62cf113f 765 *NotifyHandle = NewNotify->NotifyHandle; \r
766 \r
767 return EFI_SUCCESS;\r
768 \r
769}\r
770\r
771EFI_STATUS\r
772EFIAPI\r
773WinNtGopSimpleTextInExUnregisterKeyNotify (\r
774 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
775 IN EFI_HANDLE NotificationHandle\r
776 )\r
777/*++\r
778\r
779 Routine Description:\r
780 Remove a registered notification function from a particular keystroke.\r
781\r
782 Arguments:\r
783 This - Protocol instance pointer. \r
784 NotificationHandle - The handle of the notification function being unregistered.\r
785\r
786 Returns:\r
787 EFI_SUCCESS - The notification function was unregistered successfully.\r
788 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.\r
62cf113f 789 \r
790--*/ \r
791{\r
62cf113f 792 GOP_PRIVATE_DATA *Private;\r
793 LIST_ENTRY *Link;\r
794 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
795\r
796 if (NotificationHandle == NULL) {\r
797 return EFI_INVALID_PARAMETER;\r
798 } \r
0dc99784 799\r
800 if (((WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {\r
801 return EFI_INVALID_PARAMETER;\r
802 } \r
803\r
62cf113f 804 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
805\r
806 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
807 CurrentNotify = CR (\r
808 Link, \r
809 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
810 NotifyEntry, \r
811 WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
812 ); \r
813 if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
814 //\r
815 // Remove the notification function from NotifyList and free resources\r
816 //\r
817 RemoveEntryList (&CurrentNotify->NotifyEntry); \r
7fc80d44 818\r
62cf113f 819 gBS->FreePool (CurrentNotify); \r
820 return EFI_SUCCESS;\r
821 }\r
822 }\r
823\r
824 //\r
825 // Can not find the specified Notification Handle\r
826 //\r
8a67d804 827 return EFI_INVALID_PARAMETER;\r
62cf113f 828}\r
c9fc89a3 829\r
830/**\r
831 TODO: Add function description\r
832\r
833 @param Private TODO: add argument description\r
834\r
835 @return TODO: add return values\r
836\r
837**/\r
838EFI_STATUS\r
839WinNtGopInitializeSimpleTextInForWindow (\r
840 IN GOP_PRIVATE_DATA *Private\r
841 )\r
842{\r
843 EFI_STATUS Status;\r
844\r
845 GopPrivateCreateQ (Private);\r
846\r
847 //\r
848 // Initialize Simple Text In protoocol\r
849 //\r
850 Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;\r
851 Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;\r
852\r
853 Status = gBS->CreateEvent (\r
854 EVT_NOTIFY_WAIT,\r
855 TPL_NOTIFY,\r
856 WinNtGopSimpleTextInWaitForKey,\r
857 Private,\r
858 &Private->SimpleTextIn.WaitForKey\r
859 );\r
860\r
62cf113f 861 \r
862 Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;\r
863 Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;\r
864 Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;\r
865 Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;\r
866 Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;\r
867\r
868 Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);\r
869 \r
870 InitializeListHead (&Private->NotifyList);\r
871\r
872 Status = gBS->CreateEvent (\r
873 EVT_NOTIFY_WAIT,\r
874 TPL_NOTIFY,\r
875 WinNtGopSimpleTextInWaitForKey,\r
876 Private,\r
877 &Private->SimpleTextInEx.WaitForKeyEx\r
878 );\r
879 ASSERT_EFI_ERROR (Status);\r
880\r
881\r
c9fc89a3 882 return Status;\r
883}\r
884\r
885\r
62cf113f 886\r
c9fc89a3 887/**\r
888 TODO: Add function description\r
889\r
890 @param Private TODO: add argument description\r
891\r
892 @retval EFI_SUCCESS TODO: Add description for return value\r
893\r
894**/\r
895EFI_STATUS\r
896WinNtGopDestroySimpleTextInForWindow (\r
897 IN GOP_PRIVATE_DATA *Private\r
898 )\r
899{\r
900 GopPrivateDestroyQ (Private);\r
901 return EFI_SUCCESS;\r
902}\r