VirtualBox

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

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

commented out incorrect code; just always fail in DrvDeriveSurface

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