VirtualBox

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

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

2d: working multi-monitor + some fixing for working with not-using-VRAM mode

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