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