This covers some of the assumptions made in the metadata generation code. More to come.
From: Hans Leidekker hans@codeweavers.com
WinRT doesn't allow propput without matching propget or with more than one parameter. --- dlls/windows.gaming.input/condition_effect.c | 2 +- dlls/windows.gaming.input/constant_effect.c | 4 ++-- dlls/windows.gaming.input/periodic_effect.c | 4 ++-- dlls/windows.gaming.input/provider.idl | 4 ++-- dlls/windows.gaming.input/ramp_effect.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/windows.gaming.input/condition_effect.c b/dlls/windows.gaming.input/condition_effect.c index c3a5a1fcd8b..24bd2b4d590 100644 --- a/dlls/windows.gaming.input/condition_effect.c +++ b/dlls/windows.gaming.input/condition_effect.c @@ -129,7 +129,7 @@ static HRESULT WINAPI effect_SetParameters( IConditionForceEffect *iface, Vector TRACE( "iface %p, direction %s, positive_coeff %f, negative_coeff %f, max_positive_magnitude %f, max_negative_magnitude %f, deadzone %f, bias %f.\n", iface, debugstr_vector3( &direction ), positive_coeff, negative_coeff, max_positive_magnitude, max_negative_magnitude, deadzone, bias );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); }
static const struct IConditionForceEffectVtbl effect_vtbl = diff --git a/dlls/windows.gaming.input/constant_effect.c b/dlls/windows.gaming.input/constant_effect.c index 15763b30d67..f4c65fba11e 100644 --- a/dlls/windows.gaming.input/constant_effect.c +++ b/dlls/windows.gaming.input/constant_effect.c @@ -114,7 +114,7 @@ static HRESULT WINAPI effect_SetParameters( IConstantForceEffect *iface, Vector3
TRACE( "iface %p, direction %s, duration %I64u.\n", iface, debugstr_vector3( &direction ), duration.Duration );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); }
static HRESULT WINAPI effect_SetParametersWithEnvelope( IConstantForceEffect *iface, Vector3 direction, FLOAT attack_gain, @@ -148,7 +148,7 @@ static HRESULT WINAPI effect_SetParametersWithEnvelope( IConstantForceEffect *if attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration, release_duration.Duration, repeat_count );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); }
static const struct IConstantForceEffectVtbl effect_vtbl = diff --git a/dlls/windows.gaming.input/periodic_effect.c b/dlls/windows.gaming.input/periodic_effect.c index 8633a8fb9b9..6c001a5ffc6 100644 --- a/dlls/windows.gaming.input/periodic_effect.c +++ b/dlls/windows.gaming.input/periodic_effect.c @@ -129,7 +129,7 @@ static HRESULT WINAPI effect_SetParameters( IPeriodicForceEffect *iface, Vector3 TRACE( "iface %p, direction %s, frequency %f, phase %f, bias %f, duration %I64u.\n", iface, debugstr_vector3( &direction ), frequency, phase, bias, duration.Duration );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); }
static HRESULT WINAPI effect_SetParametersWithEnvelope( IPeriodicForceEffect *iface, Vector3 direction, FLOAT frequency, FLOAT phase, FLOAT bias, @@ -166,7 +166,7 @@ static HRESULT WINAPI effect_SetParametersWithEnvelope( IPeriodicForceEffect *if frequency, phase, bias, attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration, release_duration.Duration, repeat_count );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); }
static const struct IPeriodicForceEffectVtbl effect_vtbl = diff --git a/dlls/windows.gaming.input/provider.idl b/dlls/windows.gaming.input/provider.idl index 039948bc0b6..651c83fbd20 100644 --- a/dlls/windows.gaming.input/provider.idl +++ b/dlls/windows.gaming.input/provider.idl @@ -187,8 +187,8 @@ namespace Windows.Gaming.Input.Custom { interface IWineForceFeedbackEffectImpl : IUnknown requires Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect { - [propput] HRESULT Parameters([in] WineForceFeedbackEffectParameters parameters, - [in, optional] WineForceFeedbackEffectEnvelope *envelope); + HRESULT SetParameters([in] WineForceFeedbackEffectParameters parameters, + [in, optional] WineForceFeedbackEffectEnvelope *envelope); }
[ diff --git a/dlls/windows.gaming.input/ramp_effect.c b/dlls/windows.gaming.input/ramp_effect.c index fadcf151c04..31c310bf2d8 100644 --- a/dlls/windows.gaming.input/ramp_effect.c +++ b/dlls/windows.gaming.input/ramp_effect.c @@ -116,7 +116,7 @@ static HRESULT WINAPI effect_SetParameters( IRampForceEffect *iface, Vector3 sta TRACE( "iface %p, start_vector %s, end_vector %s, duration %I64u.\n", iface, debugstr_vector3( &start_vector ), debugstr_vector3( &end_vector ), duration.Duration );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); }
static HRESULT WINAPI effect_SetParametersWithEnvelope( IRampForceEffect *iface, Vector3 start_vector, Vector3 end_vector, FLOAT attack_gain, @@ -151,7 +151,7 @@ static HRESULT WINAPI effect_SetParametersWithEnvelope( IRampForceEffect *iface, attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration, release_duration.Duration, repeat_count );
- return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); + return IWineForceFeedbackEffectImpl_SetParameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); }
static const struct IRampForceEffectVtbl effect_vtbl =
From: Hans Leidekker hans@codeweavers.com
Like midl does. --- tools/widl/parser.l | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 9ff4e7b01f6..c57ad990c5b 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -136,7 +136,10 @@ static int token_uuid( const char *str, YYSTYPE *yylval )
static int token_str( int token, const char *str, YYSTYPE *yylval ) { - char *tmp = xstrdup( str ); + int len = strlen( str ); + char *tmp = xmalloc( len + 1 ); + + strcpy( tmp, str );
if (token == aWSTRING || token == aSTRING || token == aSQSTRING) { @@ -149,6 +152,14 @@ static int token_str( int token, const char *str, YYSTYPE *yylval ) } dst[-1] = 0; /* strip last quote */ } + else if (token == aIDENTIFIER) + { + if (len > 255) + { + warning( "truncating identifier that exceeds 255 character limit\n" ); + tmp[255] = 0; + } + }
yylval->str = tmp; return token;
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/parser.y | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 51856152296..9861e4f2423 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2612,6 +2612,8 @@ static void check_remoting_args(const var_t *func) break; } } + else if (is_attr(arg->attrs, ATTR_RETVAL)) + error_at( &arg->where, "retval parameter '%s' of function '%s' must have out attribute\n", arg->name, funcname );
check_field_common(func->declspec.type, funcname, arg); }
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/parser.y | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 9861e4f2423..baf4dddb503 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2562,6 +2562,33 @@ static void check_remoting_fields(const var_t *var, type_t *type) if (field->declspec.type) check_field_common(type, type->name, field); }
+static void check_eventadd_args(const var_t *func) +{ + const var_t *arg; + const var_list_t *arg_list = type_function_get_args(func->declspec.type); + unsigned int count = 0; + + if (!is_attr(func->attrs, ATTR_EVENTADD)) return; + + LIST_FOR_EACH_ENTRY(arg, arg_list, const var_t, entry) + { + const type_t *type = arg->declspec.type; + const type_t *ref_type = is_ptr(type) ? type_pointer_get_ref_type(type) : NULL; + + count++; + if (count == 1 && (!ref_type || ref_type->type_type != TYPE_DELEGATE)) + error_at( &arg->where, "first parameter '%s' of function '%s' must be a delegate pointer\n", + arg->name, func->name ); + + if (count == 2 && (!ref_type || !ref_type->name || strcmp(ref_type->name, "EventRegistrationToken") || + !is_attr(arg->attrs, ATTR_RETVAL))) + error_at( &arg->where, "second parameter '%s' of function '%s' must be an [out, retval] EventRegistrationToken pointer\n", + arg->name, func->name ); + + if (count > 2) error_at( &arg->where, "eventadd function '%s' has too many parameters\n", func->name ); + } +} + /* checks that arguments for a function make sense for marshalling and unmarshalling */ static void check_remoting_args(const var_t *func) { @@ -2571,6 +2598,11 @@ static void check_remoting_args(const var_t *func) if (!type_function_get_args(func->declspec.type)) return;
+ if (winrt_mode) + { + check_eventadd_args(func); + } + LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry ) { const type_t *type = arg->declspec.type;
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/parser.y | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index baf4dddb503..1e83cd2802f 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2589,6 +2589,27 @@ static void check_eventadd_args(const var_t *func) } }
+static void check_eventremove_args(const var_t *func) +{ + const var_t *arg; + const var_list_t *arg_list = type_function_get_args(func->declspec.type); + unsigned int count = 0; + + if (!is_attr(func->attrs, ATTR_EVENTREMOVE)) return; + + LIST_FOR_EACH_ENTRY(arg, arg_list, const var_t, entry) + { + const type_t *type = arg->declspec.type; + + count++; + if (count == 1 && (!type->name || strcmp(type->name, "EventRegistrationToken"))) + error_at( &arg->where, "first parameter '%s' of function '%s' must be an EventRegistrationToken\n", + arg->name, func->name ); + + if (count > 1) error_at( &arg->where, "eventremove function '%s' has too many parameters\n", func->name ); + } +} + /* checks that arguments for a function make sense for marshalling and unmarshalling */ static void check_remoting_args(const var_t *func) { @@ -2601,6 +2622,7 @@ static void check_remoting_args(const var_t *func) if (winrt_mode) { check_eventadd_args(func); + check_eventremove_args(func); }
LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/parser.y | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 1e83cd2802f..7a79f4cb9b8 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2610,6 +2610,51 @@ static void check_eventremove_args(const var_t *func) } }
+static int is_size_parameter(const var_t *param, const var_list_t *arg_list) +{ + const var_t *arg; + + LIST_FOR_EACH_ENTRY(arg, arg_list, var_t, entry) + { + const type_t *type = arg->declspec.type; + const expr_t *size_is; + + if (is_ptr(type)) type = type_pointer_get_ref_type(type); + if (type->type_type != TYPE_ARRAY || !(size_is = type_array_get_conformance(type))) continue; + + if (size_is->type == EXPR_PPTR) size_is = size_is->ref; + if (!strcmp(param->name, size_is->u.sval)) return 1; + } + return 0; +} + +static void check_propget_args(const var_t *func) +{ + const var_t *arg; + const var_list_t *arg_list = type_function_get_args(func->declspec.type); + unsigned int count = 0; + + if (!is_attr(func->attrs, ATTR_PROPGET)) return; + + LIST_FOR_EACH_ENTRY_REV(arg, arg_list, const var_t, entry) + { + const type_t *type = arg->declspec.type; + int is_size = is_size_parameter(arg, arg_list); + + count++; + if (count == 1 && (!is_ptr(type) || !is_attr(arg->attrs, ATTR_RETVAL))) + error_at( &arg->where, "last parameter '%s' of function '%s' must be an [out, retval] pointer\n", + arg->name, func->name ); + + if (count == 2 && !is_size) + error_at( &arg->where, "parameter '%s' of function '%s' must be a size_is parameter\n", + arg->name, func->name ); + + if ((is_size && count > 2) || (!is_size && count > 1)) + error_at( &arg->where, "propget function '%s' has too many parameters\n", func->name ); + } +} + /* checks that arguments for a function make sense for marshalling and unmarshalling */ static void check_remoting_args(const var_t *func) { @@ -2621,6 +2666,7 @@ static void check_remoting_args(const var_t *func)
if (winrt_mode) { + check_propget_args(func); check_eventadd_args(func); check_eventremove_args(func); }
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/parser.y | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 7a79f4cb9b8..e2b8014aaa6 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2655,6 +2655,24 @@ static void check_propget_args(const var_t *func) } }
+static void check_propput_args(const var_t *func) +{ + const var_t *arg; + const var_list_t *arg_list = type_function_get_args(func->declspec.type); + unsigned int count = 0; + + if (!is_attr(func->attrs, ATTR_PROPPUT)) return; + + LIST_FOR_EACH_ENTRY(arg, arg_list, const var_t, entry) + { + count++; + if (count > 1) error_at( &arg->where, "propput function '%s' has too many parameters\n", func->name ); + + if (is_attr(arg->attrs, ATTR_OUT)) + error_at( &arg->where, "parameter '%s' of function '%s' must be an IN parameter\n", arg->name, func->name ); + } +} + /* checks that arguments for a function make sense for marshalling and unmarshalling */ static void check_remoting_args(const var_t *func) { @@ -2667,6 +2685,7 @@ static void check_remoting_args(const var_t *func) if (winrt_mode) { check_propget_args(func); + check_propput_args(func); check_eventadd_args(func); check_eventremove_args(func); }
Rémi Bernon (@rbernon) commented about tools/widl/parser.y:
if (!type_function_get_args(func->declspec.type)) return;
- if (winrt_mode)
- {
check_eventadd_args(func);
- }
I don't think `check_remoting_args` is the right place for these checks, lets move them to `check_functions`.
Rémi Bernon (@rbernon) commented about tools/widl/parser.y:
+static void check_propput_args(const var_t *func) +{
- const var_t *arg;
- const var_list_t *arg_list = type_function_get_args(func->declspec.type);
- unsigned int count = 0;
- if (!is_attr(func->attrs, ATTR_PROPPUT)) return;
- LIST_FOR_EACH_ENTRY(arg, arg_list, const var_t, entry)
- {
count++;
if (count > 1) error_at( &arg->where, "propput function '%s' has too many parameters\n", func->name );
if (is_attr(arg->attrs, ATTR_OUT))
error_at( &arg->where, "parameter '%s' of function '%s' must be an IN parameter\n", arg->name, func->name );
- }
This should probably also support arrays like the `propget` checks.
Also let's make the code style consistent in the new code. What about these fixups: https://gitlab.winehq.org/rbernon/wine/-/commits/wip/8670