/* * Oak Video Editor - Non-Linear Video Editor * Copyright (C) 2026 Oak Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * OfxParameterSuite 的 variadic 入口。stable Rust 不能定义 * C-variadic 函数(c_variadic 仍不稳定):paramGetValue / * paramSetValue / *AtTime / derivative / integral 的 '...' 在这里 * 按参数类型解析(类型经 Rust 导出的 ofx_param_kind_of 查询), * 再转发给 Rust 的类型化实现。 * * 变长参数形状(HS: ofxhParam.cpp 各类型的 getV/setV): * get:Integer/Boolean/Choice → int*;Double→double*; * 2D/3D/颜色 → 按维度的 int* / double* 指针序列;String → * char**(写内驻指针) * set:同形状但按值传(int/double 值序列;String → char*) * * KIND_* 与 Rust 侧 param::ParamKind 枚举逐字对应。 */ #include /* Rust 导出 */ extern int ofx_param_kind_of(void *param); extern int ofx_param_get_impl(void *param, int kind, void *out); extern int ofx_param_set_impl(void *param, int kind, const void *in); extern int ofx_param_get_string_impl(void *param, char **out); extern int ofx_param_set_string_impl(void *param, const char *in); extern int ofx_param_missing_feature_impl(void *param); enum { KIND_INT = 1, KIND_INT2 = 2, KIND_INT3 = 3, KIND_DOUBLE = 4, KIND_DOUBLE2 = 5, KIND_DOUBLE3 = 6, KIND_BOOL = 7, KIND_CHOICE = 8, KIND_RGB = 9, KIND_RGBA = 10, KIND_STRING = 11, KIND_STRCHOICE = 12 }; /* get:把插件传的指针序列收进局部缓冲,调 Rust,再散回。 */ static int get_dispatch(void *param, int kind, va_list ap) { switch (kind) { case KIND_INT: case KIND_BOOL: case KIND_CHOICE: { int *v = va_arg(ap, int *); return ofx_param_get_impl(param, kind, v); } case KIND_INT2: { int *a = va_arg(ap, int *); int *b = va_arg(ap, int *); int buf[2] = { *a, *b }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; return r; } case KIND_INT3: { int *a = va_arg(ap, int *); int *b = va_arg(ap, int *); int *c = va_arg(ap, int *); int buf[3] = { *a, *b, *c }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; *c = buf[2]; return r; } case KIND_DOUBLE: { double *v = va_arg(ap, double *); return ofx_param_get_impl(param, kind, v); } case KIND_DOUBLE2: { double *a = va_arg(ap, double *); double *b = va_arg(ap, double *); double buf[2] = { *a, *b }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; return r; } case KIND_DOUBLE3: { double *a = va_arg(ap, double *); double *b = va_arg(ap, double *); double *c = va_arg(ap, double *); double buf[3] = { *a, *b, *c }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; *c = buf[2]; return r; } case KIND_RGB: { double *a = va_arg(ap, double *); double *b = va_arg(ap, double *); double *c = va_arg(ap, double *); double buf[3] = { *a, *b, *c }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; *c = buf[2]; return r; } case KIND_RGBA: { double *a = va_arg(ap, double *); double *b = va_arg(ap, double *); double *c = va_arg(ap, double *); double *d = va_arg(ap, double *); double buf[4] = { *a, *b, *c, *d }; int r = ofx_param_get_impl(param, kind, buf); *a = buf[0]; *b = buf[1]; *c = buf[2]; *d = buf[3]; return r; } case KIND_STRING: case KIND_STRCHOICE: { char **p = va_arg(ap, char **); return ofx_param_get_string_impl(param, p); } default: return 1; /* kOfxStatFailed:未知类型 */ } } /* set:按值收进局部缓冲,调 Rust。 */ static int set_dispatch(void *param, int kind, va_list ap) { switch (kind) { case KIND_INT: case KIND_BOOL: case KIND_CHOICE: { int v = va_arg(ap, int); return ofx_param_set_impl(param, kind, &v); } case KIND_INT2: { int a = va_arg(ap, int); int b = va_arg(ap, int); int buf[2] = { a, b }; return ofx_param_set_impl(param, kind, buf); } case KIND_INT3: { int a = va_arg(ap, int); int b = va_arg(ap, int); int c = va_arg(ap, int); int buf[3] = { a, b, c }; return ofx_param_set_impl(param, kind, buf); } case KIND_DOUBLE: { double v = va_arg(ap, double); return ofx_param_set_impl(param, kind, &v); } case KIND_DOUBLE2: { double a = va_arg(ap, double); double b = va_arg(ap, double); double buf[2] = { a, b }; return ofx_param_set_impl(param, kind, buf); } case KIND_DOUBLE3: { double a = va_arg(ap, double); double b = va_arg(ap, double); double c = va_arg(ap, double); double buf[3] = { a, b, c }; return ofx_param_set_impl(param, kind, buf); } case KIND_RGB: { double a = va_arg(ap, double); double b = va_arg(ap, double); double c = va_arg(ap, double); double buf[3] = { a, b, c }; return ofx_param_set_impl(param, kind, buf); } case KIND_RGBA: { double a = va_arg(ap, double); double b = va_arg(ap, double); double c = va_arg(ap, double); double d = va_arg(ap, double); double buf[4] = { a, b, c, d }; return ofx_param_set_impl(param, kind, buf); } case KIND_STRING: case KIND_STRCHOICE: { const char *s = va_arg(ap, const char *); return ofx_param_set_string_impl(param, s); } default: return 1; /* kOfxStatFailed */ } } int ofx_param_get_value_shim(void *param, ...) { va_list ap; va_start(ap, param); int kind = ofx_param_kind_of(param); int r = get_dispatch(param, kind, ap); va_end(ap); return r; } int ofx_param_get_value_at_time_shim(void *param, double time, ...) { (void)time; /* 第 1 期无动画:AtTime 即当前值(Rust 侧实现) */ va_list ap; va_start(ap, time); int kind = ofx_param_kind_of(param); int r = get_dispatch(param, kind, ap); va_end(ap); return r; } int ofx_param_set_value_shim(void *param, ...) { va_list ap; va_start(ap, param); int kind = ofx_param_kind_of(param); int r = set_dispatch(param, kind, ap); va_end(ap); return r; } int ofx_param_set_value_at_time_shim(void *param, double time, ...) { (void)time; /* 第 1 期无动画 */ va_list ap; va_start(ap, time); int kind = ofx_param_kind_of(param); int r = set_dispatch(param, kind, ap); va_end(ap); return r; } /* derivative/integral:第 1 期无动画支持;不消费 va_args, * 统一返回 kOfxStatErrMissingHostFeature。 */ int ofx_param_get_derivative_shim(void *param, double time, ...) { (void)time; return ofx_param_missing_feature_impl(param); } int ofx_param_get_integral_shim(void *param, double time1, double time2, ...) { (void)time1; (void)time2; return ofx_param_missing_feature_impl(param); }