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