3 Copyright (c) 2006 - 2007, 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
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.
18 This file produces the graphics abstration of UGA. It is called by
19 WinNtUgaDriver.c file which deals with the EFI 1.1 driver model.
20 This file just does graphics.
26 EFI_WIN_NT_THUNK_PROTOCOL
*mWinNt
;
27 DWORD mTlsIndex
= TLS_OUT_OF_INDEXES
;
28 DWORD mTlsIndexUseCount
= 0; // lets us know when we can free mTlsIndex.
29 static EFI_EVENT mUgaScreenExitBootServicesEvent
;
33 IN UGA_PRIVATE_DATA
*Private
,
34 IN UINT32 HorizontalResolution
,
35 IN UINT32 VerticalResolution
,
49 // UGA Protocol Member Functions
55 EFI_UGA_DRAW_PROTOCOL
*This
,
56 UINT32
*HorizontalResolution
,
57 UINT32
*VerticalResolution
,
64 Return the current video mode information.
67 This - Protocol instance pointer.
68 HorizontalResolution - Current video horizontal resolution in pixels
69 VerticalResolution - Current video Vertical resolution in pixels
70 ColorDepth - Current video color depth in bits per pixel
71 RefreshRate - Current video refresh rate in Hz.
74 EFI_SUCCESS - Mode information returned.
75 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
76 EFI_INVALID_PARAMETER - One of the input args was NULL.
79 // TODO: ADD IN/OUT description here
81 UGA_PRIVATE_DATA
*Private
;
83 Private
= UGA_DRAW_PRIVATE_DATA_FROM_THIS (This
);
85 if (Private
->HardwareNeedsStarting
) {
86 return EFI_NOT_STARTED
;
89 if ((HorizontalResolution
== NULL
) ||
90 (VerticalResolution
== NULL
) ||
91 (ColorDepth
== NULL
) ||
92 (RefreshRate
== NULL
)) {
93 return EFI_INVALID_PARAMETER
;
96 *HorizontalResolution
= Private
->HorizontalResolution
;
97 *VerticalResolution
= Private
->VerticalResolution
;
98 *ColorDepth
= Private
->ColorDepth
;
99 *RefreshRate
= Private
->RefreshRate
;
106 EFI_UGA_DRAW_PROTOCOL
*This
,
107 UINT32 HorizontalResolution
,
108 UINT32 VerticalResolution
,
115 Return the current video mode information.
118 This - Protocol instance pointer.
119 HorizontalResolution - Current video horizontal resolution in pixels
120 VerticalResolution - Current video Vertical resolution in pixels
121 ColorDepth - Current video color depth in bits per pixel
122 RefreshRate - Current video refresh rate in Hz.
125 EFI_SUCCESS - Mode information returned.
126 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
127 EFI_INVALID_PARAMETER - One of the input args was NULL.
130 // TODO: EFI_DEVICE_ERROR - add return value to function comment
131 // TODO: EFI_DEVICE_ERROR - add return value to function comment
132 // TODO: ADD IN/OUT description here
135 UGA_PRIVATE_DATA
*Private
;
137 EFI_UGA_PIXEL
*NewFillLine
;
143 Private
= UGA_DRAW_PRIVATE_DATA_FROM_THIS (This
);
145 if (Private
->HardwareNeedsStarting
) {
146 Status
= WinNtUgaStartWindow (
148 HorizontalResolution
,
153 if (EFI_ERROR (Status
)) {
154 return EFI_DEVICE_ERROR
;
157 Private
->HardwareNeedsStarting
= FALSE
;
160 // Change the resolution and resize of the window
164 // Free the old buffer. We do not save the content of the old buffer since the
165 // screen is to be cleared anyway. Clearing the screen is required by the EFI spec.
166 // See EFI spec chepter 10.5-EFI_UGA_DRAW_PROTOCOL.SetMode()
168 Private
->WinNtThunk
->HeapFree (Private
->WinNtThunk
->GetProcessHeap (), 0, Private
->VirtualScreenInfo
);
171 // Allocate DIB frame buffer directly from NT for performance enhancement
172 // This buffer is the virtual screen/frame buffer. This buffer is not the
173 // same a a frame buffer. The first row of this buffer will be the bottom
174 // line of the image. This is an artifact of the way we draw to the screen.
176 Size
= HorizontalResolution
* VerticalResolution
* sizeof (RGBQUAD
) + sizeof (BITMAPV4HEADER
);
177 Private
->VirtualScreenInfo
= Private
->WinNtThunk
->HeapAlloc (
178 Private
->WinNtThunk
->GetProcessHeap (),
184 // Update the virtual screen info data structure
186 Private
->VirtualScreenInfo
->bV4Size
= sizeof (BITMAPV4HEADER
);
187 Private
->VirtualScreenInfo
->bV4Width
= HorizontalResolution
;
188 Private
->VirtualScreenInfo
->bV4Height
= VerticalResolution
;
189 Private
->VirtualScreenInfo
->bV4Planes
= 1;
190 Private
->VirtualScreenInfo
->bV4BitCount
= 32;
194 Private
->VirtualScreenInfo
->bV4V4Compression
= BI_RGB
;
197 // The rest of the allocated memory block is the virtual screen buffer
199 Private
->VirtualScreen
= (RGBQUAD
*) (Private
->VirtualScreenInfo
+ 1);
202 // Use the AdjuctWindowRect fuction to calculate the real width and height
203 // of the new window including the border and caption
207 Rect
.right
= HorizontalResolution
;
208 Rect
.bottom
= VerticalResolution
;
210 Private
->WinNtThunk
->AdjustWindowRect (&Rect
, WS_OVERLAPPEDWINDOW
, 0);
212 Width
= Rect
.right
- Rect
.left
;
213 Height
= Rect
.bottom
- Rect
.top
;
216 // Retrieve the original window position information
218 Private
->WinNtThunk
->GetWindowRect (Private
->WindowHandle
, &Rect
);
221 // Adjust the window size
223 Private
->WinNtThunk
->MoveWindow (Private
->WindowHandle
, Rect
.left
, Rect
.top
, Width
, Height
, TRUE
);
227 NewFillLine
= AllocatePool (sizeof (EFI_UGA_PIXEL
) * HorizontalResolution
);
228 if (NewFillLine
== NULL
) {
229 return EFI_DEVICE_ERROR
;
232 if (Private
->FillLine
!= NULL
) {
233 FreePool (Private
->FillLine
);
236 Private
->FillLine
= NewFillLine
;
238 Private
->HorizontalResolution
= HorizontalResolution
;
239 Private
->VerticalResolution
= VerticalResolution
;
240 Private
->ColorDepth
= ColorDepth
;
241 Private
->RefreshRate
= RefreshRate
;
254 HorizontalResolution
,
256 HorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
264 IN EFI_UGA_DRAW_PROTOCOL
*This
,
265 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
266 IN EFI_UGA_BLT_OPERATION BltOperation
,
269 IN UINTN DestinationX
,
270 IN UINTN DestinationY
,
273 IN UINTN Delta OPTIONAL
278 Blt pixels from the rectangle (Width X Height) formed by the BltBuffer
279 onto the graphics screen starting a location (X, Y). (0, 0) is defined as
280 the upper left hand side of the screen. (X, Y) can be outside of the
281 current screen geometry and the BltBuffer will be cliped when it is
282 displayed. X and Y can be negative or positive. If Width or Height is
283 bigger than the current video screen the image will be clipped.
286 This - Protocol instance pointer.
287 X - X location on graphics screen.
288 Y - Y location on the graphics screen.
289 Width - Width of BltBuffer.
290 Height - Hight of BltBuffer
291 BltOperation - Operation to perform on BltBuffer and video memory
292 BltBuffer - Buffer containing data to blt into video buffer. This
293 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
294 SourceX - If the BltOperation is a EfiCopyBlt this is the source
295 of the copy. For other BLT operations this argument is not
297 SourceX - If the BltOperation is a EfiCopyBlt this is the source
298 of the copy. For other BLT operations this argument is not
302 EFI_SUCCESS - The palette is updated with PaletteArray.
303 EFI_INVALID_PARAMETER - BltOperation is not valid.
304 EFI_DEVICE_ERROR - A hardware error occured writting to the video
308 // TODO: SourceY - add argument and description to function comment
309 // TODO: DestinationX - add argument and description to function comment
310 // TODO: DestinationY - add argument and description to function comment
311 // TODO: Delta - add argument and description to function comment
313 UGA_PRIVATE_DATA
*Private
;
322 EFI_UGA_PIXEL
*FillPixel
;
324 Private
= UGA_DRAW_PRIVATE_DATA_FROM_THIS (This
);
326 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
327 return EFI_INVALID_PARAMETER
;
330 if (Width
== 0 || Height
== 0) {
331 return EFI_INVALID_PARAMETER
;
334 // If Delta is zero, then the entire BltBuffer is being used, so Delta
335 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
336 // the number of bytes in each row can be computed.
339 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
343 // We need to fill the Virtual Screen buffer with the blt data.
344 // The virtual screen is upside down, as the first row is the bootom row of
348 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
351 // Video to BltBuffer: Source is Video, destination is BltBuffer
353 if (SourceY
+ Height
> Private
->VerticalResolution
) {
354 return EFI_INVALID_PARAMETER
;
357 if (SourceX
+ Width
> Private
->HorizontalResolution
) {
358 return EFI_INVALID_PARAMETER
;
361 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
362 // We would not want a timer based event (Cursor, ...) to come in while we are
363 // doing this operation.
365 OriginalTPL
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
367 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
368 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + DestinationX
* sizeof (EFI_UGA_PIXEL
));
369 VScreen
= &Private
->VirtualScreen
[(Private
->VerticalResolution
- SrcY
- 1) * Private
->HorizontalResolution
+ SourceX
];
370 CopyMem (Blt
, VScreen
, sizeof (EFI_UGA_PIXEL
) * Width
);
374 // BltBuffer to Video: Source is BltBuffer, destination is Video
376 if (DestinationY
+ Height
> Private
->VerticalResolution
) {
377 return EFI_INVALID_PARAMETER
;
380 if (DestinationX
+ Width
> Private
->HorizontalResolution
) {
381 return EFI_INVALID_PARAMETER
;
385 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
386 // We would not want a timer based event (Cursor, ...) to come in while we are
387 // doing this operation.
389 OriginalTPL
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
391 if (BltOperation
== EfiUgaVideoFill
) {
392 FillPixel
= BltBuffer
;
393 for (Index
= 0; Index
< Width
; Index
++) {
394 Private
->FillLine
[Index
] = *FillPixel
;
398 for (Index
= 0; Index
< Height
; Index
++) {
399 if (DestinationY
<= SourceY
) {
400 SrcY
= SourceY
+ Index
;
401 DstY
= DestinationY
+ Index
;
403 SrcY
= SourceY
+ Height
- Index
- 1;
404 DstY
= DestinationY
+ Height
- Index
- 1;
407 VScreen
= &Private
->VirtualScreen
[(Private
->VerticalResolution
- DstY
- 1) * Private
->HorizontalResolution
+ DestinationX
];
408 switch (BltOperation
) {
409 case EfiUgaBltBufferToVideo
:
410 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
) + SourceX
* sizeof (EFI_UGA_PIXEL
));
411 CopyMem (VScreen
, Blt
, Width
* sizeof (EFI_UGA_PIXEL
));
414 case EfiUgaVideoToVideo
:
415 VScreenSrc
= &Private
->VirtualScreen
[(Private
->VerticalResolution
- SrcY
- 1) * Private
->HorizontalResolution
+ SourceX
];
416 CopyMem (VScreen
, VScreenSrc
, Width
* sizeof (EFI_UGA_PIXEL
));
419 case EfiUgaVideoFill
:
420 CopyMem (VScreen
, Private
->FillLine
, Width
* sizeof (EFI_UGA_PIXEL
));
426 if (BltOperation
!= EfiUgaVideoToBltBuffer
) {
428 // Mark the area we just blted as Invalid so WM_PAINT will update.
430 Rect
.left
= DestinationX
;
431 Rect
.top
= DestinationY
;
432 Rect
.right
= DestinationX
+ Width
;
433 Rect
.bottom
= DestinationY
+ Height
;
434 Private
->WinNtThunk
->InvalidateRect (Private
->WindowHandle
, &Rect
, FALSE
);
437 // Send the WM_PAINT message to the thread that is drawing the window. We
438 // are in the main thread and the window drawing is in a child thread.
439 // There is a child thread per window. We have no CriticalSection or Mutex
440 // since we write the data and the other thread displays the data. While
441 // we may miss some data for a short period of time this is no different than
442 // a write combining on writes to a frame buffer.
445 Private
->WinNtThunk
->UpdateWindow (Private
->WindowHandle
);
448 gBS
->RestoreTPL (OriginalTPL
);
455 // Construction and Destruction functions
460 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
473 // TODO: WinNtIo - add argument and description to function comment
474 // TODO: EFI_UNSUPPORTED - add return value to function comment
475 // TODO: EFI_SUCCESS - add return value to function comment
478 // Check to see if the IO abstraction represents a device type we support.
480 // This would be replaced a check of PCI subsystem ID, etc.
482 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtUgaGuid
)) {
483 return EFI_UNSUPPORTED
;
491 WinNtUgaThreadWindowProc (
500 Win32 Windows event handler.
509 // TODO: hwnd - add argument and description to function comment
510 // TODO: iMsg - add argument and description to function comment
511 // TODO: wParam - add argument and description to function comment
512 // TODO: lParam - add argument and description to function comment
514 UGA_PRIVATE_DATA
*Private
;
517 PAINTSTRUCT PaintStruct
;
522 // BugBug - if there are two instances of this DLL in memory (such as is
523 // the case for ERM), the correct instance of this function may not be called.
524 // This also means that the address of the mTlsIndex value will be wrong, and
525 // the value may be wrong too.
530 // Use mTlsIndex global to get a Thread Local Storage version of Private.
531 // This works since each Uga protocol has a unique Private data instance and
534 Private
= mWinNt
->TlsGetValue (mTlsIndex
);
535 ASSERT (NULL
!= Private
);
539 Size
= Private
->HorizontalResolution
* Private
->VerticalResolution
* sizeof (RGBQUAD
);
542 // Allocate DIB frame buffer directly from NT for performance enhancement
543 // This buffer is the virtual screen/frame buffer. This buffer is not the
544 // same a a frame buffer. The first fow of this buffer will be the bottom
545 // line of the image. This is an artifact of the way we draw to the screen.
547 Private
->VirtualScreenInfo
= Private
->WinNtThunk
->HeapAlloc (
548 Private
->WinNtThunk
->GetProcessHeap (),
553 Private
->VirtualScreenInfo
->bV4Size
= sizeof (BITMAPV4HEADER
);
554 Private
->VirtualScreenInfo
->bV4Width
= Private
->HorizontalResolution
;
555 Private
->VirtualScreenInfo
->bV4Height
= Private
->VerticalResolution
;
556 Private
->VirtualScreenInfo
->bV4Planes
= 1;
557 Private
->VirtualScreenInfo
->bV4BitCount
= 32;
561 Private
->VirtualScreenInfo
->bV4V4Compression
= BI_RGB
;
562 Private
->VirtualScreen
= (RGBQUAD
*) (Private
->VirtualScreenInfo
+ 1);
567 // I have not found a way to convert hwnd into a Private context. So for
568 // now we use this API to convert hwnd to Private data.
571 Handle
= mWinNt
->BeginPaint (hwnd
, &PaintStruct
);
573 mWinNt
->SetDIBitsToDevice (
574 Handle
, // Destination Device Context
575 0, // Destination X - 0
576 0, // Destination Y - 0
577 Private
->HorizontalResolution
, // Width
578 Private
->VerticalResolution
, // Height
581 0, // DIB Start Scan Line
582 Private
->VerticalResolution
, // Number of scan lines
583 Private
->VirtualScreen
, // Address of array of DIB bits
584 (BITMAPINFO
*) Private
->VirtualScreenInfo
, // Address of structure with bitmap info
585 DIB_RGB_COLORS
// RGB or palette indexes
588 mWinNt
->EndPaint (hwnd
, &PaintStruct
);
592 // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case
598 Key
.ScanCode
= SCAN_F10
;
600 UgaPrivateAddQ (Private
, Key
);
608 case VK_HOME
: Key
.ScanCode
= SCAN_HOME
; break;
609 case VK_END
: Key
.ScanCode
= SCAN_END
; break;
610 case VK_LEFT
: Key
.ScanCode
= SCAN_LEFT
; break;
611 case VK_RIGHT
: Key
.ScanCode
= SCAN_RIGHT
; break;
612 case VK_UP
: Key
.ScanCode
= SCAN_UP
; break;
613 case VK_DOWN
: Key
.ScanCode
= SCAN_DOWN
; break;
614 case VK_DELETE
: Key
.ScanCode
= SCAN_DELETE
; break;
615 case VK_INSERT
: Key
.ScanCode
= SCAN_INSERT
; break;
616 case VK_PRIOR
: Key
.ScanCode
= SCAN_PAGE_UP
; break;
617 case VK_NEXT
: Key
.ScanCode
= SCAN_PAGE_DOWN
; break;
618 case VK_ESCAPE
: Key
.ScanCode
= SCAN_ESC
; break;
620 case VK_F1
: Key
.ScanCode
= SCAN_F1
; break;
621 case VK_F2
: Key
.ScanCode
= SCAN_F2
; break;
622 case VK_F3
: Key
.ScanCode
= SCAN_F3
; break;
623 case VK_F4
: Key
.ScanCode
= SCAN_F4
; break;
624 case VK_F5
: Key
.ScanCode
= SCAN_F5
; break;
625 case VK_F6
: Key
.ScanCode
= SCAN_F6
; break;
626 case VK_F7
: Key
.ScanCode
= SCAN_F7
; break;
627 case VK_F8
: Key
.ScanCode
= SCAN_F8
; break;
628 case VK_F9
: Key
.ScanCode
= SCAN_F9
; break;
629 case VK_F11
: Key
.ScanCode
= SCAN_F11
; break;
630 case VK_F12
: Key
.ScanCode
= SCAN_F12
; break;
633 if (Key
.ScanCode
!= 0) {
635 UgaPrivateAddQ (Private
, Key
);
642 // The ESC key also generate WM_CHAR.
644 if (wParam
== 0x1B) {
648 for (Index
= 0; Index
< (lParam
& 0xffff); Index
++) {
650 Key
.UnicodeChar
= (CHAR16
) wParam
;
652 UgaPrivateAddQ (Private
, Key
);
660 // This close message is issued by user, core is not aware of this,
661 // so don't release the window display resource, just hide the window.
663 Private
->WinNtThunk
->ShowWindow (Private
->WindowHandle
, SW_HIDE
);
667 mWinNt
->DestroyWindow (hwnd
);
668 mWinNt
->PostQuitMessage (0);
670 mWinNt
->HeapFree (Private
->WinNtThunk
->GetProcessHeap (), 0, Private
->VirtualScreenInfo
);
672 mWinNt
->ExitThread (0);
679 return mWinNt
->DefWindowProc (hwnd
, iMsg
, wParam
, lParam
);
684 WinNtUgaThreadWinMain (
691 This thread simulates the end of WinMain () aplication. Each Winow nededs
692 to process it's events. The messages are dispatched to
693 WinNtUgaThreadWindowProc ().
695 Be very careful sine WinNtUgaThreadWinMain () and WinNtUgaThreadWindowProc ()
696 are running in a seperate thread. We have to do this to process the events.
700 lpParameter - Handle of window to manage.
704 if a WM_QUIT message is returned exit.
709 UGA_PRIVATE_DATA
*Private
;
713 Private
= (UGA_PRIVATE_DATA
*) lpParameter
;
714 ASSERT (NULL
!= Private
);
717 // Since each thread has unique private data, save the private data in Thread
718 // Local Storage slot. Then the shared global mTlsIndex can be used to get
719 // thread specific context.
721 Private
->WinNtThunk
->TlsSetValue (mTlsIndex
, Private
);
723 Private
->ThreadId
= Private
->WinNtThunk
->GetCurrentThreadId ();
725 Private
->WindowsClass
.cbSize
= sizeof (WNDCLASSEX
);
726 Private
->WindowsClass
.style
= CS_HREDRAW
| CS_VREDRAW
| CS_OWNDC
;
727 Private
->WindowsClass
.lpfnWndProc
= WinNtUgaThreadWindowProc
;
728 Private
->WindowsClass
.cbClsExtra
= 0;
729 Private
->WindowsClass
.cbWndExtra
= 0;
730 Private
->WindowsClass
.hInstance
= NULL
;
731 Private
->WindowsClass
.hIcon
= Private
->WinNtThunk
->LoadIcon (NULL
, IDI_APPLICATION
);
732 Private
->WindowsClass
.hCursor
= Private
->WinNtThunk
->LoadCursor (NULL
, IDC_ARROW
);
733 Private
->WindowsClass
.hbrBackground
= (HBRUSH
) COLOR_WINDOW
;
734 Private
->WindowsClass
.lpszMenuName
= NULL
;
735 Private
->WindowsClass
.lpszClassName
= WIN_NT_UGA_CLASS_NAME
;
736 Private
->WindowsClass
.hIconSm
= Private
->WinNtThunk
->LoadIcon (NULL
, IDI_APPLICATION
);
739 // This call will fail after the first time, but thats O.K. since we only need
740 // WIN_NT_UGA_CLASS_NAME to exist to create the window.
742 // Note: Multiple instances of this DLL will use the same instance of this
743 // Class, including the callback function, unless the Class is unregistered and
744 // successfully registered again.
746 Atom
= Private
->WinNtThunk
->RegisterClassEx (&Private
->WindowsClass
);
749 // Setting Rect values to allow for the AdjustWindowRect to provide
750 // us the correct sizes for the client area when doing the CreateWindowEx
753 Rect
.bottom
= Private
->VerticalResolution
;
755 Rect
.right
= Private
->HorizontalResolution
;
757 Private
->WinNtThunk
->AdjustWindowRect (&Rect
, WS_OVERLAPPEDWINDOW
, 0);
759 Private
->WindowHandle
= Private
->WinNtThunk
->CreateWindowEx (
761 WIN_NT_UGA_CLASS_NAME
,
766 Rect
.right
- Rect
.left
,
767 Rect
.bottom
- Rect
.top
,
775 // The reset of this thread is the standard winows program. We need a sperate
776 // thread since we must process the message loop to make windows act like
780 Private
->WinNtThunk
->ShowWindow (Private
->WindowHandle
, SW_SHOW
);
781 Private
->WinNtThunk
->UpdateWindow (Private
->WindowHandle
);
784 // Let the main thread get some work done
786 Private
->WinNtThunk
->ReleaseSemaphore (Private
->ThreadInited
, 1, NULL
);
789 // This is the message loop that all Windows programs need.
791 while (Private
->WinNtThunk
->GetMessage (&Message
, Private
->WindowHandle
, 0, 0)) {
792 Private
->WinNtThunk
->TranslateMessage (&Message
);
793 Private
->WinNtThunk
->DispatchMessage (&Message
);
796 return Message
.wParam
;
800 WinNtUgaStartWindow (
801 IN UGA_PRIVATE_DATA
*Private
,
802 IN UINT32 HorizontalResolution
,
803 IN UINT32 VerticalResolution
,
804 IN UINT32 ColorDepth
,
805 IN UINT32 RefreshRate
811 TODO: Add function description
815 Private - TODO: add argument description
816 HorizontalResolution - TODO: add argument description
817 VerticalResolution - TODO: add argument description
818 ColorDepth - TODO: add argument description
819 RefreshRate - TODO: add argument description
823 TODO: add return values
831 mWinNt
= Private
->WinNtThunk
;
834 // Initialize a Thread Local Storge variable slot. We use TLS to get the
835 // correct Private data instance into the windows thread.
837 if (mTlsIndex
== TLS_OUT_OF_INDEXES
) {
838 ASSERT (0 == mTlsIndexUseCount
);
839 mTlsIndex
= Private
->WinNtThunk
->TlsAlloc ();
843 // always increase the use count!
847 Private
->HorizontalResolution
= HorizontalResolution
;
848 Private
->VerticalResolution
= VerticalResolution
;
851 // Register to be notified on exit boot services so we can destroy the window.
853 Status
= gBS
->CreateEvent (
854 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES
,
858 &mUgaScreenExitBootServicesEvent
861 Private
->ThreadInited
= Private
->WinNtThunk
->CreateSemaphore (NULL
, 0, 1, NULL
);
862 Private
->ThreadHandle
= Private
->WinNtThunk
->CreateThread (
865 WinNtUgaThreadWinMain
,
872 // The other thread has entered the windows message loop so we can
873 // continue our initialization.
875 Private
->WinNtThunk
->WaitForSingleObject (Private
->ThreadInited
, INFINITE
);
876 Private
->WinNtThunk
->CloseHandle (Private
->ThreadInited
);
882 WinNtUgaConstructor (
883 UGA_PRIVATE_DATA
*Private
896 // TODO: Private - add argument and description to function comment
897 // TODO: EFI_SUCCESS - add return value to function comment
900 Private
->UgaDraw
.GetMode
= WinNtUgaGetMode
;
901 Private
->UgaDraw
.SetMode
= WinNtUgaSetMode
;
902 Private
->UgaDraw
.Blt
= WinNtUgaBlt
;
904 Private
->HardwareNeedsStarting
= TRUE
;
905 Private
->FillLine
= NULL
;
907 WinNtUgaInitializeSimpleTextInForWindow (Private
);
914 UGA_PRIVATE_DATA
*Private
927 // TODO: Private - add argument and description to function comment
928 // TODO: EFI_SUCCESS - add return value to function comment
930 UINT32 UnregisterReturn
;
932 if (!Private
->HardwareNeedsStarting
) {
934 // BugBug: Shutdown Uga Hardware and any child devices.
936 Private
->WinNtThunk
->SendMessage (Private
->WindowHandle
, WM_DESTROY
, 0, 0);
937 Private
->WinNtThunk
->CloseHandle (Private
->ThreadHandle
);
942 // The callback function for another window could still be called,
943 // so we need to make sure there are no more users of mTlsIndex.
945 if (0 == mTlsIndexUseCount
) {
946 ASSERT (TLS_OUT_OF_INDEXES
!= mTlsIndex
);
948 Private
->WinNtThunk
->TlsFree (mTlsIndex
);
949 mTlsIndex
= TLS_OUT_OF_INDEXES
;
951 UnregisterReturn
= Private
->WinNtThunk
->UnregisterClass (
952 Private
->WindowsClass
.lpszClassName
,
953 Private
->WindowsClass
.hInstance
957 WinNtUgaDestroySimpleTextInForWindow (Private
);
974 This is the UGA screen's callback notification function for exit-boot-services.
975 All we do here is call WinNtUgaDestructor().
980 Context - pointer to the Private structure.
989 Status
= WinNtUgaDestructor (Context
);