VirtualBox

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

Last change on this file since 4123 was 4123, checked in by vboxsync, 17 years ago

backed out small change

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