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