VirtualBox

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

Last change on this file since 22548 was 22548, checked in by vboxsync, 15 years ago

HGSMI/VBVA use port IO for guest commands in display driver instead of miniport callback.

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