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