1 /* DirectDraw IDirectDraw XF86DGA interface
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
18 * This file contains the XF86 DGA specific interface functions.
19 * We are 'allowed' to call X11 specific IDirectDraw functions.
32 #include "wine/exception.h"
35 #include "debugtools.h"
38 #define RESTORE_SIGNALS
40 DEFAULT_DEBUG_CHANNEL(ddraw
);
42 #include "dga_private.h"
44 struct ICOM_VTABLE(IDirectDraw
) dga_ddvt
;
45 struct ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
;
46 struct ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
;
48 #ifdef HAVE_LIBXXF86VM
49 static XF86VidModeModeInfo
*orig_mode
= NULL
;
52 #define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->d->private)
53 #define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
55 /*******************************************************************************
59 /* This function is used both by DGA and DGA2 drivers, thus the virtual function table
60 is not set here, but in the calling function */
61 HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface_with_VT(
62 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,
63 IUnknown
*lpunk
, void *vtable
65 ICOM_THIS(IDirectDraw2Impl
,iface
);
66 IDirectDrawSurfaceImpl
* dsurf
;
68 dga_ds_private
*dspriv
;
69 int i
, fbheight
= ddpriv
->fb_height
;
71 TRACE("(%p)->(%p,%p,%p)\n",This
,lpddsd
,lpdsf
,lpunk
);
72 if (TRACE_ON(ddraw
)) _dump_surface_desc(lpddsd
);
74 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(
77 sizeof(IDirectDrawSurfaceImpl
)
79 dsurf
= *(IDirectDrawSurfaceImpl
**)lpdsf
;
80 dsurf
->private = (dga_ds_private
*)HeapAlloc(
83 sizeof(dga_ds_private
)
85 ICOM_VTBL(dsurf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)vtable
;
87 dspriv
= (dga_ds_private
*)dsurf
->private;
88 IDirectDraw2_AddRef(iface
);
91 dsurf
->s
.ddraw
= This
;
92 dsurf
->s
.palette
= NULL
;
93 dspriv
->fb_height
= -1; /* This is to have non-on screen surfaces freed */
94 dsurf
->s
.lpClipper
= NULL
;
96 /* Copy the surface description */
97 dsurf
->s
.surface_desc
= *lpddsd
;
99 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
100 dsurf
->s
.surface_desc
.dwWidth
= This
->d
->width
;
101 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
102 dsurf
->s
.surface_desc
.dwHeight
= This
->d
->height
;
104 dsurf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
106 /* Check if this a 'primary surface' or not */
107 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
108 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
109 /* This is THE primary surface => there is DGA-specific code */
111 /* Find a viewport */
113 if (!(ddpriv
->vpmask
& (1<<i
)))
115 TRACE("using viewport %d for a primary surface\n",i
);
116 /* if i == 32 or maximum ... return error */
117 ddpriv
->vpmask
|=(1<<i
);
118 lpddsd
->lPitch
= dsurf
->s
.surface_desc
.lPitch
=
119 ddpriv
->fb_width
*PFGET_BPP(This
->d
->directdraw_pixelformat
);
121 dsurf
->s
.surface_desc
.u1
.lpSurface
=
122 ddpriv
->fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
124 dspriv
->fb_height
= i
*fbheight
;
126 /* Add flags if there were not present */
127 dsurf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
128 dsurf
->s
.surface_desc
.dwWidth
= This
->d
->width
;
129 dsurf
->s
.surface_desc
.dwHeight
= This
->d
->height
;
130 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This
->d
->width
,This
->d
->height
,lpddsd
->lPitch
);
131 /* We put our surface always in video memory */
132 SDDSCAPS(dsurf
) |= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
133 dsurf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
->directdraw_pixelformat
;
134 dsurf
->s
.chain
= NULL
;
136 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
137 IDirectDrawSurface4Impl
* back
;
138 dga_ds_private
*bspriv
;
141 for (bbc
=lpddsd
->dwBackBufferCount
;bbc
--;) {
144 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
147 sizeof(IDirectDrawSurface4Impl
)
149 IDirectDraw2_AddRef(iface
);
151 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)vtable
;
152 back
->private = HeapAlloc(
155 sizeof(dga_ds_private
)
157 bspriv
= (dga_ds_private
*)back
->private;
160 if (!(ddpriv
->vpmask
& (1<<i
)))
162 TRACE("using viewport %d for backbuffer %d\n",i
, bbc
);
163 /* if i == 32 or maximum ... return error */
164 ddpriv
->vpmask
|=(1<<i
);
166 bspriv
->fb_height
= i
*fbheight
;
167 /* Copy the surface description from the front buffer */
168 back
->s
.surface_desc
= dsurf
->s
.surface_desc
;
169 /* Change the parameters that are not the same */
170 back
->s
.surface_desc
.u1
.lpSurface
=
171 ddpriv
->fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
173 back
->s
.ddraw
= This
;
174 /* Add relevant info to front and back buffers */
175 /* FIXME: backbuffer/frontbuffer handling broken here, but
176 * will be fixed up in _Flip().
178 SDDSCAPS(dsurf
) |= DDSCAPS_FRONTBUFFER
;
179 SDDSCAPS(back
) |= DDSCAPS_FLIP
|DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
;
180 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
181 SDDSCAPS(back
) &= ~(DDSCAPS_VISIBLE
|DDSCAPS_PRIMARYSURFACE
);
182 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*lpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
186 /* There is no DGA-specific code here...
187 * Go to the common surface creation function
189 return common_off_screen_CreateSurface(This
, dsurf
);
194 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface(
195 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,
200 ret
= DGA_IDirectDraw2Impl_CreateSurface_with_VT(iface
, lpddsd
, lpdsf
, lpunk
, &dga_dds4vt
);
206 static HRESULT WINAPI
DGA_IDirectDrawImpl_SetDisplayMode(
207 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
209 ICOM_THIS(IDirectDrawImpl
,iface
);
213 TRACE("(%p)->(%ld,%ld,%ld)\n", This
, width
, height
, depth
);
215 /* We hope getting the asked for depth */
216 if ( _common_depth_to_pixelformat(depth
,iface
) != -1 ) {
217 /* I.e. no visual found or emulated */
218 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
219 return DDERR_UNSUPPORTEDMODE
;
222 if (This
->d
->width
< width
) {
223 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,This
->d
->width
);
224 return DDERR_UNSUPPORTEDMODE
;
226 This
->d
->width
= width
;
227 This
->d
->height
= height
;
229 /* adjust fb_height, so we don't overlap */
230 if (ddpriv
->fb_height
< height
)
231 ddpriv
->fb_height
= height
;
232 _common_IDirectDrawImpl_SetDisplayMode(This
);
234 #ifdef HAVE_LIBXXF86VM
236 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
237 XF86VidModeModeLine mod_tmp
;
238 /* int dotclock_tmp; */
240 /* save original video mode and set fullscreen if available*/
241 orig_mode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
242 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
243 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
244 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
245 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
246 orig_mode
->htotal
= mod_tmp
.htotal
;
247 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
248 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
249 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
250 orig_mode
->vtotal
= mod_tmp
.vtotal
;
251 orig_mode
->flags
= mod_tmp
.flags
;
252 orig_mode
->private = mod_tmp
.private;
254 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
255 for (i
=0;i
<mode_count
;i
++) {
256 if (all_modes
[i
]->hdisplay
== width
&&
257 all_modes
[i
]->vdisplay
== height
259 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
260 *vidmode
= *(all_modes
[i
]);
263 TSXFree(all_modes
[i
]->private);
265 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
269 WARN("Fullscreen mode not available!\n");
272 TRACE("SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
273 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
274 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
275 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
281 /* FIXME: this function OVERWRITES several signal handlers.
282 * can we save them? and restore them later? In a way that
283 * it works for the library too?
285 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
286 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
288 #ifdef RESTORE_SIGNALS
294 HRESULT WINAPI
DGA_IDirectDraw2Impl_GetCaps(
295 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
297 ICOM_THIS(IDirectDraw2Impl
,iface
);
300 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
301 if (!caps1
&& !caps2
)
302 return DDERR_INVALIDPARAMS
;
304 caps1
->dwVidMemTotal
= ddpriv
->fb_memsize
;
305 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
306 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
309 caps2
->dwVidMemTotal
= ddpriv
->fb_memsize
;
310 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
311 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
316 #if 0 /* Not used as of now.... */
317 static void fill_caps(LPDDCAPS caps
) {
318 /* This function tries to fill the capabilities of Wine's DDraw
319 * implementation. Needs to be fixed, though.. */
323 caps
->dwSize
= sizeof(*caps
);
324 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
/*| DDCAPS_NOHARDWARE*/;
325 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
326 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
328 caps
->dwFXAlphaCaps
= 0;
329 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
331 caps
->dwZBufferBitDepths
= DDBD_16
;
332 /* I put here 8 Mo so that D3D applications will believe they have enough
333 * memory to put textures in video memory.
334 * BTW, is this only frame buffer memory or also texture memory (for Voodoo
335 * boards for example) ?
337 caps
->dwVidMemTotal
= 8192 * 1024;
338 caps
->dwVidMemFree
= 8192 * 1024;
339 /* These are all the supported capabilities of the surfaces */
340 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
341 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
342 /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
343 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
345 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
346 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
347 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
352 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreatePalette(
353 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
355 ICOM_THIS(IDirectDraw2Impl
,iface
);
356 IDirectDrawPaletteImpl
* ddpal
;
357 dga_dp_private
*dppriv
;
361 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,lpddpal
,lpunk
);
362 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,(IDirectDrawPaletteImpl
**)lpddpal
,lpunk
,&xsize
);
365 ddpal
= *(IDirectDrawPaletteImpl
**)lpddpal
;
366 ddpal
->private = HeapAlloc(
369 sizeof(dga_dp_private
)
371 dppriv
= (dga_dp_private
*)ddpal
->private;
373 ICOM_VTBL(ddpal
)= &dga_ddpalvt
;
374 if (This
->d
->directdraw_pixelformat
.u
.dwRGBBitCount
<=8) {
375 dppriv
->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
377 ERR("why are we doing CreatePalette in hi/truecolor?\n");
380 if (dppriv
->cm
&& xsize
) {
381 for (i
=0;i
<xsize
;i
++) {
384 xc
.red
= ddpal
->palents
[i
].peRed
<<8;
385 xc
.blue
= ddpal
->palents
[i
].peBlue
<<8;
386 xc
.green
= ddpal
->palents
[i
].peGreen
<<8;
387 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
389 TSXStoreColor(display
,dppriv
->cm
,&xc
);
395 static HRESULT WINAPI
DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
396 ICOM_THIS(IDirectDraw2Impl
,iface
);
397 TRACE("(%p)->()\n",This
);
399 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
400 #ifdef RESTORE_SIGNALS
406 static ULONG WINAPI
DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
407 ICOM_THIS(IDirectDraw2Impl
,iface
);
409 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
411 if (!--(This
->ref
)) {
412 if (!--(This
->d
->ref
)) {
413 VirtualFree(ddpriv
->fb_addr
, 0, MEM_RELEASE
);
414 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
415 if (This
->d
->window
&& GetPropA(This
->d
->window
,ddProp
))
416 DestroyWindow(This
->d
->window
);
417 #ifdef HAVE_LIBXXF86VM
419 TSXF86VidModeSwitchToMode(
421 DefaultScreen(display
),
424 if (orig_mode
->privsize
)
425 TSXFree(orig_mode
->private);
431 #ifdef RESTORE_SIGNALS
434 HeapFree(GetProcessHeap(),0,This
->d
);
436 HeapFree(GetProcessHeap(),0,This
);
442 HRESULT WINAPI
DGA_IDirectDraw2Impl_QueryInterface(
443 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
445 ICOM_THIS(IDirectDraw2Impl
,iface
);
447 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
448 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
450 IDirectDraw2_AddRef(iface
);
452 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
456 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
457 IDirectDrawImpl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
458 ICOM_VTBL(dd
) = &dga_ddvt
;dd
->ref
= 1;dd
->d
= This
->d
;This
->d
++;
461 IDirectDraw2_AddRef(iface
);
462 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
466 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
467 IDirectDraw2Impl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
468 ICOM_VTBL(dd
) = &dga_dd2vt
;dd
->ref
= 1;dd
->d
= This
->d
;This
->d
++;
471 IDirectDraw2_AddRef(iface
);
472 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
475 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
476 IDirectDraw2Impl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
477 ICOM_VTBL(dd
) = &dga_dd2vt
;dd
->ref
= 1;dd
->d
= This
->d
;This
->d
++;
480 IDirectDraw2_AddRef(iface
);
481 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
484 FIXME("(%p):interface for IID %s _NOT_ found!\n",This
,debugstr_guid(refiid
));
485 return OLE_E_ENUM_NOMORE
;
488 static HRESULT WINAPI
DGA_IDirectDraw2Impl_EnumDisplayModes(
489 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
491 ICOM_THIS(IDirectDraw2Impl
,iface
);
495 } modes
[5] = { /* some usual modes */
502 static int depths
[4] = {8,16,24,32};
505 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
506 ddsfd
.dwSize
= sizeof(ddsfd
);
507 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
508 if (dwFlags
& DDEDM_REFRESHRATES
) {
509 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
510 ddsfd
.u
.dwRefreshRate
= 60;
512 ddsfd
.ddsCaps
.dwCaps
= 0;
513 ddsfd
.dwBackBufferCount
= 1;
515 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
516 ddsfd
.dwBackBufferCount
= 1;
517 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
518 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
519 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= depths
[i
];
520 /* FIXME: those masks would have to be set in depth > 8 */
522 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
523 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
524 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
525 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
526 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
527 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
529 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
531 /* FIXME: We should query those from X itself */
534 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0xF800;
535 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x07E0;
536 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x001F;
539 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
540 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
541 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
544 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
545 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
546 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
551 ddsfd
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
552 ddsfd
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
553 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
554 if (!modescb(&ddsfd
,context
)) return DD_OK
;
556 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
557 ddsfd
.dwWidth
= modes
[j
].w
;
558 ddsfd
.dwHeight
= modes
[j
].h
;
559 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
560 if (!modescb(&ddsfd
,context
)) return DD_OK
;
563 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
564 /* modeX is not standard VGA */
566 ddsfd
.dwHeight
= 200;
568 TRACE(" enumerating (320x200x%d)\n",depths
[i
]);
569 if (!modescb(&ddsfd
,context
)) return DD_OK
;
576 HRESULT WINAPI
DGA_IDirectDraw2Impl_GetDisplayMode(
577 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
579 ICOM_THIS(IDirectDraw2Impl
,iface
);
582 TRACE("(%p)->(%p)\n",This
,lpddsfd
);
583 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
584 lpddsfd
->dwHeight
= This
->d
->height
;
585 lpddsfd
->dwWidth
= This
->d
->width
;
586 lpddsfd
->lPitch
= ddpriv
->fb_width
*PFGET_BPP(This
->d
->directdraw_pixelformat
);
587 lpddsfd
->dwBackBufferCount
= 2;
588 lpddsfd
->u
.dwRefreshRate
= 60;
589 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
590 lpddsfd
->ddpfPixelFormat
= This
->d
->directdraw_pixelformat
;
592 _dump_surface_desc(lpddsfd
);
596 /* Note: Hack so we can reuse the old functions without compiler warnings */
597 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
598 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
600 # define XCAST(fun) (void *)
603 struct ICOM_VTABLE(IDirectDraw
) dga_ddvt
=
605 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
606 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
607 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
608 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
609 XCAST(Compact
)IDirectDraw2Impl_Compact
,
610 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
611 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
612 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
613 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
614 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
615 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
616 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
617 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
618 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
619 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
620 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
621 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
622 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
623 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
624 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
625 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
626 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
627 DGA_IDirectDrawImpl_SetDisplayMode
,
628 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
632 /*****************************************************************************
637 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetDisplayMode(
638 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD dwRefreshRate
, DWORD dwFlags
640 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate
, dwFlags
);
641 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
644 HRESULT WINAPI
DGA_IDirectDraw2Impl_GetAvailableVidMem(
645 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
647 ICOM_THIS(IDirectDraw2Impl
,iface
);
650 TRACE("(%p)->(%p,%p,%p)\n",This
,ddscaps
,total
,free
);
651 if (total
) *total
= ddpriv
->fb_memsize
* 1024;
652 if (free
) *free
= ddpriv
->fb_memsize
* 1024;
656 ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
=
658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
659 DGA_IDirectDraw2Impl_QueryInterface
,
660 IDirectDraw2Impl_AddRef
,
661 DGA_IDirectDraw2Impl_Release
,
662 IDirectDraw2Impl_Compact
,
663 IDirectDraw2Impl_CreateClipper
,
664 DGA_IDirectDraw2Impl_CreatePalette
,
665 DGA_IDirectDraw2Impl_CreateSurface
,
666 IDirectDraw2Impl_DuplicateSurface
,
667 DGA_IDirectDraw2Impl_EnumDisplayModes
,
668 IDirectDraw2Impl_EnumSurfaces
,
669 IDirectDraw2Impl_FlipToGDISurface
,
670 DGA_IDirectDraw2Impl_GetCaps
,
671 DGA_IDirectDraw2Impl_GetDisplayMode
,
672 IDirectDraw2Impl_GetFourCCCodes
,
673 IDirectDraw2Impl_GetGDISurface
,
674 IDirectDraw2Impl_GetMonitorFrequency
,
675 IDirectDraw2Impl_GetScanLine
,
676 IDirectDraw2Impl_GetVerticalBlankStatus
,
677 IDirectDraw2Impl_Initialize
,
678 DGA_IDirectDraw2Impl_RestoreDisplayMode
,
679 IDirectDraw2Impl_SetCooperativeLevel
,
680 DGA_IDirectDraw2Impl_SetDisplayMode
,
681 IDirectDraw2Impl_WaitForVerticalBlank
,
682 DGA_IDirectDraw2Impl_GetAvailableVidMem
685 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
686 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
688 # define XCAST(fun) (void*)
691 ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
=
693 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
694 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
695 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
696 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
697 XCAST(Compact
)IDirectDraw2Impl_Compact
,
698 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
699 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
700 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
701 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
702 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
703 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
704 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
705 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
706 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
707 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
708 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
709 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
710 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
711 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
712 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
713 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
714 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
715 XCAST(SetDisplayMode
)DGA_IDirectDrawImpl_SetDisplayMode
,
716 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
717 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2Impl_GetAvailableVidMem
,
718 IDirectDraw4Impl_GetSurfaceFromDC
,
719 IDirectDraw4Impl_RestoreAllSurfaces
,
720 IDirectDraw4Impl_TestCooperativeLevel
,
721 IDirectDraw4Impl_GetDeviceIdentifier