]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/Win/Host/WinGopInput.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmulatorPkg / Win / Host / WinGopInput.c
1 /** @file
2
3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 Module Name:
7
8 WinGopInput.c
9
10 Abstract:
11
12 This file produces the Simple Text In for an Gop window.
13
14 This stuff is linked at the hip to the Window, since the window
15 processing is done in a thread kicked off in WinNtGopImplementation.c
16
17 Since the window information is processed in an other thread we need
18 a keyboard Queue to pass data about. The Simple Text In code just
19 takes data off the Queue. The WinProc message loop takes keyboard input
20 and places it in the Queue.
21
22
23 **/
24
25 #include "WinGop.h"
26
27 /**
28 TODO: Add function description
29
30 @param Private TODO: add argument description
31
32 @retval EFI_SUCCESS TODO: Add description for return value
33
34 **/
35 EFI_STATUS
36 GopPrivateCreateQ (
37 IN GRAPHICS_PRIVATE_DATA *Private,
38 IN GOP_QUEUE_FIXED *Queue
39 )
40 {
41 InitializeCriticalSection (&Queue->Cs);
42 Queue->Front = 0;
43 Queue->Rear = 0;
44 return EFI_SUCCESS;
45 }
46
47 /**
48 TODO: Add function description
49
50 @param Private TODO: add argument description
51
52 @retval EFI_SUCCESS TODO: Add description for return value
53
54 **/
55 EFI_STATUS
56 GopPrivateDestroyQ (
57 IN GRAPHICS_PRIVATE_DATA *Private,
58 IN GOP_QUEUE_FIXED *Queue
59 )
60 {
61 Queue->Front = 0;
62 Queue->Rear = 0;
63 DeleteCriticalSection (&Queue->Cs);
64 return EFI_SUCCESS;
65 }
66
67 /**
68 TODO: Add function description
69
70 @param Private TODO: add argument description
71 @param Key TODO: add argument description
72
73 @retval EFI_NOT_READY TODO: Add description for return value
74 @retval EFI_SUCCESS TODO: Add description for return value
75
76 **/
77 EFI_STATUS
78 GopPrivateAddQ (
79 IN GRAPHICS_PRIVATE_DATA *Private,
80 IN GOP_QUEUE_FIXED *Queue,
81 IN EFI_KEY_DATA *KeyData
82 )
83 {
84 EnterCriticalSection (&Queue->Cs);
85
86 if ((Queue->Rear + 1) % MAX_Q == Queue->Front) {
87 LeaveCriticalSection (&Queue->Cs);
88 return EFI_NOT_READY;
89 }
90
91 CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
92 Queue->Rear = (Queue->Rear + 1) % MAX_Q;
93
94 LeaveCriticalSection (&Queue->Cs);
95 return EFI_SUCCESS;
96 }
97
98 /**
99 TODO: Add function description
100
101 @param Private TODO: add argument description
102 @param Key TODO: add argument description
103
104 @retval EFI_NOT_READY TODO: Add description for return value
105 @retval EFI_SUCCESS TODO: Add description for return value
106
107 **/
108 EFI_STATUS
109 GopPrivateDeleteQ (
110 IN GRAPHICS_PRIVATE_DATA *Private,
111 IN GOP_QUEUE_FIXED *Queue,
112 OUT EFI_KEY_DATA *Key
113 )
114 {
115 EnterCriticalSection (&Queue->Cs);
116
117 if (Queue->Front == Queue->Rear) {
118 LeaveCriticalSection (&Queue->Cs);
119 return EFI_NOT_READY;
120 }
121
122 CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA));
123 Queue->Front = (Queue->Front + 1) % MAX_Q;
124
125 if ((Key->Key.ScanCode == SCAN_NULL) && (Key->Key.UnicodeChar == CHAR_NULL)) {
126 if (!Private->IsPartialKeySupport) {
127 //
128 // If partial keystrok is not enabled, don't return the partial keystroke.
129 //
130 LeaveCriticalSection (&Queue->Cs);
131 ZeroMem (Key, sizeof (EFI_KEY_DATA));
132 return EFI_NOT_READY;
133 }
134 }
135
136 LeaveCriticalSection (&Queue->Cs);
137 return EFI_SUCCESS;
138 }
139
140 /**
141 TODO: Add function description
142
143 @param Private TODO: add argument description
144
145 @retval EFI_NOT_READY TODO: Add description for return value
146 @retval EFI_SUCCESS TODO: Add description for return value
147
148 **/
149 EFI_STATUS
150 GopPrivateCheckQ (
151 IN GOP_QUEUE_FIXED *Queue
152 )
153 {
154 if (Queue->Front == Queue->Rear) {
155 return EFI_NOT_READY;
156 }
157
158 return EFI_SUCCESS;
159 }
160
161 /**
162 Initialize the key state.
163
164 @param Private The GOP_PRIVATE_DATA instance.
165 @param KeyState A pointer to receive the key state information.
166 **/
167 VOID
168 InitializeKeyState (
169 IN GRAPHICS_PRIVATE_DATA *Private,
170 IN EFI_KEY_STATE *KeyState
171 )
172 {
173 KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID;
174 KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;
175
176 //
177 // Record Key shift state and toggle state
178 //
179 if (Private->LeftCtrl) {
180 KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
181 }
182
183 if (Private->RightCtrl) {
184 KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
185 }
186
187 if (Private->LeftAlt) {
188 KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;
189 }
190
191 if (Private->RightAlt) {
192 KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
193 }
194
195 if (Private->LeftShift) {
196 KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
197 }
198
199 if (Private->RightShift) {
200 KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
201 }
202
203 if (Private->LeftLogo) {
204 KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
205 }
206
207 if (Private->RightLogo) {
208 KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
209 }
210
211 if (Private->Menu) {
212 KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;
213 }
214
215 if (Private->SysReq) {
216 KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;
217 }
218
219 if (Private->CapsLock) {
220 KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
221 }
222
223 if (Private->NumLock) {
224 KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
225 }
226
227 if (Private->ScrollLock) {
228 KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
229 }
230
231 if (Private->IsPartialKeySupport) {
232 KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;
233 }
234 }
235
236 /**
237 TODO: Add function description
238
239 @param Private TODO: add argument description
240 @param Key TODO: add argument description
241
242 @retval EFI_NOT_READY TODO: Add description for return value
243 @retval EFI_SUCCESS TODO: Add description for return value
244
245 **/
246 EFI_STATUS
247 GopPrivateAddKey (
248 IN GRAPHICS_PRIVATE_DATA *Private,
249 IN EFI_INPUT_KEY Key
250 )
251 {
252 EFI_KEY_DATA KeyData;
253
254 KeyData.Key = Key;
255 InitializeKeyState (Private, &KeyData.KeyState);
256
257 //
258 // Convert Ctrl+[1-26] to Ctrl+[A-Z]
259 //
260 if ((Private->LeftCtrl || Private->RightCtrl) &&
261 (KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)
262 )
263 {
264 if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {
265 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1);
266 } else {
267 KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1);
268 }
269 }
270
271 //
272 // Unmask the Shift bit for printable char
273 //
274 if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) ||
275 ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z'))
276 )
277 {
278 KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
279 }
280
281 GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData);
282 if (Private->MakeRegisterdKeyCallback != NULL) {
283 Private->MakeRegisterdKeyCallback (Private->RegisterdKeyCallbackContext, &KeyData);
284 }
285
286 return EFI_SUCCESS;
287 }
288
289 EFI_STATUS
290 EFIAPI
291 WinNtWndCheckKey (
292 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo
293 )
294 {
295 GRAPHICS_PRIVATE_DATA *Private;
296
297 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
298
299 return GopPrivateCheckQ (&Private->QueueForRead);
300 }
301
302 EFI_STATUS
303 EFIAPI
304 WinNtWndGetKey (
305 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
306 IN EFI_KEY_DATA *KeyData
307 )
308
309 /*++
310
311 Routine Description:
312 Reads the next keystroke from the input device. The WaitForKey Event can
313 be used to test for existence of a keystroke via WaitForEvent () call.
314
315 Arguments:
316 Private - The private structure of WinNt Gop device.
317 KeyData - A pointer to a buffer that is filled in with the keystroke
318 state data for the key that was pressed.
319
320 Returns:
321 EFI_SUCCESS - The keystroke information was returned.
322 EFI_NOT_READY - There was no keystroke data available.
323 EFI_DEVICE_ERROR - The keystroke information was not returned due to
324 hardware errors.
325 EFI_INVALID_PARAMETER - KeyData is NULL.
326
327 --*/
328 {
329 EFI_STATUS Status;
330 GRAPHICS_PRIVATE_DATA *Private;
331
332 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
333
334 ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
335 InitializeKeyState (Private, &KeyData->KeyState);
336
337 Status = GopPrivateCheckQ (&Private->QueueForRead);
338 if (!EFI_ERROR (Status)) {
339 //
340 // If a Key press exists try and read it.
341 //
342 Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData);
343 if (!EFI_ERROR (Status)) {
344 //
345 // If partial keystroke is not enabled, check whether it is value key. If not return
346 // EFI_NOT_READY.
347 //
348 if (!Private->IsPartialKeySupport) {
349 if ((KeyData->Key.ScanCode == SCAN_NULL) && (KeyData->Key.UnicodeChar == CHAR_NULL)) {
350 Status = EFI_NOT_READY;
351 }
352 }
353 }
354 }
355
356 return Status;
357 }
358
359 EFI_STATUS
360 EFIAPI
361 WinNtWndKeySetState (
362 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
363 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
364 )
365 {
366 GRAPHICS_PRIVATE_DATA *Private;
367
368 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
369 Private->ScrollLock = FALSE;
370 Private->NumLock = FALSE;
371 Private->CapsLock = FALSE;
372 Private->IsPartialKeySupport = FALSE;
373
374 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
375 Private->ScrollLock = TRUE;
376 }
377
378 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
379 Private->NumLock = TRUE;
380 }
381
382 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
383 Private->CapsLock = TRUE;
384 }
385
386 if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
387 Private->IsPartialKeySupport = TRUE;
388 }
389
390 Private->KeyState.KeyToggleState = *KeyToggleState;
391 return EFI_SUCCESS;
392 }
393
394 EFI_STATUS
395 EFIAPI
396 WinNtWndRegisterKeyNotify (
397 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
398 IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack,
399 IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack,
400 IN VOID *Context
401 )
402 {
403 GRAPHICS_PRIVATE_DATA *Private;
404
405 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
406
407 Private->MakeRegisterdKeyCallback = MakeCallBack;
408 Private->BreakRegisterdKeyCallback = BreakCallBack;
409 Private->RegisterdKeyCallbackContext = Context;
410
411 return EFI_SUCCESS;
412 }
413
414 EFI_STATUS
415 EFIAPI
416 WinNtWndCheckPointer (
417 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo
418 )
419 {
420 GRAPHICS_PRIVATE_DATA *Private;
421
422 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
423
424 if (!Private->PointerStateChanged) {
425 return EFI_NOT_READY;
426 }
427
428 return EFI_SUCCESS;
429 }
430
431 EFI_STATUS
432 EFIAPI
433 WinNtWndGetPointerState (
434 IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
435 IN EFI_SIMPLE_POINTER_STATE *State
436 )
437 {
438 GRAPHICS_PRIVATE_DATA *Private;
439
440 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
441
442 if (!Private->PointerStateChanged) {
443 return EFI_NOT_READY;
444 }
445
446 State->RelativeMovementX = Private->PointerState.RelativeMovementX;
447 State->RelativeMovementY = Private->PointerState.RelativeMovementY;
448 State->RelativeMovementZ = Private->PointerState.RelativeMovementZ;
449 State->LeftButton = Private->PointerState.LeftButton;
450 State->RightButton = Private->PointerState.RightButton;
451
452 Private->PointerState.RelativeMovementX = 0;
453 Private->PointerState.RelativeMovementY = 0;
454 Private->PointerState.RelativeMovementZ = 0;
455
456 Private->PointerStateChanged = FALSE;
457
458 return EFI_SUCCESS;
459 }