VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c@ 17665

Last change on this file since 17665 was 17665, checked in by vboxsync, 16 years ago

HGSMI: the windows guest display drivers.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.2 KB
Line 
1/******************************Module*Header*******************************\
2*
3* Copyright (C) 2006-2007 Sun Microsystems, Inc.
4*
5* This file is part of VirtualBox Open Source Edition (OSE), as
6* available from http://www.virtualbox.org. This file is free software;
7* you can redistribute it and/or modify it under the terms of the GNU
8* General Public License (GPL) as published by the Free Software
9* Foundation, in version 2 as it comes in the "COPYING" file of the
10* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
11* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
12*
13* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
14* Clara, CA 95054 USA or visit http://www.sun.com if you need
15* additional information or have any questions.
16*/
17/*
18* Based in part on Microsoft DDK sample code
19*
20* *******************
21* * GDI SAMPLE CODE *
22* *******************
23*
24* Module Name: screen.c
25*
26* Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
27*
28* Copyright (c) 1992-1998 Microsoft Corporation
29\**************************************************************************/
30
31#include "driver.h"
32
33#ifdef VBOX_WITH_HGSMI
34#include <iprt/asm.h>
35#include <VBox/HGSMI/HGSMI.h>
36#include <VBox/HGSMI/HGSMIChSetup.h>
37#endif
38
39#define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"System"}
40#define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"MS Sans Serif"}
41#define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_DONTCARE, L"Courier"}
42
43// This is the basic devinfo for a default driver. This is used as a base and customized based
44// on information passed back from the miniport driver.
45
46const DEVINFO gDevInfoFrameBuffer = {
47 ( GCAPS_OPAQUERECT
48#ifdef VBOX_WITH_DDRAW
49 | GCAPS_DIRECTDRAW
50#endif
51 | GCAPS_MONO_DITHER
52 ), /* Graphics capabilities */
53 SYSTM_LOGFONT, /* Default font description */
54 HELVE_LOGFONT, /* ANSI variable font description */
55 COURI_LOGFONT, /* ANSI fixed font description */
56 0, /* Count of device fonts */
57 0, /* Preferred DIB format */
58 8, /* Width of color dither */
59 8, /* Height of color dither */
60 0 /* Default palette to use for this device */
61};
62
63static void vboxInitVBoxVideo (PPDEV ppdev, const VIDEO_MEMORY_INFORMATION *pMemoryInformation)
64{
65 ULONG cbAvailable = 0;
66
67 DWORD returnedDataLength;
68
69 ULONG iDevice;
70 uint32_t u32DisplayInfoSize;
71
72#ifndef VBOX_WITH_HGSMI
73 QUERYDISPLAYINFORESULT DispInfo;
74 RtlZeroMemory(&DispInfo, sizeof (DispInfo));
75
76 ppdev->bVBoxVideoSupported = !EngDeviceIoControl(ppdev->hDriver,
77 IOCTL_VIDEO_QUERY_DISPLAY_INFO,
78 NULL,
79 0,
80 &DispInfo,
81 sizeof(DispInfo),
82 &returnedDataLength);
83 if (ppdev->bVBoxVideoSupported)
84 {
85 iDevice = DispInfo.iDevice;
86 u32DisplayInfoSize = DispInfo.u32DisplayInfoSize;
87 }
88#else
89 QUERYHGSMIRESULT info;
90 RtlZeroMemory(&info, sizeof (info));
91
92 ppdev->bHGSMISupported = !EngDeviceIoControl(ppdev->hDriver,
93 IOCTL_VIDEO_QUERY_HGSMI_INFO,
94 NULL,
95 0,
96 &info,
97 sizeof(info),
98 &returnedDataLength);
99 if (ppdev->bHGSMISupported)
100 {
101 /* In HGSMI mode the display driver decides about the size. */
102 iDevice = info.iDevice;
103 u32DisplayInfoSize = VBVA_DISPLAY_INFORMATION_SIZE;
104 }
105#endif /* VBOX_WITH_HGSMI */
106
107#ifndef VBOX_WITH_HGSMI
108 if (ppdev->bVBoxVideoSupported)
109 {
110#else
111 if (ppdev->bHGSMISupported)
112 {
113#endif /* VBOX_WITH_HGSMI */
114 ppdev->iDevice = iDevice;
115
116 ppdev->layout.cbVRAM = pMemoryInformation->VideoRamLength;
117
118 ppdev->layout.offFrameBuffer = 0;
119 ppdev->layout.cbFrameBuffer = RT_ALIGN_32(pMemoryInformation->FrameBufferLength, 0x1000);
120
121 cbAvailable = ppdev->layout.cbVRAM - ppdev->layout.cbFrameBuffer;
122
123 if (cbAvailable <= u32DisplayInfoSize)
124 {
125#ifndef VBOX_WITH_HGSMI
126 ppdev->bVBoxVideoSupported = FALSE;
127#else
128 ppdev->bHGSMISupported = FALSE;
129#endif /* VBOX_WITH_HGSMI */
130 }
131 else
132 {
133 ppdev->layout.offDisplayInformation = ppdev->layout.cbVRAM - u32DisplayInfoSize;
134 ppdev->layout.cbDisplayInformation = u32DisplayInfoSize;
135
136 cbAvailable -= ppdev->layout.cbDisplayInformation;
137
138 /* Use minimum 64K and maximum the cbFrameBuffer for the VBVA buffer. */
139 for (ppdev->layout.cbVBVABuffer = ppdev->layout.cbFrameBuffer;
140 ppdev->layout.cbVBVABuffer >= 0x10000;
141 ppdev->layout.cbVBVABuffer /= 2)
142 {
143 if (ppdev->layout.cbVBVABuffer < cbAvailable)
144 {
145 break;
146 }
147 }
148
149 if (ppdev->layout.cbVBVABuffer >= cbAvailable)
150 {
151#ifndef VBOX_WITH_HGSMI
152 ppdev->bVBoxVideoSupported = FALSE;
153#else
154 ppdev->bHGSMISupported = FALSE;
155#endif /* VBOX_WITH_HGSMI */
156 }
157 else
158 {
159 /* Now the offscreen heap followed by the VBVA buffer. */
160 ppdev->layout.offDDRAWHeap = ppdev->layout.offFrameBuffer + ppdev->layout.cbFrameBuffer;
161
162 cbAvailable -= ppdev->layout.cbVBVABuffer;
163 ppdev->layout.cbDDRAWHeap = cbAvailable;
164
165 ppdev->layout.offVBVABuffer = ppdev->layout.offDDRAWHeap + ppdev->layout.cbDDRAWHeap;
166 }
167 }
168 }
169
170#ifndef VBOX_WITH_HGSMI
171 if (!ppdev->bVBoxVideoSupported)
172#else
173 if (!ppdev->bHGSMISupported)
174#endif /* VBOX_WITH_HGSMI */
175 {
176 ppdev->iDevice = 0;
177
178 /* Setup a layout without both the VBVA buffer and the display information. */
179 ppdev->layout.cbVRAM = pMemoryInformation->VideoRamLength;
180
181 ppdev->layout.offFrameBuffer = 0;
182 ppdev->layout.cbFrameBuffer = RT_ALIGN_32(pMemoryInformation->FrameBufferLength, 0x1000);
183
184 ppdev->layout.offDDRAWHeap = ppdev->layout.offFrameBuffer + ppdev->layout.cbFrameBuffer;
185 ppdev->layout.cbDDRAWHeap = ppdev->layout.cbVRAM - ppdev->layout.offDDRAWHeap;
186
187 ppdev->layout.offVBVABuffer = ppdev->layout.offDDRAWHeap + ppdev->layout.cbDDRAWHeap;
188 ppdev->layout.cbVBVABuffer = 0;
189
190 ppdev->layout.offDisplayInformation = ppdev->layout.offVBVABuffer + ppdev->layout.cbVBVABuffer;
191 ppdev->layout.cbDisplayInformation = 0;
192 }
193#ifdef VBOX_WITH_HGSMI
194 else
195 {
196 /* Setup HGSMI heap in the display information area. The area has some space reserved for
197 * HGSMI event flags in the beginning.
198 */
199 int rc = HGSMIHeapSetup (&ppdev->hgsmiDisplayHeap,
200 (uint8_t *)ppdev->pjScreen + ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS),
201 ppdev->layout.cbDisplayInformation - sizeof (HGSMIHOSTFLAGS),
202 ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS));
203
204 if (RT_FAILURE (rc))
205 {
206 DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: HGSMIHeapSetup failed rc = %d\n",
207 rc));
208
209 ppdev->bHGSMISupported = FALSE;
210 }
211 else
212 {
213 /* Inform the host about the HGSMIHOSTEVENTS location. */
214 void *p = HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
215 sizeof (HGSMI_BUFFER_LOCATION),
216 HGSMI_CH_HGSMI,
217 HGSMI_CC_HOST_FLAGS_LOCATION);
218
219 if (!p)
220 {
221 DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: HGSMIHeapAlloc failed\n"));
222 rc = VERR_NO_MEMORY;
223 }
224 else
225 {
226 HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&ppdev->hgsmiDisplayHeap,
227 p);
228
229 ((HGSMI_BUFFER_LOCATION *)p)->offLocation = ppdev->layout.offDisplayInformation;
230 ((HGSMI_BUFFER_LOCATION *)p)->cbLocation = sizeof (HGSMIHOSTFLAGS);
231
232 /* Submit the buffer to the host. */
233 ASMOutU16 (VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBVA_GUEST);
234 ASMOutU32 (VBE_DISPI_IOPORT_DATA, offBuffer);
235
236 HGSMIHeapFree (&ppdev->hgsmiDisplayHeap, p);
237 }
238 }
239 }
240#endif /* VBOX_WITH_HGSMI */
241
242 DISPDBG((0, "vboxInitVBoxVideo:\n"
243 " cbVRAM = 0x%X\n"
244 " offFrameBuffer = 0x%X\n"
245 " cbFrameBuffer = 0x%X\n"
246 " offDDRAWHeap = 0x%X\n"
247 " cbDDRAWHeap = 0x%X\n"
248 " offVBVABuffer = 0x%X\n"
249 " cbVBVABuffer = 0x%X\n"
250 " offDisplayInformation = 0x%X\n"
251 " cbDisplayInformation = 0x%X\n",
252 ppdev->layout.cbVRAM,
253 ppdev->layout.offFrameBuffer,
254 ppdev->layout.cbFrameBuffer,
255 ppdev->layout.offDDRAWHeap,
256 ppdev->layout.cbDDRAWHeap,
257 ppdev->layout.offVBVABuffer,
258 ppdev->layout.cbVBVABuffer,
259 ppdev->layout.offDisplayInformation,
260 ppdev->layout.cbDisplayInformation
261 ));
262}
263
264
265#ifndef VBOX_WITH_HGSMI
266/* Setup display information after remapping. */
267static void vboxSetupDisplayInfo (PPDEV ppdev, VIDEO_MEMORY_INFORMATION *pMemoryInformation)
268{
269 VBOXDISPLAYINFO *pInfo;
270 uint8_t *pu8;
271
272 pu8 = (uint8_t *)ppdev->pjScreen + ppdev->layout.offDisplayInformation;
273
274 pInfo = (VBOXDISPLAYINFO *)pu8;
275 pu8 += sizeof (VBOXDISPLAYINFO);
276
277 pInfo->hdrLink.u8Type = VBOX_VIDEO_INFO_TYPE_LINK;
278 pInfo->hdrLink.u8Reserved = 0;
279 pInfo->hdrLink.u16Length = sizeof (VBOXVIDEOINFOLINK);
280 pInfo->link.i32Offset = 0;
281
282 pInfo->hdrScreen.u8Type = VBOX_VIDEO_INFO_TYPE_SCREEN;
283 pInfo->hdrScreen.u8Reserved = 0;
284 pInfo->hdrScreen.u16Length = sizeof (VBOXVIDEOINFOSCREEN);
285 DISPDBG((1, "Setup: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
286 pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
287 pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
288 pInfo->screen.u32LineSize = 0;
289 pInfo->screen.u16Width = 0;
290 pInfo->screen.u16Height = 0;
291 pInfo->screen.bitsPerPixel = 0;
292 pInfo->screen.u8Flags = VBOX_VIDEO_INFO_SCREEN_F_NONE;
293
294 pInfo->hdrHostEvents.u8Type = VBOX_VIDEO_INFO_TYPE_HOST_EVENTS;
295 pInfo->hdrHostEvents.u8Reserved = 0;
296 pInfo->hdrHostEvents.u16Length = sizeof (VBOXVIDEOINFOHOSTEVENTS);
297 pInfo->hostEvents.fu32Events = VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE;
298
299 pInfo->hdrEnd.u8Type = VBOX_VIDEO_INFO_TYPE_END;
300 pInfo->hdrEnd.u8Reserved = 0;
301 pInfo->hdrEnd.u16Length = 0;
302
303 ppdev->pInfo = pInfo;
304}
305
306
307static void vboxUpdateDisplayInfo (PPDEV ppdev)
308{
309 if (ppdev->pInfo)
310 {
311 ppdev->pInfo->screen.u32LineSize = ppdev->lDeltaScreen;
312 ppdev->pInfo->screen.u16Width = (uint16_t)ppdev->cxScreen;
313 ppdev->pInfo->screen.u16Height = (uint16_t)ppdev->cyScreen;
314 ppdev->pInfo->screen.bitsPerPixel = (uint8_t)ppdev->ulBitCount;
315 ppdev->pInfo->screen.u8Flags = VBOX_VIDEO_INFO_SCREEN_F_ACTIVE;
316
317 DISPDBG((1, "Update: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
318 VBoxProcessDisplayInfo(ppdev);
319 }
320}
321#endif /* !VBOX_WITH_HGSMI */
322
323
324/******************************Public*Routine******************************\
325* bInitSURF
326*
327* Enables the surface. Maps the frame buffer into memory.
328*
329\**************************************************************************/
330
331BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
332{
333 DWORD returnedDataLength;
334 DWORD MaxWidth, MaxHeight;
335 VIDEO_MEMORY videoMemory;
336 VIDEO_MEMORY_INFORMATION videoMemoryInformation;
337 ULONG RemappingNeeded = 0;
338
339 //
340 // Set the current mode into the hardware.
341 //
342
343 if (EngDeviceIoControl(ppdev->hDriver,
344 IOCTL_VIDEO_SET_CURRENT_MODE,
345 &(ppdev->ulMode),
346 sizeof(ULONG),
347 &RemappingNeeded,
348 sizeof(ULONG),
349 &returnedDataLength))
350 {
351 DISPDBG((1, "DISP bInitSURF failed IOCTL_SET_MODE\n"));
352 return(FALSE);
353 }
354
355 //
356 // If this is the first time we enable the surface we need to map in the
357 // memory also.
358 //
359
360 if (bFirst || RemappingNeeded)
361 {
362 videoMemory.RequestedVirtualAddress = NULL;
363
364 if (EngDeviceIoControl(ppdev->hDriver,
365 IOCTL_VIDEO_MAP_VIDEO_MEMORY,
366 &videoMemory,
367 sizeof(VIDEO_MEMORY),
368 &videoMemoryInformation,
369 sizeof(VIDEO_MEMORY_INFORMATION),
370 &returnedDataLength))
371 {
372 DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_MAP\n"));
373 return(FALSE);
374 }
375
376 ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
377
378 if (videoMemoryInformation.FrameBufferBase !=
379 videoMemoryInformation.VideoRamBase)
380 {
381 DISPDBG((0, "VideoRamBase does not correspond to FrameBufferBase\n"));
382 }
383
384 //
385 // Make sure we can access this video memory
386 //
387
388 *(PULONG)(ppdev->pjScreen) = 0xaa55aa55;
389
390 if (*(PULONG)(ppdev->pjScreen) != 0xaa55aa55) {
391
392 DISPDBG((1, "Frame buffer memory is not accessible.\n"));
393 return(FALSE);
394 }
395
396 /* Clear VRAM to avoid distortions during the video mode change. */
397 RtlZeroMemory(ppdev->pjScreen,
398 ppdev->cyScreen * (ppdev->lDeltaScreen > 0? ppdev->lDeltaScreen: -ppdev->lDeltaScreen));
399
400 //
401 // Initialize the head of the offscreen list to NULL.
402 //
403
404 ppdev->pOffscreenList = NULL;
405
406 // It's a hardware pointer; set up pointer attributes.
407
408 MaxHeight = ppdev->PointerCapabilities.MaxHeight;
409
410 // Allocate space for two DIBs (data/mask) for the pointer. If this
411 // device supports a color Pointer, we will allocate a larger bitmap.
412 // If this is a color bitmap we allocate for the largest possible
413 // bitmap because we have no idea of what the pixel depth might be.
414
415 // Width rounded up to nearest byte multiple
416
417 if (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))
418 {
419 MaxWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
420 }
421 else
422 {
423 MaxWidth = ppdev->PointerCapabilities.MaxWidth * sizeof(DWORD);
424 }
425
426 ppdev->cjPointerAttributes =
427 sizeof(VIDEO_POINTER_ATTRIBUTES) +
428 ((sizeof(UCHAR) * MaxWidth * MaxHeight) * 2);
429
430 ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
431 EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
432
433 if (ppdev->pPointerAttributes == NULL) {
434
435 DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
436 return(FALSE);
437 }
438
439 ppdev->pPointerAttributes->Flags = ppdev->PointerCapabilities.Flags;
440 ppdev->pPointerAttributes->WidthInBytes = MaxWidth;
441 ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth;
442 ppdev->pPointerAttributes->Height = MaxHeight;
443 ppdev->pPointerAttributes->Column = 0;
444 ppdev->pPointerAttributes->Row = 0;
445 ppdev->pPointerAttributes->Enable = 0;
446
447 vboxInitVBoxVideo (ppdev, &videoMemoryInformation);
448
449#ifndef VBOX_WITH_HGSMI
450 if (ppdev->bVBoxVideoSupported)
451 {
452 /* Setup the display information. */
453 vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
454 }
455#endif /* !VBOX_WITH_HGSMI */
456 }
457
458
459 DISPDBG((1, "DISP bInitSURF: ppdev->ulBitCount %d\n", ppdev->ulBitCount));
460
461 if ( ppdev->ulBitCount == 16
462 || ppdev->ulBitCount == 24
463 || ppdev->ulBitCount == 32)
464 {
465#ifndef VBOX_WITH_HGSMI
466 if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
467 {
468 /* Enable VBVA for this video mode. */
469 vboxVbvaEnable (ppdev);
470 }
471#else
472 if (ppdev->bHGSMISupported)
473 {
474 /* Enable VBVA for this video mode. */
475 vboxVbvaEnable (ppdev);
476 }
477#endif /* VBOX_WITH_HGSMI */
478 }
479
480 DISPDBG((1, "DISP bInitSURF success\n"));
481
482#ifndef VBOX_WITH_HGSMI
483 /* Update the display information. */
484 vboxUpdateDisplayInfo (ppdev);
485#else
486 /* Inform the host about this screen layout. */
487 DISPDBG((1, "bInitSURF: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
488 VBoxProcessDisplayInfo (ppdev);
489#endif /* VBOX_WITH_HGSMI */
490
491 return(TRUE);
492}
493
494/******************************Public*Routine******************************\
495* vDisableSURF
496*
497* Disable the surface. Un-Maps the frame in memory.
498*
499\**************************************************************************/
500
501VOID vDisableSURF(PPDEV ppdev)
502{
503 DWORD returnedDataLength;
504 VIDEO_MEMORY videoMemory;
505
506 videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
507
508 if (EngDeviceIoControl(ppdev->hDriver,
509 IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
510 &videoMemory,
511 sizeof(VIDEO_MEMORY),
512 NULL,
513 0,
514 &returnedDataLength))
515 {
516 DISPDBG((0, "DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n"));
517 }
518}
519
520
521/******************************Public*Routine******************************\
522* bInitPDEV
523*
524* Determine the mode we should be in based on the DEVMODE passed in.
525* Query mini-port to get information needed to fill in the DevInfo and the
526* GdiInfo .
527*
528\**************************************************************************/
529
530BOOL bInitPDEV(
531PPDEV ppdev,
532DEVMODEW *pDevMode,
533GDIINFO *pGdiInfo,
534DEVINFO *pDevInfo)
535{
536 ULONG cModes;
537 PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
538 VIDEO_COLOR_CAPABILITIES colorCapabilities;
539 ULONG ulTemp;
540 BOOL bSelectDefault;
541 ULONG cbModeSize;
542
543 //
544 // calls the miniport to get mode information.
545 //
546
547 cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
548
549 if (cModes == 0)
550 {
551 return(FALSE);
552 }
553
554 //
555 // Now see if the requested mode has a match in that table.
556 //
557
558 pVideoModeSelected = NULL;
559 pVideoTemp = pVideoBuffer;
560
561 if ((pDevMode->dmPelsWidth == 0) &&
562 (pDevMode->dmPelsHeight == 0) &&
563 (pDevMode->dmBitsPerPel == 0) &&
564 (pDevMode->dmDisplayFrequency == 0))
565 {
566 DISPDBG((2, "Default mode requested"));
567 bSelectDefault = TRUE;
568 }
569 else
570 {
571 DISPDBG((2, "Requested mode...\n"));
572 DISPDBG((2, " Screen width -- %li\n", pDevMode->dmPelsWidth));
573 DISPDBG((2, " Screen height -- %li\n", pDevMode->dmPelsHeight));
574 DISPDBG((2, " Bits per pel -- %li\n", pDevMode->dmBitsPerPel));
575 DISPDBG((2, " Frequency -- %li\n", pDevMode->dmDisplayFrequency));
576
577 bSelectDefault = FALSE;
578 }
579
580 while (cModes--)
581 {
582 if (pVideoTemp->Length != 0)
583 {
584 if (bSelectDefault ||
585 ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
586 (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
587 (pVideoTemp->BitsPerPlane *
588 pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
589 (pVideoTemp->Frequency == pDevMode->dmDisplayFrequency)))
590 {
591 pVideoModeSelected = pVideoTemp;
592 DISPDBG((3, "Found a match\n")) ;
593 break;
594 }
595 }
596
597 pVideoTemp = (PVIDEO_MODE_INFORMATION)
598 (((PUCHAR)pVideoTemp) + cbModeSize);
599 }
600
601 //
602 // If no mode has been found, return an error
603 //
604
605 if (pVideoModeSelected == NULL)
606 {
607 EngFreeMem(pVideoBuffer);
608 DISPDBG((0,"DISP bInitPDEV failed - no valid modes\n"));
609 return(FALSE);
610 }
611
612 //
613 // Fill in the GDIINFO data structure with the information returned from
614 // the kernel driver.
615 //
616
617 ppdev->ulMode = pVideoModeSelected->ModeIndex;
618 ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
619 ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
620 ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
621 pVideoModeSelected->NumberOfPlanes;
622 ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
623
624 ppdev->flRed = pVideoModeSelected->RedMask;
625 ppdev->flGreen = pVideoModeSelected->GreenMask;
626 ppdev->flBlue = pVideoModeSelected->BlueMask;
627
628
629 if (g_bOnNT40)
630 {
631 DISPDBG((0,"DISP bInitPDEV pGdiInfo->ulVersion = %x\n", GDI_DRIVER_VERSION));
632 pGdiInfo->ulVersion = GDI_DRIVER_VERSION; /* 0x4000 -> NT4 */
633 }
634 else
635 {
636 DISPDBG((0,"DISP bInitPDEV pGdiInfo->ulVersion = %x\n", 0x5000));
637 pGdiInfo->ulVersion = 0x5000;
638 }
639
640 pGdiInfo->ulTechnology = DT_RASDISPLAY;
641 pGdiInfo->ulHorzSize = pVideoModeSelected->XMillimeter;
642 pGdiInfo->ulVertSize = pVideoModeSelected->YMillimeter;
643
644 pGdiInfo->ulHorzRes = ppdev->cxScreen;
645 pGdiInfo->ulVertRes = ppdev->cyScreen;
646 pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
647 pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
648 pGdiInfo->cBitsPixel = pVideoModeSelected->BitsPerPlane;
649 pGdiInfo->cPlanes = pVideoModeSelected->NumberOfPlanes;
650 pGdiInfo->ulVRefresh = pVideoModeSelected->Frequency;
651 /* bit block transfers are accelerated */
652 pGdiInfo->ulBltAlignment = 0;
653
654 pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
655 pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
656
657#ifdef MIPS
658 if (ppdev->ulBitCount == 8)
659 pGdiInfo->flTextCaps = (TC_RA_ABLE | TC_SCROLLBLT);
660 else
661#endif
662 pGdiInfo->flTextCaps = TC_RA_ABLE;
663
664 pGdiInfo->flRaster = 0; // flRaster is reserved by DDI
665
666 pGdiInfo->ulDACRed = pVideoModeSelected->NumberRedBits;
667 pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
668 pGdiInfo->ulDACBlue = pVideoModeSelected->NumberBlueBits;
669
670 pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
671 pGdiInfo->ulAspectY = 0x24;
672 pGdiInfo->ulAspectXY = 0x33;
673
674 pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
675 pGdiInfo->yStyleStep = 1;
676 pGdiInfo->denStyleStep = 3;
677
678 pGdiInfo->ptlPhysOffset.x = 0;
679 pGdiInfo->ptlPhysOffset.y = 0;
680 pGdiInfo->szlPhysSize.cx = 0;
681 pGdiInfo->szlPhysSize.cy = 0;
682
683 // RGB and CMY color info.
684
685 //
686 // try to get it from the miniport.
687 // if the miniport doesn ot support this feature, use defaults.
688 //
689
690 if (EngDeviceIoControl(ppdev->hDriver,
691 IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
692 NULL,
693 0,
694 &colorCapabilities,
695 sizeof(VIDEO_COLOR_CAPABILITIES),
696 &ulTemp))
697 {
698
699 DISPDBG((2, "getcolorCapabilities failed \n"));
700
701 pGdiInfo->ciDevice.Red.x = 6700;
702 pGdiInfo->ciDevice.Red.y = 3300;
703 pGdiInfo->ciDevice.Red.Y = 0;
704 pGdiInfo->ciDevice.Green.x = 2100;
705 pGdiInfo->ciDevice.Green.y = 7100;
706 pGdiInfo->ciDevice.Green.Y = 0;
707 pGdiInfo->ciDevice.Blue.x = 1400;
708 pGdiInfo->ciDevice.Blue.y = 800;
709 pGdiInfo->ciDevice.Blue.Y = 0;
710 pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
711 pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
712 pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
713
714 pGdiInfo->ciDevice.RedGamma = 20000;
715 pGdiInfo->ciDevice.GreenGamma = 20000;
716 pGdiInfo->ciDevice.BlueGamma = 20000;
717
718 }
719 else
720 {
721 pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
722 pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
723 pGdiInfo->ciDevice.Red.Y = 0;
724 pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
725 pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
726 pGdiInfo->ciDevice.Green.Y = 0;
727 pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
728 pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
729 pGdiInfo->ciDevice.Blue.Y = 0;
730 pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
731 pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
732 pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
733
734 // if we have a color device store the three color gamma values,
735 // otherwise store the unique gamma value in all three.
736
737 if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
738 {
739 pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
740 pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
741 pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
742 }
743 else
744 {
745 pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
746 pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
747 pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
748 }
749
750 };
751
752 pGdiInfo->ciDevice.Cyan.x = 0;
753 pGdiInfo->ciDevice.Cyan.y = 0;
754 pGdiInfo->ciDevice.Cyan.Y = 0;
755 pGdiInfo->ciDevice.Magenta.x = 0;
756 pGdiInfo->ciDevice.Magenta.y = 0;
757 pGdiInfo->ciDevice.Magenta.Y = 0;
758 pGdiInfo->ciDevice.Yellow.x = 0;
759 pGdiInfo->ciDevice.Yellow.y = 0;
760 pGdiInfo->ciDevice.Yellow.Y = 0;
761
762 // No dye correction for raster displays.
763
764 pGdiInfo->ciDevice.MagentaInCyanDye = 0;
765 pGdiInfo->ciDevice.YellowInCyanDye = 0;
766 pGdiInfo->ciDevice.CyanInMagentaDye = 0;
767 pGdiInfo->ciDevice.YellowInMagentaDye = 0;
768 pGdiInfo->ciDevice.CyanInYellowDye = 0;
769 pGdiInfo->ciDevice.MagentaInYellowDye = 0;
770
771 pGdiInfo->ulDevicePelsDPI = 0; // For printers only
772 pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
773
774 // Note: this should be modified later to take into account the size
775 // of the display and the resolution.
776
777 pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
778
779 pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
780
781 // Fill in the basic devinfo structure
782
783 *pDevInfo = gDevInfoFrameBuffer;
784
785 // Fill in the rest of the devinfo and GdiInfo structures.
786
787 if (ppdev->ulBitCount == 8)
788 {
789 // It is Palette Managed.
790
791 pGdiInfo->ulNumColors = 20;
792 pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
793
794 pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
795
796 pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
797 pDevInfo->iDitherFormat = BMF_8BPP;
798
799 // Assuming palette is orthogonal - all colors are same size.
800
801 ppdev->cPaletteShift = 8 - pGdiInfo->ulDACRed;
802 }
803 else
804 {
805 pGdiInfo->ulNumColors = (ULONG) (-1);
806 pGdiInfo->ulNumPalReg = 0;
807
808 if (ppdev->ulBitCount == 16)
809 {
810 pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
811 pDevInfo->iDitherFormat = BMF_16BPP;
812 }
813 else if (ppdev->ulBitCount == 24)
814 {
815 pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
816 pDevInfo->iDitherFormat = BMF_24BPP;
817 }
818 else
819 {
820 pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
821 pDevInfo->iDitherFormat = BMF_32BPP;
822 }
823 }
824
825 EngFreeMem(pVideoBuffer);
826
827 return(TRUE);
828}
829
830
831/******************************Public*Routine******************************\
832* getAvailableModes
833*
834* Calls the miniport to get the list of modes supported by the kernel driver,
835* and returns the list of modes supported by the diplay driver among those
836*
837* returns the number of entries in the videomode buffer.
838* 0 means no modes are supported by the miniport or that an error occured.
839*
840* NOTE: the buffer must be freed up by the caller.
841*
842\**************************************************************************/
843
844DWORD getAvailableModes(
845HANDLE hDriver,
846PVIDEO_MODE_INFORMATION *modeInformation,
847DWORD *cbModeSize)
848{
849 ULONG ulTemp;
850 VIDEO_NUM_MODES modes;
851 PVIDEO_MODE_INFORMATION pVideoTemp;
852
853 //
854 // Get the number of modes supported by the mini-port
855 //
856
857 if (EngDeviceIoControl(hDriver,
858 IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
859 NULL,
860 0,
861 &modes,
862 sizeof(VIDEO_NUM_MODES),
863 &ulTemp))
864 {
865 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
866 return(0);
867 }
868
869 *cbModeSize = modes.ModeInformationLength;
870
871 //
872 // Allocate the buffer for the mini-port to write the modes in.
873 //
874
875 *modeInformation = (PVIDEO_MODE_INFORMATION)
876 EngAllocMem(0, modes.NumModes *
877 modes.ModeInformationLength, ALLOC_TAG);
878
879 if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
880 {
881 DISPDBG((0, "getAvailableModes failed EngAllocMem\n"));
882
883 return 0;
884 }
885
886 //
887 // Ask the mini-port to fill in the available modes.
888 //
889
890 if (EngDeviceIoControl(hDriver,
891 IOCTL_VIDEO_QUERY_AVAIL_MODES,
892 NULL,
893 0,
894 *modeInformation,
895 modes.NumModes * modes.ModeInformationLength,
896 &ulTemp))
897 {
898
899 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
900
901 EngFreeMem(*modeInformation);
902 *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
903
904 return(0);
905 }
906
907 //
908 // Now see which of these modes are supported by the display driver.
909 // As an internal mechanism, set the length to 0 for the modes we
910 // DO NOT support.
911 //
912
913 ulTemp = modes.NumModes;
914 pVideoTemp = *modeInformation;
915
916 //
917 // Mode is rejected if it is not one plane, or not graphics, or is not
918 // one of 8, 16 or 32 bits per pel.
919 //
920
921 while (ulTemp--)
922 {
923 if ((pVideoTemp->NumberOfPlanes != 1 ) ||
924 !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
925 (pVideoTemp->AttributeFlags & VIDEO_MODE_BANKED) ||
926 ((pVideoTemp->BitsPerPlane != 8) &&
927 (pVideoTemp->BitsPerPlane != 16) &&
928 (pVideoTemp->BitsPerPlane != 24) &&
929 (pVideoTemp->BitsPerPlane != 32)))
930 {
931 pVideoTemp->Length = 0;
932 }
933
934 pVideoTemp = (PVIDEO_MODE_INFORMATION)
935 (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
936 }
937
938 return modes.NumModes;
939
940}
941
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette