Add WinNtGop driver into Nt32Pkg
[mirror_edk2.git] / Nt32Pkg / WinNtGopDxe / WinNtGopInput.c
1 /** @file
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. 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 WinNtGopInput.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 // The package level header files this module uses
33 //
34 #include <Uefi.h>
35 #include <WinNtDxe.h>
36 //
37 // The protocols, PPI and GUID defintions for this module
38 //
39 #include <Guid/EventGroup.h>
40 #include <Protocol/WinNtIo.h>
41 #include <Protocol/ComponentName.h>
42 #include <Protocol/SimpleTextIn.h>
43 #include <Protocol/DriverBinding.h>
44 #include <Protocol/GraphicsOutput.h>
45 //
46 // The Library classes this module consumes
47 //
48 #include <Library/DebugLib.h>
49 #include <Library/BaseLib.h>
50 #include <Library/UefiDriverEntryPoint.h>
51 #include <Library/UefiLib.h>
52 #include <Library/BaseMemoryLib.h>
53 #include <Library/UefiBootServicesTableLib.h>
54 #include <Library/MemoryAllocationLib.h>
55
56 #include "WinNtGop.h"
57
58
59 /**
60 TODO: Add function description
61
62 @param Private TODO: add argument description
63
64 @retval EFI_SUCCESS TODO: Add description for return value
65
66 **/
67 EFI_STATUS
68 GopPrivateCreateQ (
69 IN GOP_PRIVATE_DATA *Private
70 )
71 {
72 Private->WinNtThunk->InitializeCriticalSection (&Private->QCriticalSection);
73
74 Private->Queue.Front = 0;
75 Private->Queue.Rear = MAX_Q - 1;
76 Private->Queue.Count = 0;
77 return EFI_SUCCESS;
78 }
79
80
81 /**
82 TODO: Add function description
83
84 @param Private TODO: add argument description
85
86 @retval EFI_SUCCESS TODO: Add description for return value
87
88 **/
89 EFI_STATUS
90 GopPrivateDestroyQ (
91 IN GOP_PRIVATE_DATA *Private
92 )
93 {
94 Private->Queue.Count = 0;
95 Private->WinNtThunk->DeleteCriticalSection (&Private->QCriticalSection);
96 return EFI_SUCCESS;
97 }
98
99
100 /**
101 TODO: Add function description
102
103 @param Private TODO: add argument description
104 @param Key TODO: add argument description
105
106 @retval EFI_NOT_READY TODO: Add description for return value
107 @retval EFI_SUCCESS TODO: Add description for return value
108
109 **/
110 EFI_STATUS
111 GopPrivateAddQ (
112 IN GOP_PRIVATE_DATA *Private,
113 IN EFI_INPUT_KEY Key
114 )
115 {
116 Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);
117
118 if (Private->Queue.Count == MAX_Q) {
119 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
120 return EFI_NOT_READY;
121 }
122
123 Private->Queue.Rear = (Private->Queue.Rear + 1) % MAX_Q;
124 Private->Queue.Q[Private->Queue.Rear] = Key;
125 Private->Queue.Count++;
126
127 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
128 return EFI_SUCCESS;
129 }
130
131
132 /**
133 TODO: Add function description
134
135 @param Private TODO: add argument description
136 @param Key TODO: add argument description
137
138 @retval EFI_NOT_READY TODO: Add description for return value
139 @retval EFI_SUCCESS TODO: Add description for return value
140
141 **/
142 EFI_STATUS
143 GopPrivateDeleteQ (
144 IN GOP_PRIVATE_DATA *Private,
145 OUT EFI_INPUT_KEY *Key
146 )
147 {
148 Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);
149
150 if (Private->Queue.Count == 0) {
151 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
152 return EFI_NOT_READY;
153 }
154
155 *Key = Private->Queue.Q[Private->Queue.Front];
156 Private->Queue.Front = (Private->Queue.Front + 1) % MAX_Q;
157 Private->Queue.Count--;
158
159 Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);
160 return EFI_SUCCESS;
161 }
162
163
164 /**
165 TODO: Add function description
166
167 @param Private TODO: add argument description
168
169 @retval EFI_NOT_READY TODO: Add description for return value
170 @retval EFI_SUCCESS TODO: Add description for return value
171
172 **/
173 EFI_STATUS
174 GopPrivateCheckQ (
175 IN GOP_PRIVATE_DATA *Private
176 )
177 {
178 if (Private->Queue.Count == 0) {
179 return EFI_NOT_READY;
180 }
181
182 return EFI_SUCCESS;
183 }
184
185 //
186 // Simple Text In implementation.
187 //
188
189
190 /**
191 TODO: Add function description
192
193 @param This TODO: add argument description
194 @param ExtendedVerification TODO: add argument description
195
196 @retval EFI_SUCCESS TODO: Add description for return value
197
198 **/
199 EFI_STATUS
200 EFIAPI
201 WinNtGopSimpleTextInReset (
202 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
203 IN BOOLEAN ExtendedVerification
204 )
205 {
206 GOP_PRIVATE_DATA *Private;
207 EFI_INPUT_KEY Key;
208 EFI_TPL OldTpl;
209
210 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
211
212 //
213 // Enter critical section
214 //
215 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
216
217 //
218 // A reset is draining the Queue
219 //
220 while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)
221 ;
222
223 //
224 // Leave critical section and return
225 //
226 gBS->RestoreTPL (OldTpl);
227 return EFI_SUCCESS;
228 }
229
230
231 /**
232 TODO: Add function description
233
234 @param This TODO: add argument description
235 @param Key TODO: add argument description
236
237 @return TODO: add return values
238
239 **/
240 STATIC
241 EFI_STATUS
242 EFIAPI
243 WinNtGopSimpleTextInReadKeyStroke (
244 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
245 OUT EFI_INPUT_KEY *Key
246 )
247 {
248 GOP_PRIVATE_DATA *Private;
249 EFI_STATUS Status;
250 EFI_TPL OldTpl;
251
252 Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
253
254 //
255 // Enter critical section
256 //
257 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
258
259 Status = GopPrivateCheckQ (Private);
260 if (!EFI_ERROR (Status)) {
261 //
262 // If a Key press exists try and read it.
263 //
264 Status = GopPrivateDeleteQ (Private, Key);
265 }
266
267 //
268 // Leave critical section and return
269 //
270 gBS->RestoreTPL (OldTpl);
271
272 return Status;
273 }
274
275
276 /**
277 TODO: Add function description
278
279 @param Event TODO: add argument description
280 @param Context TODO: add argument description
281
282 @return TODO: add return values
283
284 **/
285 STATIC
286 VOID
287 EFIAPI
288 WinNtGopSimpleTextInWaitForKey (
289 IN EFI_EVENT Event,
290 IN VOID *Context
291 )
292 {
293 GOP_PRIVATE_DATA *Private;
294 EFI_STATUS Status;
295 EFI_TPL OldTpl;
296
297 Private = (GOP_PRIVATE_DATA *) Context;
298
299 //
300 // Enter critical section
301 //
302 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
303
304 Status = GopPrivateCheckQ (Private);
305 if (!EFI_ERROR (Status)) {
306 //
307 // If a there is a key in the queue signal our event.
308 //
309 gBS->SignalEvent (Event);
310 } else {
311 //
312 // We need to sleep or NT will schedule this thread with such high
313 // priority that WinProc thread will never run and we will not see
314 // keyboard input. This Sleep makes the syste run 10x faster, so don't
315 // remove it.
316 //
317 Private->WinNtThunk->Sleep (1);
318 }
319
320 //
321 // Leave critical section and return
322 //
323 gBS->RestoreTPL (OldTpl);
324 }
325
326
327 /**
328 TODO: Add function description
329
330 @param Private TODO: add argument description
331
332 @return TODO: add return values
333
334 **/
335 EFI_STATUS
336 WinNtGopInitializeSimpleTextInForWindow (
337 IN GOP_PRIVATE_DATA *Private
338 )
339 {
340 EFI_STATUS Status;
341
342 GopPrivateCreateQ (Private);
343
344 //
345 // Initialize Simple Text In protoocol
346 //
347 Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;
348 Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;
349
350 Status = gBS->CreateEvent (
351 EVT_NOTIFY_WAIT,
352 TPL_NOTIFY,
353 WinNtGopSimpleTextInWaitForKey,
354 Private,
355 &Private->SimpleTextIn.WaitForKey
356 );
357
358 return Status;
359 }
360
361
362 /**
363 TODO: Add function description
364
365 @param Private TODO: add argument description
366
367 @retval EFI_SUCCESS TODO: Add description for return value
368
369 **/
370 EFI_STATUS
371 WinNtGopDestroySimpleTextInForWindow (
372 IN GOP_PRIVATE_DATA *Private
373 )
374 {
375 GopPrivateDestroyQ (Private);
376 return EFI_SUCCESS;
377 }