VirtualBox

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

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

Added QUERYESCSUPPORT support

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