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