]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/EmuGopDxe/GopScreen.c
EmulatorPkg: Apply uncrustify changes
[mirror_edk2.git] / EmulatorPkg / EmuGopDxe / GopScreen.c
CommitLineData
79e4f2a5
RN
1/*++ @file\r
2\r
ce8c1d92 3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
79e4f2a5 4Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
e3ba31da 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
79e4f2a5
RN
6\r
7Module Name:\r
8\r
9 EmuGopScreen.c\r
10\r
11Abstract:\r
12\r
13 This file produces the graphics abstration of UGA. It is called by\r
14 EmuGopDriver.c file which deals with the EFI 1.1 driver model.\r
15 This file just does graphics.\r
16\r
17**/\r
18\r
19#include "Gop.h"\r
20\r
a550d468 21EFI_EVENT mGopScreenExitBootServicesEvent;\r
79e4f2a5 22\r
a550d468
MK
23GOP_MODE_DATA mGopModeData[] = {\r
24 { 800, 600, 0, 0 },\r
25 { 640, 480, 0, 0 },\r
26 { 720, 400, 0, 0 },\r
27 { 1024, 768, 0, 0 },\r
28 { 1280, 1024, 0, 0 }\r
29};\r
79e4f2a5
RN
30\r
31/**\r
32 Returns information for an available graphics mode that the graphics device\r
33 and the set of active video output devices supports.\r
34\r
35 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
36 @param ModeNumber The mode number to return information on.\r
37 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.\r
38 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.\r
39\r
40 @retval EFI_SUCCESS Mode information returned.\r
41 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.\r
42 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.\r
43 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()\r
44 @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
45\r
46**/\r
47EFI_STATUS\r
48EFIAPI\r
49EmuGopQuerytMode (\r
50 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
51 IN UINT32 ModeNumber,\r
52 OUT UINTN *SizeOfInfo,\r
53 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
54 )\r
55{\r
56 GOP_PRIVATE_DATA *Private;\r
57\r
58 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
59\r
a550d468 60 if ((Info == NULL) || (SizeOfInfo == NULL) || ((UINTN)ModeNumber >= This->Mode->MaxMode)) {\r
79e4f2a5
RN
61 return EFI_INVALID_PARAMETER;\r
62 }\r
63\r
64 *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
65 if (*Info == NULL) {\r
66 return EFI_OUT_OF_RESOURCES;\r
67 }\r
68\r
69 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
70\r
a550d468 71 (*Info)->Version = 0;\r
79e4f2a5
RN
72 (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
73 (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution;\r
a550d468
MK
74 (*Info)->PixelFormat = PixelBltOnly;\r
75 (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
79e4f2a5
RN
76\r
77 return EFI_SUCCESS;\r
78}\r
79\r
79e4f2a5
RN
80/**\r
81 Set the video device into the specified mode and clears the visible portions of\r
82 the output display to black.\r
83\r
84 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
85 @param ModeNumber Abstraction that defines the current video mode.\r
86\r
87 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.\r
88 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
89 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.\r
90\r
91**/\r
92EFI_STATUS\r
93EFIAPI\r
94EmuGopSetMode (\r
95 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
96 IN UINT32 ModeNumber\r
97 )\r
98{\r
a550d468
MK
99 EFI_STATUS Status;\r
100 GOP_PRIVATE_DATA *Private;\r
101 GOP_MODE_DATA *ModeData;\r
102 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;\r
79e4f2a5
RN
103\r
104 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
105\r
106 if (ModeNumber >= This->Mode->MaxMode) {\r
107 return EFI_UNSUPPORTED;\r
108 }\r
109\r
a550d468
MK
110 ModeData = &Private->ModeData[ModeNumber];\r
111 This->Mode->Mode = ModeNumber;\r
79e4f2a5 112 Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
a550d468
MK
113 Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
114 Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
79e4f2a5
RN
115\r
116 if (Private->HardwareNeedsStarting) {\r
117 Status = EmuGopStartWindow (\r
a550d468
MK
118 Private,\r
119 ModeData->HorizontalResolution,\r
120 ModeData->VerticalResolution,\r
121 ModeData->ColorDepth,\r
122 ModeData->RefreshRate\r
123 );\r
79e4f2a5
RN
124 if (EFI_ERROR (Status)) {\r
125 return EFI_DEVICE_ERROR;\r
126 }\r
127\r
128 Private->HardwareNeedsStarting = FALSE;\r
129 }\r
130\r
a550d468
MK
131 Status = Private->EmuGraphicsWindow->Size (\r
132 Private->EmuGraphicsWindow,\r
133 ModeData->HorizontalResolution,\r
134 ModeData->VerticalResolution\r
135 );\r
79e4f2a5 136\r
ce8c1d92
RN
137 Fill.Red = 0;\r
138 Fill.Green = 0;\r
139 Fill.Blue = 0;\r
79e4f2a5
RN
140 This->Blt (\r
141 This,\r
142 &Fill,\r
143 EfiBltVideoFill,\r
144 0,\r
145 0,\r
146 0,\r
147 0,\r
148 ModeData->HorizontalResolution,\r
149 ModeData->VerticalResolution,\r
150 ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
151 );\r
152 return EFI_SUCCESS;\r
153}\r
154\r
79e4f2a5
RN
155/**\r
156 Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
157\r
158 @param This Protocol instance pointer.\r
159 @param BltBuffer Buffer containing data to blit into video buffer. This\r
160 buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
161 @param BltOperation Operation to perform on BlitBuffer and video memory\r
162 @param SourceX X coordinate of source for the BltBuffer.\r
163 @param SourceY Y coordinate of source for the BltBuffer.\r
164 @param DestinationX X coordinate of destination for the BltBuffer.\r
165 @param DestinationY Y coordinate of destination for the BltBuffer.\r
166 @param Width Width of rectangle in BltBuffer in pixels.\r
167 @param Height Hight of rectangle in BltBuffer in pixels.\r
168 @param Delta OPTIONAL\r
169\r
170 @retval EFI_SUCCESS The Blt operation completed.\r
171 @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
f034c05c 172 @retval EFI_DEVICE_ERROR A hardware error occurred writting to the video buffer.\r
79e4f2a5
RN
173\r
174**/\r
175EFI_STATUS\r
176EFIAPI\r
177EmuGopBlt (\r
a550d468
MK
178 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
179 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
180 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
181 IN UINTN SourceX,\r
182 IN UINTN SourceY,\r
183 IN UINTN DestinationX,\r
184 IN UINTN DestinationY,\r
185 IN UINTN Width,\r
186 IN UINTN Height,\r
187 IN UINTN Delta OPTIONAL\r
79e4f2a5
RN
188 )\r
189{\r
a550d468
MK
190 GOP_PRIVATE_DATA *Private;\r
191 EFI_TPL OriginalTPL;\r
192 EFI_STATUS Status;\r
193 EMU_GRAPHICS_WINDOWS__BLT_ARGS GopBltArgs;\r
79e4f2a5
RN
194\r
195 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
196\r
197 if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {\r
198 return EFI_INVALID_PARAMETER;\r
199 }\r
200\r
a550d468 201 if ((Width == 0) || (Height == 0)) {\r
79e4f2a5
RN
202 return EFI_INVALID_PARAMETER;\r
203 }\r
a550d468 204\r
79e4f2a5
RN
205 //\r
206 // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
207 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
208 // the number of bytes in each row can be computed.\r
209 //\r
210 if (Delta == 0) {\r
211 Delta = Width * sizeof (EFI_UGA_PIXEL);\r
212 }\r
213\r
214 //\r
215 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
216 // We would not want a timer based event (Cursor, ...) to come in while we are\r
217 // doing this operation.\r
218 //\r
219 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
220\r
221 //\r
222 // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to\r
223 // GopBlt() API of Unix UGA IO protocol.\r
224 //\r
225 GopBltArgs.DestinationX = DestinationX;\r
226 GopBltArgs.DestinationY = DestinationY;\r
227 GopBltArgs.Height = Height;\r
228 GopBltArgs.Width = Width;\r
229 GopBltArgs.SourceX = SourceX;\r
230 GopBltArgs.SourceY = SourceY;\r
231 GopBltArgs.Delta = Delta;\r
a550d468
MK
232 Status = Private->EmuGraphicsWindow->Blt (\r
233 Private->EmuGraphicsWindow,\r
234 (EFI_UGA_PIXEL *)BltBuffer,\r
235 (EFI_UGA_BLT_OPERATION)BltOperation,\r
236 &GopBltArgs\r
237 );\r
79e4f2a5
RN
238\r
239 gBS->RestoreTPL (OriginalTPL);\r
240\r
241 return Status;\r
242}\r
243\r
79e4f2a5
RN
244//\r
245// Construction and Destruction functions\r
246//\r
247\r
248EFI_STATUS\r
249EmuGopSupported (\r
250 IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk\r
251 )\r
252{\r
253 //\r
254 // Check to see if the IO abstraction represents a device type we support.\r
255 //\r
256 // This would be replaced a check of PCI subsystem ID, etc.\r
257 //\r
258 if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) {\r
259 return EFI_UNSUPPORTED;\r
260 }\r
261\r
262 return EFI_SUCCESS;\r
263}\r
264\r
79e4f2a5
RN
265EFI_STATUS\r
266EmuGopStartWindow (\r
a550d468
MK
267 IN GOP_PRIVATE_DATA *Private,\r
268 IN UINT32 HorizontalResolution,\r
269 IN UINT32 VerticalResolution,\r
270 IN UINT32 ColorDepth,\r
271 IN UINT32 RefreshRate\r
79e4f2a5
RN
272 )\r
273{\r
a550d468 274 EFI_STATUS Status;\r
79e4f2a5
RN
275\r
276 //\r
277 // Register to be notified on exit boot services so we can destroy the window.\r
278 //\r
279 Status = gBS->CreateEvent (\r
280 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
281 TPL_CALLBACK,\r
282 ShutdownGopEvent,\r
283 Private,\r
284 &mGopScreenExitBootServicesEvent\r
285 );\r
286\r
287 Status = Private->EmuIoThunk->Open (Private->EmuIoThunk);\r
288 if (!EFI_ERROR (Status)) {\r
289 Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface;\r
290\r
291 // Register callback to support RegisterKeyNotify()\r
a550d468
MK
292 Status = Private->EmuGraphicsWindow->RegisterKeyNotify (\r
293 Private->EmuGraphicsWindow,\r
294 GopPrivateMakeCallbackFunction,\r
295 GopPrivateBreakCallbackFunction,\r
296 Private\r
297 );\r
79e4f2a5
RN
298 ASSERT_EFI_ERROR (Status);\r
299 }\r
a550d468 300\r
79e4f2a5
RN
301 return Status;\r
302}\r
303\r
304EFI_STATUS\r
305EmuGopConstructor (\r
a550d468 306 GOP_PRIVATE_DATA *Private\r
79e4f2a5
RN
307 )\r
308{\r
309 Private->ModeData = mGopModeData;\r
310\r
a550d468
MK
311 Private->GraphicsOutput.QueryMode = EmuGopQuerytMode;\r
312 Private->GraphicsOutput.SetMode = EmuGopSetMode;\r
313 Private->GraphicsOutput.Blt = EmuGopBlt;\r
79e4f2a5
RN
314\r
315 //\r
316 // Allocate buffer for Graphics Output Protocol mode information\r
317 //\r
318 Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
319 if (Private->GraphicsOutput.Mode == NULL) {\r
320 return EFI_OUT_OF_RESOURCES;\r
321 }\r
a550d468 322\r
79e4f2a5
RN
323 Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
324 if (Private->GraphicsOutput.Mode->Info == NULL) {\r
325 return EFI_OUT_OF_RESOURCES;\r
326 }\r
327\r
a550d468 328 Private->GraphicsOutput.Mode->MaxMode = sizeof (mGopModeData) / sizeof (GOP_MODE_DATA);\r
79e4f2a5
RN
329 //\r
330 // Till now, we have no idea about the window size.\r
331 //\r
a550d468
MK
332 Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
333 Private->GraphicsOutput.Mode->Info->Version = 0;\r
79e4f2a5 334 Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
a550d468
MK
335 Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
336 Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
337 Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
338 Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;\r
339 Private->GraphicsOutput.Mode->FrameBufferSize = 0;\r
79e4f2a5 340\r
a550d468
MK
341 Private->HardwareNeedsStarting = TRUE;\r
342 Private->EmuGraphicsWindow = NULL;\r
79e4f2a5
RN
343\r
344 EmuGopInitializeSimpleTextInForWindow (Private);\r
345\r
346 EmuGopInitializeSimplePointerForWindow (Private);\r
347\r
348 return EFI_SUCCESS;\r
349}\r
350\r
79e4f2a5
RN
351EFI_STATUS\r
352EmuGopDestructor (\r
a550d468 353 GOP_PRIVATE_DATA *Private\r
79e4f2a5
RN
354 )\r
355{\r
356 if (!Private->HardwareNeedsStarting) {\r
357 Private->EmuIoThunk->Close (Private->EmuIoThunk);\r
358 Private->EmuGraphicsWindow = NULL;\r
359 }\r
360\r
361 //\r
362 // Free graphics output protocol occupied resource\r
363 //\r
364 if (Private->GraphicsOutput.Mode != NULL) {\r
365 if (Private->GraphicsOutput.Mode->Info != NULL) {\r
366 FreePool (Private->GraphicsOutput.Mode->Info);\r
367 }\r
a550d468 368\r
79e4f2a5
RN
369 FreePool (Private->GraphicsOutput.Mode);\r
370 }\r
371\r
372 return EFI_SUCCESS;\r
373}\r
374\r
79e4f2a5
RN
375VOID\r
376EFIAPI\r
377ShutdownGopEvent (\r
378 IN EFI_EVENT Event,\r
379 IN VOID *Context\r
380 )\r
a550d468 381\r
79e4f2a5
RN
382/*++\r
383\r
384Routine Description:\r
385\r
386 This is the UGA screen's callback notification function for exit-boot-services.\r
387 All we do here is call EmuGopDestructor().\r
388\r
389Arguments:\r
390\r
391 Event - not used\r
392 Context - pointer to the Private structure.\r
393\r
394Returns:\r
395\r
396 None.\r
397\r
398**/\r
399{\r
400 EmuGopDestructor (Context);\r
401}\r