PATCH: Enhance ddraw COM management (resubmitting)

Christian Costa titan.costa at wanadoo.fr
Sun Nov 10 08:44:44 CST 2002


This is a resubmit of my previous patch.

This time, I've fixed the conflict with the ICOM_THIS_MULTI
macro from obj_base.h by using ICOM_THIS_OBJECT instead.
To make the patch smaller, I've only focused on the ddraw COM infrastructure
and changed some references to the ICOM_OBJECT macro that was needed.

I've also a small doc that explains how to implement objects
with multiple interfaces using the macros define in ddcomimpl.h.
I will submit it later when it's finished.

Modified files :
dlls/ddraw/ddcomimpl.h
dlls/ddraw/dclipper/main.c
dlls/ddraw/ddraw/main.c
dlls/ddraw/dpalette/main.c
dlls/ddraw/durface/dib.c
dlls/ddraw/durface/main.c

Changelog :
Enhance ddraw COM macros by adding a pointer to the object itself after 
each VTable.

-------------- next part --------------
Index: ddcomimpl.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddcomimpl.h,v
retrieving revision 1.2
diff -u -r1.2 ddcomimpl.h
--- ddcomimpl.h	9 Mar 2002 23:29:35 -0000	1.2
+++ ddcomimpl.h	10 Nov 2002 14:25:38 -0000
@@ -17,37 +17,53 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _DDCOMIMPL_H_
+#define _DDCOMIMPL_H_
+
 #include <stddef.h>
 
+#define INTERFACE(iface) \
+        struct { \
+		 iface interface; \
+		 LPVOID object; \
+	       }
+
+typedef INTERFACE(LPVOID) Interface;
+
 /* Generates the name for a vtable pointer for a given interface. */
 /* The canonical name for a single interface is "lpVtbl". */
 #define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface
 #define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)
 
-/* Declares a vtable pointer field in an implementation. */
+/* Declares an interface in an implementation. */
 #define ICOM_VFIELD_MULTI(iface) \
-	iface ICOM_VFIELD_MULTI_NAME(iface)
-
-/* Returns the offset of a vtable pointer within an implementation object. */
-#define ICOM_VFIELD_OFFSET(impltype, iface) \
-	offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))
+	INTERFACE(iface) ICOM_VFIELD_MULTI_NAME(iface)
 
 /* Given an interface pointer, returns the implementation pointer. */
-#define ICOM_OBJECT(impltype, ifacename, ifaceptr)		\
-	(impltype*)((ifaceptr) == NULL ? NULL			\
-		  : (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))
+#define ICOM_OBJECT(impltype, ifaceptr) \
+        (impltype*)(((LPVOID)ifaceptr) == NULL ? NULL \
+		    : ((Interface*)(ifaceptr))->object)
+
+#define ICOM_THIS_OBJECT(impltype, ifaceptr) \
+	impltype* This = ICOM_OBJECT(impltype, ifaceptr)
 
+/* Same as ICOM_THIS_OBJECT but compatible with current DDRAW code */
 #define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \
-	impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)
+	impltype* This = ICOM_OBJECT(impltype, ifaceptr)
 
 /* Given an object and interface name, returns a pointer to that interface. */
 #define ICOM_INTERFACE(implobj, iface) \
-	(&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
+	(&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)).interface)
 
+/* Initialize an object's interface */
 #define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
 	do { \
-	  (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \
+	  (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).interface.lpVtbl = &(vtblname); \
+          (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).object = implobj; \
 	} while (0)
 
-#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr)	\
-	ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
+#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr) \
+	ICOM_INTERFACE(ICOM_OBJECT(impltype, ifaceptr), ifnameto)
+	
+#endif /* _DDCOMIMPL_H_ */
+
Index: dclipper/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dclipper/main.c,v
retrieving revision 1.8
diff -u -r1.8 main.c
--- dclipper/main.c	31 May 2002 23:25:45 -0000	1.8
+++ dclipper/main.c	10 Nov 2002 14:25:39 -0000
@@ -184,7 +184,7 @@
 
     if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
 
-    pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
+    pOwner = ICOM_OBJECT(IDirectDrawImpl, lpDD);
     This->ddraw_owner = pOwner;
     Main_DirectDraw_AddClipper(pOwner, This);
 
Index: ddraw/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddraw/main.c,v
retrieving revision 1.25
diff -u -r1.25 main.c
--- ddraw/main.c	18 Oct 2002 23:48:59 -0000	1.25
+++ ddraw/main.c	10 Nov 2002 14:25:41 -0000
@@ -414,8 +414,7 @@
 	ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE
 				 | DDSCAPS_BACKBUFFER);
 
