VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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