VirtualBox

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

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

hgsmi/guest video driver: backwards compatibility with < WinXP: make newer videoport functions picked up at runtime

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

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