1 /* DirectDraw IDirectDraw Xlib interface
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
7 * This file contains the Xlib specific interface functions.
23 #include "debugtools.h"
26 DEFAULT_DEBUG_CHANNEL(ddraw
);
28 #include "x11_private.h"
30 #define DDPRIVATE(x) x11_dd_private *ddpriv = ((x11_dd_private*)(x)->d->private)
31 #define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
32 #define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
34 static inline BOOL
get_option( const char *name
, BOOL def
) {
35 return PROFILE_GetWineIniBool( "x11drv", name
, def
);
38 int _common_depth_to_pixelformat(DWORD depth
,LPDIRECTDRAW ddraw
)
40 ICOM_THIS(IDirectDrawImpl
,ddraw
);
42 XPixmapFormatValues
*pf
;
44 int nvisuals
, npixmap
, i
;
47 DDPIXELFORMAT
*pixelformat
= &(This
->d
->directdraw_pixelformat
);
48 DDPIXELFORMAT
*screen_pixelformat
= &(This
->d
->screen_pixelformat
);
50 This
->d
->pixel_convert
= NULL
;
51 This
->d
->palette_convert
= NULL
;
53 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
54 pf
= TSXListPixmapFormats(display
, &npixmap
);
56 for (i
= 0; i
< npixmap
; i
++) {
57 if (pf
[i
].depth
== depth
) {
60 for (j
= 0; j
< nvisuals
; j
++) {
61 if (vi
[j
].depth
== pf
[i
].depth
) {
62 pixelformat
->dwSize
= sizeof(*pixelformat
);
64 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
|DDPF_RGB
;
65 pixelformat
->u1
.dwRBitMask
= 0;
66 pixelformat
->u2
.dwGBitMask
= 0;
67 pixelformat
->u3
.dwBBitMask
= 0;
69 pixelformat
->dwFlags
= DDPF_RGB
;
70 pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
71 pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
72 pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
74 pixelformat
->dwFourCC
= 0;
75 pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
76 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
77 *screen_pixelformat
= *pixelformat
;
78 This
->d
->pixmap_depth
= depth
;
81 goto clean_up_and_exit
;
84 FIXME("No visual corresponding to pixmap format (depth=%ld)!\n",depth
);
89 /* We try now to find an emulated mode */
92 for (c
= 0; c
< sizeof(ModeEmulations
) / sizeof(Convert
); c
++) {
93 if ((ModeEmulations
[c
].dest
.depth
== depth
) &&
94 (ModeEmulations
[c
].dest
.bpp
== depth
)
96 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
97 for (i
= 0; i
< npixmap
; i
++) {
98 if ((pf
[i
].depth
== ModeEmulations
[c
].screen
.depth
) &&
99 (pf
[i
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
102 for (j
= 0; j
< nvisuals
; j
++) {
103 if (vi
[j
].depth
== pf
[i
].depth
) {
104 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
105 screen_pixelformat
->dwFlags
= DDPF_RGB
;
106 screen_pixelformat
->dwFourCC
= 0;
107 screen_pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
108 screen_pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
109 screen_pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
110 screen_pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
111 screen_pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
113 pixelformat
->dwSize
= sizeof(*pixelformat
);
114 pixelformat
->dwFourCC
= 0;
116 pixelformat
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
117 pixelformat
->u
.dwRGBBitCount
= 8;
118 pixelformat
->u1
.dwRBitMask
= 0;
119 pixelformat
->u2
.dwGBitMask
= 0;
120 pixelformat
->u3
.dwBBitMask
= 0;
122 pixelformat
->dwFlags
= DDPF_RGB
;
123 pixelformat
->u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
124 pixelformat
->u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
125 pixelformat
->u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
126 pixelformat
->u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
128 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
129 This
->d
->pixmap_depth
= vi
[j
].depth
;
132 This
->d
->pixel_convert
=ModeEmulations
[c
].funcs
.pixel_convert
;
133 This
->d
->palette_convert
=ModeEmulations
[c
].funcs
.palette_convert
;
134 goto clean_up_and_exit
;
141 ERR("No emulation found for depth %ld!\n",depth
);
151 /*******************************************************************************
155 /* Error handlers for Image creation */
156 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
161 static XImage
*create_xshmimage(
162 IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
167 int (*WineXHandler
)(Display
*, XErrorEvent
*);
169 img
= TSXShmCreateImage(display
,
170 DefaultVisualOfScreen(X11DRV_GetXScreen()),
171 This
->d
->pixmap_depth
,
175 lpdsf
->s
.surface_desc
.dwWidth
,
176 lpdsf
->s
.surface_desc
.dwHeight
180 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
181 ddpriv
->xshm_active
= 0;
185 dspriv
->shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
187 if (dspriv
->shminfo
.shmid
< 0) {
188 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
189 ddpriv
->xshm_active
= 0;
190 TSXDestroyImage(img
);
194 dspriv
->shminfo
.shmaddr
=img
->data
=(char*)shmat(dspriv
->shminfo
.shmid
,0,0);
196 if (img
->data
== (char *) -1) {
197 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
198 ddpriv
->xshm_active
= 0;
199 TSXDestroyImage(img
);
200 shmctl(dspriv
->shminfo
.shmid
, IPC_RMID
, 0);
203 dspriv
->shminfo
.readOnly
= False
;
205 /* This is where things start to get trickier....
206 * First, we flush the current X connections to be sure to catch all
207 * non-XShm related errors
209 TSXSync(display
, False
);
210 /* Then we enter in the non-thread safe part of the tests */
211 EnterCriticalSection( &X11DRV_CritSection
);
213 /* Reset the error flag, sets our new error handler and try to attach
217 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
218 XShmAttach(display
, &(dspriv
->shminfo
));
219 XSync(display
, False
);
221 /* Check the error flag */
223 /* An error occured */
227 shmdt(dspriv
->shminfo
.shmaddr
);
228 shmctl(dspriv
->shminfo
.shmid
, IPC_RMID
, 0);
229 XSetErrorHandler(WineXHandler
);
231 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
232 ddpriv
->xshm_active
= 0;
234 /* Leave the critical section */
235 LeaveCriticalSection( &X11DRV_CritSection
);
238 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
239 * this works, but it may be a bit overkill....
241 XSetErrorHandler(WineXHandler
);
242 LeaveCriticalSection( &X11DRV_CritSection
);
244 shmctl(dspriv
->shminfo
.shmid
, IPC_RMID
, 0);
246 if (This
->d
->pixel_convert
!= NULL
) {
247 int bpp
= PFGET_BPP(This
->d
->directdraw_pixelformat
);
248 lpdsf
->s
.surface_desc
.u1
.lpSurface
= VirtualAlloc(
250 lpdsf
->s
.surface_desc
.dwWidth
*
251 lpdsf
->s
.surface_desc
.dwHeight
*
253 MEM_RESERVE
| MEM_COMMIT
,
257 lpdsf
->s
.surface_desc
.u1
.lpSurface
= img
->data
;
258 VirtualAlloc(img
->data
, img
->bytes_per_line
* img
->height
, MEM_RESERVE
|MEM_SYSTEM
, PAGE_READWRITE
);
262 #endif /* HAVE_LIBXXSHM */
264 static XImage
*create_ximage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
268 int bpp
= PFGET_BPP(This
->d
->directdraw_pixelformat
);
269 int screen_bpp
= PFGET_BPP(This
->d
->screen_pixelformat
);
272 if (ddpriv
->xshm_active
)
273 img
= create_xshmimage(This
, lpdsf
);
277 /* Allocate surface memory */
278 lpdsf
->s
.surface_desc
.u1
.lpSurface
= VirtualAlloc(
280 lpdsf
->s
.surface_desc
.dwWidth
*
281 lpdsf
->s
.surface_desc
.dwHeight
*
283 MEM_RESERVE
| MEM_COMMIT
,
287 if (This
->d
->pixel_convert
!= NULL
)
288 img_data
= VirtualAlloc(
290 lpdsf
->s
.surface_desc
.dwWidth
*
291 lpdsf
->s
.surface_desc
.dwHeight
*
293 MEM_RESERVE
| MEM_COMMIT
,
297 img_data
= lpdsf
->s
.surface_desc
.u1
.lpSurface
;
299 /* In this case, create an XImage */
300 img
= TSXCreateImage(display
,
301 DefaultVisualOfScreen(X11DRV_GetXScreen()),
302 This
->d
->pixmap_depth
,
306 lpdsf
->s
.surface_desc
.dwWidth
,
307 lpdsf
->s
.surface_desc
.dwHeight
,
309 lpdsf
->s
.surface_desc
.dwWidth
*screen_bpp
314 if (This
->d
->pixel_convert
!= NULL
)
315 lpdsf
->s
.surface_desc
.lPitch
= bpp
*lpdsf
->s
.surface_desc
.dwWidth
;
317 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
321 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreateSurface(
322 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,
325 ICOM_THIS(IDirectDraw2Impl
,iface
);
326 IDirectDrawSurfaceImpl
* dsurf
;
327 x11_ds_private
*dspriv
;
329 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This
,lpddsd
,lpdsf
,lpunk
);
331 if (TRACE_ON(ddraw
)) _dump_surface_desc(lpddsd
);
336 sizeof(IDirectDrawSurfaceImpl
)
338 dsurf
= (IDirectDrawSurfaceImpl
*)*lpdsf
;
340 dsurf
->private = HeapAlloc(
343 sizeof(x11_ds_private
)
345 ICOM_VTBL(dsurf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&xlib_dds4vt
;
346 dspriv
= (x11_ds_private
*)dsurf
->private;
348 dsurf
->s
.ddraw
= This
;
349 IDirectDraw2_AddRef(iface
);
351 dsurf
->s
.palette
= NULL
;
352 dsurf
->s
.lpClipper
= NULL
;
353 dspriv
->image
= NULL
; /* This is for off-screen buffers */
355 /* Copy the surface description */
356 dsurf
->s
.surface_desc
= *lpddsd
;
358 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
359 dsurf
->s
.surface_desc
.dwWidth
= This
->d
->width
;
360 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
361 dsurf
->s
.surface_desc
.dwHeight
= This
->d
->height
;
362 dsurf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
364 /* Check if this a 'primary surface' or not */
365 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
366 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
370 /* Add flags if there were not present */
371 dsurf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
372 dsurf
->s
.surface_desc
.dwWidth
= This
->d
->width
;
373 dsurf
->s
.surface_desc
.dwHeight
= This
->d
->height
;
374 dsurf
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
375 dsurf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
->directdraw_pixelformat
;
377 TRACE("using standard XImage for a primary surface (%p)\n", dsurf
);
378 /* Create the XImage */
379 img
= create_ximage(This
,(IDirectDrawSurface4Impl
*)dsurf
);
381 return DDERR_OUTOFMEMORY
;
384 /* Check for backbuffers */
385 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
386 IDirectDrawSurface4Impl
* back
;
390 for (i
=lpddsd
->dwBackBufferCount
;i
--;) {
391 x11_ds_private
*bspriv
;
392 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
395 sizeof(IDirectDrawSurface4Impl
)
397 TRACE("allocated back-buffer (%p)\n", back
);
399 IDirectDraw2_AddRef(iface
);
400 back
->s
.ddraw
= This
;
403 ICOM_VTBL(back
)=(ICOM_VTABLE(IDirectDrawSurface4
)*)&xlib_dds4vt
;
404 /* Copy the surface description from the front buffer */
405 back
->s
.surface_desc
= dsurf
->s
.surface_desc
;
406 back
->s
.surface_desc
.u1
.lpSurface
= NULL
;
408 back
->private = HeapAlloc(
411 sizeof(x11_ds_private
)
413 bspriv
= (x11_ds_private
*)back
->private;
415 /* Create the XImage. */
416 img
= create_ximage(This
, back
);
418 return DDERR_OUTOFMEMORY
;
419 TRACE("bspriv = %p\n",bspriv
);
422 /* Add relevant info to front and back buffers */
423 /* FIXME: backbuffer/frontbuffer handling broken here, but
424 * will be fixed up in _Flip().
426 SDDSCAPS(dsurf
) |= DDSCAPS_FRONTBUFFER
;
427 SDDSCAPS(back
) |= DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
|DDSCAPS_FLIP
;
428 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
429 SDDSCAPS(back
) &= ~(DDSCAPS_VISIBLE
|DDSCAPS_PRIMARYSURFACE
);
430 TRACE("attaching surface %p to %p\n",back
,*lpdsf
);
431 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*lpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
435 /* There is no Xlib-specific code here...
436 * Go to the common surface creation function
438 return common_off_screen_CreateSurface(This
,dsurf
);
444 * The Xlib Implementation tries to use the passed hwnd as drawing window,
445 * even when the approbiate bitmasks are not specified.
447 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetCooperativeLevel(
448 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
450 ICOM_THIS(IDirectDraw2Impl
,iface
);
453 FIXME("(%p)->(%08lx,%08lx)\n",This
,(DWORD
)hwnd
,cooplevel
);
455 _dump_cooperativelevel(cooplevel
);
456 This
->d
->mainWindow
= hwnd
;
458 /* This will be overwritten in the case of Full Screen mode.
459 Windowed games could work with that :-) */
461 WND
*tmpWnd
= WIN_FindWndPtr(hwnd
);
462 ddpriv
->drawable
= X11DRV_WND_GetXWindow(tmpWnd
);
463 WIN_ReleaseWndPtr(tmpWnd
);
465 if( !ddpriv
->drawable
) {
466 ddpriv
->drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
467 WIN_ReleaseDesktop();
469 TRACE("Setting drawable to %ld\n", ddpriv
->drawable
);
474 static HRESULT WINAPI
Xlib_IDirectDrawImpl_SetDisplayMode(
475 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
477 ICOM_THIS(IDirectDrawImpl
,iface
);
483 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
484 This
, width
, height
, depth
);
486 switch ((c
= _common_depth_to_pixelformat(depth
,iface
))) {
488 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
489 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
490 return DDERR_UNSUPPORTEDMODE
;
492 /* No conversion. Good. */
495 DPRINTF("DirectDraw warning: running in depth-conversion mode %d. Should run using a %ld depth for optimal performances.\n", c
,depth
);
498 This
->d
->width
= width
;
499 This
->d
->height
= height
;
501 _common_IDirectDrawImpl_SetDisplayMode(This
);
503 tmpWnd
= WIN_FindWndPtr(This
->d
->window
);
504 This
->d
->paintable
= 1;
505 ddpriv
->drawable
= ((X11DRV_WND_DATA
*) tmpWnd
->pDriverData
)->window
;
506 WIN_ReleaseWndPtr(tmpWnd
);
508 /* We don't have a context for this window. Host off the desktop */
509 if( !ddpriv
->drawable
)
511 ddpriv
->drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
512 WIN_ReleaseDesktop();
514 TRACE("Setting drawable to %ld\n", ddpriv
->drawable
);
516 if (get_option( "DXGrab", 0 )) {
517 /* Confine cursor movement (risky, but the user asked for it) */
518 TSXGrabPointer(display
, ddpriv
->drawable
, True
, 0, GrabModeAsync
, GrabModeAsync
, ddpriv
->drawable
, None
, CurrentTime
);
524 static void fill_caps(LPDDCAPS caps
) {
525 /* This function tries to fill the capabilities of Wine's DDraw implementation.
526 Need to be fixed, though.. */
530 caps
->dwSize
= sizeof(*caps
);
531 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
/*| DDCAPS_NOHARDWARE*/;
532 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
533 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
535 caps
->dwFXAlphaCaps
= 0;
536 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
538 caps
->dwZBufferBitDepths
= DDBD_16
;
539 /* I put here 8 Mo so that D3D applications will believe they have enough memory
540 to put textures in video memory.
541 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
543 caps
->dwVidMemTotal
= 8192 * 1024;
544 caps
->dwVidMemFree
= 8192 * 1024;
545 /* These are all the supported capabilities of the surfaces */
546 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
547 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
548 /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
549 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
551 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
552 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
553 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
557 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetCaps(
558 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
560 ICOM_THIS(IDirectDraw2Impl
,iface
);
561 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
563 /* Put the same caps for the two capabilities */
570 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreatePalette(
571 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,
572 LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
574 ICOM_THIS(IDirectDraw2Impl
,iface
);
575 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
579 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
580 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
583 (*ilpddpal
)->private = HeapAlloc(
586 sizeof(x11_dp_private
)
588 ICOM_VTBL(*ilpddpal
) = &xlib_ddpalvt
;
592 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_QueryInterface(
593 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
595 ICOM_THIS(IDirectDraw2Impl
,iface
);
597 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
598 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
600 IDirectDraw2_AddRef(iface
);
602 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
606 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
607 IDirectDrawImpl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
608 IDirectDraw2_AddRef(iface
);
610 dd
->ref
= 1;ICOM_VTBL(dd
) = &xlib_ddvt
;dd
->d
= This
->d
;This
->d
->ref
++;
613 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
616 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
617 IDirectDraw2Impl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
618 IDirectDraw2_AddRef(iface
);
620 dd
->ref
= 1;ICOM_VTBL(dd
) = &xlib_dd2vt
;dd
->d
= This
->d
;This
->d
->ref
++;
623 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
626 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
627 IDirectDraw4Impl
*dd
= HeapAlloc(GetProcessHeap(),0,sizeof(*dd
));
628 dd
->ref
= 1;ICOM_VTBL(dd
) = &xlib_dd4vt
;dd
->d
= This
->d
;This
->d
->ref
++;
631 IDirectDraw2_AddRef(iface
);
632 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
636 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
637 return create_direct3d(obj
,This
);
638 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
639 return create_direct3d2(obj
,This
);
640 if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
641 return create_direct3d3(obj
,This
);
643 FIXME("(%p):interface for IID %s _NOT_ found!\n",This
,debugstr_guid(refiid
));
644 return OLE_E_ENUM_NOMORE
;
647 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_EnumDisplayModes(
648 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
650 ICOM_THIS(IDirectDraw2Impl
,iface
);
652 XPixmapFormatValues
*pf
;
654 int xbpp
= 1, nvisuals
, npixmap
, i
, emu
;
655 int has_mode
[] = { 0, 0, 0, 0 };
656 int has_depth
[] = { 8, 15, 16, 24 };
660 } modes
[] = { /* some of the usual modes */
668 DWORD maxWidth
, maxHeight
;
670 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
671 ddsfd
.dwSize
= sizeof(ddsfd
);
672 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
|DDSD_PITCH
;
673 if (dwFlags
& DDEDM_REFRESHRATES
) {
674 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
675 ddsfd
.u
.dwRefreshRate
= 60;
677 maxWidth
= GetSystemMetrics(SM_CXSCREEN
);
678 maxHeight
= GetSystemMetrics(SM_CYSCREEN
);
680 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
681 pf
= TSXListPixmapFormats(display
, &npixmap
);
685 while ((i
< npixmap
) || (emu
!= 4)) {
691 for (j
= 0; j
< 4; j
++) {
692 if (has_depth
[j
] == pf
[i
].depth
) {
703 if (has_mode
[mode_index
] == 0) {
704 if (mode_index
== 0) {
707 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
708 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
709 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
710 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
711 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
712 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
713 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
714 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
715 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
719 has_mode
[mode_index
] = 1;
721 /* All the 'true color' depths (15, 16 and 24)
722 First, find the corresponding visual to extract the bit masks */
723 for (j
= 0; j
< nvisuals
; j
++) {
724 if (vi
[j
].depth
== pf
[i
].depth
) {
725 ddsfd
.ddsCaps
.dwCaps
= 0;
726 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
727 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
728 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
729 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
730 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= vi
[j
].red_mask
;
731 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= vi
[j
].green_mask
;
732 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= vi
[j
].blue_mask
;
733 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
735 xbpp
= pf
[i
].bits_per_pixel
/8;
738 has_mode
[mode_index
] = 1;
743 WARN("Did not find visual corresponding the the pixmap format !\n");
748 /* Now to emulated modes */
749 if (has_mode
[emu
] == 0) {
752 int depth
= has_depth
[emu
];
754 for (c
= 0; (c
< sizeof(ModeEmulations
) / sizeof(Convert
)) && (send_mode
== 0); c
++) {
755 if (ModeEmulations
[c
].dest
.depth
== depth
) {
756 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
757 for (l
= 0; (l
< npixmap
) && (send_mode
== 0); l
++) {
758 if ((pf
[l
].depth
== ModeEmulations
[c
].screen
.depth
) &&
759 (pf
[l
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
761 for (j
= 0; (j
< nvisuals
) && (send_mode
== 0); j
++) {
762 if ((vi
[j
].depth
== pf
[l
].depth
) &&
763 (vi
[j
].red_mask
== ModeEmulations
[c
].screen
.rmask
) &&
764 (vi
[j
].green_mask
== ModeEmulations
[c
].screen
.gmask
) &&
765 (vi
[j
].blue_mask
== ModeEmulations
[c
].screen
.bmask
)) {
766 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
767 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
769 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
770 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
771 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
772 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
773 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
775 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
776 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
777 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
778 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
779 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
781 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
786 WARN("No visual corresponding to pixmap format !\n");
800 if (TRACE_ON(ddraw
)) {
801 TRACE("Enumerating with pixel format : \n");
802 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
806 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
807 /* Do not enumerate modes we cannot handle anyway */
808 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
811 ddsfd
.dwWidth
= modes
[mode
].w
;
812 ddsfd
.dwHeight
= modes
[mode
].h
;
813 ddsfd
.lPitch
= ddsfd
.dwWidth
* xbpp
;
815 /* Now, send the mode description to the application */
816 TRACE(" - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
817 if (!modescb(&ddsfd
, context
))
821 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
822 /* modeX is not standard VGA */
824 ddsfd
.dwHeight
= 200;
825 ddsfd
.lPitch
= 320 * xbpp
;
826 if (!modescb(&ddsfd
, context
))
838 /* Note: Hack so we can reuse the old functions without compiler warnings */
839 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
840 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
842 # define XCAST(fun) (void *)
845 ICOM_VTABLE(IDirectDraw
) xlib_ddvt
= {
846 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
847 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
848 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
849 XCAST(Release
)IDirectDraw2Impl_Release
,
850 XCAST(Compact
)IDirectDraw2Impl_Compact
,
851 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
852 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
853 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
854 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
855 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
856 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
857 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
858 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
859 XCAST(GetDisplayMode
)IDirectDraw2Impl_GetDisplayMode
,
860 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
861 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
862 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
863 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
864 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
865 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
866 XCAST(RestoreDisplayMode
)IDirectDraw2Impl_RestoreDisplayMode
,
867 XCAST(SetCooperativeLevel
)Xlib_IDirectDraw2Impl_SetCooperativeLevel
,
868 Xlib_IDirectDrawImpl_SetDisplayMode
,
869 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
874 /*****************************************************************************
879 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetDisplayMode(
880 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD dwRefreshRate
,DWORD dwFlags
882 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate
, dwFlags
);
883 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
886 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetAvailableVidMem(
887 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
889 ICOM_THIS(IDirectDraw2Impl
,iface
);
890 TRACE("(%p)->(%p,%p,%p)\n",This
,ddscaps
,total
,free
);
891 if (total
) *total
= 16* 1024 * 1024;
892 if (free
) *free
= 16* 1024 * 1024;
896 ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
= {
897 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
898 Xlib_IDirectDraw2Impl_QueryInterface
,
899 IDirectDraw2Impl_AddRef
,
900 IDirectDraw2Impl_Release
,
901 IDirectDraw2Impl_Compact
,
902 IDirectDraw2Impl_CreateClipper
,
903 Xlib_IDirectDraw2Impl_CreatePalette
,
904 Xlib_IDirectDraw2Impl_CreateSurface
,
905 IDirectDraw2Impl_DuplicateSurface
,
906 Xlib_IDirectDraw2Impl_EnumDisplayModes
,
907 IDirectDraw2Impl_EnumSurfaces
,
908 IDirectDraw2Impl_FlipToGDISurface
,
909 Xlib_IDirectDraw2Impl_GetCaps
,
910 IDirectDraw2Impl_GetDisplayMode
,
911 IDirectDraw2Impl_GetFourCCCodes
,
912 IDirectDraw2Impl_GetGDISurface
,
913 IDirectDraw2Impl_GetMonitorFrequency
,
914 IDirectDraw2Impl_GetScanLine
,
915 IDirectDraw2Impl_GetVerticalBlankStatus
,
916 IDirectDraw2Impl_Initialize
,
917 IDirectDraw2Impl_RestoreDisplayMode
,
918 Xlib_IDirectDraw2Impl_SetCooperativeLevel
,
919 Xlib_IDirectDraw2Impl_SetDisplayMode
,
920 IDirectDraw2Impl_WaitForVerticalBlank
,
921 Xlib_IDirectDraw2Impl_GetAvailableVidMem
924 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
925 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
927 # define XCAST(fun) (void*)
930 ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
= {
931 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
932 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
933 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
934 XCAST(Release
)IDirectDraw2Impl_Release
,
935 XCAST(Compact
)IDirectDraw2Impl_Compact
,
936 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
937 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
938 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
939 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
940 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
941 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
942 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
943 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
944 XCAST(GetDisplayMode
)IDirectDraw2Impl_GetDisplayMode
,
945 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
946 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
947 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
948 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
949 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
950 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
951 XCAST(RestoreDisplayMode
)IDirectDraw2Impl_RestoreDisplayMode
,
952 XCAST(SetCooperativeLevel
)Xlib_IDirectDraw2Impl_SetCooperativeLevel
,
953 XCAST(SetDisplayMode
)Xlib_IDirectDrawImpl_SetDisplayMode
,
954 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
955 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2Impl_GetAvailableVidMem
,
956 IDirectDraw4Impl_GetSurfaceFromDC
,
957 IDirectDraw4Impl_RestoreAllSurfaces
,
958 IDirectDraw4Impl_TestCooperativeLevel
,
959 IDirectDraw4Impl_GetDeviceIdentifier