VirtualBox

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

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

HGSMI/VBVA updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.4 KB
Line 
1/******************************Module*Header*******************************\
2*
3 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
4 *
5 * This file is part of VirtualBox Open Source Edition (OSE), as
6 * available from http://www.virtualbox.org. This file is free software;
7 * you can redistribute it and/or modify it under the terms of the GNU
8 * General Public License (GPL) as published by the Free Software
9 * Foundation, in version 2 as it comes in the "COPYING" file of the
10 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
11 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
12 *
13 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
14 * Clara, CA 95054 USA or visit http://www.sun.com if you need
15 * additional information or have any questions.
16*/
17/*
18* Based in part on Microsoft DDK sample code
19*
20* *******************
21* * GDI SAMPLE CODE *
22* *******************
23*
24* Module Name: screen.c
25*
26* Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
27*
28* Copyright (c) 1992-1998 Microsoft Corporation
29\**************************************************************************/
30
31#include "driver.h"
32
33#ifdef VBOX_WITH_HGSMI
34#include <iprt/asm.h>
35#include <VBox/log.h>
36#include <VBox/HGSMI/HGSMI.h>
37#include <VBox/HGSMI/HGSMIChSetup.h>
38#endif
39
40#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"}
41#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"}
42#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"}
43
44// This is the basic devinfo for a default driver. This is used as a base and customized based
45// on information passed back from the miniport driver.
46
47const DEVINFO gDevInfoFrameBuffer = {
48 ( GCAPS_OPAQUERECT
49#ifdef VBOX_WITH_DDRAW
50 | GCAPS_DIRECTDRAW
51#endif
52 | GCAPS_MONO_DITHER
53 ), /* Graphics capabilities */
54 SYSTM_LOGFONT, /* Default font description */
55 HELVE_LOGFONT, /* ANSI variable font description */
56 COURI_LOGFONT, /* ANSI fixed font description */
57 0, /* Count of device fonts */
58 0, /* Preferred DIB format */
59 8, /* Width of color dither */
60 8, /* Height of color dither */
61 0 /* Default palette to use for this device */
62};
63
64static void vboxInitVBoxVideo (PPDEV ppdev, const VIDEO_MEMORY_INFORMATION *pMemoryInformation)
65{
66 ULONG cbAvailable = 0;
67
68 DWORD returnedDataLength;
69
70 ULONG iDevice;
71 uint32_t u32DisplayInfoSize;
72 uint32_t u32MinVBVABufferSize;
73
74#ifndef VBOX_WITH_HGSMI
75 QUERYDISPLAYINFORESULT DispInfo;
76 RtlZeroMemory(&DispInfo, sizeof (DispInfo));
77
78 ppdev->bVBoxVideoSupported = !EngDeviceIoControl(ppdev->hDriver,
79 IOCTL_VIDEO_QUERY_DISPLAY_INFO,
80 NULL,
81 0,
82 &DispInfo,
83 sizeof(DispInfo),
84 &returnedDataLength);
85 if (ppdev->bVBoxVideoSupported)
86 {
87 iDevice = DispInfo.iDevice;
88 u32DisplayInfoSize = DispInfo.u32DisplayInfoSize;
89 u32MinVBVABufferSize = 0; /* In old mode the buffer is not used at all. */
90 }
91#else
92 QUERYHGSMIRESULT info;
93 RtlZeroMemory(&info, sizeof (info));
94
95 ppdev->bHGSMISupported = !EngDeviceIoControl(ppdev->hDriver,
96 IOCTL_VIDEO_QUERY_HGSMI_INFO,
97 NULL,
98 0,
99 &info,
100 sizeof(info),
101 &returnedDataLength);
102 if (ppdev->bHGSMISupported)
103 {
104 HGSMIQUERYCALLBACKS Callbacks;
105 DWORD err;
106 RtlZeroMemory(&Callbacks, sizeof(Callbacks));
107
108 iDevice = info.iDevice;
109 u32DisplayInfoSize = info.u32DisplayInfoSize;
110 u32MinVBVABufferSize = info.u32MinVBVABufferSize;
111
112 err = EngDeviceIoControl(ppdev->hDriver,
113 IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS,
114 NULL,
115 0,
116 &Callbacks,
117 sizeof(Callbacks),
118 &returnedDataLength);
119 Assert(!err);
120 if(!err)
121 {
122 HGSMIQUERYCPORTPROCS PortProcs;
123 RtlZeroMemory(&PortProcs, sizeof(PortProcs));
124
125 ppdev->hMpHGSMI = Callbacks.hContext;
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 else
276 {
277 ppdev->IOPortGuestCommand = info.IOPortGuestCommand;
278 }
279 }
280#endif /* VBOX_WITH_HGSMI */
281
282 DISPDBG((0, "vboxInitVBoxVideo:\n"
283 " cbVRAM = 0x%X\n"
284 " offFrameBuffer = 0x%X\n"
285 " cbFrameBuffer = 0x%X\n"
286 " offDDRAWHeap = 0x%X\n"
287 " cbDDRAWHeap = 0x%X\n"
288 " offVBVABuffer = 0x%X\n"
289 " cbVBVABuffer = 0x%X\n"
290 " offDisplayInformation = 0x%X\n"
291 " cbDisplayInformation = 0x%X\n",
292 ppdev->layout.cbVRAM,
293 ppdev->layout.offFrameBuffer,
294 ppdev->layout.cbFrameBuffer,
295 ppdev->layout.offDDRAWHeap,
296 ppdev->layout.cbDDRAWHeap,
297 ppdev->layout.offVBVABuffer,
298 ppdev->layout.cbVBVABuffer,
299 ppdev->layout.offDisplayInformation,
300 ppdev->layout.cbDisplayInformation
301 ));
302}
303
304
305#ifndef VBOX_WITH_HGSMI
306/* Setup display information after remapping. */
307static void vboxSetupDisplayInfo (PPDEV ppdev, VIDEO_MEMORY_INFORMATION *pMemoryInformation)
308{
309 VBOXDISPLAYINFO *pInfo;
310 uint8_t *pu8;
311
312 pu8 = (uint8_t *)ppdev->pjScreen + ppdev->layout.offDisplayInformation;
313
314 pInfo = (VBOXDISPLAYINFO *)pu8;
315 pu8 += sizeof (VBOXDISPLAYINFO);
316
317 pInfo->hdrLink.u8Type = VBOX_VIDEO_INFO_TYPE_LINK;
318 pInfo->hdrLink.u8Reserved = 0;
319 pInfo->hdrLink.u16Length = sizeof (VBOXVIDEOINFOLINK);
320 pInfo->link.i32Offset = 0;
321
322 pInfo->hdrScreen.u8Type = VBOX_VIDEO_INFO_TYPE_SCREEN;
323 pInfo->hdrScreen.u8Reserved = 0;
324 pInfo->hdrScreen.u16Length = sizeof (VBOXVIDEOINFOSCREEN);
325 DISPDBG((1, "Setup: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
326 pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
327 pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
328 pInfo->screen.u32LineSize = 0;
329 pInfo->screen.u16Width = 0;
330 pInfo->screen.u16Height = 0;
331 pInfo->screen.bitsPerPixel = 0;
332 pInfo->screen.u8Flags = VBOX_VIDEO_INFO_SCREEN_F_NONE;
333
334 pInfo->hdrHostEvents.u8Type = VBOX_VIDEO_INFO_TYPE_HOST_EVENTS;
335 pInfo->hdrHostEvents.u8Reserved = 0;
336 pInfo->hdrHostEvents.u16Length = sizeof (VBOXVIDEOINFOHOSTEVENTS);
337 pInfo->hostEvents.fu32Events = VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE;
338
339 pInfo->hdrEnd.u8Type = VBOX_VIDEO_INFO_TYPE_END;
340 pInfo->hdrEnd.u8Reserved = 0;
341 pInfo->hdrEnd.u16Length = 0;
342
343 ppdev->pInfo = pInfo;
344}
345
346
347static void vboxUpdateDisplayInfo (PPDEV ppdev)
348{
349 if (ppdev->pInfo)
350 {
351 ppdev->pInfo->screen.u32LineSize = ppdev->lDeltaScreen;
352 ppdev->pInfo->screen.u16Width = (uint16_t)ppdev->cxScreen;
353 ppdev->pInfo->screen.u16Height = (uint16_t)ppdev->cyScreen;
354 ppdev->pInfo->screen.bitsPerPixel = (uint8_t)ppdev->ulBitCount;
355 ppdev->pInfo->screen.u8Flags = VBOX_VIDEO_INFO_SCREEN_F_ACTIVE;
356
357 DISPDBG((1, "Update: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
358 VBoxProcessDisplayInfo(ppdev);
359 }
360}
361#endif /* !VBOX_WITH_HGSMI */
362
363
364/******************************Public*Routine******************************\
365* bInitSURF
366*
367* Enables the surface. Maps the frame buffer into memory.
368*
369\**************************************************************************/
370
371BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
372{
373 DWORD returnedDataLength;
374 DWORD MaxWidth, MaxHeight;
375 VIDEO_MEMORY videoMemory;
376 VIDEO_MEMORY_INFORMATION videoMemoryInformation;
377 ULONG RemappingNeeded = 0;
378
379 //
380 // Set the current mode into the hardware.
381 //
382
383 if (EngDeviceIoControl(ppdev->hDriver,
384 IOCTL_VIDEO_SET_CURRENT_MODE,
385 &(ppdev->ulMode),
386 sizeof(ULONG),
387 &RemappingNeeded,
388 sizeof(ULONG),
389 &returnedDataLength))
390 {
391 DISPDBG((1, "DISP bInitSURF failed IOCTL_SET_MODE\n"));
392 return(FALSE);
393 }
394
395 //
396 // If this is the first time we enable the surface we need to map in the
397 // memory also.
398 //
399
400 if (bFirst || RemappingNeeded)
401 {
402 videoMemory.RequestedVirtualAddress = NULL;
403
404 if (EngDeviceIoControl(ppdev->hDriver,
405 IOCTL_VIDEO_MAP_VIDEO_MEMORY,
406 &videoMemory,
407 sizeof(VIDEO_MEMORY),
408 &videoMemoryInformation,
409 sizeof(VIDEO_MEMORY_INFORMATION),
410 &returnedDataLength))
411 {
412 DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_MAP\n"));
413 return(FALSE);
414 }
415
416 ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
417
418 if (videoMemoryInformation.FrameBufferBase !=
419 videoMemoryInformation.VideoRamBase)
420 {
421 DISPDBG((0, "VideoRamBase does not correspond to FrameBufferBase\n"));
422 }
423
424 //
425 // Make sure we can access this video memory
426 //
427
428 *(PULONG)(ppdev->pjScreen) = 0xaa55aa55;
429
430 if (*(PULONG)(ppdev->pjScreen) != 0xaa55aa55) {
431
432 DISPDBG((1, "Frame buffer memory is not accessible.\n"));
433 return(FALSE);
434 }
435
436 /* Clear VRAM to avoid distortions during the video mode change. */
437 RtlZeroMemory(ppdev->pjScreen,
438 ppdev->cyScreen * (ppdev->lDeltaScreen > 0? ppdev->lDeltaScreen: -ppdev->lDeltaScreen));
439
440 //
441 // Initialize the head of the offscreen list to NULL.
442 //
443
444 ppdev->pOffscreenList = NULL;
445
446 // It's a hardware pointer; set up pointer attributes.
447
448 MaxHeight = ppdev->PointerCapabilities.MaxHeight;
449
450 // Allocate space for two DIBs (data/mask) for the pointer. If this
451 // device supports a color Pointer, we will allocate a larger bitmap.
452 // If this is a color bitmap we allocate for the largest possible
453 // bitmap because we have no idea of what the pixel depth might be.
454
455 // Width rounded up to nearest byte multiple
456
457 if (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))
458 {
459 MaxWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
460 }
461 else
462 {
463 MaxWidth = ppdev->PointerCapabilities.MaxWidth * sizeof(DWORD);
464 }
465
466 ppdev->cjPointerAttributes =
467 sizeof(VIDEO_POINTER_ATTRIBUTES) +
468 ((sizeof(UCHAR) * MaxWidth * MaxHeight) * 2);
469
470 ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
471 EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
472
473 if (ppdev->pPointerAttributes == NULL) {
474
475 DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
476 return(FALSE);
477 }
478
479 ppdev->pPointerAttributes->Flags = ppdev->PointerCapabilities.Flags;
480 ppdev->pPointerAttributes->WidthInBytes = MaxWidth;
481 ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth;
482 ppdev->pPointerAttributes->Height = MaxHeight;
483 ppdev->pPointerAttributes->Column = 0;
484 ppdev->pPointerAttributes->Row = 0;
485 ppdev->pPointerAttributes->Enable = 0;
486
487 vboxInitVBoxVideo (ppdev, &videoMemoryInformation);
488
489#ifndef VBOX_WITH_HGSMI
490 if (ppdev->bVBoxVideoSupported)
491 {
492 /* Setup the display information. */
493 vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
494 }
495#endif /* !VBOX_WITH_HGSMI */
496 }
497
498
499 DISPDBG((1, "DISP bInitSURF: ppdev->ulBitCount %d\n", ppdev->ulBitCount));
500
501 if ( ppdev->ulBitCount == 16
502 || ppdev->ulBitCount == 24
503 || ppdev->ulBitCount == 32)
504 {
505#ifndef VBOX_WITH_HGSMI
506 if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
507 {
508 /* Enable VBVA for this video mode. */
509 vboxVbvaEnable (ppdev);
510 }
511#else
512 if (ppdev->bHGSMISupported)
513 {
514 /* Enable VBVA for this video mode. */
515 ppdev->bHGSMISupported = vboxVbvaEnable (ppdev);
516 LogRel(("VBoxDisp[%d]: VBVA %senabled\n", ppdev->iDevice, ppdev->bHGSMISupported? "": "not "));
517 }
518#endif /* VBOX_WITH_HGSMI */
519 }
520
521 DISPDBG((1, "DISP bInitSURF success\n"));
522
523#ifndef VBOX_WITH_HGSMI
524 /* Update the display information. */
525 vboxUpdateDisplayInfo (ppdev);
526#else
527 /* Inform the host about this screen layout. */
528 DISPDBG((1, "bInitSURF: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
529 VBoxProcessDisplayInfo (ppdev);
530#endif /* VBOX_WITH_HGSMI */
531
532#ifdef VBOX_WITH_VIDEOHWACCEL
533 /* tells we can process host commands */
534 vboxVHWAEnable(ppdev);
535#endif
536
537 return(TRUE);
538}
539
540/******************************Public*Routine******************************\
541* vDisableSURF
542*
543* Disable the surface. Un-Maps the frame in memory.
544*
545\**************************************************************************/
546
547VOID vDisableSURF(PPDEV ppdev)
548{
549 DWORD returnedDataLength;
550 VIDEO_MEMORY videoMemory;
551
552 videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
553
554 if (EngDeviceIoControl(ppdev->hDriver,
555 IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
556 &videoMemory,
557 sizeof(VIDEO_MEMORY),
558 NULL,
559 0,
560 &returnedDataLength))
561 {
562 DISPDBG((0, "DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n"));
563 }
564}
565
566
567/******************************Public*Routine******************************\
568* bInitPDEV
569*
570* Determine the mode we should be in based on the DEVMODE passed in.
571* Query mini-port to get information needed to fill in the DevInfo and the
572* GdiInfo .
573*
574\**************************************************************************/
575
576BOOL bInitPDEV(
577PPDEV ppdev,
578DEVMODEW *pDevMode,
579GDIINFO *pGdiInfo,
580DEVINFO *pDevInfo)
581{
582 ULONG cModes;
583 PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
584 VIDEO_COLOR_CAPABILITIES colorCapabilities;
585 ULONG ulTemp;
586 BOOL bSelectDefault;
587 ULONG cbModeSize;
588
589 //
590 // calls the miniport to get mode information.
591 //
592
593 cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
594
595 if (cModes == 0)
596 {
597 return(FALSE);
598 }
599
600 //
601 // Now see if the requested mode has a match in that table.
602 //
603
604 pVideoModeSelected = NULL;
605 pVideoTemp = pVideoBuffer;
606
607 if ((pDevMode->dmPelsWidth == 0) &&
608 (pDevMode->dmPelsHeight == 0) &&
609 (pDevMode->dmBitsPerPel == 0) &&
610 (pDevMode->dmDisplayFrequency == 0))
611 {
612 DISPDBG((2, "Default mode requested"));
613 bSelectDefault = TRUE;
614 }
615 else
616 {
617 DISPDBG((2, "Requested mode...\n"));
618 DISPDBG((2, " Screen width -- %li\n", pDevMode->dmPelsWidth));
619 DISPDBG((2, " Screen height -- %li\n", pDevMode->dmPelsHeight));
620 DISPDBG((2, " Bits per pel -- %li\n", pDevMode->dmBitsPerPel));
621 DISPDBG((2, " Frequency -- %li\n", pDevMode->dmDisplayFrequency));
622
623 bSelectDefault = FALSE;
624 }
625
626 while (cModes--)
627 {
628 if (pVideoTemp->Length != 0)
629 {
630 if (bSelectDefault ||
631 ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
632 (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
633 (pVideoTemp->BitsPerPlane *
634 pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
635 (pVideoTemp->Frequency == pDevMode->dmDisplayFrequency)))
636 {
637 pVideoModeSelected = pVideoTemp;
638 DISPDBG((3, "Found a match\n")) ;
639 break;
640 }
641 }
642
643 pVideoTemp = (PVIDEO_MODE_INFORMATION)
644 (((PUCHAR)pVideoTemp) + cbModeSize);
645 }
646
647 //
648 // If no mode has been found, return an error
649 //
650
651 if (pVideoModeSelected == NULL)
652 {
653 EngFreeMem(pVideoBuffer);
654 DISPDBG((0,"DISP bInitPDEV failed - no valid modes\n"));
655 return(FALSE);
656 }
657
658 //
659 // Fill in the GDIINFO data structure with the information returned from
660 // the kernel driver.
661 //
662
663 ppdev->ulMode = pVideoModeSelected->ModeIndex;
664 ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
665 ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
666 ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
667 pVideoModeSelected->NumberOfPlanes;
668 ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
669
670 ppdev->flRed = pVideoModeSelected->RedMask;
671 ppdev->flGreen = pVideoModeSelected->GreenMask;
672 ppdev->flBlue = pVideoModeSelected->BlueMask;
673
674
675 if (g_bOnNT40)
676 {
677 DISPDBG((0,"DISP bInitPDEV pGdiInfo->ulVersion = %x\n", GDI_DRIVER_VERSION));
678 pGdiInfo->ulVersion = GDI_DRIVER_VERSION; /* 0x4000 -> NT4 */
679 }
680 else
681 {
682 DISPDBG((0,"DISP bInitPDEV pGdiInfo->ulVersion = %x\n", 0x5000));
683 pGdiInfo->ulVersion = 0x5000;
684 }
685
686 pGdiInfo->ulTechnology = DT_RASDISPLAY;
687 pGdiInfo->ulHorzSize = pVideoModeSelected->XMillimeter;
688 pGdiInfo->ulVertSize = pVideoModeSelected->YMillimeter;
689
690 pGdiInfo->ulHorzRes = ppdev->cxScreen;
691 pGdiInfo->ulVertRes = ppdev->cyScreen;
692 pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
693 pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
694 pGdiInfo->cBitsPixel = pVideoModeSelected->BitsPerPlane;
695 pGdiInfo->cPlanes = pVideoModeSelected->NumberOfPlanes;
696 pGdiInfo->ulVRefresh = pVideoModeSelected->Frequency;
697 /* bit block transfers are accelerated */
698 pGdiInfo->ulBltAlignment = 0;
699
700 pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
701 pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
702
703#ifdef MIPS
704 if (ppdev->ulBitCount == 8)
705 pGdiInfo->flTextCaps = (TC_RA_ABLE | TC_SCROLLBLT);
706 else
707#endif
708 pGdiInfo->flTextCaps = TC_RA_ABLE;
709
710 pGdiInfo->flRaster = 0; // flRaster is reserved by DDI
711
712 pGdiInfo->ulDACRed = pVideoModeSelected->NumberRedBits;
713 pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
714 pGdiInfo->ulDACBlue = pVideoModeSelected->NumberBlueBits;
715
716 pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
717 pGdiInfo->ulAspectY = 0x24;
718 pGdiInfo->ulAspectXY = 0x33;
719
720 pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
721 pGdiInfo->yStyleStep = 1;
722 pGdiInfo->denStyleStep = 3;
723
724 pGdiInfo->ptlPhysOffset.x = 0;
725 pGdiInfo->ptlPhysOffset.y = 0;
726 pGdiInfo->szlPhysSize.cx = 0;
727 pGdiInfo->szlPhysSize.cy = 0;
728
729 // RGB and CMY color info.
730
731 //
732 // try to get it from the miniport.
733 // if the miniport doesn ot support this feature, use defaults.
734 //
735
736 if (EngDeviceIoControl(ppdev->hDriver,
737 IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
738 NULL,
739 0,
740 &colorCapabilities,
741 sizeof(VIDEO_COLOR_CAPABILITIES),
742 &ulTemp))
743 {
744
745 DISPDBG((2, "getcolorCapabilities failed \n"));
746
747 pGdiInfo->ciDevice.Red.x = 6700;
748 pGdiInfo->ciDevice.Red.y = 3300;
749 pGdiInfo->ciDevice.Red.Y = 0;
750 pGdiInfo->ciDevice.Green.x = 2100;
751 pGdiInfo->ciDevice.Green.y = 7100;
752 pGdiInfo->ciDevice.Green.Y = 0;
753 pGdiInfo->ciDevice.Blue.x = 1400;
754 pGdiInfo->ciDevice.Blue.y = 800;
755 pGdiInfo->ciDevice.Blue.Y = 0;
756 pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
757 pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
758 pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
759
760 pGdiInfo->ciDevice.RedGamma = 20000;
761 pGdiInfo->ciDevice.GreenGamma = 20000;
762 pGdiInfo->ciDevice.BlueGamma = 20000;
763
764 }
765 else
766 {
767 pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
768 pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
769 pGdiInfo->ciDevice.Red.Y = 0;
770 pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
771 pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
772 pGdiInfo->ciDevice.Green.Y = 0;
773 pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
774 pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
775 pGdiInfo->ciDevice.Blue.Y = 0;
776 pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
777 pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
778 pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
779
780 // if we have a color device store the three color gamma values,
781 // otherwise store the unique gamma value in all three.
782
783 if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
784 {
785 pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
786 pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
787 pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
788 }
789 else
790 {
791 pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
792 pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
793 pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
794 }
795
796 };
797
798 pGdiInfo->ciDevice.Cyan.x = 0;
799 pGdiInfo->ciDevice.Cyan.y = 0;
800 pGdiInfo->ciDevice.Cyan.Y = 0;
801 pGdiInfo->ciDevice.Magenta.x = 0;
802 pGdiInfo->ciDevice.Magenta.y = 0;
803 pGdiInfo->ciDevice.Magenta.Y = 0;
804 pGdiInfo->ciDevice.Yellow.x = 0;
805 pGdiInfo->ciDevice.Yellow.y = 0;
806 pGdiInfo->ciDevice.Yellow.Y = 0;
807
808 // No dye correction for raster displays.
809
810 pGdiInfo->ciDevice.MagentaInCyanDye = 0;
811 pGdiInfo->ciDevice.YellowInCyanDye = 0;
812 pGdiInfo->ciDevice.CyanInMagentaDye = 0;
813 pGdiInfo->ciDevice.YellowInMagentaDye = 0;
814 pGdiInfo->ciDevice.CyanInYellowDye = 0;
815 pGdiInfo->ciDevice.MagentaInYellowDye = 0;
816
817 pGdiInfo->ulDevicePelsDPI = 0; // For printers only
818 pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
819
820 // Note: this should be modified later to take into account the size
821 // of the display and the resolution.
822
823 pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
824
825 pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
826
827 // Fill in the basic devinfo structure
828
829 *pDevInfo = gDevInfoFrameBuffer;
830
831 // Fill in the rest of the devinfo and GdiInfo structures.
832
833 if (ppdev->ulBitCount == 8)
834 {
835 // It is Palette Managed.
836
837 pGdiInfo->ulNumColors = 20;
838 pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
839
840 pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
841
842 pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
843 pDevInfo->iDitherFormat = BMF_8BPP;
844
845 // Assuming palette is orthogonal - all colors are same size.
846
847 ppdev->cPaletteShift = 8 - pGdiInfo->ulDACRed;
848 }
849 else
850 {
851 pGdiInfo->ulNumColors = (ULONG) (-1);
852 pGdiInfo->ulNumPalReg = 0;
853
854 if (ppdev->ulBitCount == 16)
855 {
856 pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
857 pDevInfo->iDitherFormat = BMF_16BPP;
858 }
859 else if (ppdev->ulBitCount == 24)
860 {
861 pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
862 pDevInfo->iDitherFormat = BMF_24BPP;
863 }
864 else
865 {
866 pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
867 pDevInfo->iDitherFormat = BMF_32BPP;
868 }
869 }
870
871 EngFreeMem(pVideoBuffer);
872
873 return(TRUE);
874}
875
876
877/******************************Public*Routine******************************\
878* getAvailableModes
879*
880* Calls the miniport to get the list of modes supported by the kernel driver,
881* and returns the list of modes supported by the diplay driver among those
882*
883* returns the number of entries in the videomode buffer.
884* 0 means no modes are supported by the miniport or that an error occurred.
885*
886* NOTE: the buffer must be freed up by the caller.
887*
888\**************************************************************************/
889
890DWORD getAvailableModes(
891HANDLE hDriver,
892PVIDEO_MODE_INFORMATION *modeInformation,
893DWORD *cbModeSize)
894{
895 ULONG ulTemp;
896 VIDEO_NUM_MODES modes;
897 PVIDEO_MODE_INFORMATION pVideoTemp;
898
899 //
900 // Get the number of modes supported by the mini-port
901 //
902
903 if (EngDeviceIoControl(hDriver,
904 IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
905 NULL,
906 0,
907 &modes,
908 sizeof(VIDEO_NUM_MODES),
909 &ulTemp))
910 {
911 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
912 return(0);
913 }
914
915 *cbModeSize = modes.ModeInformationLength;
916
917 //
918 // Allocate the buffer for the mini-port to write the modes in.
919 //
920
921 *modeInformation = (PVIDEO_MODE_INFORMATION)
922 EngAllocMem(0, modes.NumModes *
923 modes.ModeInformationLength, ALLOC_TAG);
924
925 if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
926 {
927 DISPDBG((0, "getAvailableModes failed EngAllocMem\n"));
928
929 return 0;
930 }
931
932 //
933 // Ask the mini-port to fill in the available modes.
934 //
935
936 if (EngDeviceIoControl(hDriver,
937 IOCTL_VIDEO_QUERY_AVAIL_MODES,
938 NULL,
939 0,
940 *modeInformation,
941 modes.NumModes * modes.ModeInformationLength,
942 &ulTemp))
943 {
944
945 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
946
947 EngFreeMem(*modeInformation);
948 *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
949
950 return(0);
951 }
952
953 //
954 // Now see which of these modes are supported by the display driver.
955 // As an internal mechanism, set the length to 0 for the modes we
956 // DO NOT support.
957 //
958
959 ulTemp = modes.NumModes;
960 pVideoTemp = *modeInformation;
961
962 //
963 // Mode is rejected if it is not one plane, or not graphics, or is not
964 // one of 8, 16 or 32 bits per pel.
965 //
966
967 while (ulTemp--)
968 {
969 if ((pVideoTemp->NumberOfPlanes != 1 ) ||
970 !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
971 (pVideoTemp->AttributeFlags & VIDEO_MODE_BANKED) ||
972 ((pVideoTemp->BitsPerPlane != 8) &&
973 (pVideoTemp->BitsPerPlane != 16) &&
974 (pVideoTemp->BitsPerPlane != 24) &&
975 (pVideoTemp->BitsPerPlane != 32)))
976 {
977 pVideoTemp->Length = 0;
978 }
979
980 pVideoTemp = (PVIDEO_MODE_INFORMATION)
981 (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
982 }
983
984 return modes.NumModes;
985
986}
987
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