Index: client.c =================================================================== RCS file: /home/wine/wine/tools/widl/client.c,v retrieving revision 1.63 diff -u -r1.63 client.c --- client.c 12 Dec 2007 15:30:54 -0000 1.63 +++ client.c 18 Jan 2008 23:11:46 -0000 @@ -268,6 +268,80 @@ } +typedef struct +{ + struct list link; + char *type_name; +} bindingpair_type; + +static int write_client_genericbindingpairs(type_t *iface) +{ + bindingpair_type *btype; + bindingpair_type *current, *next; + struct list genericbindingpairs = LIST_INIT(genericbindingpairs); + const func_t *func; + const var_t *arg; + int found, count = 0; + + if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) + { + if (func->args) LIST_FOR_EACH_ENTRY( arg, func->args, const var_t, entry ) { + + if (is_attr(arg->type->attrs, ATTR_HANDLE)) + { + found = 0; + + /* see if this handle type has already been found */ + LIST_FOR_EACH_ENTRY_SAFE(current, next, &genericbindingpairs, bindingpair_type, link) { + if (!strcmp(current->type_name, arg->type->name)) + { + found = 1; + break; + } + } + + if (!found) + { + btype = xmalloc(sizeof(*btype)); + btype->type_name = xmalloc(strlen(arg->type->name) + 1); + strcpy(btype->type_name, arg->type->name); + list_add_tail(&genericbindingpairs, &btype->link); + } + } + } + } + + LIST_FOR_EACH_ENTRY_SAFE(current, next, &genericbindingpairs, bindingpair_type, link) { + + if (++count == 1) + { + print_client("static const GENERIC_BINDING_ROUTINE_PAIR %s___BindingRoutines[] = {\n", iface->name); + indent++; + } + + print_client("{\n"); + indent++; + print_client("(GENERIC_BINDING_ROUTINE)%s_bind,\n", current->type_name); + print_client("(GENERIC_UNBIND_ROUTINE)%s_unbind\n", current->type_name); + indent--; + print_client("},\n"); + + /* free */ + list_remove(¤t->link); + free(current->type_name); + free(current); + } + + if (count) + { + indent--; + print_client("}\n"); + } + + return count; +} + + static void write_stubdescdecl(type_t *iface) { print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); @@ -278,6 +352,9 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines) { const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int generic_binding_pairs; + + generic_binding_pairs = write_client_genericbindingpairs(iface); print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); print_client("{\n"); @@ -294,7 +371,10 @@ indent--; print_client("},\n"); print_client("0,\n"); - print_client("0,\n"); + if (generic_binding_pairs) + print_client("%s___BindingRoutines,\n", iface->name); + else + print_client("0,\n"); if (expr_eval_routines) print_client("ExprEvalRoutines,\n"); else