1 /* DirectDrawSurface Xlib implementation
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
17 #include "debugtools.h"
18 #include "x11_private.h"
21 /* for d3d texture stuff */
22 # include "mesa_private.h"
25 DEFAULT_DEBUG_CHANNEL(ddraw);
27 #define VISIBLE(x) (SDDSCAPS(x) & (DDSCAPS_VISIBLE|DDSCAPS_PRIMARYSURFACE))
29 #define DDPRIVATE(x) x11_dd_private *ddpriv = ((x11_dd_private*)(x)->private)
30 #define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
31 #define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
33 /******************************************************************************
34 * IDirectDrawSurface methods
36 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
37 * DDS and DDS2 use those functions. (Function calls did not change (except
38 * using different DirectDrawSurfaceX version), just added flags and functions)
40 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_QueryInterface(
41 LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
43 ICOM_THIS(IDirectDrawSurface4Impl,iface);
45 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
47 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
48 * the same interface. And IUnknown does that too of course.
50 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
51 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
52 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
53 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
54 IsEqualGUID( &IID_IUnknown, refiid )
57 IDirectDrawSurface4_AddRef(iface);
59 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
63 if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) ) {
64 /* Texture interface */
65 *obj = d3dtexture2_create(This);
66 IDirectDrawSurface4_AddRef(iface);
67 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
70 if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) ) {
71 /* Texture interface */
72 *obj = d3dtexture_create(This);
73 IDirectDrawSurface4_AddRef(iface);
74 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
77 #endif /* HAVE_MESAGL */
78 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
79 return OLE_E_ENUM_NOMORE;
82 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
83 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
85 ICOM_THIS(IDirectDrawSurface4Impl,iface);
87 DDPRIVATE(This->s.ddraw);
89 IDirectDrawSurface4_AddRef(iface);
91 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",This,lprect,lpddsd,flags,(DWORD)hnd);
92 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
93 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
94 This,lprect,lpddsd,flags,(DWORD)hnd);
96 /* First, copy the Surface description */
97 *lpddsd = This->s.surface_desc;
98 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
99 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
101 /* If asked only for a part, change the surface pointer */
103 TRACE(" lprect: %dx%d-%dx%d\n",
104 lprect->top,lprect->left,lprect->bottom,lprect->right
106 if ((lprect->top < 0) ||
107 (lprect->left < 0) ||
108 (lprect->bottom < 0) ||
109 (lprect->right < 0)) {
110 ERR(" Negative values in LPRECT !!!\n");
111 IDirectDrawSurface4_Release(iface);
112 return DDERR_INVALIDPARAMS;
114 lpddsd->u1.lpSurface=(LPVOID)((char*)This->s.surface_desc.u1.lpSurface+
115 (lprect->top*This->s.surface_desc.lPitch) +
116 lprect->left*GET_BPP(This->s.surface_desc));
118 assert(This->s.surface_desc.u1.lpSurface);
119 /* wait for any previous operations to complete */
121 if (dspriv->image && VISIBLE(This) && ddpriv->xshm_active) {
123 int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
124 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
126 X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
132 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
134 DDPRIVATE(This->s.ddraw);
135 if (This->s.ddraw->d.pixel_convert != NULL)
136 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
138 This->s.surface_desc.dwWidth,
139 This->s.surface_desc.dwHeight,
140 This->s.surface_desc.lPitch,
144 if (ddpriv->xshm_active) {
146 X11DRV_EVENT_WaitReplaceShmCompletion( &(ddpriv->xshm_compl), This->s.ddraw->d.drawable );
148 /* let WaitShmCompletions track 'em for now */
149 /* (you may want to track it again whenever you implement DX7's partial
150 * surface locking, where threads have concurrent access) */
151 X11DRV_EVENT_PrepareShmCompletion( ddpriv->drawable );
152 TSXShmPutImage(display,
154 DefaultGCOfScreen(X11DRV_GetXScreen()),
157 dspriv->image->width,
158 dspriv->image->height,
161 /* make sure the image is transferred ASAP */
168 DefaultGCOfScreen(X11DRV_GetXScreen()),
171 dspriv->image->width,
172 dspriv->image->height
176 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
177 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
179 ICOM_THIS(IDirectDrawSurface4Impl,iface);
180 DDPRIVATE(This->s.ddraw);
182 TRACE("(%p)->Unlock(%p)\n",This,surface);
184 /*if (!This->s.ddraw->d.paintable)
187 /* Only redraw the screen when unlocking the buffer that is on screen */
188 if (dspriv->image && VISIBLE(This)) {
189 Xlib_copy_surface_on_screen(This);
190 if (This->s.palette) {
191 DPPRIVATE(This->s.palette);
193 TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
196 IDirectDrawSurface4_Release(iface);
200 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
201 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
203 ICOM_THIS(IDirectDrawSurface4Impl,iface);
205 DDPRIVATE(This->s.ddraw);
207 x11_ds_private *fspriv;
209 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
211 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
212 if (!This->s.ddraw->d.paintable)
215 iflipto = _common_find_flipto(This,iflipto);
216 fspriv = (x11_ds_private*)iflipto->private;
218 /* We need to switch the lowlevel surfaces, for xlib this is: */
219 /* The surface pointer */
220 surf = This->s.surface_desc.u1.lpSurface;
221 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
222 iflipto->s.surface_desc.u1.lpSurface = surf;
224 /* the associated ximage */
225 image = dspriv->image;
226 dspriv->image = fspriv->image;
227 fspriv->image = image;
230 if (ddpriv->xshm_active) {
232 int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
233 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
235 X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
238 Xlib_copy_surface_on_screen(This);
239 if (iflipto->s.palette) {
240 DPPRIVATE(iflipto->s.palette);
242 TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
247 /* The IDirectDrawSurface4::SetPalette method attaches the specified
248 * DirectDrawPalette object to a surface. The surface uses this palette for all
249 * subsequent operations. The palette change takes place immediately.
251 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
252 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
254 ICOM_THIS(IDirectDrawSurface4Impl,iface);
255 DDPRIVATE(This->s.ddraw);
256 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
257 x11_dp_private *dppriv;
260 TRACE("(%p)->(%p)\n",This,ipal);
263 if( This->s.palette != NULL )
264 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
265 This->s.palette = ipal;
268 dppriv = (x11_dp_private*)ipal->private;
271 (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8)
273 dppriv->cm = TSXCreateColormap(
276 DefaultVisualOfScreen(X11DRV_GetXScreen()),
279 if (!Options.managed)
280 TSXInstallColormap(display,dppriv->cm);
282 for (i=0;i<256;i++) {
285 xc.red = ipal->palents[i].peRed<<8;
286 xc.blue = ipal->palents[i].peBlue<<8;
287 xc.green = ipal->palents[i].peGreen<<8;
288 xc.flags = DoRed|DoBlue|DoGreen;
290 TSXStoreColor(display,dppriv->cm,&xc);
292 TSXInstallColormap(display,dppriv->cm);
294 /* According to spec, we are only supposed to
295 * AddRef if this is not the same palette.
297 if ( This->s.palette != ipal ) {
299 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
300 if( This->s.palette != NULL )
301 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
302 This->s.palette = ipal;
303 /* Perform the refresh */
304 TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
309 ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
310 ICOM_THIS(IDirectDrawSurface4Impl,iface);
312 DDPRIVATE(This->s.ddraw);
314 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
318 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
320 if (dspriv->image != NULL) {
321 if (This->s.ddraw->d.pixel_convert != NULL) {
322 /* In pixel conversion mode, there are 2 buffers to release. */
323 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
326 if (ddpriv->xshm_active) {
327 TSXShmDetach(display, &(dspriv->shminfo));
328 TSXDestroyImage(dspriv->image);
329 shmdt(dspriv->shminfo.shmaddr);
333 HeapFree(GetProcessHeap(),0,dspriv->image->data);
334 dspriv->image->data = NULL;
335 TSXDestroyImage(dspriv->image);
338 dspriv->image->data = NULL;
341 if (ddpriv->xshm_active) {
342 TSXShmDetach(display, &(dspriv->shminfo));
343 TSXDestroyImage(dspriv->image);
344 shmdt(dspriv->shminfo.shmaddr);
348 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
349 TSXDestroyImage(dspriv->image);
354 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
357 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
359 /* Free the DIBSection (if any) */
360 if (This->s.hdc != 0) {
361 SelectObject(This->s.hdc, This->s.holdbitmap);
362 DeleteDC(This->s.hdc);
363 DeleteObject(This->s.DIBsection);
366 /* Free the clipper if present */
367 if(This->s.lpClipper)
368 IDirectDrawClipper_Release(This->s.lpClipper);
369 HeapFree(GetProcessHeap(),0,This->private);
370 HeapFree(GetProcessHeap(),0,This);
374 ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
376 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
377 Xlib_IDirectDrawSurface4Impl_QueryInterface,
378 IDirectDrawSurface4Impl_AddRef,
379 Xlib_IDirectDrawSurface4Impl_Release,
380 IDirectDrawSurface4Impl_AddAttachedSurface,
381 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
382 IDirectDrawSurface4Impl_Blt,
383 IDirectDrawSurface4Impl_BltBatch,
384 IDirectDrawSurface4Impl_BltFast,
385 IDirectDrawSurface4Impl_DeleteAttachedSurface,
386 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
387 IDirectDrawSurface4Impl_EnumOverlayZOrders,
388 Xlib_IDirectDrawSurface4Impl_Flip,
389 IDirectDrawSurface4Impl_GetAttachedSurface,
390 IDirectDrawSurface4Impl_GetBltStatus,
391 IDirectDrawSurface4Impl_GetCaps,
392 IDirectDrawSurface4Impl_GetClipper,
393 IDirectDrawSurface4Impl_GetColorKey,
394 IDirectDrawSurface4Impl_GetDC,
395 IDirectDrawSurface4Impl_GetFlipStatus,
396 IDirectDrawSurface4Impl_GetOverlayPosition,
397 IDirectDrawSurface4Impl_GetPalette,
398 IDirectDrawSurface4Impl_GetPixelFormat,
399 IDirectDrawSurface4Impl_GetSurfaceDesc,
400 IDirectDrawSurface4Impl_Initialize,
401 IDirectDrawSurface4Impl_IsLost,
402 Xlib_IDirectDrawSurface4Impl_Lock,
403 IDirectDrawSurface4Impl_ReleaseDC,
404 IDirectDrawSurface4Impl_Restore,
405 IDirectDrawSurface4Impl_SetClipper,
406 IDirectDrawSurface4Impl_SetColorKey,
407 IDirectDrawSurface4Impl_SetOverlayPosition,
408 Xlib_IDirectDrawSurface4Impl_SetPalette,
409 Xlib_IDirectDrawSurface4Impl_Unlock,
410 IDirectDrawSurface4Impl_UpdateOverlay,
411 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
412 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
413 IDirectDrawSurface4Impl_GetDDInterface,
414 IDirectDrawSurface4Impl_PageLock,
415 IDirectDrawSurface4Impl_PageUnlock,
416 IDirectDrawSurface4Impl_SetSurfaceDesc,
417 IDirectDrawSurface4Impl_SetPrivateData,
418 IDirectDrawSurface4Impl_GetPrivateData,
419 IDirectDrawSurface4Impl_FreePrivateData,
420 IDirectDrawSurface4Impl_GetUniquenessValue,
421 IDirectDrawSurface4Impl_ChangeUniquenessValue