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