widl #11: support interface ptrs

Huw D M Davies h.davies1 at physics.ox.ac.uk
Fri Jan 14 09:22:03 CST 2005


        Huw Davies <huw at codeweavers.com>
        Add support for interface ptrs including the special cases for
        IUnknown and IDispatch.
-- 
Huw Davies
huw at codeweavers.com
Index: tools/widl/typelib.c
===================================================================
RCS file: /home/wine/wine/tools/widl/typelib.c,v
retrieving revision 1.6
diff -u -p -r1.6 typelib.c
--- tools/widl/typelib.c	12 Jan 2005 19:28:59 -0000	1.6
+++ tools/widl/typelib.c	14 Jan 2005 15:20:37 -0000
@@ -132,19 +132,18 @@ unsigned short get_type_vt(type_t *t)
   case RPC_FC_UP:
   case RPC_FC_OP:
   case RPC_FC_FP:
-    /* it's a pointer... */
-    if (t->ref && t->ref->type == RPC_FC_IP) {
-      /* it's to an interface, which one? */
-      if (match(t->ref->name, "IDispatch"))
-        return VT_DISPATCH;
-      if (match(t->ref->name, "IUnknown"))
-        return VT_UNKNOWN;
-    }
     if(t->ref)
       return VT_PTR;
 
     error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
     break;
+  case RPC_FC_IP:
+    if(match(t->name, "IUnknown"))
+      return VT_UNKNOWN;
+    if(match(t->name, "IDispatch"))
+      return VT_DISPATCH;
+    return VT_USERDEFINED;
+        
   case RPC_FC_STRUCT:
     return VT_USERDEFINED;
   case 0:
Index: tools/widl/write_msft.c
===================================================================
RCS file: /home/wine/wine/tools/widl/write_msft.c,v
retrieving revision 1.7
diff -u -p -r1.7 write_msft.c
--- tools/widl/write_msft.c	12 Jan 2005 19:28:59 -0000	1.7
+++ tools/widl/write_msft.c	14 Jan 2005 15:20:37 -0000
@@ -745,6 +745,13 @@ static int encode_type(
 	*alignment = 1;
 	break;
 
+    case VT_UNKNOWN:
+    case VT_DISPATCH:
+        *encoded_type = default_type;
+        *width = 4;
+        *alignment = 4;
+        break;
+
     case VT_PTR:
       {
         int next_vt;
@@ -754,6 +761,14 @@ static int encode_type(
         }
 
 	encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size);
+        if(type->ref->type == RPC_FC_IP) {
+            chat("encode_type: skipping ptr\n");
+            *encoded_type = target_type;
+            *width = 4;
+            *alignment = 4;
+            *decoded_size = child_size;
+            break;
+        }
 
 	for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
 	    typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@@ -828,11 +843,10 @@ static int encode_type(
     case VT_USERDEFINED:
       {
         int typeinfo_offset;
-	chat("USERDEFINED.\n");
-        chat("type %p name = %s idx %d\n", type, type->name, type->typelib_idx);
+        chat("encode_type: VT_USERDEFINED - type %p name = %s idx %d\n", type, type->name, type->typelib_idx);
 
         if(type->typelib_idx == -1)
-            error("trying to ref not added type\n");
+            error("encode_type: trying to ref not added type\n");
 
         typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
 	for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
@@ -851,11 +865,23 @@ static int encode_type(
 	*encoded_type = typeoffset;
 	*width = 0;
 	*alignment = 1;
+
+        if(type->type == RPC_FC_IP) {
+            typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
+	    typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
+
+	    typedata[0] = (0x7fff << 16) | VT_PTR;
+	    typedata[1] = *encoded_type;
+            *encoded_type = typeoffset;
+            *width = 4;
+            *alignment = 4;
+            *decoded_size += 8;
+        }            
 	break;
       }
 
     default:
-	error("Unrecognized type %d.\n", vt);
+	error("encode_type: unrecognized type %d.\n", vt);
 	*encoded_type = default_type;
 	*width = 0;
 	*alignment = 1;
@@ -894,9 +920,19 @@ static int encode_var(
 
     chat("encode_var: var %p var->tname %s var->type %p var->ptr_level %d var->type->ref %p\n", var, var->tname, var->type, var->ptr_level, var->type->ref);
     if(var->ptr_level--) {
-	encode_var(typelib, var, &target_type, NULL, NULL, &child_size);
+        int skip_ptr;
+	skip_ptr = encode_var(typelib, var, &target_type, NULL, NULL, &child_size);
         var->ptr_level++;
 
+        if(skip_ptr == 2) {
+            chat("encode_var: skipping ptr\n");
+            *encoded_type = target_type;
+            *decoded_size = child_size;
+            *width = 4;
+            *alignment = 4;
+            return 0;
+        }
+
 	for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
 	    typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
 	    if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break;
@@ -978,7 +1014,9 @@ static int encode_var(
         if(!type) error("encode_var: type->ref is null\n");
         vt = get_type_vt(type);
     }
-    return encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
+    encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
+    if(type->type == RPC_FC_IP) return 2;
+    return 0;
 }
 
     



More information about the wine-patches mailing list