-	primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7,
-			      *ppSurf);
+	primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,*ppSurf);
 	pPrev = *ppSurf;
 	IDirectDrawSurface7_AddRef(pPrev);
 
@@ -560,8 +559,7 @@
 {
     ICOM_THIS(IDirectDrawImpl,iface);
 
-    IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, src);
+    IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl, src);
 
     TRACE("(%p)->(%p,%p)\n",This,src,dst);
 
Index: dpalette/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dpalette/main.c,v
retrieving revision 1.7
diff -u -r1.7 main.c
--- dpalette/main.c	10 Jul 2002 03:05:43 -0000	1.7
+++ dpalette/main.c	10 Nov 2002 14:25:42 -0000
@@ -162,8 +162,7 @@
 	    LPDIRECTDRAWSURFACE7 psurf = NULL;
 	    IDirectDraw7_GetGDISurface(ICOM_INTERFACE(This->ddraw_owner,IDirectDraw7), &psurf);
 	    if (psurf) {
-		IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-							   IDirectDrawSurface7, psurf);
+		IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, psurf);
 		surf->update_palette(surf, This, dwStart, dwCount, palent);
 		IDirectDrawSurface7_Release(psurf);
 	    }
Index: dsurface/dib.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/dib.c,v
retrieving revision 1.18
diff -u -r1.18 dib.c
--- dsurface/dib.c	6 Nov 2002 19:53:45 -0000	1.18
+++ dsurface/dib.c	10 Nov 2002 14:25:46 -0000
@@ -1038,8 +1038,7 @@
 							    &back_caps, &tgt);
 	if (!FAILED(hr))
 	{
-	    IDirectDrawSurfaceImpl* target = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-							 IDirectDrawSurface7,tgt);
+	    IDirectDrawSurfaceImpl* target = ICOM_OBJECT(IDirectDrawSurfaceImpl, tgt);
 	    IDirectDrawSurface7_Release(tgt);
 	    target->get_dc(target, &dc);
 	    SetDIBColorTable(dc, dwStart, dwCount, col);
Index: dsurface/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.c,v
retrieving revision 1.32
diff -u -r1.32 main.c
--- dsurface/main.c	4 Nov 2002 22:34:11 -0000	1.32
+++ dsurface/main.c	10 Nov 2002 14:25:46 -0000
@@ -288,8 +288,7 @@
 					  LPDIRECTDRAWSURFACE7 pAttach)
 {
     ICOM_THIS(IDirectDrawSurfaceImpl, iface);
-    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, pAttach);
+    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, pAttach);
 
     TRACE("(%p)->(%p)\n",This,pAttach);
 
@@ -385,8 +384,7 @@
 					     LPDIRECTDRAWSURFACE7 pAttach)
 {
     ICOM_THIS(IDirectDrawSurfaceImpl, iface);
-    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl,
-					       IDirectDrawSurface7, pAttach);
+    IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, pAttach);
 
     TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach);
 
@@ -508,8 +506,7 @@
 	hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt);
 	if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */
 
-	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-			     tgt);
+	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, tgt);
 	IDirectDrawSurface7_Release(tgt);
     }
     else
@@ -523,8 +520,7 @@
 	/* Verify that override is on this flip chain. We assume that
 	 * surf is the head of the flipping chain, because it's the front
 	 * buffer. */
-	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,
-			     override);
+	target = ICOM_OBJECT(IDirectDrawSurfaceImpl, override);
 
 	/* Either target is (indirectly) attached to This or This is
 	 * (indirectly) attached to target. */
@@ -1052,8 +1048,7 @@
 	IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper,
 						  IDirectDrawClipper));
 
-    This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper,
-				pDDClipper);
+    This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, pDDClipper);
     if (pDDClipper != NULL)
 	IDirectDrawClipper_AddRef(pDDClipper);
 
@@ -1135,8 +1130,7 @@
 						  IDirectDrawPalette));
     }
 
-    This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette,
-				pPalette);
+    This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, pPalette);
     if (pPalette != NULL) {
 	IDirectDrawPalette_AddRef(pPalette);
 	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)


More information about the wine-patches mailing list