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