VirtualBox

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

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

header updates

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