VirtualBox

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

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

HGSMI for the graphics device: the windows guest display driver prototype code.

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