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