1 /** @file
2 
3 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
4 Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
5 
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef _VIRTUAL_KEYBOARD_H_
11 #define _VIRTUAL_KEYBOARD_H_
12 
13 
14 #include <Guid/StatusCodeDataTypeId.h>
15 #include <Protocol/DevicePath.h>
16 #include <Protocol/PlatformVirtualKeyboard.h>
17 #include <Protocol/SimpleTextIn.h>
18 #include <Protocol/SimpleTextInEx.h>
19 
20 #include <Library/BaseLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/IoLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/ReportStatusCodeLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiDriverEntryPoint.h>
29 #include <Library/UefiLib.h>
30 
31 //
32 // Driver Binding Externs
33 //
34 extern EFI_DRIVER_BINDING_PROTOCOL  gVirtualKeyboardDriverBinding;
35 extern EFI_COMPONENT_NAME_PROTOCOL  gVirtualKeyboardComponentName;
36 extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;
37 
38 
39 //
40 // VIRTUAL Keyboard Defines
41 //
42 #define CHAR_SCANCODE                        0xe0
43 #define CHAR_ESC                             0x1b
44 
45 #define KEYBOARD_TIMEOUT                     65536   // 0.07s
46 #define KEYBOARD_WAITFORVALUE_TIMEOUT        1000000 // 1s
47 #define KEYBOARD_BAT_TIMEOUT                 4000000 // 4s
48 #define KEYBOARD_TIMER_INTERVAL              500000  // 0.5s
49 
50 #define QUEUE_MAX_COUNT                      32
51 
52 #define KEYBOARD_SCAN_CODE_MAX_COUNT         32
53 
54 //
55 // VIRTUAL Keyboard Device Structure
56 //
57 #define VIRTUAL_KEYBOARD_DEV_SIGNATURE SIGNATURE_32 ('V', 'K', 'B', 'D')
58 #define VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('v', 'k', 'c', 'n')
59 
60 typedef struct _VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY {
61   UINTN                                      Signature;
62   EFI_KEY_DATA                               KeyData;
63   EFI_KEY_NOTIFY_FUNCTION                    KeyNotificationFn;
64   LIST_ENTRY                                 NotifyEntry;
65 } VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY;
66 
67 typedef struct {
68   UINTN                                      Front;
69   UINTN                                      Rear;
70   EFI_KEY_DATA                               Buffer[QUEUE_MAX_COUNT];
71 } SIMPLE_QUEUE;
72 
73 typedef struct {
74   UINT8                                      Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
75   UINTN                                      Head;
76   UINTN                                      Tail;
77 } SCAN_CODE_QUEUE;
78 
79 typedef struct {
80   UINTN                                      Signature;
81   EFI_HANDLE                                 Handle;
82   PLATFORM_VIRTUAL_KBD_PROTOCOL              *PlatformVirtual;
83   EFI_SIMPLE_TEXT_INPUT_PROTOCOL             SimpleTextIn;
84   EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL          SimpleTextInputEx;
85 
86   //
87   // Buffer storing EFI_KEY_DATA
88   //
89   SIMPLE_QUEUE                               Queue;
90   SIMPLE_QUEUE                               QueueForNotify;
91 
92   //
93   // Notification Function List
94   //
95   LIST_ENTRY                                 NotifyList;
96   EFI_EVENT                                  KeyNotifyProcessEvent;
97   EFI_EVENT                                  TimerEvent;
98 } VIRTUAL_KEYBOARD_DEV;
99 
100 #define VIRTUAL_KEYBOARD_DEV_FROM_THIS(a)  CR (a, VIRTUAL_KEYBOARD_DEV, SimpleTextIn, VIRTUAL_KEYBOARD_DEV_SIGNATURE)
101 #define TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) \
102   CR (a, \
103       VIRTUAL_KEYBOARD_DEV, \
104       SimpleTextInputEx, \
105       VIRTUAL_KEYBOARD_DEV_SIGNATURE \
106       )
107 
108 //
109 // Global Variables
110 //
111 extern EFI_DRIVER_BINDING_PROTOCOL   gVirtualKeyboardDriverBinding;
112 
113 //
114 // Driver Binding Protocol functions
115 //
116 
117 /**
118   Check whether the driver supports this device.
119 
120   @param  This                   The Udriver binding protocol.
121   @param  Controller             The controller handle to check.
122   @param  RemainingDevicePath    The remaining device path.
123 
124   @retval EFI_SUCCESS            The driver supports this controller.
125   @retval other                  This device isn't supported.
126 
127 **/
128 EFI_STATUS
129 EFIAPI
130 VirtualKeyboardDriverBindingSupported (
131   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
132   IN EFI_HANDLE                   Controller,
133   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
134   );
135 
136 /**
137   Starts the device with this driver.
138 
139   @param  This                   The driver binding instance.
140   @param  Controller             Handle of device to bind driver to.
141   @param  RemainingDevicePath    Optional parameter use to pick a specific child
142                                  device to start.
143 
144   @retval EFI_SUCCESS            The controller is controlled by the driver.
145   @retval Other                  This controller cannot be started.
146 
147 **/
148 EFI_STATUS
149 EFIAPI
150 VirtualKeyboardDriverBindingStart (
151   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
152   IN EFI_HANDLE                   Controller,
153   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
154   );
155 
156 /**
157   Stop the device handled by this driver.
158 
159   @param  This                   The driver binding protocol.
160   @param  Controller             The controller to release.
161   @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
162   @param  ChildHandleBuffer      The array of child handle.
163 
164   @retval EFI_SUCCESS            The device was stopped.
165   @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
166   @retval Others                 Fail to uninstall protocols attached on the device.
167 
168 **/
169 EFI_STATUS
170 EFIAPI
171 VirtualKeyboardDriverBindingStop (
172   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
173   IN  EFI_HANDLE                   Controller,
174   IN  UINTN                        NumberOfChildren,
175   IN  EFI_HANDLE                   *ChildHandleBuffer
176   );
177 
178 /**
179   Retrieves a Unicode string that is the user readable name of the driver.
180 
181   This function retrieves the user readable name of a driver in the form of a
182   Unicode string. If the driver specified by This has a user readable name in
183   the language specified by Language, then a pointer to the driver name is
184   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
185   by This does not support the language specified by Language,
186   then EFI_UNSUPPORTED is returned.
187 
188   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
189                                 EFI_COMPONENT_NAME_PROTOCOL instance.
190 
191   @param  Language[in]          A pointer to a Null-terminated ASCII string
192                                 array indicating the language. This is the
193                                 language of the driver name that the caller is
194                                 requesting, and it must match one of the
195                                 languages specified in SupportedLanguages. The
196                                 number of languages supported by a driver is up
197                                 to the driver writer. Language is specified
198                                 in RFC 4646 or ISO 639-2 language code format.
199 
200   @param  DriverName[out]       A pointer to the Unicode string to return.
201                                 This Unicode string is the name of the
202                                 driver specified by This in the language
203                                 specified by Language.
204 
205   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
206                                 This and the language specified by Language was
207                                 returned in DriverName.
208 
209   @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
210 
211   @retval EFI_INVALID_PAVIRTUALETER DriverName is NULL.
212 
213   @retval EFI_UNSUPPORTED       The driver specified by This does not support
214                                 the language specified by Language.
215 
216 **/
217 EFI_STATUS
218 EFIAPI
219 VirtualKeyboardComponentNameGetDriverName (
220   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
221   IN  CHAR8                        *Language,
222   OUT CHAR16                       **DriverName
223   );
224 
225 
226 /**
227   Retrieves a Unicode string that is the user readable name of the controller
228   that is being managed by a driver.
229 
230   This function retrieves the user readable name of the controller specified by
231   ControllerHandle and ChildHandle in the form of a Unicode string. If the
232   driver specified by This has a user readable name in the language specified by
233   Language, then a pointer to the controller name is returned in ControllerName,
234   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
235   managing the controller specified by ControllerHandle and ChildHandle,
236   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
237   support the language specified by Language, then EFI_UNSUPPORTED is returned.
238 
239   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
240                                 EFI_COMPONENT_NAME_PROTOCOL instance.
241 
242   @param  ControllerHandle[in]  The handle of a controller that the driver
243                                 specified by This is managing.  This handle
244                                 specifies the controller whose name is to be
245                                 returned.
246 
247   @param  ChildHandle[in]       The handle of the child controller to retrieve
248                                 the name of.  This is an optional parameter that
249                                 may be NULL.  It will be NULL for device
250                                 drivers.  It will also be NULL for a bus drivers
251                                 that wish to retrieve the name of the bus
252                                 controller.  It will not be NULL for a bus
253                                 driver that wishes to retrieve the name of a
254                                 child controller.
255 
256   @param  Language[in]          A pointer to a Null-terminated ASCII string
257                                 array indicating the language.  This is the
258                                 language of the driver name that the caller is
259                                 requesting, and it must match one of the
260                                 languages specified in SupportedLanguages. The
261                                 number of languages supported by a driver is up
262                                 to the driver writer. Language is specified in
263                                 RFC 4646 or ISO 639-2 language code format.
264 
265   @param  ControllerName[out]   A pointer to the Unicode string to return.
266                                 This Unicode string is the name of the
267                                 controller specified by ControllerHandle and
268                                 ChildHandle in the language specified by
269                                 Language from the point of view of the driver
270                                 specified by This.
271 
272   @retval EFI_SUCCESS           The Unicode string for the user readable name in
273                                 the language specified by Language for the
274                                 driver specified by This was returned in
275                                 DriverName.
276 
277   @retval EFI_INVALID_PAVIRTUALETER ControllerHandle is NULL.
278 
279   @retval EFI_INVALID_PAVIRTUALETER ChildHandle is not NULL and it is not a valid
280                                 EFI_HANDLE.
281 
282   @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
283 
284   @retval EFI_INVALID_PAVIRTUALETER ControllerName is NULL.
285 
286   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
287                                 managing the controller specified by
288                                 ControllerHandle and ChildHandle.
289 
290   @retval EFI_UNSUPPORTED       The driver specified by This does not support
291                                 the language specified by Language.
292 
293 **/
294 EFI_STATUS
295 EFIAPI
296 VirtualKeyboardComponentNameGetControllerName (
297   IN  EFI_COMPONENT_NAME_PROTOCOL      *This,
298   IN  EFI_HANDLE                       ControllerHandle,
299   IN  EFI_HANDLE                       ChildHandle        OPTIONAL,
300   IN  CHAR8                            *Language,
301   OUT CHAR16                           **ControllerName
302   );
303 
304 
305 //
306 // Simple Text Input Protocol functions
307 //
308 /**
309   Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
310 
311   @param  This                  Pointer of simple text Protocol.
312   @param  ExtendedVerification  Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
313 
314   @retval EFI_SUCCESS           The command byte is written successfully.
315   @retval EFI_DEVICE_ERROR      Errors occurred during resetting keyboard.
316 
317 **/
318 EFI_STATUS
319 EFIAPI
320 VirtualKeyboardReset (
321   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
322   IN  BOOLEAN                         ExtendedVerification
323   );
324 
325 /**
326   Reset the input device and optionaly run diagnostics
327 
328   @param  This                  Protocol instance pointer.
329   @param  ExtendedVerification  Driver may perform diagnostics on reset.
330 
331   @retval EFI_SUCCESS           The device was reset.
332   @retval EFI_DEVICE_ERROR      The device is not functioning properly and could
333                                 not be reset.
334 
335 **/
336 EFI_STATUS
337 EFIAPI
338 VirtualKeyboardResetEx (
339   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
340   IN BOOLEAN                            ExtendedVerification
341   );
342 
343 /**
344   Set certain state for the input device.
345 
346   @param  This              Protocol instance pointer.
347   @param  KeyToggleState    A pointer to the EFI_KEY_TOGGLE_STATE to set the
348                             state for the input device.
349 
350   @retval EFI_SUCCESS           The device state was set successfully.
351   @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could
352                                 not have the setting adjusted.
353   @retval EFI_UNSUPPORTED       The device does not have the ability to set its state.
354   @retval EFI_INVALID_PAVIRTUALETER KeyToggleState is NULL.
355 
356 **/
357 EFI_STATUS
358 EFIAPI
359 VirtualKeyboardSetState (
360   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
361   IN EFI_KEY_TOGGLE_STATE               *KeyToggleState
362   );
363 
364 /**
365   Register a notification function for a particular keystroke for the input device.
366 
367   @param  This                    Protocol instance pointer.
368   @param  KeyData                 A pointer to a buffer that is filled in with the keystroke
369                                   information data for the key that was pressed.
370   @param  KeyNotificationFunction Points to the function to be called when the key
371                                   sequence is typed specified by KeyData.
372   @param  NotifyHandle            Points to the unique handle assigned to the registered notification.
373 
374 
375   @retval EFI_SUCCESS             The notification function was registered successfully.
376   @retval EFI_OUT_OF_RESOURCES    Unable to allocate resources for necesssary data structures.
377   @retval EFI_INVALID_PAVIRTUALETER   KeyData or NotifyHandle is NULL.
378 
379 **/
380 EFI_STATUS
381 EFIAPI
382 VirtualKeyboardRegisterKeyNotify (
383   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
384   IN EFI_KEY_DATA                       *KeyData,
385   IN EFI_KEY_NOTIFY_FUNCTION            KeyNotificationFunction,
386   OUT VOID                              **NotifyHandle
387   );
388 
389 /**
390   Remove a registered notification function from a particular keystroke.
391 
392   @param  This                 Protocol instance pointer.
393   @param  NotificationHandle   The handle of the notification function being unregistered.
394 
395   @retval EFI_SUCCESS             The notification function was unregistered successfully.
396   @retval EFI_INVALID_PAVIRTUALETER   The NotificationHandle is invalid.
397 
398 **/
399 EFI_STATUS
400 EFIAPI
401 VirtualKeyboardUnregisterKeyNotify (
402   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
403   IN VOID                               *NotificationHandle
404   );
405 
406 //
407 // Private worker functions
408 //
409 /**
410   Free keyboard notify list.
411 
412   @param  ListHead   The list head
413 
414   @retval EFI_SUCCESS           Free the notify list successfully
415   @retval EFI_INVALID_PAVIRTUALETER ListHead is invalid.
416 
417 **/
418 EFI_STATUS
419 VirtualKeyboardFreeNotifyList (
420   IN OUT LIST_ENTRY           *ListHead
421   );
422 
423 /**
424   Check if key is registered.
425 
426   @param  RegsiteredData    A pointer to a buffer that is filled in with the keystroke
427                             state data for the key that was registered.
428   @param  InputData         A pointer to a buffer that is filled in with the keystroke
429                             state data for the key that was pressed.
430 
431   @retval TRUE              Key be pressed matches a registered key.
432   @retval FLASE             Match failed.
433 
434 **/
435 BOOLEAN
436 IsKeyRegistered (
437   IN EFI_KEY_DATA  *RegsiteredData,
438   IN EFI_KEY_DATA  *InputData
439   );
440 
441 /**
442   Waiting on the keyboard event, if there's any key pressed by the user, signal the event
443 
444   @param  Event       The event that be siganlled when any key has been stroked.
445   @param  Context     Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
446 
447 **/
448 VOID
449 EFIAPI
450 VirtualKeyboardWaitForKey (
451   IN  EFI_EVENT  Event,
452   IN  VOID       *Context
453   );
454 
455 /**
456   Waiting on the keyboard event, if there's any key pressed by the user, signal the event
457 
458   @param  Event    The event that be siganlled when any key has been stroked.
459   @param  Context  Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
460 
461 **/
462 VOID
463 EFIAPI
464 VirtualKeyboardWaitForKeyEx (
465   IN  EFI_EVENT  Event,
466   IN  VOID       *Context
467   );
468 
469 /**
470   Timer event handler: read a series of key stroke from 8042
471   and put them into memory key buffer.
472   It is registered as running under TPL_NOTIFY
473 
474   @param  Event   The timer event
475   @param  Context A VIRTUAL_KEYBOARD_DEV pointer
476 
477 **/
478 VOID
479 EFIAPI
480 VirtualKeyboardTimerHandler (
481   IN EFI_EVENT    Event,
482   IN VOID         *Context
483   );
484 
485 /**
486   Process key notify.
487 
488   @param  Event                 Indicates the event that invoke this function.
489   @param  Context               Indicates the calling context.
490 **/
491 VOID
492 EFIAPI
493 KeyNotifyProcessHandler (
494   IN  EFI_EVENT                 Event,
495   IN  VOID                      *Context
496   );
497 
498 /**
499   Read out the scan code of the key that has just been stroked.
500 
501   @param  This        Pointer of simple text Protocol.
502   @param  Key         Pointer for store the key that read out.
503 
504   @retval EFI_SUCCESS The key is read out successfully.
505   @retval other       The key reading failed.
506 
507 **/
508 EFI_STATUS
509 EFIAPI
510 VirtualKeyboardReadKeyStroke (
511   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
512   OUT EFI_INPUT_KEY                   *Key
513   );
514 
515 /**
516   Reads the next keystroke from the input device. The WaitForKey Event can
517   be used to test for existance of a keystroke via WaitForEvent () call.
518 
519   @param  This         Protocol instance pointer.
520   @param  KeyData      A pointer to a buffer that is filled in with the keystroke
521                        state data for the key that was pressed.
522 
523   @retval  EFI_SUCCESS           The keystroke information was returned.
524   @retval  EFI_NOT_READY         There was no keystroke data availiable.
525   @retval  EFI_DEVICE_ERROR      The keystroke information was not returned due to
526                                  hardware errors.
527   @retval  EFI_INVALID_PAVIRTUALETER KeyData is NULL.
528 
529 **/
530 EFI_STATUS
531 EFIAPI
532 VirtualKeyboardReadKeyStrokeEx (
533   IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
534   OUT EFI_KEY_DATA                      *KeyData
535   );
536 
537 #endif /* _VIRTUAL_KEYBOARD_H_ */
538