From fabfa59aea5c5b3201142382038beb3e76cb7567 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 5 Sep 2014 17:33:03 +0200 Subject: [PATCH] widl: Handle aggregate returns in a MSVC compatible way. Aggregates are returned through an implicit parameter after the this/interface pointer. Note that this follows the C++ convention, affected methods are not callable from C with the Microsoft headers. --- dlls/d2d1/brush.c | 25 ++++++++++++++----------- dlls/d2d1/render_target.c | 25 ++++++++++++++----------- tools/widl/header.c | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index d8b769b6c9d..ed92d6060a3 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -227,13 +227,14 @@ static void STDMETHODCALLTYPE d2d_solid_color_brush_SetColor(ID2D1SolidColorBrus FIXME("iface %p, color %p stub!\n", iface, color); } -static D2D1_COLOR_F STDMETHODCALLTYPE d2d_solid_color_brush_GetColor(ID2D1SolidColorBrush *iface) +static D2D1_COLOR_F * STDMETHODCALLTYPE d2d_solid_color_brush_GetColor(ID2D1SolidColorBrush *iface, D2D1_COLOR_F *color) { static const D2D1_COLOR_F black = {0.0f, 0.0f, 0.0f, 1.0f}; - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, color %p stub!\n", iface, color); - return black; + *color = black; + return color; } static const struct ID2D1SolidColorBrushVtbl d2d_solid_color_brush_vtbl = @@ -360,21 +361,23 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearG FIXME("iface %p, end_point {%.8e, %.8e} stub!\n", iface, end_point.x, end_point.y); } -static D2D1_POINT_2F STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush *iface) +static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush *iface, + D2D1_POINT_2F *point) { - static const D2D1_POINT_2F point = {0.0f, 0.0f}; - - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, point %p stub!\n", iface, point); + point->x = 0.0f; + point->y = 0.0f; return point; } -static D2D1_POINT_2F STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush *iface) +static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush *iface, + D2D1_POINT_2F *point) { - static const D2D1_POINT_2F point = {0.0f, 0.0f}; - - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, point %p stub!\n", iface, point); + point->x = 0.0f; + point->y = 0.0f; return point; } diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 864cd318a56..9664fde2d4b 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -450,12 +450,13 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget return S_OK; } -static D2D1_PIXEL_FORMAT STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface) +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface, + D2D1_PIXEL_FORMAT *format) { - static const D2D1_PIXEL_FORMAT format = {DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN}; - - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, format %p stub!\n", iface, format); + format->format = DXGI_FORMAT_UNKNOWN; + format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN; return format; } @@ -485,22 +486,24 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *if *dpi_y = render_target->dpi_y; } -static D2D1_SIZE_F STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface) +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size) { - static const D2D1_SIZE_F size = {0.0f, 0.0f}; - - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, size %p stub!\n", iface, size); + size->width = 0.0f; + size->height = 0.0f; return size; } -static D2D1_SIZE_U STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface) +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface, + D2D1_SIZE_U *pixel_size) { struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); - TRACE("iface %p.\n", iface); + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); - return render_target->pixel_size; + *pixel_size = render_target->pixel_size; + return pixel_size; } static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface) diff --git a/tools/widl/header.c b/tools/widl/header.c index 4f2222aab44..f0f0156dfa3 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -828,6 +828,13 @@ static int is_inherited_method(const type_t *iface, const var_t *func) return 0; } +static int is_aggregate_return(const var_t *func) +{ + enum type_type type = type_get_type(type_function_get_rettype(func->type)); + return type == TYPE_STRUCT || type == TYPE_UNION || + type == TYPE_COCLASS || type == TYPE_INTERFACE; +} + static void write_method_macro(FILE *header, const type_t *iface, const char *name) { const statement_t *stmt; @@ -846,7 +853,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const char *na first_iface = 0; } - if (!is_callas(func->attrs) && !is_inherited_method(iface, func)) { + if (!is_callas(func->attrs) && !is_inherited_method(iface, func) && + !is_aggregate_return(func)) { const var_t *arg; fprintf(header, "#define %s_%s(This", name, get_name(func)); @@ -947,12 +955,24 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const char fprintf(header, " %s_%s(", name, get_name(func)); write_args(header, type_get_function_args(func->type), name, 1, FALSE); fprintf(header, ") {\n"); - fprintf(header, " %s", is_void(type_function_get_rettype(func->type)) ? "" : "return "); - fprintf(header, "This->lpVtbl->%s(This", get_name(func)); + ++indentation; + if (!is_aggregate_return(func)) { + indent(header, 0); + fprintf(header, "%sThis->lpVtbl->%s(This", + is_void(type_function_get_rettype(func->type)) ? "" : "return ", + get_name(func)); + } else { + indent(header, 0); + write_type_decl_left(header, type_function_get_rettype(func->type)); + fprintf(header, " __ret;\n"); + indent(header, 0); + fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_name(func)); + } if (type_get_function_args(func->type)) LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) fprintf(header, ",%s", arg->name); fprintf(header, ");\n"); + --indentation; fprintf(header, "}\n"); } } @@ -979,11 +999,26 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char if (!callconv) callconv = "STDMETHODCALLTYPE"; indent(header, 0); write_type_decl_left(header, type_function_get_rettype(func->type)); + if (is_aggregate_return(func)) + fprintf(header, " *"); if (is_inherited_method(iface, func)) fprintf(header, " (%s *%s_%s)(\n", callconv, iface->name, func->name); else fprintf(header, " (%s *%s)(\n", callconv, get_name(func)); - write_args(header, type_get_function_args(func->type), name, 1, TRUE); + ++indentation; + indent(header, 0); + fprintf(header, "%s *This", name); + if (is_aggregate_return(func)) { + fprintf(header, ",\n"); + indent(header, 0); + write_type_decl_left(header, type_function_get_rettype(func->type)); + fprintf(header, " *__ret"); + } + --indentation; + if (type_get_function_args(func->type)) { + fprintf(header, ",\n"); + write_args(header, type_get_function_args(func->type), name, 0, TRUE); + } fprintf(header, ");\n"); fprintf(header, "\n"); } -- 2.11.4.GIT