VirtualBox

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

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

Less strict size check

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