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