VirtualBox

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

Last change on this file since 35650 was 34665, checked in by vboxsync, 14 years ago

Additions/common/VBoxVideo and Additions/WINNT/Graphics: some adjustments to the common VBoxVideo code

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