]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2KbdTextIn.c
CommitLineData
f713c4fe 1/** @file\r
b6763e03 2 Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
3 provided by Ps2KbdCtrller.c.\r
05fbd06d 4\r
896ae6fc 5Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
180a5a35 6This program and the accompanying materials\r
df0dcb5e 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
05fbd06d 13\r
f8cd287b 14**/\r
05fbd06d 15\r
05fbd06d 16\r
05fbd06d 17#include "Ps2Keyboard.h"\r
18\r
b6763e03 19/**\r
c220787b
RN
20 Check whether the EFI key buffer is empty.\r
21\r
22 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
23\r
24 @retval TRUE The EFI key buffer is empty.\r
25 @retval FALSE The EFI key buffer isn't empty.\r
26**/\r
27BOOLEAN\r
28IsEfikeyBufEmpty (\r
29 IN EFI_KEY_QUEUE *Queue\r
30 )\r
31{\r
32 return (BOOLEAN) (Queue->Head == Queue->Tail);\r
33}\r
34\r
c220787b
RN
35/**\r
36 Read & remove one key data from the EFI key buffer.\r
5829afe3 37\r
c220787b
RN
38 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
39 @param KeyData Receive the key data.\r
40\r
41 @retval EFI_SUCCESS The key data is popped successfully.\r
42 @retval EFI_NOT_READY There is no key data available.\r
b6763e03 43**/\r
05fbd06d 44EFI_STATUS\r
c220787b
RN
45PopEfikeyBufHead (\r
46 IN EFI_KEY_QUEUE *Queue,\r
5829afe3 47 OUT EFI_KEY_DATA *KeyData OPTIONAL\r
b6763e03 48 )\r
49{\r
c220787b
RN
50 if (IsEfikeyBufEmpty (Queue)) {\r
51 return EFI_NOT_READY;\r
52 }\r
b6763e03 53 //\r
c220787b 54 // Retrieve and remove the values\r
b6763e03 55 //\r
5829afe3 56 if (KeyData != NULL) {\r
57 CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));\r
58 }\r
c220787b 59 Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
b6763e03 60 return EFI_SUCCESS;\r
61}\r
05fbd06d 62\r
5829afe3 63/**\r
64 Push one key data to the EFI key buffer.\r
65\r
66 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
67 @param KeyData The key data to push.\r
68**/\r
69VOID\r
70PushEfikeyBufTail (\r
71 IN EFI_KEY_QUEUE *Queue,\r
72 IN EFI_KEY_DATA *KeyData\r
73 )\r
74{\r
75 if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {\r
76 //\r
77 // If Queue is full, pop the one from head.\r
78 //\r
79 PopEfikeyBufHead (Queue, NULL);\r
80 }\r
81 CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));\r
82 Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
83}\r
84\r
bcd70414 85/**\r
b6763e03 86 Judge whether is a registed key\r
87\r
5829afe3 88 @param RegsiteredData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 89 state data for the key that was registered.\r
5829afe3 90 @param InputData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 91 state data for the key that was pressed.\r
bcd70414 92\r
b6763e03 93 @retval TRUE Key be pressed matches a registered key.\r
5829afe3 94 @retval FLASE Match failed.\r
95\r
bcd70414 96**/\r
f3d1e940 97BOOLEAN\r
98IsKeyRegistered (\r
99 IN EFI_KEY_DATA *RegsiteredData,\r
100 IN EFI_KEY_DATA *InputData\r
b6763e03 101 )\r
102\r
103{\r
104 ASSERT (RegsiteredData != NULL && InputData != NULL);\r
5829afe3 105\r
b6763e03 106 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
107 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
5829afe3 108 return FALSE;\r
109 }\r
110\r
b6763e03 111 //\r
112 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
113 //\r
114 if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
115 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
5829afe3 116 return FALSE;\r
117 }\r
b6763e03 118 if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
119 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
5829afe3 120 return FALSE;\r
121 }\r
122\r
b6763e03 123 return TRUE;\r
124\r
125}\r
f3d1e940 126\r
bcd70414 127/**\r
5829afe3 128 Reads the next keystroke from the input device. The WaitForKey Event can\r
bcd70414 129 be used to test for existance of a keystroke via WaitForEvent () call.\r
5829afe3 130\r
b6763e03 131 @param ConsoleInDev Ps2 Keyboard private structure\r
5829afe3 132 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 133 state data for the key that was pressed.\r
f3d1e940 134\r
5829afe3 135\r
b6763e03 136 @retval EFI_SUCCESS The keystroke information was returned.\r
137 @retval EFI_NOT_READY There was no keystroke data availiable.\r
5829afe3 138 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
b6763e03 139 hardware errors.\r
5829afe3 140 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
bcd70414 141\r
142**/\r
f3d1e940 143EFI_STATUS\r
144KeyboardReadKeyStrokeWorker (\r
145 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,\r
146 OUT EFI_KEY_DATA *KeyData\r
147 )\r
f3d1e940 148\r
f3d1e940 149{\r
150 EFI_STATUS Status;\r
151 EFI_TPL OldTpl;\r
5829afe3 152\r
f3d1e940 153 if (KeyData == NULL) {\r
154 return EFI_INVALID_PARAMETER;\r
155 }\r
5829afe3 156\r
f3d1e940 157 //\r
158 // Enter critical section\r
159 //\r
160 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
161\r
c220787b 162 KeyboardTimerHandler (NULL, ConsoleInDev);\r
5829afe3 163\r
c220787b
RN
164 if (ConsoleInDev->KeyboardErr) {\r
165 Status = EFI_DEVICE_ERROR;\r
166 } else {\r
167 Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);\r
896ae6fc
RN
168 if (Status == EFI_NOT_READY) {\r
169 ZeroMem (&KeyData->Key, sizeof (KeyData->Key));\r
170 InitializeKeyState (ConsoleInDev, &KeyData->KeyState);\r
171 }\r
f3d1e940 172 }\r
173\r
c220787b
RN
174 gBS->RestoreTPL (OldTpl);\r
175 return Status;\r
f3d1e940 176}\r
177\r
bcd70414 178/**\r
b6763e03 179 Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()\r
bcd70414 180\r
b6763e03 181 @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
5829afe3 182 @param ExtendedVerification Indicate that the driver may perform a more\r
183 exhaustive verification operation of the device during\r
184 reset, now this par is ignored in this driver\r
bcd70414 185\r
186**/\r
05fbd06d 187EFI_STATUS\r
188EFIAPI\r
189KeyboardEfiReset (\r
190 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
191 IN BOOLEAN ExtendedVerification\r
192 )\r
05fbd06d 193{\r
194 EFI_STATUS Status;\r
195 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
196 EFI_TPL OldTpl;\r
197\r
198 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
199 if (ConsoleIn->KeyboardErr) {\r
200 return EFI_DEVICE_ERROR;\r
201 }\r
202\r
203 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
204 EFI_PROGRESS_CODE,\r
205 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,\r
206 ConsoleIn->DevicePath\r
207 );\r
208\r
209 //\r
210 // Enter critical section\r
211 //\r
212 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
213\r
214 //\r
215 // Call InitKeyboard to initialize the keyboard\r
216 //\r
217 Status = InitKeyboard (ConsoleIn, ExtendedVerification);\r
218 if (EFI_ERROR (Status)) {\r
219 //\r
220 // Leave critical section and return\r
221 //\r
222 gBS->RestoreTPL (OldTpl);\r
223 return EFI_DEVICE_ERROR;\r
224 }\r
05fbd06d 225\r
226 //\r
227 // Leave critical section and return\r
228 //\r
229 gBS->RestoreTPL (OldTpl);\r
230\r
231 //\r
232 // Report the status If a stuck key was detected\r
233 //\r
234 if (KeyReadStatusRegister (ConsoleIn) & 0x01) {\r
235 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
236 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
237 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,\r
238 ConsoleIn->DevicePath\r
239 );\r
240 }\r
241 //\r
242 // Report the status If keyboard is locked\r
243 //\r
f713c4fe 244 if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {\r
05fbd06d 245 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
246 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
247 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,\r
248 ConsoleIn->DevicePath\r
249 );\r
250 }\r
251\r
252 return EFI_SUCCESS;\r
253}\r
254\r
bcd70414 255/**\r
b6763e03 256 Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().\r
bcd70414 257\r
258 @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
5829afe3 259 @param Key The output buffer for key value\r
bcd70414 260\r
261 @retval EFI_SUCCESS success to read key stroke\r
262**/\r
05fbd06d 263EFI_STATUS\r
264EFIAPI\r
265KeyboardReadKeyStroke (\r
266 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
267 OUT EFI_INPUT_KEY *Key\r
268 )\r
05fbd06d 269{\r
270 EFI_STATUS Status;\r
271 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
f3d1e940 272 EFI_KEY_DATA KeyData;\r
05fbd06d 273\r
274 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
0a6f4824 275\r
5829afe3 276 //\r
277 // Considering if the partial keystroke is enabled, there maybe a partial\r
278 // keystroke in the queue, so here skip the partial keystroke and get the\r
279 // next key from the queue\r
280 //\r
281 while (1) {\r
282 //\r
283 // If there is no pending key, then return.\r
284 //\r
285 Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);\r
286 if (EFI_ERROR (Status)) {\r
287 return Status;\r
288 }\r
289 //\r
290 // If it is partial keystroke, skip it.\r
291 //\r
292 if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
293 continue;\r
294 }\r
9891f791
RN
295 //\r
296 // Translate the CTRL-Alpha characters to their corresponding control value\r
297 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
298 //\r
299 if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
300 if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
301 KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
302 } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
303 KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
304 }\r
305 }\r
306\r
5829afe3 307 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
308 return EFI_SUCCESS;\r
309 }\r
05fbd06d 310}\r
311\r
bcd70414 312/**\r
313 Event notification function for SIMPLE_TEXT_IN.WaitForKey event\r
314 Signal the event if there is key available\r
315\r
316 @param Event the event object\r
317 @param Context waitting context\r
318\r
319**/\r
05fbd06d 320VOID\r
321EFIAPI\r
322KeyboardWaitForKey (\r
323 IN EFI_EVENT Event,\r
324 IN VOID *Context\r
325 )\r
05fbd06d 326{\r
c220787b
RN
327 EFI_TPL OldTpl;\r
328 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
5829afe3 329 EFI_KEY_DATA KeyData;\r
05fbd06d 330\r
c220787b 331 ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
05fbd06d 332\r
333 //\r
334 // Enter critical section\r
335 //\r
336 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
5829afe3 337\r
c220787b 338 KeyboardTimerHandler (NULL, ConsoleIn);\r
05fbd06d 339\r
c220787b 340 if (!ConsoleIn->KeyboardErr) {\r
05fbd06d 341 //\r
5829afe3 342 // WaitforKey doesn't suppor the partial key.\r
343 // Considering if the partial keystroke is enabled, there maybe a partial\r
344 // keystroke in the queue, so here skip the partial keystroke and get the\r
345 // next key from the queue\r
05fbd06d 346 //\r
5829afe3 347 while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {\r
348 CopyMem (\r
349 &KeyData,\r
350 &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),\r
351 sizeof (EFI_KEY_DATA)\r
352 );\r
353 if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
354 PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);\r
355 continue;\r
356 }\r
357 //\r
358 // if there is pending value key, signal the event.\r
359 //\r
c220787b 360 gBS->SignalEvent (Event);\r
5829afe3 361 break;\r
c220787b 362 }\r
05fbd06d 363 }\r
364 //\r
365 // Leave critical section and return\r
366 //\r
367 gBS->RestoreTPL (OldTpl);\r
05fbd06d 368}\r
369\r
bcd70414 370/**\r
371 Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event\r
372 Signal the event if there is key available\r
373\r
374 @param Event event object\r
375 @param Context waiting context\r
376\r
377**/\r
f3d1e940 378VOID\r
379EFIAPI\r
380KeyboardWaitForKeyEx (\r
381 IN EFI_EVENT Event,\r
382 IN VOID *Context\r
383 )\r
f3d1e940 384\r
f3d1e940 385{\r
c220787b 386 KeyboardWaitForKey (Event, Context);\r
f3d1e940 387}\r
388\r
bcd70414 389/**\r
390 Reset the input device and optionaly run diagnostics\r
391\r
b6763e03 392 @param This Protocol instance pointer.\r
393 @param ExtendedVerification Driver may perform diagnostics on reset.\r
bcd70414 394\r
b6763e03 395 @retval EFI_SUCCESS The device was reset.\r
5829afe3 396 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
bcd70414 397 not be reset.\r
398\r
399**/\r
f3d1e940 400EFI_STATUS\r
401EFIAPI\r
402KeyboardEfiResetEx (\r
403 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
404 IN BOOLEAN ExtendedVerification\r
405 )\r
f3d1e940 406\r
f3d1e940 407{\r
f3d1e940 408 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
f3d1e940 409\r
5829afe3 410 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
f3d1e940 411\r
c220787b 412 return ConsoleInDev->ConIn.Reset (\r
5829afe3 413 &ConsoleInDev->ConIn,\r
c220787b
RN
414 ExtendedVerification\r
415 );\r
f3d1e940 416}\r
417\r
bcd70414 418/**\r
5829afe3 419 Reads the next keystroke from the input device. The WaitForKey Event can\r
f3d1e940 420 be used to test for existance of a keystroke via WaitForEvent () call.\r
421\r
bcd70414 422\r
b6763e03 423 @param This Protocol instance pointer.\r
5829afe3 424 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 425 state data for the key that was pressed.\r
f3d1e940 426\r
b6763e03 427 @retval EFI_SUCCESS The keystroke information was returned.\r
428 @retval EFI_NOT_READY There was no keystroke data availiable.\r
5829afe3 429 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
b6763e03 430 hardware errors.\r
5829afe3 431 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
bcd70414 432\r
433**/\r
434EFI_STATUS\r
435EFIAPI\r
436KeyboardReadKeyStrokeEx (\r
437 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
438 OUT EFI_KEY_DATA *KeyData\r
439 )\r
f3d1e940 440\r
f3d1e940 441{\r
442 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
443\r
444 if (KeyData == NULL) {\r
445 return EFI_INVALID_PARAMETER;\r
446 }\r
447\r
448 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
449 return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);\r
f3d1e940 450}\r
451\r
bcd70414 452/**\r
453 Set certain state for the input device.\r
454\r
b6763e03 455 @param This Protocol instance pointer.\r
5829afe3 456 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
b6763e03 457 state for the input device.\r
bcd70414 458\r
b6763e03 459 @retval EFI_SUCCESS The device state was set successfully.\r
5829afe3 460 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could\r
b6763e03 461 not have the setting adjusted.\r
462 @retval EFI_UNSUPPORTED The device does not have the ability to set its state.\r
5829afe3 463 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
bcd70414 464\r
5829afe3 465**/\r
f3d1e940 466EFI_STATUS\r
467EFIAPI\r
468KeyboardSetState (\r
469 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
470 IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
471 )\r
f3d1e940 472\r
f3d1e940 473{\r
474 EFI_STATUS Status;\r
475 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
476 EFI_TPL OldTpl;\r
477\r
478 if (KeyToggleState == NULL) {\r
479 return EFI_INVALID_PARAMETER;\r
480 }\r
5829afe3 481\r
f3d1e940 482 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
483\r
484 //\r
485 // Enter critical section\r
486 //\r
487 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
488\r
489 if (ConsoleInDev->KeyboardErr) {\r
490 Status = EFI_DEVICE_ERROR;\r
491 goto Exit;\r
492 }\r
493\r
c220787b 494 if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
f3d1e940 495 Status = EFI_UNSUPPORTED;\r
496 goto Exit;\r
497 }\r
5829afe3 498\r
f3d1e940 499 //\r
500 // Update the status light\r
501 //\r
5829afe3 502 ConsoleInDev->ScrollLock = FALSE;\r
503 ConsoleInDev->NumLock = FALSE;\r
504 ConsoleInDev->CapsLock = FALSE;\r
505 ConsoleInDev->IsSupportPartialKey = FALSE;\r
f3d1e940 506\r
507 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
508 ConsoleInDev->ScrollLock = TRUE;\r
5829afe3 509 }\r
f3d1e940 510 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
511 ConsoleInDev->NumLock = TRUE;\r
512 }\r
513 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
514 ConsoleInDev->CapsLock = TRUE;\r
515 }\r
5829afe3 516 if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
517 ConsoleInDev->IsSupportPartialKey = TRUE;\r
518 }\r
f3d1e940 519\r
520 Status = UpdateStatusLights (ConsoleInDev);\r
521 if (EFI_ERROR (Status)) {\r
5829afe3 522 Status = EFI_DEVICE_ERROR;\r
f3d1e940 523 }\r
524\r
5829afe3 525Exit:\r
f3d1e940 526 //\r
527 // Leave critical section and return\r
528 //\r
529 gBS->RestoreTPL (OldTpl);\r
530\r
531 return Status;\r
532\r
533}\r
bcd70414 534\r
535/**\r
536 Register a notification function for a particular keystroke for the input device.\r
537\r
b6763e03 538 @param This Protocol instance pointer.\r
5829afe3 539 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
cc9a430c
DB
540 information data for the key that was pressed. If KeyData.Key,\r
541 KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState\r
542 are 0, then any incomplete keystroke will trigger a notification of\r
543 the KeyNotificationFunction.\r
5829afe3 544 @param KeyNotificationFunction Points to the function to be called when the key\r
cc9a430c
DB
545 sequence is typed specified by KeyData. This notification function\r
546 should be called at <=TPL_CALLBACK.\r
5829afe3 547 @param NotifyHandle Points to the unique handle assigned to the registered notification.\r
bcd70414 548\r
b6763e03 549 @retval EFI_SUCCESS The notification function was registered successfully.\r
550 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.\r
5829afe3 551 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.\r
552\r
553**/\r
f3d1e940 554EFI_STATUS\r
555EFIAPI\r
556KeyboardRegisterKeyNotify (\r
557 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
558 IN EFI_KEY_DATA *KeyData,\r
559 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
402e4a9d 560 OUT VOID **NotifyHandle\r
f3d1e940 561 )\r
f3d1e940 562{\r
563 EFI_STATUS Status;\r
564 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
565 EFI_TPL OldTpl;\r
566 LIST_ENTRY *Link;\r
5829afe3 567 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
f3d1e940 568 KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
569\r
570 if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
571 return EFI_INVALID_PARAMETER;\r
572 }\r
5829afe3 573\r
f3d1e940 574 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
575\r
576 //\r
577 // Enter critical section\r
578 //\r
579 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
580\r
581 //\r
582 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
583 //\r
584 for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {\r
585 CurrentNotify = CR (\r
5829afe3 586 Link,\r
587 KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
588 NotifyEntry,\r
f3d1e940 589 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
590 );\r
5829afe3 591 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
f3d1e940 592 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
402e4a9d 593 *NotifyHandle = CurrentNotify;\r
f3d1e940 594 Status = EFI_SUCCESS;\r
595 goto Exit;\r
596 }\r
597 }\r
5829afe3 598 }\r
599\r
f3d1e940 600 //\r
601 // Allocate resource to save the notification function\r
5829afe3 602 //\r
f3d1e940 603 NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
604 if (NewNotify == NULL) {\r
605 Status = EFI_OUT_OF_RESOURCES;\r
606 goto Exit;\r
607 }\r
608\r
5829afe3 609 NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
f3d1e940 610 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
611 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
612 InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);\r
613\r
402e4a9d 614 *NotifyHandle = NewNotify;\r
f3d1e940 615 Status = EFI_SUCCESS;\r
616\r
617Exit:\r
618 //\r
619 // Leave critical section and return\r
620 //\r
621 gBS->RestoreTPL (OldTpl);\r
5829afe3 622 return Status;\r
f3d1e940 623\r
624}\r
625\r
bcd70414 626/**\r
627 Remove a registered notification function from a particular keystroke.\r
628\r
5829afe3 629 @param This Protocol instance pointer.\r
b6763e03 630 @param NotificationHandle The handle of the notification function being unregistered.\r
bcd70414 631\r
5829afe3 632\r
b6763e03 633 @retval EFI_SUCCESS The notification function was unregistered successfully.\r
634 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
5829afe3 635\r
636**/\r
f3d1e940 637EFI_STATUS\r
638EFIAPI\r
639KeyboardUnregisterKeyNotify (\r
640 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
402e4a9d 641 IN VOID *NotificationHandle\r
f3d1e940 642 )\r
f3d1e940 643{\r
644 EFI_STATUS Status;\r
645 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
646 EFI_TPL OldTpl;\r
647 LIST_ENTRY *Link;\r
5829afe3 648 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
f3d1e940 649\r
650 if (NotificationHandle == NULL) {\r
651 return EFI_INVALID_PARAMETER;\r
5829afe3 652 }\r
0dc99784 653\r
f3d1e940 654 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
5829afe3 655\r
f3d1e940 656 //\r
657 // Enter critical section\r
658 //\r
5829afe3 659 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
f3d1e940 660\r
661 for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {\r
662 CurrentNotify = CR (\r
5829afe3 663 Link,\r
664 KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
665 NotifyEntry,\r
f3d1e940 666 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
5829afe3 667 );\r
402e4a9d 668 if (CurrentNotify == NotificationHandle) {\r
f3d1e940 669 //\r
670 // Remove the notification function from NotifyList and free resources\r
671 //\r
5829afe3 672 RemoveEntryList (&CurrentNotify->NotifyEntry);\r
673\r
674 gBS->FreePool (CurrentNotify);\r
f3d1e940 675 Status = EFI_SUCCESS;\r
676 goto Exit;\r
677 }\r
678 }\r
679\r
680 //\r
681 // Can not find the specified Notification Handle\r
682 //\r
8a67d804 683 Status = EFI_INVALID_PARAMETER;\r
f3d1e940 684Exit:\r
685 //\r
686 // Leave critical section and return\r
687 //\r
688 gBS->RestoreTPL (OldTpl);\r
689 return Status;\r
690}\r
691\r
7863d11c
SZ
692/**\r
693 Process key notify.\r
694\r
695 @param Event Indicates the event that invoke this function.\r
696 @param Context Indicates the calling context.\r
697**/\r
698VOID\r
699EFIAPI\r
700KeyNotifyProcessHandler (\r
701 IN EFI_EVENT Event,\r
702 IN VOID *Context\r
703 )\r
704{\r
705 EFI_STATUS Status;\r
706 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
707 EFI_KEY_DATA KeyData;\r
708 LIST_ENTRY *Link;\r
709 LIST_ENTRY *NotifyList;\r
710 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
711 EFI_TPL OldTpl;\r
712\r
713 ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
714\r
715 //\r
716 // Invoke notification functions.\r
717 //\r
718 NotifyList = &ConsoleIn->NotifyList;\r
719 while (TRUE) {\r
720 //\r
721 // Enter critical section\r
0a6f4824 722 //\r
7863d11c
SZ
723 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
724 Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);\r
725 //\r
726 // Leave critical section\r
727 //\r
728 gBS->RestoreTPL (OldTpl);\r
729 if (EFI_ERROR (Status)) {\r
730 break;\r
731 }\r
732 for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
733 CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
734 if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
735 CurrentNotify->KeyNotificationFn (&KeyData);\r
736 }\r
737 }\r
738 }\r
739}\r
740\r