TianoCore EDK2 master
Loading...
Searching...
No Matches
WinGopScreen.c
Go to the documentation of this file.
1
19#include "WinGop.h"
20
21DWORD mTlsIndex = TLS_OUT_OF_INDEXES;
22DWORD mTlsIndexUseCount = 0; // lets us know when we can free mTlsIndex.
23
24BOOLEAN
25WinNtGopConvertParamToEfiKeyShiftState (
27 IN WPARAM *wParam,
28 IN LPARAM *lParam,
29 IN BOOLEAN Flag
30 )
31{
32 switch (*wParam) {
33 //
34 // BUGBUG: Only GetAsyncKeyState() and GetKeyState() can distinguish
35 // left and right Ctrl, and Shift key.
36 // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL.
37 // Therefor, we can not set the correct Shift state here.
38 //
39 case VK_SHIFT:
40 if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {
41 Private->RightShift = Flag;
42 } else {
43 Private->LeftShift = Flag;
44 }
45
46 return TRUE;
47
48 case VK_LSHIFT:
49 Private->LeftShift = Flag;
50 return TRUE;
51
52 case VK_RSHIFT:
53 Private->RightShift = Flag;
54 return TRUE;
55
56 case VK_CONTROL:
57 if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {
58 Private->RightCtrl = Flag;
59 } else {
60 Private->LeftCtrl = Flag;
61 }
62
63 return TRUE;
64
65 case VK_LCONTROL:
66 Private->LeftCtrl = Flag;
67 return TRUE;
68
69 case VK_RCONTROL:
70 Private->RightCtrl = Flag;
71 return TRUE;
72
73 case VK_LWIN:
74 Private->LeftLogo = Flag;
75 return TRUE;
76
77 case VK_RWIN:
78 Private->RightLogo = Flag;
79 return TRUE;
80
81 case VK_APPS:
82 Private->Menu = Flag;
83 return TRUE;
84 //
85 // BUGBUG: PrintScreen/SysRq can not trigger WM_KEYDOWN message,
86 // so SySReq shift state is not supported here.
87 //
88 case VK_PRINT:
89 Private->SysReq = Flag;
90 return TRUE;
91 //
92 // For Alt Keystroke.
93 //
94 case VK_MENU:
95 if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {
96 Private->RightAlt = Flag;
97 } else {
98 Private->LeftAlt = Flag;
99 }
100
101 return TRUE;
102
103 default:
104 return FALSE;
105 }
106}
107
108BOOLEAN
109WinNtGopConvertParamToEfiKey (
110 IN GRAPHICS_PRIVATE_DATA *Private,
111 IN WPARAM *wParam,
112 IN LPARAM *lParam,
113 IN EFI_INPUT_KEY *Key
114 )
115{
116 BOOLEAN Flag;
117
118 Flag = FALSE;
119 switch (*wParam) {
120 case VK_HOME: Key->ScanCode = SCAN_HOME;
121 Flag = TRUE;
122 break;
123 case VK_END: Key->ScanCode = SCAN_END;
124 Flag = TRUE;
125 break;
126 case VK_LEFT: Key->ScanCode = SCAN_LEFT;
127 Flag = TRUE;
128 break;
129 case VK_RIGHT: Key->ScanCode = SCAN_RIGHT;
130 Flag = TRUE;
131 break;
132 case VK_UP: Key->ScanCode = SCAN_UP;
133 Flag = TRUE;
134 break;
135 case VK_DOWN: Key->ScanCode = SCAN_DOWN;
136 Flag = TRUE;
137 break;
138 case VK_DELETE: Key->ScanCode = SCAN_DELETE;
139 Flag = TRUE;
140 break;
141 case VK_INSERT: Key->ScanCode = SCAN_INSERT;
142 Flag = TRUE;
143 break;
144 case VK_PRIOR: Key->ScanCode = SCAN_PAGE_UP;
145 Flag = TRUE;
146 break;
147 case VK_NEXT: Key->ScanCode = SCAN_PAGE_DOWN;
148 Flag = TRUE;
149 break;
150 case VK_ESCAPE: Key->ScanCode = SCAN_ESC;
151 Flag = TRUE;
152 break;
153
154 case VK_F1: Key->ScanCode = SCAN_F1;
155 Flag = TRUE;
156 break;
157 case VK_F2: Key->ScanCode = SCAN_F2;
158 Flag = TRUE;
159 break;
160 case VK_F3: Key->ScanCode = SCAN_F3;
161 Flag = TRUE;
162 break;
163 case VK_F4: Key->ScanCode = SCAN_F4;
164 Flag = TRUE;
165 break;
166 case VK_F5: Key->ScanCode = SCAN_F5;
167 Flag = TRUE;
168 break;
169 case VK_F6: Key->ScanCode = SCAN_F6;
170 Flag = TRUE;
171 break;
172 case VK_F7: Key->ScanCode = SCAN_F7;
173 Flag = TRUE;
174 break;
175 case VK_F8: Key->ScanCode = SCAN_F8;
176 Flag = TRUE;
177 break;
178 case VK_F9: Key->ScanCode = SCAN_F9;
179 Flag = TRUE;
180 break;
181 case VK_F11: Key->ScanCode = SCAN_F11;
182 Flag = TRUE;
183 break;
184 case VK_F12: Key->ScanCode = SCAN_F12;
185 Flag = TRUE;
186 break;
187
188 case VK_F13: Key->ScanCode = SCAN_F13;
189 Flag = TRUE;
190 break;
191 case VK_F14: Key->ScanCode = SCAN_F14;
192 Flag = TRUE;
193 break;
194 case VK_F15: Key->ScanCode = SCAN_F15;
195 Flag = TRUE;
196 break;
197 case VK_F16: Key->ScanCode = SCAN_F16;
198 Flag = TRUE;
199 break;
200 case VK_F17: Key->ScanCode = SCAN_F17;
201 Flag = TRUE;
202 break;
203 case VK_F18: Key->ScanCode = SCAN_F18;
204 Flag = TRUE;
205 break;
206 case VK_F19: Key->ScanCode = SCAN_F19;
207 Flag = TRUE;
208 break;
209 case VK_F20: Key->ScanCode = SCAN_F20;
210 Flag = TRUE;
211 break;
212 case VK_F21: Key->ScanCode = SCAN_F21;
213 Flag = TRUE;
214 break;
215 case VK_F22: Key->ScanCode = SCAN_F22;
216 Flag = TRUE;
217 break;
218 case VK_F23: Key->ScanCode = SCAN_F23;
219 Flag = TRUE;
220 break;
221 case VK_F24: Key->ScanCode = SCAN_F24;
222 Flag = TRUE;
223 break;
224 case VK_PAUSE: Key->ScanCode = SCAN_PAUSE;
225 Flag = TRUE;
226 break;
227
228 //
229 // Set toggle state
230 //
231 case VK_NUMLOCK:
232 Private->NumLock = (BOOLEAN)(!Private->NumLock);
233 Flag = TRUE;
234 break;
235 case VK_SCROLL:
236 Private->ScrollLock = (BOOLEAN)(!Private->ScrollLock);
237 Flag = TRUE;
238 break;
239 case VK_CAPITAL:
240 Private->CapsLock = (BOOLEAN)(!Private->CapsLock);
241 Flag = TRUE;
242 break;
243 }
244
245 return (WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, lParam, TRUE)) == TRUE ? TRUE : Flag;
246}
247
248//
249// GOP Protocol Member Functions
250//
251
256EFIAPI
259 IN UINT32 Width,
260 IN UINT32 Height
261 )
262{
263 RETURN_STATUS RStatus;
265 GRAPHICS_PRIVATE_DATA *Private;
266 RECT Rect;
267 BITMAPV4HEADER *VirtualScreenInfo;
268 FRAME_BUFFER_CONFIGURE *FrameBufferConfigure;
269 UINTN FrameBufferConfigureSize;
270
271 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
272
273 //
274 // Allocate DIB frame buffer directly from NT for performance enhancement
275 // This buffer is the virtual screen/frame buffer.
276 //
277 VirtualScreenInfo = HeapAlloc (
278 GetProcessHeap (),
279 HEAP_ZERO_MEMORY,
280 Width * Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER)
281 );
282 if (VirtualScreenInfo == NULL) {
283 return EFI_OUT_OF_RESOURCES;
284 }
285
286 //
287 // Update the virtual screen info data structure
288 // Use negative Height to make sure screen/buffer are using the same coordinate.
289 //
290 VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);
291 VirtualScreenInfo->bV4Width = Width;
292 VirtualScreenInfo->bV4Height = -(LONG)Height;
293 VirtualScreenInfo->bV4Planes = 1;
294 VirtualScreenInfo->bV4BitCount = 32;
295 //
296 // uncompressed
297 //
298 VirtualScreenInfo->bV4V4Compression = BI_RGB;
299
300 Info.HorizontalResolution = Width;
301 Info.VerticalResolution = Height;
303 Info.PixelsPerScanLine = Width;
304 FrameBufferConfigureSize = 0;
305 RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, NULL, &FrameBufferConfigureSize);
306 ASSERT (RStatus == EFI_BUFFER_TOO_SMALL);
307 FrameBufferConfigure = AllocatePool (FrameBufferConfigureSize);
308 if (FrameBufferConfigure == NULL) {
309 HeapFree (GetProcessHeap (), 0, VirtualScreenInfo);
310 return EFI_OUT_OF_RESOURCES;
311 }
312
313 RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, FrameBufferConfigure, &FrameBufferConfigureSize);
314 ASSERT_RETURN_ERROR (RStatus);
315
316 if (Private->FrameBufferConfigure != NULL) {
317 FreePool (Private->FrameBufferConfigure);
318 }
319
320 Private->FrameBufferConfigure = FrameBufferConfigure;
321
322 //
323 // Free the old buffer. We do not save the content of the old buffer since the
324 // screen is to be cleared anyway. Clearing the screen is required by the EFI spec.
325 // See UEFI spec -EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode()
326 //
327 if (Private->VirtualScreenInfo != NULL) {
328 HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);
329 }
330
331 Private->VirtualScreenInfo = VirtualScreenInfo;
332
333 Private->Width = Width;
334 Private->Height = Height;
335
336 //
337 // Use the AdjuctWindowRect fuction to calculate the real width and height
338 // of the new window including the border and caption
339 //
340 Rect.left = 0;
341 Rect.top = 0;
342 Rect.right = Width;
343 Rect.bottom = Height;
344
345 AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);
346
347 Width = Rect.right - Rect.left;
348 Height = Rect.bottom - Rect.top;
349
350 //
351 // Retrieve the original window position information
352 //
353 GetWindowRect (Private->WindowHandle, &Rect);
354
355 //
356 // Adjust the window size
357 //
358 MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);
359
360 return EFI_SUCCESS;
361}
362
393// TODO: SourceY - add argument and description to function comment
394// TODO: DestinationX - add argument and description to function comment
395// TODO: DestinationY - add argument and description to function comment
396// TODO: Delta - add argument and description to function comment
400 IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
401 IN EFI_UGA_BLT_OPERATION BltOperation,
403 )
404{
405 RETURN_STATUS RStatus;
406 GRAPHICS_PRIVATE_DATA *Private;
407 RECT Rect;
408
409 Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
410 RStatus = FrameBufferBlt (
411 Private->FrameBufferConfigure,
412 BltBuffer,
413 BltOperation,
414 Args->SourceX,
415 Args->SourceY,
416 Args->DestinationX,
417 Args->DestinationY,
418 Args->Width,
419 Args->Height,
420 Args->Delta
421 );
422 if (RETURN_ERROR (RStatus)) {
423 return (EFI_STATUS)RStatus;
424 }
425
426 if (BltOperation != EfiBltVideoToBltBuffer) {
427 //
428 // Mark the area we just blted as Invalid so WM_PAINT will update.
429 //
430 Rect.left = (LONG)Args->DestinationX;
431 Rect.top = (LONG)Args->DestinationY;
432 Rect.right = (LONG)(Args->DestinationX + Args->Width);
433 Rect.bottom = (LONG)(Args->DestinationY + Args->Height);
434 InvalidateRect (Private->WindowHandle, &Rect, FALSE);
435
436 //
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.
443 //
444
445 UpdateWindow (Private->WindowHandle);
446 }
447
448 return EFI_SUCCESS;
449}
450
459// TODO: hwnd - add argument and description to function comment
460// TODO: iMsg - add argument and description to function comment
461// TODO: wParam - add argument and description to function comment
462// TODO: lParam - add argument and description to function comment
463LRESULT
464CALLBACK
466 IN HWND hwnd,
467 IN UINT iMsg,
468 IN WPARAM wParam,
469 IN LPARAM lParam
470 )
471{
472 GRAPHICS_PRIVATE_DATA *Private;
473 HDC Handle;
474 PAINTSTRUCT PaintStruct;
475 LPARAM Index;
476 EFI_INPUT_KEY Key;
477 BOOLEAN AltIsPress;
478 INT32 PosX;
479 INT32 PosY;
480
481 //
482 // Use mTlsIndex global to get a Thread Local Storage version of Private.
483 // This works since each Gop protocol has a unique Private data instance and
484 // a unique thread.
485 //
486 AltIsPress = FALSE;
487 Private = TlsGetValue (mTlsIndex);
488 ASSERT (NULL != Private);
489
490 switch (iMsg) {
491 case WM_PAINT:
492 Handle = BeginPaint (hwnd, &PaintStruct);
493
494 SetDIBitsToDevice (
495 Handle, // Destination Device Context
496 0, // Destination X - 0
497 0, // Destination Y - 0
498 Private->Width, // Width
499 Private->Height, // Height
500 0, // Source X
501 0, // Source Y
502 0, // DIB Start Scan Line
503 Private->Height, // Number of scan lines
504 Private->VirtualScreenInfo + 1, // Address of array of DIB bits
505 (BITMAPINFO *)Private->VirtualScreenInfo, // Address of structure with bitmap info
506 DIB_RGB_COLORS // RGB or palette indexes
507 );
508
509 EndPaint (hwnd, &PaintStruct);
510 return 0;
511
512 //
513 // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case
514 // WM_SYSKEYDOWN is posted when F10 is pressed or
515 // holds down ALT key and then presses another key.
516 //
517 case WM_SYSKEYDOWN:
518
519 Key.ScanCode = 0;
520 Key.UnicodeChar = CHAR_NULL;
521 switch (wParam) {
522 case VK_F10:
523 Key.ScanCode = SCAN_F10;
524 Key.UnicodeChar = CHAR_NULL;
525 GopPrivateAddKey (Private, Key);
526 return 0;
527 }
528
529 //
530 // If ALT or ALT + modifier key is pressed.
531 //
532 if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {
533 if (Key.ScanCode != 0) {
534 //
535 // If ALT is pressed with other ScanCode.
536 // Always revers the left Alt for simple.
537 //
538 Private->LeftAlt = TRUE;
539 }
540
541 GopPrivateAddKey (Private, Key);
542 //
543 // When Alt is released there is no windoes message, so
544 // clean it after using it.
545 //
546 Private->RightAlt = FALSE;
547 Private->LeftAlt = FALSE;
548 return 0;
549 }
550
551 AltIsPress = TRUE;
552
553 case WM_CHAR:
554 //
555 // The ESC key also generate WM_CHAR.
556 //
557 if (wParam == 0x1B) {
558 return 0;
559 }
560
561 if (AltIsPress == TRUE) {
562 //
563 // If AltIsPress is true that means the Alt key is pressed.
564 //
565 Private->LeftAlt = TRUE;
566 }
567
568 for (Index = 0; Index < (lParam & 0xffff); Index++) {
569 if (wParam != 0) {
570 Key.UnicodeChar = (CHAR16)wParam;
571 Key.ScanCode = SCAN_NULL;
572 GopPrivateAddKey (Private, Key);
573 }
574 }
575
576 if (AltIsPress == TRUE) {
577 //
578 // When Alt is released there is no windoes message, so
579 // clean it after using it.
580 //
581 Private->LeftAlt = FALSE;
582 Private->RightAlt = FALSE;
583 }
584
585 return 0;
586
587 case WM_SYSKEYUP:
588 //
589 // ALT is pressed with another key released
590 //
591 WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);
592 return 0;
593
594 case WM_KEYDOWN:
595 Key.ScanCode = SCAN_NULL;
596 Key.UnicodeChar = CHAR_NULL;
597 //
598 // A value key press will cause a WM_KEYDOWN first, then cause a WM_CHAR
599 // So if there is no modifier key updated, skip the WM_KEYDOWN even.
600 //
601 if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {
602 //
603 // Support the partial keystroke, add all keydown event into the queue.
604 //
605 GopPrivateAddKey (Private, Key);
606 }
607
608 return 0;
609
610 case WM_KEYUP:
611 WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);
612 return 0;
613
614 case WM_MOUSEMOVE:
615 PosX = GET_X_LPARAM (lParam);
616 PosY = GET_Y_LPARAM (lParam);
617
618 if (Private->PointerPreviousX != PosX) {
619 Private->PointerState.RelativeMovementX += (PosX - Private->PointerPreviousX);
620 Private->PointerPreviousX = PosX;
621 Private->PointerStateChanged = TRUE;
622 }
623
624 if (Private->PointerPreviousY != PosY) {
625 Private->PointerState.RelativeMovementY += (PosY - Private->PointerPreviousY);
626 Private->PointerPreviousY = PosY;
627 Private->PointerStateChanged = TRUE;
628 }
629
630 Private->PointerState.RelativeMovementZ = 0;
631 return 0;
632
633 case WM_LBUTTONDOWN:
634 Private->PointerState.LeftButton = TRUE;
635 Private->PointerStateChanged = TRUE;
636 return 0;
637
638 case WM_LBUTTONUP:
639 Private->PointerState.LeftButton = FALSE;
640 Private->PointerStateChanged = TRUE;
641 return 0;
642
643 case WM_RBUTTONDOWN:
644 Private->PointerState.RightButton = TRUE;
645 Private->PointerStateChanged = TRUE;
646 return 0;
647
648 case WM_RBUTTONUP:
649 Private->PointerState.RightButton = FALSE;
650 Private->PointerStateChanged = TRUE;
651 return 0;
652
653 case WM_CLOSE:
654 //
655 // This close message is issued by user, core is not aware of this,
656 // so don't release the window display resource, just hide the window.
657 //
658 ShowWindow (Private->WindowHandle, SW_HIDE);
659 return 0;
660
661 case WM_DESTROY:
662 DestroyWindow (hwnd);
663 PostQuitMessage (0);
664
665 HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);
666
667 ExitThread (0);
668
669 default:
670 break;
671 }
672
673 return DefWindowProc (hwnd, iMsg, wParam, lParam);
674}
675
688DWORD
689WINAPI
691 LPVOID lpParameter
692 )
693{
694 MSG Message;
695 GRAPHICS_PRIVATE_DATA *Private;
696 RECT Rect;
697
698 Private = (GRAPHICS_PRIVATE_DATA *)lpParameter;
699 ASSERT (NULL != Private);
700
701 //
702 // Since each thread has unique private data, save the private data in Thread
703 // Local Storage slot. Then the shared global mTlsIndex can be used to get
704 // thread specific context.
705 //
706 TlsSetValue (mTlsIndex, Private);
707
708 Private->ThreadId = GetCurrentThreadId ();
709
710 Private->WindowsClass.cbSize = sizeof (WNDCLASSEX);
711 Private->WindowsClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
712 Private->WindowsClass.lpfnWndProc = WinNtGopThreadWindowProc;
713 Private->WindowsClass.cbClsExtra = 0;
714 Private->WindowsClass.cbWndExtra = 0;
715 Private->WindowsClass.hInstance = NULL;
716 Private->WindowsClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
717 Private->WindowsClass.hCursor = LoadCursor (NULL, IDC_ARROW);
718 Private->WindowsClass.hbrBackground = (HBRUSH)(UINTN)COLOR_WINDOW;
719 Private->WindowsClass.lpszMenuName = NULL;
720 Private->WindowsClass.lpszClassName = WIN_NT_GOP_CLASS_NAME;
721 Private->WindowsClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
722
723 //
724 // Use 100 x 100 as initial Window size.
725 //
726 Private->Width = 100;
727 Private->Height = 100;
728
729 //
730 // This call will fail after the first time, but thats O.K. since we only need
731 // WIN_NT_GOP_CLASS_NAME to exist to create the window.
732 //
733 RegisterClassEx (&Private->WindowsClass);
734
735 //
736 // Setting Rect values to allow for the AdjustWindowRect to provide
737 // us the correct sizes for the client area when doing the CreateWindowEx
738 //
739 Rect.top = 0;
740 Rect.bottom = Private->Height;
741 Rect.left = 0;
742 Rect.right = Private->Width;
743
744 AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);
745
746 Private->WindowHandle = CreateWindowEx (
747 0,
748 WIN_NT_GOP_CLASS_NAME,
749 Private->WindowName,
750 WS_OVERLAPPEDWINDOW,
751 CW_USEDEFAULT,
752 CW_USEDEFAULT,
753 Rect.right - Rect.left,
754 Rect.bottom - Rect.top,
755 NULL,
756 NULL,
757 NULL,
758 (VOID **)&Private
759 );
760
761 //
762 // The reset of this thread is the standard windows program. We need a separate
763 // thread since we must process the message loop to make windows act like
764 // windows.
765 //
766
767 ShowWindow (Private->WindowHandle, SW_SHOW);
768 UpdateWindow (Private->WindowHandle);
769
770 //
771 // Let the main thread get some work done
772 //
773 ReleaseSemaphore (Private->ThreadInited, 1, NULL);
774
775 //
776 // This is the message loop that all Windows programs need.
777 //
778 while (GetMessage (&Message, Private->WindowHandle, 0, 0)) {
779 TranslateMessage (&Message);
780 DispatchMessage (&Message);
781 }
782
783 return (DWORD)Message.wParam;
784}
785
799EFIAPI
802 )
803{
804 DWORD NewThreadId;
805 GRAPHICS_PRIVATE_DATA *Private;
806
807 Private = AllocateZeroPool (sizeof (*Private));
808
809 GopPrivateCreateQ (Private, &Private->QueueForRead);
810
811 Private->Signature = GRAPHICS_PRIVATE_DATA_SIGNATURE;
812 Private->GraphicsWindowIo.Size = WinNtWndSize;
813 Private->GraphicsWindowIo.CheckKey = WinNtWndCheckKey;
814 Private->GraphicsWindowIo.GetKey = WinNtWndGetKey;
815 Private->GraphicsWindowIo.KeySetState = WinNtWndKeySetState;
816 Private->GraphicsWindowIo.RegisterKeyNotify = WinNtWndRegisterKeyNotify;
817 Private->GraphicsWindowIo.Blt = WinNtWndBlt;
818 Private->GraphicsWindowIo.CheckPointer = WinNtWndCheckPointer;
819 Private->GraphicsWindowIo.GetPointerState = WinNtWndGetPointerState;
820
821 Private->WindowName = This->ConfigString;
822 //
823 // Initialize a Thread Local Storge variable slot. We use TLS to get the
824 // correct Private data instance into the windows thread.
825 //
826 if (mTlsIndex == TLS_OUT_OF_INDEXES) {
827 ASSERT (0 == mTlsIndexUseCount);
828 mTlsIndex = TlsAlloc ();
829 }
830
831 //
832 // always increase the use count!
833 //
834 mTlsIndexUseCount++;
835
836 Private->ThreadInited = CreateSemaphore (NULL, 0, 1, NULL);
837 Private->ThreadHandle = CreateThread (
838 NULL,
839 0,
841 (VOID *)Private,
842 0,
843 &NewThreadId
844 );
845
846 //
847 // The other thread has entered the windows message loop so we can
848 // continue our initialization.
849 //
850 WaitForSingleObject (Private->ThreadInited, INFINITE);
851 CloseHandle (Private->ThreadInited);
852
853 This->Private = Private;
854 This->Interface = &Private->GraphicsWindowIo;
855
856 return EFI_SUCCESS;
857}
858
860EFIAPI
861WinNtGraphicsWindowClose (
863 )
864{
865 GRAPHICS_PRIVATE_DATA *Private;
866
867 Private = (GRAPHICS_PRIVATE_DATA *)This->Private;
868
869 //
870 // BugBug: Shutdown GOP Hardware and any child devices.
871 //
872 SendMessage (Private->WindowHandle, WM_DESTROY, 0, 0);
873 CloseHandle (Private->ThreadHandle);
874
875 mTlsIndexUseCount--;
876
877 //
878 // The callback function for another window could still be called,
879 // so we need to make sure there are no more users of mTlsIndex.
880 //
881 if (0 == mTlsIndexUseCount) {
882 ASSERT (TLS_OUT_OF_INDEXES != mTlsIndex);
883
884 TlsFree (mTlsIndex);
885 mTlsIndex = TLS_OUT_OF_INDEXES;
886
887 UnregisterClass (
888 Private->WindowsClass.lpszClassName,
889 Private->WindowsClass.hInstance
890 );
891 }
892
893 GopPrivateDestroyQ (Private, &Private->QueueForRead);
894 return EFI_SUCCESS;
895}
896
897EMU_IO_THUNK_PROTOCOL mWinNtWndThunkIo = {
898 &gEmuGraphicsWindowProtocolGuid,
899 NULL,
900 NULL,
901 0,
903 WinNtGraphicsWindowClose,
904 NULL
905};
UINT64 UINTN
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
RETURN_STATUS EFIAPI FrameBufferBlt(IN FRAME_BUFFER_CONFIGURE *Configure, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta)
RETURN_STATUS EFIAPI FrameBufferBltConfigure(IN VOID *FrameBuffer, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN OUT FRAME_BUFFER_CONFIGURE *Configure, IN OUT UINTN *ConfigureSize)
#define NULL
Definition: Base.h:319
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
@ EfiBltVideoToBltBuffer
@ PixelBlueGreenRedReserved8BitPerColor
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI TlsFree(IN VOID *Tls)
Definition: CryptLib.c:3749
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_UGA_BLT_OPERATION
Definition: UgaDraw.h:83
EFI_STATUS GopPrivateDestroyQ(IN GRAPHICS_PRIVATE_DATA *Private, IN GOP_QUEUE_FIXED *Queue)
Definition: WinGopInput.c:56
EFI_STATUS GopPrivateCreateQ(IN GRAPHICS_PRIVATE_DATA *Private, IN GOP_QUEUE_FIXED *Queue)
Definition: WinGopInput.c:36
EFI_STATUS GopPrivateAddKey(IN GRAPHICS_PRIVATE_DATA *Private, IN EFI_INPUT_KEY Key)
Definition: WinGopInput.c:247
EFI_STATUS EFIAPI WinNtWndSize(IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, IN UINT32 Width, IN UINT32 Height)
Definition: WinGopScreen.c:257
DWORD WINAPI WinNtGopThreadWinMain(LPVOID lpParameter)
Definition: WinGopScreen.c:690
EFI_STATUS EFIAPI WinNtGraphicsWindowOpen(IN EMU_IO_THUNK_PROTOCOL *This)
Definition: WinGopScreen.c:800
LRESULT CALLBACK WinNtGopThreadWindowProc(IN HWND hwnd, IN UINT iMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: WinGopScreen.c:465
EFI_STATUS WinNtWndBlt(IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, IN EFI_UGA_BLT_OPERATION BltOperation, IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args)
Definition: WinGopScreen.c:398
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat