VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c@ 3550

Last change on this file since 3550 was 3550, checked in by vboxsync, 18 years ago

More logging

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.5 KB
Line 
1/******************************Module*Header*******************************\
2*
3* *******************
4* * GDI SAMPLE CODE *
5* *******************
6*
7* Module Name: enable.c
8*
9* This module contains the functions that enable and disable the
10* driver, the pdev, and the surface.
11*
12* Copyright (c) 1992-1998 Microsoft Corporation
13\**************************************************************************/
14
15#include "driver.h"
16#include "dd.h"
17#include <VBoxDisplay.h>
18
19// The driver function table with all function index/address pairs
20
21// Hook functions to track dirty rectangles and generate RDP orders.
22// NT4 functions
23DRVFN gadrvfn_nt4[] = {
24 { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, // 0
25 { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, // 1
26 { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, // 2
27 { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, // 3
28 { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, // 4
29 { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // 5
30 { INDEX_DrvOffset, (PFN) DrvOffset }, // 6
31 { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }, // 8
32 { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush }, // 12
33 { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // 13
34 { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // 14
35 { INDEX_DrvFillPath, (PFN) DrvFillPath }, // 15
36 { INDEX_DrvPaint, (PFN) DrvPaint }, // 17
37 { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, // 18
38 { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, // 19
39 { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt, }, // 20
40 { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, // 22
41 { INDEX_DrvTextOut, (PFN) DrvTextOut }, // 23
42 { INDEX_DrvEscape, (PFN) DrvEscape }, // 24
43 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, // 29
44 { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, // 30
45 { INDEX_DrvLineTo, (PFN) DrvLineTo }, // 31
46 { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, // 38
47 { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // 40
48 { INDEX_DrvGetModes, (PFN) DrvGetModes }, // 41
49#ifdef VBOX_WITH_DDRAW
50 { INDEX_DrvGetDirectDrawInfo, (PFN) DrvGetDirectDrawInfo }, // 59 0x3b
51 { INDEX_DrvEnableDirectDraw, (PFN) DrvEnableDirectDraw }, // 60 0x3c
52 { INDEX_DrvDisableDirectDraw, (PFN) DrvDisableDirectDraw }, // 61 0x3d
53#endif
54};
55/* Experimental begin */
56BOOL APIENTRY DrvResetPDEV(
57 DHPDEV dhpdevOld,
58 DHPDEV dhpdevNew
59 )
60{
61 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, dhpdevOld, dhpdevNew));
62 return TRUE;
63}
64
65BOOL DrvNineGrid (PVOID x1, PVOID x2, PVOID x3, PVOID x4, PVOID x5, PVOID x6, PVOID x7, PVOID x8, PVOID x9)
66{
67 DISPDBG((0, "Experimental %s: %p, %p, %p, %p, %p, %p, %p, %p, %p\n", __FUNCTION__, x1, x2, x3, x4, x5, x6, x7, x8, x9));
68 return FALSE;
69}
70
71VOID APIENTRY DrvDestroyFont(
72 FONTOBJ *pfo)
73{
74 DISPDBG((0, "Experimental %s: %p\n", __FUNCTION__, pfo));
75}
76
77ULONG APIENTRY DrvEscape(SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut)
78{
79 PDEV* ppdev = (PDEV*) pso->dhpdev;
80
81 DISPDBG((0, "%s: %p, %p, %p, %p, %p, %p\n", __FUNCTION__, pso, iEsc, cjIn, pvIn, cjOut, pvOut));
82
83 switch(iEsc)
84 {
85#ifdef VBOX_WITH_OPENGL
86 case OPENGL_GETINFO:
87 {
88 if ( cjOut >= sizeof(OPENGL_INFO)
89 && pvOut)
90 {
91 POPENGL_INFO pInfo = (POPENGL_INFO)pvOut;
92
93 pInfo->dwVersion = 2;
94 pInfo->dwDriverVersion = 1;
95 pInfo->szDriverName[0] = 'V';
96 pInfo->szDriverName[1] = 'B';
97 pInfo->szDriverName[2] = 'o';
98 pInfo->szDriverName[3] = 'x';
99 pInfo->szDriverName[4] = 'O';
100 pInfo->szDriverName[5] = 'G';
101 pInfo->szDriverName[6] = 'L';
102 pInfo->szDriverName[7] = 0;
103
104 DISPDBG((0, "OPENGL_GETINFO\n"));
105 return cjOut;
106 }
107 else
108 DISPDBG((0, "OPENGL_GETINFO invalid size %d\n", cjOut)); /* It doesn't matter that we fail here. Opengl32 will fall back to software rendering when this escape is not supported. */
109 break;
110 }
111#endif
112
113 case VBOXESC_SETVISIBLEREGION:
114 {
115 LPRGNDATA lpRgnData = (LPRGNDATA)pvIn;
116
117 DISPDBG((0, "VBOXESC_SETVISIBLEREGION\n"));
118
119 if ( cjIn >= sizeof(RGNDATAHEADER)
120 && pvIn
121 && lpRgnData->rdh.dwSize == sizeof(RGNDATAHEADER)
122 && lpRgnData->rdh.iType == RDH_RECTANGLES
123 && cjIn == lpRgnData->rdh.nCount * sizeof(RECT) + sizeof(RGNDATAHEADER))
124 {
125 DWORD ulReturn, i;
126 PRTRECT pRTRect;
127 RECT *pRect = (RECT *)&lpRgnData->Buffer;
128
129 pRTRect = (PRTRECT) EngAllocMem(0, lpRgnData->rdh.nCount*sizeof(RTRECT), ALLOC_TAG);
130 for (i=0;i<lpRgnData->rdh.nCount;i++)
131 {
132 pRTRect[i].xLeft = pRect->left;
133 pRTRect[i].yBottom = pRect->bottom;
134 pRTRect[i].xRight = pRect->right;
135 pRTRect[i].yTop = pRect->top;
136 }
137
138 if (EngDeviceIoControl(ppdev->hDriver,
139 IOCTL_VIDEO_VBOX_SETVISIBLEREGION,
140 pRTRect,
141 lpRgnData->rdh.nCount*sizeof(RTRECT),
142 NULL,
143 0,
144 &ulReturn))
145 {
146 DISPDBG((0, "DISP DrvAssertMode failed IOCTL_VIDEO_VBOX_SETVISIBLEREGION\n"));
147 return 0;
148 }
149 else
150 {
151 DISPDBG((0, "DISP IOCTL_VIDEO_VBOX_SETVISIBLEREGION successful\n"));
152 return 1;
153 }
154
155 }
156 else
157 {
158 if (pvIn)
159 DISPDBG((0, "check failed rdh.dwSize=%x iType=%d size=%d expected size=%d\n", lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, cjIn, lpRgnData->rdh.nCount * sizeof(RECT) + sizeof(RGNDATAHEADER)));
160 }
161
162 break;
163 }
164
165 case QUERYESCSUPPORT:
166 if ( cjIn == sizeof(DWORD)
167 && pvIn)
168 {
169 DWORD nEscapeQuery = *(DWORD *)pvIn;
170
171 switch(nEscapeQuery)
172 {
173#ifdef VBOX_WITH_OPENGL
174 case OPENGL_GETINFO:
175 return 1;
176#endif
177 default:
178 DISPDBG((0, "QUERYESCSUPPORT %d unsupported\n", nEscapeQuery));
179 break;
180 }
181 }
182 else
183 DISPDBG((0, "QUERYESCSUPPORT invalid size %d\n", cjOut));
184 break;
185
186 default:
187 DISPDBG((0, "Unsupported Escape %d\n", iEsc));
188 break;
189 }
190 return 0;
191}
192
193BOOL DrvConnect (PVOID x1, PVOID x2, PVOID x3, PVOID x4)
194{
195 DISPDBG((0, "Experimental %s: %p, %p, %p, %p\n", __FUNCTION__, x1, x2, x3, x4));
196 return TRUE;
197}
198
199BOOL DrvDisconnect (PVOID x1, PVOID x2)
200{
201 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
202 return FALSE;
203}
204
205BOOL DrvReconnect (PVOID x1, PVOID x2)
206{
207 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
208 return FALSE;
209}
210
211BOOL DrvShadowConnect (PVOID x1, PVOID x2)
212{
213 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
214 return FALSE;
215}
216
217BOOL DrvShadowDisconnect (PVOID x1, PVOID x2)
218{
219 DISPDBG((0, "Experimental %s: %p, %p\n", __FUNCTION__, x1, x2));
220 return FALSE;
221}
222
223
224/* Experimental end */
225
226// W2K,XP functions
227DRVFN gadrvfn_nt5[] = {
228 { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, // 0 0x0
229 { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, // 1 0x1
230 { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, // 2 0x2
231 { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, // 3 0x3
232 { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, // 4 0x4
233 { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // 5 0x5
234 { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }, // 8 0x8
235 { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush }, // 12 0xc
236 { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // 13 0xd
237 { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // 14 0xe
238 { INDEX_DrvFillPath, (PFN) DrvFillPath }, // 15 0xf
239 { INDEX_DrvPaint, (PFN) DrvPaint }, // 17 0x11
240 { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, // 18 0x12
241 { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, // 19 0x13
242 { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt, }, // 20 0x14
243 { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, // 22 0x16
244 { INDEX_DrvTextOut, (PFN) DrvTextOut }, // 23 0x17
245 { INDEX_DrvEscape, (PFN) DrvEscape }, // 24 0x18
246 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, // 29 0x1d
247 { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, // 30 0x1e
248 { INDEX_DrvLineTo, (PFN) DrvLineTo }, // 31 0x1f
249 { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, // 38 0x26
250 { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // 40 0x28
251 { INDEX_DrvGetModes, (PFN) DrvGetModes }, // 41 0x29
252#ifdef VBOX_WITH_DDRAW
253 { INDEX_DrvGetDirectDrawInfo, (PFN) DrvGetDirectDrawInfo }, // 59 0x3b
254 { INDEX_DrvEnableDirectDraw, (PFN) DrvEnableDirectDraw }, // 60 0x3c
255 { INDEX_DrvDisableDirectDraw, (PFN) DrvDisableDirectDraw }, // 61 0x3d
256 { INDEX_DrvDeriveSurface, (PFN) DrvDeriveSurface }, // 85
257#endif
258 { INDEX_DrvNotify, (PFN) DrvNotify }, // 87 0x57
259// /* Experimental. */
260// { 0x7, (PFN) DrvResetPDEV }, // 0x7
261// { 0x5b, (PFN) DrvNineGrid }, // 0x5b
262// { 0x2b, (PFN) DrvDestroyFont }, // 0x2b
263// { 0x18, (PFN) DrvEscape }, // 0x18
264// { 0x4d, (PFN) DrvConnect }, // 0x4d
265// { 0x4e, (PFN) DrvDisconnect }, // 0x4e
266// { 0x4f, (PFN) DrvReconnect }, // 0x4f
267// { 0x50, (PFN) DrvShadowConnect }, // 0x50
268// { 0x51, (PFN) DrvShadowDisconnect }, // 0x51
269
270};
271
272// Required hook bits will be set up according to DDI version
273static ULONG gflHooks = 0;
274
275#define HOOKS_BMF8BPP gflHooks
276#define HOOKS_BMF16BPP gflHooks
277#define HOOKS_BMF24BPP gflHooks
278#define HOOKS_BMF32BPP gflHooks
279
280HSEMAPHORE ghsemHwBuffer = 0;
281
282/******************************Public*Routine******************************\
283* DrvEnableDriver
284*
285* Enables the driver by retrieving the drivers function table and version.
286*
287\**************************************************************************/
288
289BOOL DrvEnableDriver(
290ULONG iEngineVersion,
291ULONG cj,
292PDRVENABLEDATA pded)
293{
294// Engine Version is passed down so future drivers can support previous
295// engine versions. A next generation driver can support both the old
296// and new engine conventions if told what version of engine it is
297// working with. For the first version the driver does nothing with it.
298
299 iEngineVersion;
300
301 DISPDBG((0, "VBoxDisp::DrvEnableDriver called. iEngine version = %08X\n", iEngineVersion));
302
303 // Set up hook flags to intercept all functions which can generate VRDP orders
304 gflHooks = HOOK_BITBLT | HOOK_TEXTOUT | HOOK_FILLPATH |
305 HOOK_COPYBITS | HOOK_STROKEPATH | HOOK_LINETO |
306 HOOK_PAINT | HOOK_STRETCHBLT | HOOK_SYNCHRONIZEACCESS;
307
308// Fill in as much as we can.
309
310 if (cj >= sizeof(DRVENABLEDATA))
311 pded->pdrvfn = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
312 gadrvfn_nt5:
313 gadrvfn_nt4;
314
315
316 if (cj >= (sizeof(ULONG) * 2))
317 pded->c = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
318 sizeof(gadrvfn_nt5) / sizeof(DRVFN):
319 sizeof(gadrvfn_nt4) / sizeof(DRVFN);
320
321// DDI version this driver was targeted for is passed back to engine.
322// Future graphic's engine may break calls down to old driver format.
323
324 if (cj >= sizeof(ULONG))
325 pded->iDriverVersion = (iEngineVersion >= DDI_DRIVER_VERSION_NT5)?
326 DDI_DRIVER_VERSION_NT5:
327 DDI_DRIVER_VERSION_NT4;
328
329 if (!ghsemHwBuffer)
330 {
331 ghsemHwBuffer = EngCreateSemaphore ();
332 }
333
334 return(TRUE);
335}
336
337/******************************Public*Routine******************************\
338* DrvDisableDriver
339*
340* Tells the driver it is being disabled. Release any resources allocated in
341* DrvEnableDriver.
342*
343\**************************************************************************/
344
345VOID DrvDisableDriver(VOID)
346{
347 DISPDBG((0, "VBoxDisp::DrvDisableDriver called.\n"));
348
349 if (ghsemHwBuffer)
350 {
351 EngDeleteSemaphore (ghsemHwBuffer);
352 ghsemHwBuffer = NULL;
353 }
354
355 return;
356}
357
358/******************************Public*Routine******************************\
359* DrvEnablePDEV
360*
361* DDI function, Enables the Physical Device.
362*
363* Return Value: device handle to pdev.
364*
365\**************************************************************************/
366
367DHPDEV DrvEnablePDEV(
368DEVMODEW *pDevmode, // Pointer to DEVMODE
369PWSTR pwszLogAddress, // Logical address
370ULONG cPatterns, // number of patterns
371HSURF *ahsurfPatterns, // return standard patterns
372ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
373ULONG *pGdiInfo, // Pointer to GdiInfo structure
374ULONG cjDevInfo, // Length of following PDEVINFO structure
375DEVINFO *pDevInfo, // physical device information structure
376HDEV hdev, // HDEV, used for callbacks
377PWSTR pwszDeviceName, // DeviceName - not used
378HANDLE hDriver) // Handle to base driver
379{
380 GDIINFO GdiInfo;
381 DEVINFO DevInfo;
382 PPDEV ppdev = (PPDEV) NULL;
383
384 DISPDBG((0, "VBoxDisp::DrvEnablePDEV called\n"));
385
386 UNREFERENCED_PARAMETER(pwszLogAddress);
387 UNREFERENCED_PARAMETER(pwszDeviceName);
388
389 RtlZeroMemory(&DevInfo, sizeof (DEVINFO));
390 RtlZeroMemory(&GdiInfo, sizeof (GDIINFO));
391
392 // Allocate a physical device structure.
393
394 ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
395
396 if (ppdev == (PPDEV) NULL)
397 {
398 DISPDBG((0, "DISP DrvEnablePDEV failed EngAllocMem\n"));
399 return((DHPDEV) 0);
400 }
401
402 memset(ppdev, 0, sizeof(PDEV));
403
404 // Save the screen handle in the PDEV.
405
406 ppdev->hDriver = hDriver;
407
408 // Get the current screen mode information. Set up device caps and devinfo.
409
410 if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo))
411 {
412 DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
413 goto error_free;
414 }
415
416 // Initialize the cursor information.
417
418 if (!bInitPointer(ppdev, &DevInfo))
419 {
420 // Not a fatal error...
421 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
422 }
423
424 // Initialize palette information.
425
426 if (!bInitPaletteInfo(ppdev, &DevInfo))
427 {
428 DISPDBG((0, "DrvEnablePDEV failed bInitPalette\n"));
429 goto error_free;
430 }
431
432// // Start a thread that will process notifications from VMMDev
433// if (!bInitNotificationThread(ppdev))
434// {
435// DISPDBG((0, "DrvEnablePDEV failed bInitNotificationThread\n"));
436// goto error_free;
437// }
438
439 // Copy the devinfo into the engine buffer.
440
441 DISPDBG((0, "VBoxDisp::DrvEnablePDEV: sizeof(DEVINFO) = %d, cjDevInfo = %d, alpha = %d\n", sizeof(DEVINFO), cjDevInfo, DevInfo.flGraphicsCaps2 & GCAPS2_ALPHACURSOR));
442
443// @todo seems to be not necessary. these bits are initialized in screen.c DevInfo.flGraphicsCaps |= GCAPS_OPAQUERECT |
444// GCAPS_DITHERONREALIZE |
445// GCAPS_PALMANAGED |
446// GCAPS_ALTERNATEFILL |
447// GCAPS_WINDINGFILL |
448// GCAPS_MONO_DITHER |
449// GCAPS_COLOR_DITHER |
450// GCAPS_ASYNCMOVE;
451//
452// DevInfo.flGraphicsCaps |= GCAPS_DITHERONREALIZE;
453
454 DevInfo.flGraphicsCaps2 |= GCAPS2_RESERVED1; /* @todo figure out what is this. */
455
456 memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo));
457
458 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
459 // pdev.
460
461 memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
462
463 DISPDBG((0, "VBoxDisp::DrvEnablePDEV completed\n"));
464
465 return((DHPDEV) ppdev);
466
467 // Error case for failure.
468error_free:
469 EngFreeMem(ppdev);
470 return((DHPDEV) 0);
471}
472
473/******************************Public*Routine******************************\
474* DrvCompletePDEV
475*
476* Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
477*
478\**************************************************************************/
479
480VOID DrvCompletePDEV(
481DHPDEV dhpdev,
482HDEV hdev)
483{
484 DISPDBG((0, "VBoxDisp::DrvCompletePDEV called\n"));
485 ((PPDEV) dhpdev)->hdevEng = hdev;
486}
487
488/******************************Public*Routine******************************\
489* DrvDisablePDEV
490*
491* Release the resources allocated in DrvEnablePDEV. If a surface has been
492* enabled DrvDisableSurface will have already been called.
493*
494\**************************************************************************/
495
496VOID DrvDisablePDEV(
497DHPDEV dhpdev)
498{
499 DISPDBG((0, "VBoxDisp::DrvDisablePDEV called\n"));
500// vStopNotificationThread ((PPDEV) dhpdev);
501 vDisablePalette((PPDEV) dhpdev);
502
503 /* Free the driver's VBVA resources. */
504 vboxVbvaDisable ((PPDEV) dhpdev);
505
506 EngFreeMem(dhpdev);
507}
508
509/******************************Public*Routine******************************\
510* VOID DrvOffset
511*
512* DescriptionText
513*
514\**************************************************************************/
515
516BOOL DrvOffset(
517SURFOBJ* pso,
518LONG x,
519LONG y,
520FLONG flReserved)
521{
522 PDEV* ppdev = (PDEV*) pso->dhpdev;
523
524 // Add back last offset that we subtracted. I could combine the next
525 // two statements, but I thought this was more clear. It's not
526 // performance critical anyway.
527
528 ppdev->pjScreen += ((ppdev->ptlOrg.y * ppdev->lDeltaScreen) +
529 (ppdev->ptlOrg.x * ((ppdev->ulBitCount+1) >> 3)));
530
531 // Subtract out new offset
532
533 ppdev->pjScreen -= ((y * ppdev->lDeltaScreen) +
534 (x * ((ppdev->ulBitCount+1) >> 3)));
535
536 ppdev->ptlOrg.x = x;
537 ppdev->ptlOrg.y = y;
538
539 return(TRUE);
540}
541
542/******************************Public*Routine******************************\
543* DrvEnableSurface
544*
545* Enable the surface for the device. Hook the calls this driver supports.
546*
547* Return: Handle to the surface if successful, 0 for failure.
548*
549\**************************************************************************/
550
551HSURF DrvEnableSurface(
552DHPDEV dhpdev)
553{
554 PPDEV ppdev;
555 HSURF hsurf;
556 SIZEL sizl;
557 ULONG ulBitmapType;
558 FLONG flHooks;
559
560 DISPDBG((0, "DISP DrvEnableSurface called\n"));
561
562 // Create engine bitmap around frame buffer.
563
564 ppdev = (PPDEV) dhpdev;
565
566 ppdev->ptlOrg.x = 0;
567 ppdev->ptlOrg.y = 0;
568
569 if (!bInitSURF(ppdev, TRUE))
570 {
571 DISPDBG((0, "DISP DrvEnableSurface failed bInitSURF\n"));
572 return(FALSE);
573 }
574
575 DISPDBG((0, "DISP DrvEnableSurface bInitSURF success\n"));
576
577 sizl.cx = ppdev->cxScreen;
578 sizl.cy = ppdev->cyScreen;
579
580 if (ppdev->ulBitCount == 8)
581 {
582 if (!bInit256ColorPalette(ppdev)) {
583 DISPDBG((0, "DISP DrvEnableSurface failed to init the 8bpp palette\n"));
584 return(FALSE);
585 }
586 ulBitmapType = BMF_8BPP;
587 flHooks = HOOKS_BMF8BPP;
588 }
589 else if (ppdev->ulBitCount == 16)
590 {
591 ulBitmapType = BMF_16BPP;
592 flHooks = HOOKS_BMF16BPP;
593 }
594 else if (ppdev->ulBitCount == 24)
595 {
596 ulBitmapType = BMF_24BPP;
597 flHooks = HOOKS_BMF24BPP;
598 }
599 else
600 {
601 ulBitmapType = BMF_32BPP;
602 flHooks = HOOKS_BMF32BPP;
603 }
604
605 hsurf = (HSURF) EngCreateBitmap(sizl,
606 ppdev->lDeltaScreen,
607 ulBitmapType,
608 (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
609 (PVOID) (ppdev->pjScreen));
610
611 if (hsurf == (HSURF) 0)
612 {
613 DISPDBG((0, "DISP DrvEnableSurface failed EngCreateBitmap\n"));
614 goto l_Failure;
615 }
616 else
617 {
618 ppdev->hsurfScreenBitmap = hsurf;
619
620 if (!EngAssociateSurface(hsurf, ppdev->hdevEng, 0))
621 {
622 DISPDBG((0, "DISP DrvEnableSurface failed EngAssociateSurface for ScreenBitmap.\n"));
623 goto l_Failure;
624 }
625 else
626 {
627 SURFOBJ *pso = EngLockSurface(hsurf);
628
629 ppdev->psoScreenBitmap = pso;
630
631 hsurf = (HSURF) EngCreateDeviceSurface((DHSURF)pso,
632 sizl,
633 ulBitmapType);
634
635 if (hsurf == (HSURF) 0)
636 {
637 DISPDBG((0, "DISP DrvEnableSurface failed EngCreateDeviceSurface\n"));
638 goto l_Failure;
639 }
640 else
641 {
642 ppdev->hsurfScreen = hsurf;
643
644 if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
645 {
646 DISPDBG((0, "DISP DrvEnableSurface failed EngAssociateSurface for Screen.\n"));
647 goto l_Failure;
648 }
649 else
650 {
651 ppdev->flHooks = flHooks;
652 ppdev->ulBitmapType = ulBitmapType;
653 }
654 }
655 }
656 }
657
658 return ppdev->hsurfScreen;
659
660l_Failure:
661
662 DrvDisableSurface(dhpdev);
663
664 return((HSURF)0);
665}
666
667/******************************Public*Routine******************************\
668* DrvDisableSurface
669*
670* Free resources allocated by DrvEnableSurface. Release the surface.
671*
672\**************************************************************************/
673
674VOID DrvDisableSurface(
675DHPDEV dhpdev)
676{
677 PPDEV ppdev = (PPDEV)dhpdev;
678
679 DISPDBG((0, "VBoxDisp::DrvDisableSurface called\n"));
680 if (ppdev->psoScreenBitmap)
681 {
682 EngUnlockSurface (ppdev->psoScreenBitmap);
683 ppdev->psoScreenBitmap = NULL;
684 }
685
686 if (ppdev->hsurfScreen)
687 {
688 EngDeleteSurface(ppdev->hsurfScreen);
689 ppdev->hsurfScreen = (HSURF)0;
690 }
691
692 if (ppdev->hsurfScreenBitmap)
693 {
694 EngDeleteSurface(ppdev->hsurfScreenBitmap);
695 ppdev->hsurfScreenBitmap = (HSURF)0;
696 }
697
698 vDisableSURF(ppdev);
699}
700
701/******************************Public*Routine******************************\
702* DrvAssertMode
703*
704* This asks the device to reset itself to the mode of the pdev passed in.
705*
706\**************************************************************************/
707
708BOOL DrvAssertMode(
709DHPDEV dhpdev,
710BOOL bEnable)
711{
712 PPDEV ppdev = (PPDEV) dhpdev;
713 ULONG ulReturn;
714 PBYTE pjScreen;
715
716 DISPDBG((0, "DISP DrvAssertMode called bEnable = %d\n", bEnable));
717
718 if (bEnable)
719 {
720 pjScreen = ppdev->pjScreen;
721
722 if (!bInitSURF(ppdev, FALSE))
723 {
724 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
725 return (FALSE);
726 }
727
728 if (pjScreen != ppdev->pjScreen)
729 {
730 HSURF hsurf;
731 SIZEL sizl;
732 SURFOBJ *pso;
733
734 DISPDBG((0, "DISP DrvAssertMode Screen pointer has changed!!!\n"));
735
736 sizl.cx = ppdev->cxScreen;
737 sizl.cy = ppdev->cyScreen;
738
739 hsurf = (HSURF) EngCreateBitmap(sizl,
740 ppdev->lDeltaScreen,
741 ppdev->ulBitmapType,
742 (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
743 (PVOID) (ppdev->pjScreen));
744
745 if (hsurf == (HSURF) 0)
746 {
747 DISPDBG((0, "DISP DrvAssertMode failed EngCreateBitmap\n"));
748 return FALSE;
749 }
750
751 pso = EngLockSurface(hsurf);
752
753 if (ppdev->psoScreenBitmap)
754 {
755 EngUnlockSurface (ppdev->psoScreenBitmap);
756 ppdev->psoScreenBitmap = NULL;
757 }
758
759 if (ppdev->hsurfScreenBitmap)
760 {
761 EngDeleteSurface(ppdev->hsurfScreenBitmap);
762 ppdev->hsurfScreenBitmap = (HSURF)0;
763 }
764
765 ppdev->hsurfScreenBitmap = hsurf;
766 ppdev->psoScreenBitmap = pso;
767 }
768
769 if (!EngAssociateSurface(ppdev->hsurfScreenBitmap, ppdev->hdevEng, 0))
770 {
771 DISPDBG((0, "DISP DrvAssertMode failed EngAssociateSurface for ScreenBitmap.\n"));
772 return FALSE;
773 }
774
775 if (!EngAssociateSurface(ppdev->hsurfScreen, ppdev->hdevEng, ppdev->flHooks))
776 {
777 DISPDBG((0, "DISP DrvAssertMode failed EngAssociateSurface for Screen.\n"));
778 return FALSE;
779 }
780
781 return TRUE;
782 }
783 else
784 {
785 //
786 // We must give up the display.
787 // Call the kernel driver to reset the device to a known state.
788 //
789
790 if (EngDeviceIoControl(ppdev->hDriver,
791 IOCTL_VIDEO_RESET_DEVICE,
792 NULL,
793 0,
794 NULL,
795 0,
796 &ulReturn))
797 {
798 DISPDBG((0, "DISP DrvAssertMode failed IOCTL\n"));
799 return FALSE;
800 }
801 else
802 {
803 return TRUE;
804 }
805 }
806}
807
808/******************************Public*Routine******************************\
809* DrvGetModes
810*
811* Returns the list of available modes for the device.
812*
813\**************************************************************************/
814
815ULONG DrvGetModes(
816HANDLE hDriver,
817ULONG cjSize,
818DEVMODEW *pdm)
819
820{
821
822 DWORD cModes;
823 DWORD cbOutputSize;
824 PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
825 DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
826 DWORD cbModeSize;
827
828 DISPDBG((3, "DrvGetModes\n"));
829
830 cModes = getAvailableModes(hDriver,
831 (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
832 &cbModeSize);
833
834 if (cModes == 0)
835 {
836 DISPDBG((0, "DrvGetModes failed to get mode information"));
837 return 0;
838 }
839
840 if (pdm == NULL)
841 {
842 cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
843 }
844 else
845 {
846 //
847 // Now copy the information for the supported modes back into the output
848 // buffer
849 //
850
851 cbOutputSize = 0;
852
853 pVideoTemp = pVideoModeInformation;
854
855 do
856 {
857 if (pVideoTemp->Length != 0)
858 {
859 if (cOutputModes == 0)
860 {
861 break;
862 }
863
864 //
865 // Zero the entire structure to start off with.
866 //
867
868 memset(pdm, 0, sizeof(DEVMODEW));
869
870 //
871 // Set the name of the device to the name of the DLL.
872 //
873
874 memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
875
876 pdm->dmSpecVersion = DM_SPECVERSION;
877 pdm->dmDriverVersion = DM_SPECVERSION;
878 pdm->dmSize = sizeof(DEVMODEW);
879 pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
880
881 pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
882 pVideoTemp->BitsPerPlane;
883 pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
884 pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
885 pdm->dmDisplayFrequency = pVideoTemp->Frequency;
886 pdm->dmDisplayFlags = 0;
887
888 pdm->dmFields = DM_BITSPERPEL |
889 DM_PELSWIDTH |
890 DM_PELSHEIGHT |
891 DM_DISPLAYFREQUENCY |
892 DM_DISPLAYFLAGS ;
893
894 //
895 // Go to the next DEVMODE entry in the buffer.
896 //
897
898 cOutputModes--;
899
900 pdm = (LPDEVMODEW) ( ((ULONG_PTR)pdm) + sizeof(DEVMODEW)
901 + DRIVER_EXTRA_SIZE);
902
903 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
904
905 }
906
907 pVideoTemp = (PVIDEO_MODE_INFORMATION)
908 (((PUCHAR)pVideoTemp) + cbModeSize);
909
910 } while (--cModes);
911 }
912
913 EngFreeMem(pVideoModeInformation);
914
915 return cbOutputSize;
916
917}
918
919VOID DrvSynchronize(
920IN DHPDEV dhpdev,
921IN RECTL *prcl)
922{
923}
924
925/******************************Public*Routine******************************\
926* DrvNotify
927*
928* Called by GDI to notify us of certain "interesting" events
929*
930* DN_DEVICE_ORIGIN is used to communicate the X/Y offsets of individual monitors
931* when DualView is in effect.
932*
933\**************************************************************************/
934
935VOID DrvNotify(
936SURFOBJ *pso,
937ULONG iType,
938PVOID pvData)
939{
940 PDEV* ppdev = (PDEV*) pso->dhpdev;
941
942 DISPDBG((0, "VBoxDisp::DrvNotify called.\n"));
943
944 switch(iType)
945 {
946 case DN_DEVICE_ORIGIN:
947 ppdev->ptlDevOrg = *(PPOINTL)pvData;
948 DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p, pInfo = %p)\n", ppdev->ptlDevOrg.x,
949 ppdev->ptlDevOrg.y, pso, ppdev->pInfo));
950 if (ppdev->pInfo)
951 {
952 ppdev->pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
953 ppdev->pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
954 VBoxProcessDisplayInfo(ppdev);
955 }
956 break;
957 case DN_DRAWING_BEGIN:
958 DISPDBG((3, "DN_DRAWING_BEGIN (PSO = %p)\n", pso));
959 break;
960 }
961}
962
963#ifdef VBOX_WITH_DDRAW
964//--------------------------Public Routine-------------------------------------
965//
966// HBITMAP DrvDeriveSurface
967//
968// This function derives and creates a GDI surface from the specified
969// DirectDraw surface.
970//
971// Parameters
972// pDirectDraw-----Points to a DD_DIRECTDRAW_GLOBAL structure that describes
973// the DirectDraw object.
974// pSurface--------Points to a DD_SURFACE_LOCAL structure that describes the
975// DirectDraw surface around which to wrap a GDI surface.
976//
977// Return Value
978// DrvDeriveSurface returns a handle to the created GDI surface upon success.
979// It returns NULL if the call fails or if the driver cannot accelerate GDI
980// drawing to the specified DirectDraw surface.
981//
982// Comments
983// DrvDeriveSurface allows the driver to create a GDI surface around a
984// DirectDraw video memory or AGP surface object in order to allow accelerated
985// GDI drawing to the surface. If the driver does not hook this call, all GDI
986// drawing to DirectDraw surfaces is done in software using the DIB engine.
987//
988// GDI calls DrvDeriveSurface with RGB surfaces only.
989//
990// The driver should call DrvCreateDeviceBitmap to create a GDI surface of the
991// same size and format as that of the DirectDraw surface. Space for the
992// actual pixels need not be allocated since it already exists.
993//
994//-----------------------------------------------------------------------------
995HBITMAP DrvDeriveSurface(DD_DIRECTDRAW_GLOBAL* pDirectDraw, DD_SURFACE_LOCAL* pSurface)
996{
997 PPDEV pDev = (PPDEV)pDirectDraw->dhpdev;
998 HBITMAP hbmDevice;
999 DD_SURFACE_GLOBAL* pSurfaceGlobal;
1000 SIZEL sizl;
1001
1002 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1003
1004 pSurfaceGlobal = pSurface->lpGbl;
1005
1006 //
1007 // GDI should never call us for a non-RGB surface, but let's assert just
1008 // to make sure they're doing their job properly.
1009 //
1010 AssertMsg(!(pSurfaceGlobal->ddpfSurface.dwFlags & DDPF_FOURCC), ("GDI called us with a non-RGB surface!"));
1011
1012#if 0
1013 // The GDI driver does not accelerate surfaces in AGP memory,
1014 // thus we fail the call
1015
1016 if (pSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
1017 {
1018 DISPDBG((0, "DrvDeriveSurface return NULL, surface in AGP memory"));
1019 return 0;
1020 }
1021
1022 // The GDI driver does not accelerate managed surface,
1023 // thus we fail the call
1024 if (pSurface->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
1025 {
1026 DISPDBG((0, "DrvDeriveSurface return NULL, surface is managed"));
1027 return 0;
1028 }
1029
1030 //
1031 // The rest of our driver expects GDI calls to come in with the same
1032 // format as the primary surface. So we'd better not wrap a device
1033 // bitmap around an RGB format that the rest of our driver doesn't
1034 // understand. Also, we must check to see that it is not a surface
1035 // whose pitch does not match the primary surface.
1036 //
1037 // NOTE: Most surfaces created by this driver are allocated as 2D surfaces
1038 // whose lPitch's are equal to the screen pitch. However, overlay surfaces
1039 // are allocated such that there lPitch's are usually different then the
1040 // screen pitch. The hardware can not accelerate drawing operations to
1041 // these surfaces and thus we fail to derive these surfaces.
1042 //
1043 if ( (pSurfaceGlobal->ddpfSurface.dwRGBBitCount == pDev->ulBitCount) )
1044 {
1045 SIZEL sizel;
1046 DWORD ulBitmapType, flHooks;
1047
1048 sizl.cx = pSurfaceGlobal->wWidth;
1049 sizl.cy = pSurfaceGlobal->wHeight;
1050
1051 if (pDev->ulBitCount == 8)
1052 {
1053 if (!bInit256ColorPalette(pDev)) {
1054 DISPDBG((0, "DISP DrvEnableSurface failed to init the 8bpp palette\n"));
1055 return(FALSE);
1056 }
1057 ulBitmapType = BMF_8BPP;
1058 flHooks = HOOKS_BMF8BPP;
1059 }
1060 else if (pDev->ulBitCount == 16)
1061 {
1062 ulBitmapType = BMF_16BPP;
1063 flHooks = HOOKS_BMF16BPP;
1064 }
1065 else if (pDev->ulBitCount == 24)
1066 {
1067 ulBitmapType = BMF_24BPP;
1068 flHooks = HOOKS_BMF24BPP;
1069 }
1070 else
1071 {
1072 ulBitmapType = BMF_32BPP;
1073 flHooks = HOOKS_BMF32BPP;
1074 }
1075
1076 hbmDevice = EngCreateBitmap(sizl,
1077 pDev->lDeltaScreen,
1078 ulBitmapType,
1079 (pDev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0,
1080 (PVOID) (pDev->pjScreen));
1081 if (hbmDevice)
1082 {
1083 VOID* pvScan0 = pDev->pjScreen + pSurfaceGlobal->fpVidMem;
1084
1085 //
1086 // Note that HOOK_SYNCHRONIZE must always be hooked when we
1087 // give GDI a pointer to the bitmap bits. We don't need to
1088 // do it here since HOOK_SYNCHRONIZE is always set in our
1089 // pdev->flHooks
1090 //
1091 ULONG flags = MS_NOTSYSTEMMEMORY;
1092
1093 if ( EngModifySurface((HSURF)hbmDevice,
1094 pDev->hdevEng,
1095 pDev->flHooks,
1096 flags,
1097 (DHSURF)hbmDevice,
1098 pvScan0,
1099 pSurfaceGlobal->lPitch,
1100 NULL) )
1101 {
1102 SURFOBJ* surfobj = EngLockSurface((HSURF) hbmDevice);
1103 AssertMsg(surfobj->iType == STYPE_BITMAP, ("expected STYPE_BITMAP"));
1104 surfobj->iType = STYPE_DEVBITMAP;
1105 EngUnlockSurface(surfobj);
1106
1107 DISPDBG((0, "DrvDeriveSurface return succeed"));
1108 return(hbmDevice);
1109 }
1110
1111 DISPDBG((0, "DrvDeriveSurface: EngModifySurface failed"));
1112 EngDeleteSurface((HSURF)hbmDevice);
1113 }
1114 }
1115
1116 DISPDBG((0, "DrvDeriveSurface return NULL"));
1117 DISPDBG((0, "pSurfaceGlobal->ddpfSurface.dwRGBBitCount = %d, lPitch =%ld", pSurfaceGlobal->ddpfSurface.dwRGBBitCount,pSurfaceGlobal->lPitch));
1118#endif
1119
1120 return(0);
1121}
1122#endif /* VBOX_WITH_DDRAW */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette