]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/UnixUgaDxe/UnixUgaScreen.c
85c104331bcc7480188ca9336384f34e47d1449e
[mirror_edk2.git] / UnixPkg / UnixUgaDxe / UnixUgaScreen.c
1 /*++
2
3 Copyright (c) 2006 - 2010, 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 UnixUgaScreen.c
15
16 Abstract:
17
18 This file produces the graphics abstration of UGA. It is called by
19 UnixUgaDriver.c file which deals with the EFI 1.1 driver model.
20 This file just does graphics.
21
22 --*/
23
24 #include "UnixUga.h"
25
26 EFI_UNIX_THUNK_PROTOCOL *mUnix;
27 EFI_EVENT mUgaScreenExitBootServicesEvent;
28
29 EFI_STATUS
30 UnixUgaStartWindow (
31 IN UGA_PRIVATE_DATA *Private,
32 IN UINT32 HorizontalResolution,
33 IN UINT32 VerticalResolution,
34 IN UINT32 ColorDepth,
35 IN UINT32 RefreshRate
36 );
37
38 VOID
39 EFIAPI
40 KillNtUgaThread (
41 IN EFI_EVENT Event,
42 IN VOID *Context
43 );
44
45 //
46 // UGA Protocol Member Functions
47 //
48
49 EFI_STATUS
50 EFIAPI
51 UnixUgaGetMode (
52 EFI_UGA_DRAW_PROTOCOL *This,
53 UINT32 *HorizontalResolution,
54 UINT32 *VerticalResolution,
55 UINT32 *ColorDepth,
56 UINT32 *RefreshRate
57 )
58 /*++
59
60 Routine Description:
61 Return the current video mode information.
62
63 Arguments:
64 This - Protocol instance pointer.
65 HorizontalResolution - Current video horizontal resolution in pixels
66 VerticalResolution - Current video Vertical resolution in pixels
67 ColorDepth - Current video color depth in bits per pixel
68 RefreshRate - Current video refresh rate in Hz.
69
70 Returns:
71 EFI_SUCCESS - Mode information returned.
72 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
73 EFI_INVALID_PARAMETER - One of the input args was NULL.
74
75 --*/
76 // TODO: ADD IN/OUT description here
77 {
78 UGA_PRIVATE_DATA *Private;
79
80 Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
81
82 if (Private->HardwareNeedsStarting) {
83 return EFI_NOT_STARTED;
84 }
85
86 if ((HorizontalResolution == NULL) ||
87 (VerticalResolution == NULL) ||
88 (ColorDepth == NULL) ||
89 (RefreshRate == NULL)) {
90 return EFI_INVALID_PARAMETER;
91 }
92
93 *HorizontalResolution = Private->HorizontalResolution;
94 *VerticalResolution = Private->VerticalResolution;
95 *ColorDepth = Private->ColorDepth;
96 *RefreshRate = Private->RefreshRate;
97 return EFI_SUCCESS;
98 }
99
100 EFI_STATUS
101 EFIAPI
102 UnixUgaSetMode (
103 EFI_UGA_DRAW_PROTOCOL *This,
104 UINT32 HorizontalResolution,
105 UINT32 VerticalResolution,
106 UINT32 ColorDepth,
107 UINT32 RefreshRate
108 )
109 /*++
110
111 Routine Description:
112 Return the current video mode information.
113
114 Arguments:
115 This - Protocol instance pointer.
116 HorizontalResolution - Current video horizontal resolution in pixels
117 VerticalResolution - Current video Vertical resolution in pixels
118 ColorDepth - Current video color depth in bits per pixel
119 RefreshRate - Current video refresh rate in Hz.
120
121 Returns:
122 EFI_SUCCESS - Mode information returned.
123 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
124 EFI_INVALID_PARAMETER - One of the input args was NULL.
125
126 --*/
127 // TODO: EFI_DEVICE_ERROR - add return value to function comment
128 // TODO: EFI_DEVICE_ERROR - add return value to function comment
129 // TODO: ADD IN/OUT description here
130 {
131 EFI_STATUS Status;
132 UGA_PRIVATE_DATA *Private;
133 EFI_UGA_PIXEL Fill;
134
135 Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
136
137 if (Private->HardwareNeedsStarting) {
138 Status = UnixUgaStartWindow (
139 Private,
140 HorizontalResolution,
141 VerticalResolution,
142 ColorDepth,
143 RefreshRate
144 );
145 if (EFI_ERROR (Status)) {
146 return EFI_DEVICE_ERROR;
147 }
148
149 Private->HardwareNeedsStarting = FALSE;
150 }
151 Status = Private->UgaIo->UgaSize(Private->UgaIo,
152 HorizontalResolution,
153 VerticalResolution);
154
155 Private->HorizontalResolution = HorizontalResolution;
156 Private->VerticalResolution = VerticalResolution;
157 Private->ColorDepth = ColorDepth;
158 Private->RefreshRate = RefreshRate;
159
160 Fill.Red = 0x7f;
161 Fill.Green = 0x7F;
162 Fill.Blue = 0x7f;
163 This->Blt (
164 This,
165 &Fill,
166 EfiUgaVideoFill,
167 0,
168 0,
169 0,
170 0,
171 HorizontalResolution,
172 VerticalResolution,
173 HorizontalResolution * sizeof (EFI_UGA_PIXEL)
174 );
175 return EFI_SUCCESS;
176 }
177
178 EFI_STATUS
179 EFIAPI
180 UnixUgaBlt (
181 IN EFI_UGA_DRAW_PROTOCOL *This,
182 IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
183 IN EFI_UGA_BLT_OPERATION BltOperation,
184 IN UINTN SourceX,
185 IN UINTN SourceY,
186 IN UINTN DestinationX,
187 IN UINTN DestinationY,
188 IN UINTN Width,
189 IN UINTN Height,
190 IN UINTN Delta OPTIONAL
191 )
192 /*++
193
194 Routine Description:
195 Blt pixels from the rectangle (Width X Height) formed by the BltBuffer
196 onto the graphics screen starting a location (X, Y). (0, 0) is defined as
197 the upper left hand side of the screen. (X, Y) can be outside of the
198 current screen geometry and the BltBuffer will be cliped when it is
199 displayed. X and Y can be negative or positive. If Width or Height is
200 bigger than the current video screen the image will be clipped.
201
202 Arguments:
203 This - Protocol instance pointer.
204 X - X location on graphics screen.
205 Y - Y location on the graphics screen.
206 Width - Width of BltBuffer.
207 Height - Hight of BltBuffer
208 BltOperation - Operation to perform on BltBuffer and video memory
209 BltBuffer - Buffer containing data to blt into video buffer. This
210 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
211 SourceX - If the BltOperation is a EfiCopyBlt this is the source
212 of the copy. For other BLT operations this argument is not
213 used.
214 SourceX - If the BltOperation is a EfiCopyBlt this is the source
215 of the copy. For other BLT operations this argument is not
216 used.
217
218 Returns:
219 EFI_SUCCESS - The palette is updated with PaletteArray.
220 EFI_INVALID_PARAMETER - BltOperation is not valid.
221 EFI_DEVICE_ERROR - A hardware error occured writting to the video
222 buffer.
223
224 --*/
225 // TODO: SourceY - add argument and description to function comment
226 // TODO: DestinationX - add argument and description to function comment
227 // TODO: DestinationY - add argument and description to function comment
228 // TODO: Delta - add argument and description to function comment
229 {
230 UGA_PRIVATE_DATA *Private;
231 EFI_TPL OriginalTPL;
232 EFI_STATUS Status;
233 UGA_BLT_ARGS UgaBltArgs;
234
235 Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);
236
237 if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {
238 return EFI_INVALID_PARAMETER;
239 }
240
241 if (Width == 0 || Height == 0) {
242 return EFI_INVALID_PARAMETER;
243 }
244 //
245 // If Delta is zero, then the entire BltBuffer is being used, so Delta
246 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
247 // the number of bytes in each row can be computed.
248 //
249 if (Delta == 0) {
250 Delta = Width * sizeof (EFI_UGA_PIXEL);
251 }
252
253 //
254 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
255 // We would not want a timer based event (Cursor, ...) to come in while we are
256 // doing this operation.
257 //
258 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
259
260 //
261 // Package UGA Draw protocol parameters to UGA_BLT_ARGS structure to adapt to Unix UGA IO protocol.
262 //
263 UgaBltArgs.DestinationX = DestinationX;
264 UgaBltArgs.DestinationY = DestinationY;
265 UgaBltArgs.Height = Height;
266 UgaBltArgs.Width = Width;
267 UgaBltArgs.SourceX = SourceX;
268 UgaBltArgs.SourceY = SourceY;
269 UgaBltArgs.Delta = Delta;
270 Status = Private->UgaIo->UgaBlt (Private->UgaIo,
271 BltBuffer,
272 BltOperation,
273 &UgaBltArgs
274 );
275
276 gBS->RestoreTPL (OriginalTPL);
277
278 return Status;
279 }
280
281
282 //
283 // Construction and Destruction functions
284 //
285
286 EFI_STATUS
287 UnixUgaSupported (
288 IN EFI_UNIX_IO_PROTOCOL *UnixIo
289 )
290 /*++
291
292 Routine Description:
293
294 Arguments:
295
296 Returns:
297
298 None
299
300 --*/
301 // TODO: UnixIo - add argument and description to function comment
302 // TODO: EFI_UNSUPPORTED - add return value to function comment
303 // TODO: EFI_SUCCESS - add return value to function comment
304 {
305 //
306 // Check to see if the IO abstraction represents a device type we support.
307 //
308 // This would be replaced a check of PCI subsystem ID, etc.
309 //
310 if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixUgaGuid)) {
311 return EFI_UNSUPPORTED;
312 }
313
314 return EFI_SUCCESS;
315 }
316
317
318 EFI_STATUS
319 UnixUgaStartWindow (
320 IN UGA_PRIVATE_DATA *Private,
321 IN UINT32 HorizontalResolution,
322 IN UINT32 VerticalResolution,
323 IN UINT32 ColorDepth,
324 IN UINT32 RefreshRate
325 )
326 /*++
327
328 Routine Description:
329
330 TODO: Add function description
331
332 Arguments:
333
334 Private - TODO: add argument description
335 HorizontalResolution - TODO: add argument description
336 VerticalResolution - TODO: add argument description
337 ColorDepth - TODO: add argument description
338 RefreshRate - TODO: add argument description
339
340 Returns:
341
342 TODO: add return values
343
344 --*/
345 {
346 EFI_STATUS Status;
347
348 mUnix = Private->UnixThunk;
349
350 Private->HorizontalResolution = HorizontalResolution;
351 Private->VerticalResolution = VerticalResolution;
352
353 //
354 // Register to be notified on exit boot services so we can destroy the window.
355 //
356 Status = gBS->CreateEvent (
357 EVT_SIGNAL_EXIT_BOOT_SERVICES,
358 TPL_CALLBACK,
359 KillNtUgaThread,
360 Private,
361 &mUgaScreenExitBootServicesEvent
362 );
363
364 Status = Private->UnixThunk->UgaCreate(&Private->UgaIo, Private->WindowName);
365 return Status;
366 }
367
368 EFI_STATUS
369 UnixUgaConstructor (
370 UGA_PRIVATE_DATA *Private
371 )
372 /*++
373
374 Routine Description:
375
376 Arguments:
377
378 Returns:
379
380 None
381
382 --*/
383 // TODO: Private - add argument and description to function comment
384 // TODO: EFI_SUCCESS - add return value to function comment
385 {
386
387 Private->UgaDraw.GetMode = UnixUgaGetMode;
388 Private->UgaDraw.SetMode = UnixUgaSetMode;
389 Private->UgaDraw.Blt = UnixUgaBlt;
390
391 Private->HardwareNeedsStarting = TRUE;
392 Private->UgaIo = NULL;
393
394 UnixUgaInitializeSimpleTextInForWindow (Private);
395
396 return EFI_SUCCESS;
397 }
398
399 EFI_STATUS
400 UnixUgaDestructor (
401 UGA_PRIVATE_DATA *Private
402 )
403 /*++
404
405 Routine Description:
406
407 Arguments:
408
409 Returns:
410
411 None
412
413 --*/
414 // TODO: Private - add argument and description to function comment
415 // TODO: EFI_SUCCESS - add return value to function comment
416 {
417 if (!Private->HardwareNeedsStarting) {
418 Private->UgaIo->UgaClose(Private->UgaIo);
419 Private->UgaIo = NULL;
420 }
421
422 return EFI_SUCCESS;
423 }
424
425 VOID
426 EFIAPI
427 KillNtUgaThread (
428 IN EFI_EVENT Event,
429 IN VOID *Context
430 )
431 /*++
432
433 Routine Description:
434
435 This is the UGA screen's callback notification function for exit-boot-services.
436 All we do here is call UnixUgaDestructor().
437
438 Arguments:
439
440 Event - not used
441 Context - pointer to the Private structure.
442
443 Returns:
444
445 None.
446
447 --*/
448 {
449 EFI_STATUS Status;
450 Status = UnixUgaDestructor (Context);
451 }