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"
28 DEFAULT_DEBUG_CHANNEL(ddraw);
30 #include "x11_private.h"
32 #define DDPRIVATE(x) x11_dd_private *ddpriv = ((x11_dd_private*)(x)->private)
33 #define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
34 #define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
36 static inline BOOL get_option( const char *name, BOOL def ) {
37 return PROFILE_GetWineIniBool( "x11drv", name, def );
40 int _common_depth_to_pixelformat(
41 DWORD depth, DDPIXELFORMAT *pixelformat,DDPIXELFORMAT *screen_pixelformat,
45 XPixmapFormatValues *pf;
47 int nvisuals, npixmap, i;
51 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
52 pf = TSXListPixmapFormats(display, &npixmap);
54 for (i = 0; i < npixmap; i++) {
55 if (pf[i].depth == depth) {
58 for (j = 0; j < nvisuals; j++) {
59 if (vi[j].depth == pf[i].depth) {
60 pixelformat->dwSize = sizeof(*pixelformat);
62 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
63 pixelformat->u1.dwRBitMask = 0;
64 pixelformat->u2.dwGBitMask = 0;
65 pixelformat->u3.dwBBitMask = 0;
67 pixelformat->dwFlags = DDPF_RGB;
68 pixelformat->u1.dwRBitMask = vi[j].red_mask;
69 pixelformat->u2.dwGBitMask = vi[j].green_mask;
70 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
72 pixelformat->dwFourCC = 0;
73 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
74 pixelformat->u4.dwRGBAlphaBitMask= 0;
76 *screen_pixelformat = *pixelformat;
79 *pix_depth = vi[j].depth;
83 goto clean_up_and_exit;
86 WARN("No visual corresponding to pixmap format !\n");
91 /* We try now to find an emulated mode */
94 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
95 if (ModeEmulations[c].dest.depth == 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;
131 *pix_depth = vi[j].depth;
135 goto clean_up_and_exit;
137 ERR("No visual corresponding to pixmap format !\n");
152 /*******************************************************************************
156 /* Error handlers for Image creation */
157 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
162 static XImage *create_xshmimage(
163 IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf
168 int (*WineXHandler)(Display *, XErrorEvent *);
170 img = TSXShmCreateImage(display,
171 DefaultVisualOfScreen(X11DRV_GetXScreen()),
172 This->d.pixmap_depth,
176 lpdsf->s.surface_desc.dwWidth,
177 lpdsf->s.surface_desc.dwHeight
181 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
182 ddpriv->xshm_active = 0;
186 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);
271 if (ddpriv->xshm_active)
272 img = create_xshmimage(This, lpdsf);
276 /* Allocate surface memory */
277 lpdsf->s.surface_desc.u1.lpSurface = VirtualAlloc(
279 lpdsf->s.surface_desc.dwWidth *
280 lpdsf->s.surface_desc.dwHeight *
282 MEM_RESERVE | MEM_COMMIT,
286 if (This->d.pixel_convert != NULL)
287 img_data = HeapAlloc(
290 lpdsf->s.surface_desc.dwWidth *
291 lpdsf->s.surface_desc.dwHeight *
295 img_data = lpdsf->s.surface_desc.u1.lpSurface;
297 /* In this case, create an XImage */
298 img = TSXCreateImage(display,
299 DefaultVisualOfScreen(X11DRV_GetXScreen()),
300 This->d.pixmap_depth,
304 lpdsf->s.surface_desc.dwWidth,
305 lpdsf->s.surface_desc.dwHeight,
307 lpdsf->s.surface_desc.dwWidth*bpp
312 /* assert(bpp*lpdsf->s.surface_desc.dwWidth == img->bytes_per_line); */
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 TRACE("using standard XImage for a primary surface (%p)\n", dsurf);
371 /* Create the XImage */
372 img = create_ximage(This,(IDirectDrawSurface4Impl*)dsurf);
374 return DDERR_OUTOFMEMORY;
377 /* Add flags if there were not present */
378 dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
379 dsurf->s.surface_desc.dwWidth = This->d.width;
380 dsurf->s.surface_desc.dwHeight = This->d.height;
381 dsurf->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
382 dsurf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
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;
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,
487 &(This->d.directdraw_pixelformat),
488 &(This->d.screen_pixelformat),
489 &(This->d.pixmap_depth)))) {
491 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
492 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
493 return DDERR_UNSUPPORTEDMODE;
497 This->d.pixel_convert = NULL;
498 This->d.palette_convert = NULL;
502 DPRINTF("DirectDraw warning: running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
503 /* Set the depth convertion routines */
504 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
505 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
508 This->d.width = width;
509 This->d.height = height;
511 _common_IDirectDrawImpl_SetDisplayMode(This);
513 tmpWnd = WIN_FindWndPtr(This->d.window);
514 This->d.paintable = 1;
515 ddpriv->drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
516 WIN_ReleaseWndPtr(tmpWnd);
518 /* We don't have a context for this window. Host off the desktop */
519 if( !ddpriv->drawable )
521 ddpriv->drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
522 WIN_ReleaseDesktop();
524 TRACE("Setting drawable to %ld\n", ddpriv->drawable);
526 if (get_option( "DXGrab", 0 )) {
527 /* Confine cursor movement (risky, but the user asked for it) */
528 TSXGrabPointer(display, ddpriv->drawable, True, 0, GrabModeAsync, GrabModeAsync, ddpriv->drawable, None, CurrentTime);
534 static void fill_caps(LPDDCAPS caps) {
535 /* This function tries to fill the capabilities of Wine's DDraw implementation.
536 Need to be fixed, though.. */
540 caps->dwSize = sizeof(*caps);
541 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
542 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
543 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
545 caps->dwFXAlphaCaps = 0;
546 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
548 caps->dwZBufferBitDepths = DDBD_16;
549 /* I put here 8 Mo so that D3D applications will believe they have enough memory
550 to put textures in video memory.
551 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
553 caps->dwVidMemTotal = 8192 * 1024;
554 caps->dwVidMemFree = 8192 * 1024;
555 /* These are all the supported capabilities of the surfaces */
556 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
557 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
558 /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
559 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
561 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
562 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
563 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
567 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
568 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
570 ICOM_THIS(IDirectDraw2Impl,iface);
571 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
573 /* Put the same caps for the two capabilities */
580 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
581 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,
582 LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
584 ICOM_THIS(IDirectDraw2Impl,iface);
585 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
589 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
590 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
593 (*ilpddpal)->private = HeapAlloc(
596 sizeof(x11_dp_private)
598 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
602 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
603 ICOM_THIS(IDirectDraw2Impl,iface);
604 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
606 if (!--(This->ref)) {
607 if (This->d.window && GetPropA(This->d.window,ddProp))
608 DestroyWindow(This->d.window);
609 HeapFree(GetProcessHeap(),0,This);
612 /* FIXME: destroy window ... */
616 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
617 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
619 ICOM_THIS(IDirectDraw2Impl,iface);
621 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
622 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
624 IDirectDraw2_AddRef(iface);
626 TRACE(" Creating IUnknown interface (%p)\n", *obj);
630 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
631 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
632 IDirectDraw2_AddRef(iface);
635 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
639 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
640 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
641 IDirectDraw2_AddRef(iface);
644 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
648 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
649 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
650 IDirectDraw2_AddRef(iface);
653 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
658 if ( IsEqualGUID( &IID_IDirect3D, refiid ) )
659 return create_direct3d(obj,This);
660 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) )
661 return create_direct3d2(obj,This);
662 if ( IsEqualGUID( &IID_IDirect3D3, refiid ) )
663 return create_direct3d3(obj,This);
665 FIXME("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
666 return OLE_E_ENUM_NOMORE;
669 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
670 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
672 ICOM_THIS(IDirectDraw2Impl,iface);
674 XPixmapFormatValues *pf;
676 int xbpp = 1, nvisuals, npixmap, i, emu;
677 int has_mode[] = { 0, 0, 0, 0 };
678 int has_depth[] = { 8, 15, 16, 24 };
682 } modes[] = { /* some of the usual modes */
690 DWORD maxWidth, maxHeight;
692 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
693 ddsfd.dwSize = sizeof(ddsfd);
694 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
695 if (dwFlags & DDEDM_REFRESHRATES) {
696 ddsfd.dwFlags |= DDSD_REFRESHRATE;
697 ddsfd.u.dwRefreshRate = 60;
699 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
700 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
702 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
703 pf = TSXListPixmapFormats(display, &npixmap);
707 while ((i < npixmap) || (emu != 4)) {
713 for (j = 0; j < 4; j++) {
714 if (has_depth[j] == pf[i].depth) {
725 if (has_mode[mode_index] == 0) {
726 if (mode_index == 0) {
729 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
730 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
731 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
732 ddsfd.ddpfPixelFormat.dwFourCC = 0;
733 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
734 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
735 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
736 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
737 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
741 has_mode[mode_index] = 1;
743 /* All the 'true color' depths (15, 16 and 24)
744 First, find the corresponding visual to extract the bit masks */
745 for (j = 0; j < nvisuals; j++) {
746 if (vi[j].depth == pf[i].depth) {
747 ddsfd.ddsCaps.dwCaps = 0;
748 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
749 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
750 ddsfd.ddpfPixelFormat.dwFourCC = 0;
751 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
752 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
753 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
754 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
755 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
757 xbpp = pf[i].bits_per_pixel/8;
760 has_mode[mode_index] = 1;
765 WARN("Did not find visual corresponding the the pixmap format !\n");
770 /* Now to emulated modes */
771 if (has_mode[emu] == 0) {
774 int depth = has_depth[emu];
776 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
777 if (ModeEmulations[c].dest.depth == depth) {
778 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
779 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
780 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
781 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
783 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
784 if ((vi[j].depth == pf[l].depth) &&
785 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
786 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
787 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
788 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
789 ddsfd.ddpfPixelFormat.dwFourCC = 0;
791 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
792 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
793 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
794 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
795 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
797 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
798 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
799 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
800 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
801 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
803 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
808 WARN("No visual corresponding to pixmap format !\n");
822 if (TRACE_ON(ddraw)) {
823 TRACE("Enumerating with pixel format : \n");
824 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
828 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
829 /* Do not enumerate modes we cannot handle anyway */
830 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
833 ddsfd.dwWidth = modes[mode].w;
834 ddsfd.dwHeight= modes[mode].h;
835 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
837 /* Now, send the mode description to the application */
838 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
839 if (!modescb(&ddsfd, context))
843 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
844 /* modeX is not standard VGA */
846 ddsfd.dwHeight = 200;
847 ddsfd.lPitch = 320 * xbpp;
848 if (!modescb(&ddsfd, context))
860 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
861 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
863 ICOM_THIS(IDirectDraw2Impl,iface);
864 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
865 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
866 lpddsfd->dwHeight = This->d.height;
867 lpddsfd->dwWidth = This->d.width;
868 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
869 lpddsfd->dwBackBufferCount = 2;
870 lpddsfd->u.dwRefreshRate = 60;
871 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
872 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
874 _dump_surface_desc(lpddsfd);
878 /* Note: Hack so we can reuse the old functions without compiler warnings */
879 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
880 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
882 # define XCAST(fun) (void *)
885 ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
886 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
887 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
888 XCAST(AddRef)IDirectDraw2Impl_AddRef,
889 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
890 XCAST(Compact)IDirectDraw2Impl_Compact,
891 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
892 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
893 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
894 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
895 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
896 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
897 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
898 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
899 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
900 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
901 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
902 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
903 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
904 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
905 XCAST(Initialize)IDirectDraw2Impl_Initialize,
906 XCAST(RestoreDisplayMode)IDirectDraw2Impl_RestoreDisplayMode,
907 XCAST(SetCooperativeLevel)Xlib_IDirectDraw2Impl_SetCooperativeLevel,
908 Xlib_IDirectDrawImpl_SetDisplayMode,
909 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
914 /*****************************************************************************
919 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
920 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
922 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
923 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
926 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
927 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
929 ICOM_THIS(IDirectDraw2Impl,iface);
930 TRACE("(%p)->(%p,%p,%p)\n",This,ddscaps,total,free);
931 if (total) *total = 16* 1024 * 1024;
932 if (free) *free = 16* 1024 * 1024;
936 ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
937 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
938 Xlib_IDirectDraw2Impl_QueryInterface,
939 IDirectDraw2Impl_AddRef,
940 Xlib_IDirectDraw2Impl_Release,
941 IDirectDraw2Impl_Compact,
942 IDirectDraw2Impl_CreateClipper,
943 Xlib_IDirectDraw2Impl_CreatePalette,
944 Xlib_IDirectDraw2Impl_CreateSurface,
945 IDirectDraw2Impl_DuplicateSurface,
946 Xlib_IDirectDraw2Impl_EnumDisplayModes,
947 IDirectDraw2Impl_EnumSurfaces,
948 IDirectDraw2Impl_FlipToGDISurface,
949 Xlib_IDirectDraw2Impl_GetCaps,
950 Xlib_IDirectDraw2Impl_GetDisplayMode,
951 IDirectDraw2Impl_GetFourCCCodes,
952 IDirectDraw2Impl_GetGDISurface,
953 IDirectDraw2Impl_GetMonitorFrequency,
954 IDirectDraw2Impl_GetScanLine,
955 IDirectDraw2Impl_GetVerticalBlankStatus,
956 IDirectDraw2Impl_Initialize,
957 IDirectDraw2Impl_RestoreDisplayMode,
958 Xlib_IDirectDraw2Impl_SetCooperativeLevel,
959 Xlib_IDirectDraw2Impl_SetDisplayMode,
960 IDirectDraw2Impl_WaitForVerticalBlank,
961 Xlib_IDirectDraw2Impl_GetAvailableVidMem
964 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
965 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
967 # define XCAST(fun) (void*)
970 ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
971 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
972 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
973 XCAST(AddRef)IDirectDraw2Impl_AddRef,
974 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
975 XCAST(Compact)IDirectDraw2Impl_Compact,
976 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
977 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
978 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
979 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
980 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
981 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
982 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
983 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
984 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
985 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
986 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
987 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
988 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
989 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
990 XCAST(Initialize)IDirectDraw2Impl_Initialize,
991 XCAST(RestoreDisplayMode)IDirectDraw2Impl_RestoreDisplayMode,
992 XCAST(SetCooperativeLevel)Xlib_IDirectDraw2Impl_SetCooperativeLevel,
993 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
994 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
995 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
996 IDirectDraw4Impl_GetSurfaceFromDC,
997 IDirectDraw4Impl_RestoreAllSurfaces,
998 IDirectDraw4Impl_TestCooperativeLevel,
999 IDirectDraw4Impl_GetDeviceIdentifier