VirtualBox

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

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

fixed typo, it means occurred, not occured

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