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_OPENGL */
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 /* DO NOT AddRef the surface! Lock/Unlock are NOT guaranteed to come in
90 * matched pairs! - Marcus Meissner 20000509 */
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 /* DO NOT Release the surface! Lock/Unlock are NOT guaranteed to come in
197 * matched pairs! - Marcus Meissner 20000509 */
201 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
202 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
204 ICOM_THIS(IDirectDrawSurface4Impl,iface);
206 DDPRIVATE(This->s.ddraw);
208 x11_ds_private *fspriv;
210 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
212 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
213 if (!This->s.ddraw->d.paintable)
216 iflipto = _common_find_flipto(This,iflipto);
217 fspriv = (x11_ds_private*)iflipto->private;
219 /* We need to switch the lowlevel surfaces, for xlib this is: */
220 /* The surface pointer */
221 surf = This->s.surface_desc.u1.lpSurface;
222 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
223 iflipto->s.surface_desc.u1.lpSurface = surf;
225 /* the associated ximage */
226 image = dspriv->image;
227 dspriv->image = fspriv->image;
228 fspriv->image = image;
231 if (ddpriv->xshm_active) {
233 int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
234 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
236 X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
239 Xlib_copy_surface_on_screen(This);
240 if (iflipto->s.palette) {
241 DPPRIVATE(iflipto->s.palette);
243 TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
248 /* The IDirectDrawSurface4::SetPalette method attaches the specified
249 * DirectDrawPalette object to a surface. The surface uses this palette for all
250 * subsequent operations. The palette change takes place immediately.
252 HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
253 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
255 ICOM_THIS(IDirectDrawSurface4Impl,iface);
256 DDPRIVATE(This->s.ddraw);
257 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
258 x11_dp_private *dppriv;
261 TRACE("(%p)->(%p)\n",This,ipal);
264 if( This->s.palette != NULL )
265 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
266 This->s.palette = ipal;
269 dppriv = (x11_dp_private*)ipal->private;
272 (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8)
274 dppriv->cm = TSXCreateColormap(
277 DefaultVisualOfScreen(X11DRV_GetXScreen()),
280 if (!Options.managed)
281 TSXInstallColormap(display,dppriv->cm);
283 for (i=0;i<256;i++) {
286 xc.red = ipal->palents[i].peRed<<8;
287 xc.blue = ipal->palents[i].peBlue<<8;
288 xc.green = ipal->palents[i].peGreen<<8;
289 xc.flags = DoRed|DoBlue|DoGreen;
291 TSXStoreColor(display,dppriv->cm,&xc);
293 TSXInstallColormap(display,dppriv->cm);
295 /* According to spec, we are only supposed to
296 * AddRef if this is not the same palette.
298 if ( This->s.palette != ipal ) {
300 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
301 if( This->s.palette != NULL )
302 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
303 This->s.palette = ipal;
304 /* Perform the refresh */
305 TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
310 ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
311 ICOM_THIS(IDirectDrawSurface4Impl,iface);
313 DDPRIVATE(This->s.ddraw);
315 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
319 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
321 if (dspriv->image != NULL) {
322 if (This->s.ddraw->d.pixel_convert != NULL) {
323 /* In pixel conversion mode, there are 2 buffers to release. */
324 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
327 if (ddpriv->xshm_active) {
328 TSXShmDetach(display, &(dspriv->shminfo));
329 TSXDestroyImage(dspriv->image);
330 shmdt(dspriv->shminfo.shmaddr);
334 HeapFree(GetProcessHeap(),0,dspriv->image->data);
335 dspriv->image->data = NULL;
336 TSXDestroyImage(dspriv->image);
339 dspriv->image->data = NULL;
342 if (ddpriv->xshm_active) {
343 TSXShmDetach(display, &(dspriv->shminfo));
344 TSXDestroyImage(dspriv->image);
345 shmdt(dspriv->shminfo.shmaddr);
349 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
350 TSXDestroyImage(dspriv->image);
355 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
358 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
360 /* Free the DIBSection (if any) */
361 if (This->s.hdc != 0) {
362 SelectObject(This->s.hdc, This->s.holdbitmap);
363 DeleteDC(This->s.hdc);
364 DeleteObject(This->s.DIBsection);
367 /* Free the clipper if present */
368 if(This->s.lpClipper)
369 IDirectDrawClipper_Release(This->s.lpClipper);
370 HeapFree(GetProcessHeap(),0,This->private);
371 HeapFree(GetProcessHeap(),0,This);
375 ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
378 Xlib_IDirectDrawSurface4Impl_QueryInterface,
379 IDirectDrawSurface4Impl_AddRef,
380 Xlib_IDirectDrawSurface4Impl_Release,
381 IDirectDrawSurface4Impl_AddAttachedSurface,
382 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
383 IDirectDrawSurface4Impl_Blt,
384 IDirectDrawSurface4Impl_BltBatch,
385 IDirectDrawSurface4Impl_BltFast,
386 IDirectDrawSurface4Impl_DeleteAttachedSurface,
387 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
388 IDirectDrawSurface4Impl_EnumOverlayZOrders,
389 Xlib_IDirectDrawSurface4Impl_Flip,
390 IDirectDrawSurface4Impl_GetAttachedSurface,
391 IDirectDrawSurface4Impl_GetBltStatus,
392 IDirectDrawSurface4Impl_GetCaps,
393 IDirectDrawSurface4Impl_GetClipper,
394 IDirectDrawSurface4Impl_GetColorKey,
395 IDirectDrawSurface4Impl_GetDC,
396 IDirectDrawSurface4Impl_GetFlipStatus,
397 IDirectDrawSurface4Impl_GetOverlayPosition,
398 IDirectDrawSurface4Impl_GetPalette,
399 IDirectDrawSurface4Impl_GetPixelFormat,
400 IDirectDrawSurface4Impl_GetSurfaceDesc,
401 IDirectDrawSurface4Impl_Initialize,
402 IDirectDrawSurface4Impl_IsLost,
403 Xlib_IDirectDrawSurface4Impl_Lock,
404 IDirectDrawSurface4Impl_ReleaseDC,
405 IDirectDrawSurface4Impl_Restore,
406 IDirectDrawSurface4Impl_SetClipper,
407 IDirectDrawSurface4Impl_SetColorKey,
408 IDirectDrawSurface4Impl_SetOverlayPosition,
409 Xlib_IDirectDrawSurface4Impl_SetPalette,
410 Xlib_IDirectDrawSurface4Impl_Unlock,
411 IDirectDrawSurface4Impl_UpdateOverlay,
412 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
413 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
414 IDirectDrawSurface4Impl_GetDDInterface,
415 IDirectDrawSurface4Impl_PageLock,
416 IDirectDrawSurface4Impl_PageUnlock,
417 IDirectDrawSurface4Impl_SetSurfaceDesc,
418 IDirectDrawSurface4Impl_SetPrivateData,
419 IDirectDrawSurface4Impl_GetPrivateData,
420 IDirectDrawSurface4Impl_FreePrivateData,
421 IDirectDrawSurface4Impl_GetUniquenessValue,
422 IDirectDrawSurface4Impl_ChangeUniquenessValue