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