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