VirtualBox

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

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

win guest video: get rid of >= XP functions

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