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