]>
Commit | Line | Data |
---|---|---|
949f388f | 1 | /*++ @file |
2 | ||
224e1333 | 3 | Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> |
949f388f | 4 | Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR> |
5 | This program and the accompanying materials | |
6 | are licensed and made available under the terms and conditions of the BSD License | |
7 | which accompanies this distribution. The full text of the license may be found at | |
8 | http://opensource.org/licenses/bsd-license.php | |
9 | ||
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
12 | ||
13 | ||
14 | **/ | |
15 | ||
16 | #include "Gop.h" | |
17 | ||
18 | ||
19 | BOOLEAN | |
20 | GopPrivateIsKeyRegistered ( | |
21 | IN EFI_KEY_DATA *RegsiteredData, | |
22 | IN EFI_KEY_DATA *InputData | |
23 | ) | |
24 | /*++ | |
25 | ||
26 | Routine Description: | |
27 | ||
28 | Arguments: | |
29 | ||
d18d8a1d | 30 | RegsiteredData - A pointer to a buffer that is filled in with the keystroke |
949f388f | 31 | state data for the key that was registered. |
d18d8a1d | 32 | InputData - A pointer to a buffer that is filled in with the keystroke |
949f388f | 33 | state data for the key that was pressed. |
34 | ||
35 | Returns: | |
36 | TRUE - Key be pressed matches a registered key. | |
d18d8a1d | 37 | FLASE - Match failed. |
38 | ||
949f388f | 39 | **/ |
40 | { | |
41 | ASSERT (RegsiteredData != NULL && InputData != NULL); | |
d18d8a1d | 42 | |
949f388f | 43 | if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || |
44 | (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { | |
d18d8a1d | 45 | return FALSE; |
46 | } | |
47 | ||
949f388f | 48 | // |
49 | // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. | |
50 | // | |
51 | if (RegsiteredData->KeyState.KeyShiftState != 0 && | |
52 | RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) { | |
d18d8a1d | 53 | return FALSE; |
54 | } | |
949f388f | 55 | if (RegsiteredData->KeyState.KeyToggleState != 0 && |
56 | RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) { | |
d18d8a1d | 57 | return FALSE; |
58 | } | |
59 | ||
949f388f | 60 | return TRUE; |
61 | ||
62 | } | |
63 | ||
64 | ||
65 | VOID | |
66 | EFIAPI | |
67 | GopPrivateMakeCallbackFunction ( | |
68 | IN VOID *Context, | |
69 | IN EFI_KEY_DATA *KeyData | |
70 | ) | |
d18d8a1d | 71 | { |
949f388f | 72 | LIST_ENTRY *Link; |
73 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
74 | GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context; | |
d18d8a1d | 75 | |
949f388f | 76 | KeyMapMake (KeyData); |
77 | ||
78 | for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
79 | CurrentNotify = CR ( | |
d18d8a1d | 80 | Link, |
81 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
82 | NotifyEntry, | |
949f388f | 83 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE |
84 | ); | |
d18d8a1d | 85 | if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { |
86 | // We could be called at a high TPL so signal an event to call the registered function | |
949f388f | 87 | // at a lower TPL. |
88 | gBS->SignalEvent (CurrentNotify->Event); | |
89 | } | |
d18d8a1d | 90 | } |
949f388f | 91 | } |
92 | ||
93 | ||
94 | VOID | |
95 | EFIAPI | |
96 | GopPrivateBreakCallbackFunction ( | |
97 | IN VOID *Context, | |
98 | IN EFI_KEY_DATA *KeyData | |
99 | ) | |
d18d8a1d | 100 | { |
949f388f | 101 | KeyMapBreak (KeyData); |
102 | } | |
103 | ||
104 | ||
105 | ||
106 | // | |
107 | // Simple Text In implementation. | |
108 | // | |
109 | ||
110 | /** | |
111 | Reset the input device and optionally run diagnostics | |
112 | ||
113 | @param This Protocol instance pointer. | |
114 | @param ExtendedVerification Driver may perform diagnostics on reset. | |
115 | ||
116 | @retval EFI_SUCCESS The device was reset. | |
117 | @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. | |
118 | ||
119 | **/ | |
120 | EFI_STATUS | |
121 | EFIAPI | |
122 | EmuGopSimpleTextInReset ( | |
123 | IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, | |
124 | IN BOOLEAN ExtendedVerification | |
125 | ) | |
126 | { | |
127 | GOP_PRIVATE_DATA *Private; | |
128 | EFI_KEY_DATA KeyData; | |
129 | EFI_TPL OldTpl; | |
130 | ||
131 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
132 | if (Private->EmuGraphicsWindow == NULL) { | |
133 | return EFI_SUCCESS; | |
134 | } | |
135 | ||
136 | // | |
137 | // Enter critical section | |
138 | // | |
139 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
140 | ||
141 | // | |
142 | // A reset is draining the Queue | |
143 | // | |
144 | while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) | |
145 | ; | |
146 | ||
147 | // | |
148 | // Leave critical section and return | |
149 | // | |
150 | gBS->RestoreTPL (OldTpl); | |
151 | return EFI_SUCCESS; | |
152 | } | |
153 | ||
154 | ||
155 | /** | |
156 | Reads the next keystroke from the input device. The WaitForKey Event can | |
157 | be used to test for existence of a keystroke via WaitForEvent () call. | |
158 | ||
159 | @param This Protocol instance pointer. | |
160 | @param Key A pointer to a buffer that is filled in with the keystroke | |
161 | information for the key that was pressed. | |
162 | ||
163 | @retval EFI_SUCCESS The keystroke information was returned. | |
164 | @retval EFI_NOT_READY There was no keystroke data available. | |
165 | @retval EFI_DEVICE_ERROR The keystroke information was not returned due to | |
166 | hardware errors. | |
167 | ||
168 | **/ | |
169 | EFI_STATUS | |
170 | EFIAPI | |
171 | EmuGopSimpleTextInReadKeyStroke ( | |
172 | IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, | |
173 | OUT EFI_INPUT_KEY *Key | |
174 | ) | |
175 | { | |
176 | GOP_PRIVATE_DATA *Private; | |
177 | EFI_STATUS Status; | |
178 | EFI_TPL OldTpl; | |
179 | EFI_KEY_DATA KeyData; | |
180 | ||
181 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
182 | if (Private->EmuGraphicsWindow == NULL) { | |
183 | return EFI_NOT_READY; | |
184 | } | |
185 | ||
186 | // | |
187 | // Enter critical section | |
188 | // | |
189 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
190 | ||
191 | Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData); | |
192 | CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); | |
193 | ||
194 | // | |
195 | // Leave critical section and return | |
196 | // | |
197 | gBS->RestoreTPL (OldTpl); | |
198 | ||
199 | return Status; | |
200 | } | |
201 | ||
202 | ||
203 | ||
204 | /** | |
d18d8a1d | 205 | SimpleTextIn and SimpleTextInEx Notify Wait Event |
949f388f | 206 | |
207 | @param Event Event whose notification function is being invoked. | |
208 | @param Context Pointer to GOP_PRIVATE_DATA. | |
209 | ||
210 | **/ | |
211 | VOID | |
212 | EFIAPI | |
213 | EmuGopSimpleTextInWaitForKey ( | |
214 | IN EFI_EVENT Event, | |
215 | IN VOID *Context | |
216 | ) | |
217 | { | |
218 | GOP_PRIVATE_DATA *Private; | |
219 | EFI_STATUS Status; | |
220 | EFI_TPL OldTpl; | |
221 | ||
222 | Private = (GOP_PRIVATE_DATA *) Context; | |
223 | if (Private->EmuGraphicsWindow == NULL) { | |
224 | return; | |
225 | } | |
226 | ||
227 | // | |
228 | // Enter critical section | |
229 | // | |
230 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
231 | ||
232 | Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow); | |
233 | if (!EFI_ERROR (Status)) { | |
234 | // | |
235 | // If a there is a key in the queue signal our event. | |
236 | // | |
237 | gBS->SignalEvent (Event); | |
238 | } | |
239 | // | |
240 | // Leave critical section and return | |
241 | // | |
242 | gBS->RestoreTPL (OldTpl); | |
243 | } | |
244 | ||
245 | ||
246 | // | |
247 | // Simple Text Input Ex protocol functions | |
248 | // | |
249 | ||
250 | ||
251 | /** | |
252 | The Reset() function resets the input device hardware. As part | |
253 | of initialization process, the firmware/device will make a quick | |
254 | but reasonable attempt to verify that the device is functioning. | |
255 | If the ExtendedVerification flag is TRUE the firmware may take | |
256 | an extended amount of time to verify the device is operating on | |
257 | reset. Otherwise the reset operation is to occur as quickly as | |
258 | possible. The hardware verification process is not defined by | |
259 | this specification and is left up to the platform firmware or | |
260 | driver to implement. | |
261 | ||
262 | @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
263 | ||
264 | @param ExtendedVerification Indicates that the driver may | |
265 | perform a more exhaustive | |
266 | verification operation of the | |
267 | device during reset. | |
268 | ||
269 | ||
270 | @retval EFI_SUCCESS The device was reset. | |
d18d8a1d | 271 | |
949f388f | 272 | @retval EFI_DEVICE_ERROR The device is not functioning |
273 | correctly and could not be reset. | |
274 | ||
275 | **/ | |
276 | EFI_STATUS | |
277 | EFIAPI | |
278 | EmuGopSimpleTextInExResetEx ( | |
279 | IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
280 | IN BOOLEAN ExtendedVerification | |
281 | ) | |
282 | /*++ | |
283 | ||
284 | Routine Description: | |
285 | Reset the input device and optionaly run diagnostics | |
286 | ||
287 | Arguments: | |
288 | This - Protocol instance pointer. | |
289 | ExtendedVerification - Driver may perform diagnostics on reset. | |
290 | ||
291 | Returns: | |
292 | EFI_SUCCESS - The device was reset. | |
293 | ||
294 | **/ | |
295 | { | |
296 | GOP_PRIVATE_DATA *Private; | |
297 | ||
298 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
d18d8a1d | 299 | |
949f388f | 300 | return EFI_SUCCESS; |
301 | } | |
302 | ||
303 | ||
304 | ||
305 | /** | |
306 | The function reads the next keystroke from the input device. If | |
307 | there is no pending keystroke the function returns | |
308 | EFI_NOT_READY. If there is a pending keystroke, then | |
309 | KeyData.Key.ScanCode is the EFI scan code defined in Error! | |
310 | Reference source not found. The KeyData.Key.UnicodeChar is the | |
311 | actual printable character or is zero if the key does not | |
312 | represent a printable character (control key, function key, | |
313 | etc.). The KeyData.KeyState is shift state for the character | |
314 | reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode . | |
315 | When interpreting the data from this function, it should be | |
316 | noted that if a class of printable characters that are | |
317 | normally adjusted by shift modifiers (e.g. Shift Key + "f" | |
318 | key) would be presented solely as a KeyData.Key.UnicodeChar | |
319 | without the associated shift state. So in the previous example | |
320 | of a Shift Key + "f" key being pressed, the only pertinent | |
321 | data returned would be KeyData.Key.UnicodeChar with the value | |
322 | of "F". This of course would not typically be the case for | |
323 | non-printable characters such as the pressing of the Right | |
324 | Shift Key + F10 key since the corresponding returned data | |
325 | would be reflected both in the KeyData.KeyState.KeyShiftState | |
326 | and KeyData.Key.ScanCode values. UEFI drivers which implement | |
327 | the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return | |
328 | KeyData.Key and KeyData.KeyState values. These drivers must | |
329 | always return the most current state of | |
330 | KeyData.KeyState.KeyShiftState and | |
331 | KeyData.KeyState.KeyToggleState. It should also be noted that | |
332 | certain input devices may not be able to produce shift or toggle | |
333 | state information, and in those cases the high order bit in the | |
334 | respective Toggle and Shift state fields should not be active. | |
335 | ||
d18d8a1d | 336 | |
949f388f | 337 | @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. |
338 | ||
339 | @param KeyData A pointer to a buffer that is filled in with | |
340 | the keystroke state data for the key that was | |
341 | pressed. | |
342 | ||
d18d8a1d | 343 | |
949f388f | 344 | @retval EFI_SUCCESS The keystroke information was |
345 | returned. | |
d18d8a1d | 346 | |
949f388f | 347 | @retval EFI_NOT_READY There was no keystroke data available. |
348 | EFI_DEVICE_ERROR The keystroke | |
349 | information was not returned due to | |
350 | hardware errors. | |
351 | ||
352 | ||
353 | **/ | |
354 | EFI_STATUS | |
355 | EFIAPI | |
356 | EmuGopSimpleTextInExReadKeyStrokeEx ( | |
357 | IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
358 | OUT EFI_KEY_DATA *KeyData | |
359 | ) | |
360 | /*++ | |
361 | ||
362 | Routine Description: | |
d18d8a1d | 363 | Reads the next keystroke from the input device. The WaitForKey Event can |
949f388f | 364 | be used to test for existance of a keystroke via WaitForEvent () call. |
365 | ||
366 | Arguments: | |
367 | This - Protocol instance pointer. | |
d18d8a1d | 368 | KeyData - A pointer to a buffer that is filled in with the keystroke |
949f388f | 369 | state data for the key that was pressed. |
370 | ||
371 | Returns: | |
372 | EFI_SUCCESS - The keystroke information was returned. | |
373 | EFI_NOT_READY - There was no keystroke data availiable. | |
d18d8a1d | 374 | EFI_DEVICE_ERROR - The keystroke information was not returned due to |
949f388f | 375 | hardware errors. |
d18d8a1d | 376 | EFI_INVALID_PARAMETER - KeyData is NULL. |
949f388f | 377 | |
378 | **/ | |
379 | { | |
380 | EFI_STATUS Status; | |
381 | GOP_PRIVATE_DATA *Private; | |
382 | EFI_TPL OldTpl; | |
383 | ||
384 | ||
385 | if (KeyData == NULL) { | |
386 | return EFI_INVALID_PARAMETER; | |
387 | } | |
388 | ||
389 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
390 | if (Private->EmuGraphicsWindow == NULL) { | |
391 | return EFI_NOT_READY; | |
392 | } | |
393 | ||
394 | // | |
395 | // Enter critical section | |
396 | // | |
397 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
398 | ||
399 | Status = Private->EmuGraphicsWindow->GetKey(Private->EmuGraphicsWindow, KeyData); | |
400 | ||
401 | // | |
402 | // Leave critical section and return | |
403 | // | |
404 | gBS->RestoreTPL (OldTpl); | |
405 | ||
406 | return Status; | |
407 | } | |
408 | ||
409 | ||
410 | ||
411 | /** | |
412 | The SetState() function allows the input device hardware to | |
413 | have state settings adjusted. | |
d18d8a1d | 414 | |
949f388f | 415 | @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. |
d18d8a1d | 416 | |
949f388f | 417 | @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to |
418 | set the state for the input device. | |
d18d8a1d | 419 | |
420 | ||
949f388f | 421 | @retval EFI_SUCCESS The device state was set appropriately. |
422 | ||
423 | @retval EFI_DEVICE_ERROR The device is not functioning | |
424 | correctly and could not have the | |
425 | setting adjusted. | |
426 | ||
427 | @retval EFI_UNSUPPORTED The device does not support the | |
428 | ability to have its state set. | |
429 | ||
430 | **/ | |
431 | EFI_STATUS | |
432 | EFIAPI | |
433 | EmuGopSimpleTextInExSetState ( | |
434 | IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
435 | IN EFI_KEY_TOGGLE_STATE *KeyToggleState | |
436 | ) | |
437 | { | |
438 | GOP_PRIVATE_DATA *Private; | |
439 | EFI_STATUS Status; | |
440 | EFI_TPL OldTpl; | |
441 | ||
442 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
443 | if (Private->EmuGraphicsWindow == NULL) { | |
444 | return EFI_NOT_READY; | |
445 | } | |
446 | ||
447 | // | |
448 | // Enter critical section | |
449 | // | |
450 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
451 | ||
452 | Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState); | |
453 | // | |
454 | // Leave critical section and return | |
455 | // | |
456 | gBS->RestoreTPL (OldTpl); | |
457 | ||
458 | return Status; | |
459 | } | |
460 | ||
461 | ||
462 | /** | |
d18d8a1d | 463 | SimpleTextIn and SimpleTextInEx Notify Wait Event |
949f388f | 464 | |
465 | @param Event Event whose notification function is being invoked. | |
466 | @param Context Pointer to GOP_PRIVATE_DATA. | |
467 | ||
468 | **/ | |
469 | VOID | |
470 | EFIAPI | |
471 | EmuGopRegisterKeyCallback ( | |
472 | IN EFI_EVENT Event, | |
473 | IN VOID *Context | |
474 | ) | |
475 | { | |
476 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context; | |
d18d8a1d | 477 | |
949f388f | 478 | ExNotify->KeyNotificationFn (&ExNotify->KeyData); |
479 | } | |
480 | ||
481 | ||
482 | ||
483 | /** | |
484 | The RegisterKeystrokeNotify() function registers a function | |
485 | which will be called when a specified keystroke will occur. | |
d18d8a1d | 486 | |
949f388f | 487 | @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. |
d18d8a1d | 488 | |
949f388f | 489 | @param KeyData A pointer to a buffer that is filled in with |
490 | the keystroke information for the key that was | |
491 | pressed. | |
d18d8a1d | 492 | |
949f388f | 493 | @param KeyNotificationFunction Points to the function to be |
494 | called when the key sequence | |
495 | is typed specified by KeyData. | |
d18d8a1d | 496 | |
497 | ||
949f388f | 498 | @param NotifyHandle Points to the unique handle assigned to |
499 | the registered notification. | |
d18d8a1d | 500 | |
949f388f | 501 | @retval EFI_SUCCESS The device state was set |
502 | appropriately. | |
503 | ||
504 | @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary | |
505 | data structures. | |
506 | ||
507 | **/ | |
508 | EFI_STATUS | |
509 | EFIAPI | |
510 | EmuGopSimpleTextInExRegisterKeyNotify ( | |
511 | IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
512 | IN EFI_KEY_DATA *KeyData, | |
513 | IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, | |
514 | OUT EFI_HANDLE *NotifyHandle | |
515 | ) | |
516 | { | |
517 | EFI_STATUS Status; | |
518 | GOP_PRIVATE_DATA *Private; | |
519 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
520 | LIST_ENTRY *Link; | |
521 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; | |
522 | ||
523 | if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) { | |
524 | return EFI_INVALID_PARAMETER; | |
525 | } | |
526 | ||
527 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
528 | ||
529 | // | |
530 | // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. | |
531 | // | |
532 | for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
533 | CurrentNotify = CR ( | |
d18d8a1d | 534 | Link, |
535 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
536 | NotifyEntry, | |
949f388f | 537 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE |
538 | ); | |
d18d8a1d | 539 | if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { |
949f388f | 540 | if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { |
541 | *NotifyHandle = CurrentNotify->NotifyHandle; | |
542 | return EFI_SUCCESS; | |
543 | } | |
544 | } | |
d18d8a1d | 545 | } |
546 | ||
949f388f | 547 | // |
548 | // Allocate resource to save the notification function | |
d18d8a1d | 549 | // |
949f388f | 550 | NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY)); |
551 | if (NewNotify == NULL) { | |
552 | return EFI_OUT_OF_RESOURCES; | |
553 | } | |
554 | ||
d18d8a1d | 555 | NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; |
949f388f | 556 | NewNotify->KeyNotificationFn = KeyNotificationFunction; |
557 | NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; | |
558 | CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); | |
559 | InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry); | |
d18d8a1d | 560 | |
949f388f | 561 | Status = gBS->CreateEvent ( |
562 | EVT_NOTIFY_SIGNAL, | |
563 | TPL_NOTIFY, | |
564 | EmuGopRegisterKeyCallback, | |
565 | NewNotify, | |
566 | &NewNotify->Event | |
567 | ); | |
568 | ASSERT_EFI_ERROR (Status); | |
569 | ||
570 | ||
d18d8a1d | 571 | *NotifyHandle = NewNotify->NotifyHandle; |
572 | ||
949f388f | 573 | return EFI_SUCCESS; |
d18d8a1d | 574 | |
949f388f | 575 | } |
576 | ||
577 | ||
578 | /** | |
579 | The UnregisterKeystrokeNotify() function removes the | |
580 | notification which was previously registered. | |
d18d8a1d | 581 | |
949f388f | 582 | @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. |
d18d8a1d | 583 | |
949f388f | 584 | @param NotificationHandle The handle of the notification |
585 | function being unregistered. | |
d18d8a1d | 586 | |
949f388f | 587 | @retval EFI_SUCCESS The device state was set appropriately. |
d18d8a1d | 588 | |
949f388f | 589 | @retval EFI_INVALID_PARAMETER The NotificationHandle is |
590 | invalid. | |
591 | ||
592 | **/ | |
593 | EFI_STATUS | |
594 | EFIAPI | |
595 | EmuGopSimpleTextInExUnregisterKeyNotify ( | |
596 | IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
597 | IN EFI_HANDLE NotificationHandle | |
598 | ) | |
599 | /*++ | |
600 | ||
601 | Routine Description: | |
602 | Remove a registered notification function from a particular keystroke. | |
603 | ||
604 | Arguments: | |
d18d8a1d | 605 | This - Protocol instance pointer. |
949f388f | 606 | NotificationHandle - The handle of the notification function being unregistered. |
607 | ||
608 | Returns: | |
609 | EFI_SUCCESS - The notification function was unregistered successfully. | |
610 | EFI_INVALID_PARAMETER - The NotificationHandle is invalid. | |
d18d8a1d | 611 | |
612 | **/ | |
949f388f | 613 | { |
614 | GOP_PRIVATE_DATA *Private; | |
615 | LIST_ENTRY *Link; | |
616 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
617 | ||
618 | if (NotificationHandle == NULL) { | |
619 | return EFI_INVALID_PARAMETER; | |
d18d8a1d | 620 | } |
949f388f | 621 | |
622 | if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) { | |
623 | return EFI_INVALID_PARAMETER; | |
d18d8a1d | 624 | } |
949f388f | 625 | |
626 | Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
627 | ||
628 | for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
629 | CurrentNotify = CR ( | |
d18d8a1d | 630 | Link, |
631 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
632 | NotifyEntry, | |
949f388f | 633 | EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE |
d18d8a1d | 634 | ); |
949f388f | 635 | if (CurrentNotify->NotifyHandle == NotificationHandle) { |
636 | // | |
637 | // Remove the notification function from NotifyList and free resources | |
638 | // | |
d18d8a1d | 639 | RemoveEntryList (&CurrentNotify->NotifyEntry); |
640 | ||
949f388f | 641 | gBS->CloseEvent (CurrentNotify->Event); |
642 | ||
d18d8a1d | 643 | gBS->FreePool (CurrentNotify); |
949f388f | 644 | return EFI_SUCCESS; |
645 | } | |
646 | } | |
647 | ||
648 | // | |
649 | // Can not find the specified Notification Handle | |
650 | // | |
651 | return EFI_INVALID_PARAMETER; | |
652 | } | |
653 | ||
654 | ||
655 | ||
656 | /** | |
657 | Initialize SimplelTextIn and SimpleTextInEx protocols in the Private | |
658 | context structure. | |
659 | ||
d18d8a1d | 660 | @param Private Context structure to fill in. |
949f388f | 661 | |
662 | @return EFI_SUCCESS Initialization was a success | |
663 | ||
664 | **/ | |
665 | EFI_STATUS | |
666 | EmuGopInitializeSimpleTextInForWindow ( | |
667 | IN GOP_PRIVATE_DATA *Private | |
668 | ) | |
669 | { | |
670 | EFI_STATUS Status; | |
671 | ||
672 | // | |
673 | // Initialize Simple Text In protoocol | |
674 | // | |
675 | Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset; | |
676 | Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke; | |
677 | ||
678 | Status = gBS->CreateEvent ( | |
679 | EVT_NOTIFY_WAIT, | |
680 | TPL_NOTIFY, | |
681 | EmuGopSimpleTextInWaitForKey, | |
682 | Private, | |
683 | &Private->SimpleTextIn.WaitForKey | |
684 | ); | |
685 | ASSERT_EFI_ERROR (Status); | |
d18d8a1d | 686 | |
687 | ||
949f388f | 688 | // |
689 | // Initialize Simple Text In Ex | |
690 | // | |
d18d8a1d | 691 | |
949f388f | 692 | Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx; |
693 | Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx; | |
694 | Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState; | |
695 | Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify; | |
696 | Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify; | |
697 | ||
698 | Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE); | |
d18d8a1d | 699 | |
949f388f | 700 | InitializeListHead (&Private->NotifyList); |
701 | ||
702 | Status = gBS->CreateEvent ( | |
703 | EVT_NOTIFY_WAIT, | |
704 | TPL_NOTIFY, | |
705 | EmuGopSimpleTextInWaitForKey, | |
706 | Private, | |
707 | &Private->SimpleTextInEx.WaitForKeyEx | |
708 | ); | |
709 | ASSERT_EFI_ERROR (Status); | |
710 | ||
711 | ||
712 | return Status; | |
713 | } | |
714 | ||
715 | ||
716 | ||
717 | ||
718 | ||
719 | ||
720 | ||
721 | // | |
722 | // Simple Pointer implementation. | |
723 | // | |
724 | ||
725 | ||
d18d8a1d | 726 | /** |
949f388f | 727 | Resets the pointer device hardware. |
d18d8a1d | 728 | |
949f388f | 729 | @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL |
d18d8a1d | 730 | instance. |
949f388f | 731 | @param ExtendedVerification Indicates that the driver may perform a more exhaustive |
d18d8a1d | 732 | verification operation of the device during reset. |
733 | ||
949f388f | 734 | @retval EFI_SUCCESS The device was reset. |
d18d8a1d | 735 | @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. |
736 | ||
949f388f | 737 | **/ |
738 | EFI_STATUS | |
739 | EFIAPI | |
740 | EmuGopSimplePointerReset ( | |
741 | IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
742 | IN BOOLEAN ExtendedVerification | |
743 | ) | |
744 | { | |
745 | GOP_PRIVATE_DATA *Private; | |
746 | EFI_SIMPLE_POINTER_STATE State; | |
747 | EFI_TPL OldTpl; | |
748 | ||
749 | Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); | |
750 | if (Private->EmuGraphicsWindow == NULL) { | |
751 | return EFI_SUCCESS; | |
752 | } | |
753 | ||
754 | // | |
755 | // Enter critical section | |
756 | // | |
757 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
758 | ||
759 | // | |
760 | // A reset is draining the Queue | |
761 | // | |
762 | while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) | |
763 | ; | |
764 | ||
765 | // | |
766 | // Leave critical section and return | |
767 | // | |
768 | gBS->RestoreTPL (OldTpl); | |
769 | return EFI_SUCCESS; | |
770 | } | |
771 | ||
772 | ||
d18d8a1d | 773 | /** |
949f388f | 774 | Retrieves the current state of a pointer device. |
d18d8a1d | 775 | |
949f388f | 776 | @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL |
d18d8a1d | 777 | instance. |
949f388f | 778 | @param State A pointer to the state information on the pointer device. |
d18d8a1d | 779 | |
949f388f | 780 | @retval EFI_SUCCESS The state of the pointer device was returned in State. |
781 | @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to | |
d18d8a1d | 782 | GetState(). |
949f388f | 783 | @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's |
d18d8a1d | 784 | current state. |
785 | ||
949f388f | 786 | **/ |
787 | EFI_STATUS | |
788 | EFIAPI | |
789 | EmuGopSimplePointerGetState ( | |
790 | IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
791 | IN OUT EFI_SIMPLE_POINTER_STATE *State | |
792 | ) | |
793 | { | |
794 | GOP_PRIVATE_DATA *Private; | |
795 | EFI_STATUS Status; | |
796 | EFI_TPL OldTpl; | |
797 | ||
798 | Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); | |
799 | if (Private->EmuGraphicsWindow == NULL) { | |
800 | return EFI_NOT_READY; | |
801 | } | |
802 | ||
803 | // | |
804 | // Enter critical section | |
805 | // | |
806 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
807 | ||
808 | Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State); | |
809 | // | |
810 | // Leave critical section and return | |
811 | // | |
812 | gBS->RestoreTPL (OldTpl); | |
813 | ||
814 | return Status; | |
815 | } | |
816 | ||
817 | ||
818 | /** | |
d18d8a1d | 819 | SimplePointer Notify Wait Event |
949f388f | 820 | |
821 | @param Event Event whose notification function is being invoked. | |
822 | @param Context Pointer to GOP_PRIVATE_DATA. | |
823 | ||
824 | **/ | |
825 | VOID | |
826 | EFIAPI | |
827 | EmuGopSimplePointerWaitForInput ( | |
828 | IN EFI_EVENT Event, | |
829 | IN VOID *Context | |
830 | ) | |
831 | { | |
832 | GOP_PRIVATE_DATA *Private; | |
833 | EFI_STATUS Status; | |
834 | EFI_TPL OldTpl; | |
835 | ||
836 | Private = (GOP_PRIVATE_DATA *) Context; | |
837 | if (Private->EmuGraphicsWindow == NULL) { | |
838 | return; | |
839 | } | |
840 | ||
841 | // | |
842 | // Enter critical section | |
843 | // | |
844 | OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
845 | ||
846 | Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow); | |
847 | if (!EFI_ERROR (Status)) { | |
848 | // | |
849 | // If the pointer state has changed, signal our event. | |
850 | // | |
851 | gBS->SignalEvent (Event); | |
852 | } | |
853 | // | |
854 | // Leave critical section and return | |
855 | // | |
856 | gBS->RestoreTPL (OldTpl); | |
857 | } | |
858 | ||
859 | ||
860 | /** | |
d18d8a1d | 861 | SimplePointer constructor |
949f388f | 862 | |
d18d8a1d | 863 | @param Private Context structure to fill in. |
949f388f | 864 | |
d18d8a1d | 865 | @retval EFI_SUCCESS Constructor had success |
949f388f | 866 | |
867 | **/ | |
868 | EFI_STATUS | |
869 | EmuGopInitializeSimplePointerForWindow ( | |
870 | IN GOP_PRIVATE_DATA *Private | |
871 | ) | |
872 | { | |
873 | EFI_STATUS Status; | |
874 | ||
875 | // | |
876 | // Initialize Simple Pointer protoocol | |
877 | // | |
878 | Private->PointerMode.ResolutionX = 1; | |
879 | Private->PointerMode.ResolutionY = 1; | |
880 | Private->PointerMode.ResolutionZ = 1; | |
881 | Private->PointerMode.LeftButton = TRUE; | |
882 | Private->PointerMode.RightButton = TRUE; | |
883 | ||
884 | Private->SimplePointer.Reset = EmuGopSimplePointerReset; | |
885 | Private->SimplePointer.GetState = EmuGopSimplePointerGetState; | |
886 | Private->SimplePointer.Mode = &Private->PointerMode; | |
887 | ||
888 | Status = gBS->CreateEvent ( | |
889 | EVT_NOTIFY_WAIT, | |
890 | TPL_NOTIFY, | |
891 | EmuGopSimplePointerWaitForInput, | |
892 | Private, | |
893 | &Private->SimplePointer.WaitForInput | |
894 | ); | |
895 | ||
896 | return Status; | |
897 | } |