1235 lines
32 KiB
C
1235 lines
32 KiB
C
/* WirePlumber
|
|
*
|
|
* Copyright © 2021 Collabora Ltd.
|
|
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <wp/wp.h>
|
|
#include <wplua/wplua.h>
|
|
|
|
#include <spa/utils/type.h>
|
|
|
|
#define MAX_LUA_TYPES 9
|
|
|
|
/* Builder */
|
|
|
|
typedef gboolean (*primitive_lua_add_func) (WpSpaPodBuilder *, WpSpaIdValue,
|
|
lua_State *, int);
|
|
|
|
struct primitive_lua_type {
|
|
WpSpaType primitive_type;
|
|
primitive_lua_add_func primitive_lua_add_funcs[MAX_LUA_TYPES];
|
|
};
|
|
|
|
static inline gboolean
|
|
builder_add_boolean_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
wp_spa_pod_builder_add_boolean (b, lua_toboolean (L, idx));
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_boolean_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_boolean (b, lua_tointeger (L, idx) > 0);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_boolean_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_boolean (b,
|
|
g_strcmp0 (value, "true") == 0 || g_strcmp0 (value, "1") == 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_id_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_id (b, lua_tointeger (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_id_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
WpSpaIdTable id_table = NULL;
|
|
WpSpaIdValue id_val = NULL;
|
|
if (key_id) {
|
|
wp_spa_id_value_get_value_type (key_id, &id_table);
|
|
if (id_table) {
|
|
id_val = wp_spa_id_table_find_value_from_short_name (id_table, value);
|
|
wp_spa_pod_builder_add_id (b, wp_spa_id_value_number (id_val));
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_int_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
gboolean value = lua_toboolean (L, idx);
|
|
wp_spa_pod_builder_add_int (b, value ? 1 : 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_int_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_int (b, lua_tointeger (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_int_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_int (b, strtol (value, NULL, 10));
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_long_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
gboolean value = lua_toboolean (L, idx);
|
|
wp_spa_pod_builder_add_long (b, value ? 1 : 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_long_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_long (b, lua_tointeger (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_long_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_long (b, strtol (value, NULL, 10));
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_float_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
gboolean value = lua_toboolean (L, idx);
|
|
wp_spa_pod_builder_add_float (b, value ? 1.0f : 0.0f);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_float_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isnumber (L, idx) && !lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_float (b, lua_tonumber (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_double_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
gboolean value = lua_toboolean (L, idx);
|
|
wp_spa_pod_builder_add_double (b, value ? 1.0f : 0.0f);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_double_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isnumber (L, idx) && !lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_double (b, lua_tonumber (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_string_lua_boolean (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
gboolean value = lua_toboolean (L, idx);
|
|
wp_spa_pod_builder_add_string (b, value ? "true" : "false");
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_string_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
g_autofree gchar *value = NULL;
|
|
value = lua_isinteger (L, idx) ?
|
|
g_strdup_printf ("%lld", lua_tointeger (L, idx)) :
|
|
g_strdup_printf ("%f", lua_tonumber (L, idx));
|
|
wp_spa_pod_builder_add_string (b, value);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_string_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_string (b, value);
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_bytes_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
gint64 value = lua_tointeger (L, idx);
|
|
wp_spa_pod_builder_add_bytes (b, (gconstpointer)&value, sizeof (value));
|
|
} else {
|
|
double value = lua_tonumber (L, idx);
|
|
wp_spa_pod_builder_add_bytes (b, (gconstpointer)&value, sizeof (value));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_bytes_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_bytes (b, (gconstpointer)value, strlen (value));
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_fd_lua_number (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
if (lua_isinteger (L, idx)) {
|
|
wp_spa_pod_builder_add_fd (b, lua_tointeger (L, idx));
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_fd_lua_string (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
const gchar *value = lua_tostring (L, idx);
|
|
wp_spa_pod_builder_add_fd (b, strtol (value, NULL, 10));
|
|
return TRUE;
|
|
}
|
|
|
|
static inline gboolean
|
|
is_pod_type_compatible (WpSpaType type, WpSpaPod *pod)
|
|
{
|
|
/* Check if the pod type matches */
|
|
if (type == wp_spa_pod_get_spa_type (pod))
|
|
return TRUE;
|
|
|
|
/* Otherwise, check if the child type of Choice pod matches */
|
|
if (wp_spa_pod_is_choice (pod)) {
|
|
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod);
|
|
WpSpaType child_type = wp_spa_pod_get_spa_type (child);
|
|
if (type == child_type)
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static inline gboolean
|
|
builder_add_lua_userdata (WpSpaPodBuilder *b, WpSpaIdValue key_id,
|
|
lua_State *L, int idx)
|
|
{
|
|
WpSpaPod *pod = wplua_checkboxed (L, idx, WP_TYPE_SPA_POD);
|
|
if (pod) {
|
|
if (key_id) {
|
|
WpSpaType prop_type = wp_spa_id_value_get_value_type (key_id, NULL);
|
|
if (is_pod_type_compatible (prop_type, pod)) {
|
|
wp_spa_pod_builder_add_pod (b, pod);
|
|
return TRUE;
|
|
}
|
|
} else {
|
|
wp_spa_pod_builder_add_pod (b, pod);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static const struct primitive_lua_type primitive_lua_types[] = {
|
|
{SPA_TYPE_Bool, {
|
|
[LUA_TBOOLEAN] = builder_add_boolean_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_boolean_lua_number,
|
|
[LUA_TSTRING] = builder_add_boolean_lua_string,
|
|
}},
|
|
{SPA_TYPE_Id, {
|
|
[LUA_TNUMBER] = builder_add_id_lua_number,
|
|
[LUA_TSTRING] = builder_add_id_lua_string,
|
|
}},
|
|
{SPA_TYPE_Int, {
|
|
[LUA_TBOOLEAN] = builder_add_int_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_int_lua_number,
|
|
[LUA_TSTRING] = builder_add_int_lua_string,
|
|
}},
|
|
{SPA_TYPE_Long, {
|
|
[LUA_TBOOLEAN] = builder_add_long_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_long_lua_number,
|
|
[LUA_TSTRING] = builder_add_long_lua_string,
|
|
}},
|
|
{SPA_TYPE_Float, {
|
|
[LUA_TBOOLEAN] = builder_add_float_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_float_lua_number,
|
|
}},
|
|
{SPA_TYPE_Double, {
|
|
[LUA_TBOOLEAN] = builder_add_double_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_double_lua_number,
|
|
}},
|
|
{SPA_TYPE_String, {
|
|
[LUA_TBOOLEAN] = builder_add_string_lua_boolean,
|
|
[LUA_TNUMBER] = builder_add_string_lua_number,
|
|
[LUA_TSTRING] = builder_add_string_lua_string,
|
|
}},
|
|
{SPA_TYPE_Bytes, {
|
|
[LUA_TNUMBER] = builder_add_bytes_lua_number,
|
|
[LUA_TSTRING] = builder_add_bytes_lua_string,
|
|
}},
|
|
{SPA_TYPE_Fd, {
|
|
[LUA_TNUMBER] = builder_add_fd_lua_number,
|
|
[LUA_TSTRING] = builder_add_fd_lua_string,
|
|
}},
|
|
{0, {}},
|
|
};
|
|
|
|
static gboolean
|
|
builder_add_key (WpSpaPodBuilder *b, WpSpaIdTable table, lua_State *L, int idx)
|
|
{
|
|
/* Number */
|
|
if (lua_type (L, -1) == LUA_TNUMBER) {
|
|
wp_spa_pod_builder_add_id (b, lua_tonumber (L, idx));
|
|
return TRUE;
|
|
}
|
|
|
|
/* String */
|
|
else if (lua_type (L, -1) == LUA_TSTRING) {
|
|
const gchar *key = lua_tostring (L, idx);
|
|
WpSpaIdValue val = wp_spa_id_table_find_value_from_short_name (table, key);
|
|
if (val) {
|
|
wp_spa_pod_builder_add_id (b, wp_spa_id_value_number (val));
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
builder_add_value (WpSpaPodBuilder *b, WpSpaType array_type, lua_State *L,
|
|
int idx)
|
|
{
|
|
int ltype = lua_type (L, idx);
|
|
guint i;
|
|
|
|
if (ltype < 0 || ltype >= MAX_LUA_TYPES)
|
|
return FALSE;
|
|
|
|
for (i = 0; primitive_lua_types[i].primitive_type; i++) {
|
|
const struct primitive_lua_type *t = primitive_lua_types + i;
|
|
if (t->primitive_type == array_type) {
|
|
primitive_lua_add_func f = t->primitive_lua_add_funcs[ltype];
|
|
if (f) {
|
|
return f (b, NULL, L, idx);
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
builder_add_table (lua_State *L, WpSpaPodBuilder *builder)
|
|
{
|
|
const gchar *type_name = NULL;
|
|
WpSpaType type = WP_SPA_TYPE_INVALID;
|
|
WpSpaIdTable table = NULL;
|
|
|
|
luaL_checktype (L, 1, LUA_TTABLE);
|
|
|
|
lua_pushnil (L);
|
|
while (lua_next (L, 1)) {
|
|
/* First filed is always the item type or table */
|
|
if (type == WP_SPA_TYPE_INVALID && !table) {
|
|
if (lua_type (L, -1) == LUA_TSTRING) {
|
|
type_name = lua_tostring (L, -1);
|
|
type = wp_spa_type_from_name (type_name);
|
|
if (type == WP_SPA_TYPE_INVALID) {
|
|
table = wp_spa_id_table_from_name (type_name);
|
|
if (!table)
|
|
luaL_error (L, "Unknown type '%s'", type_name);
|
|
}
|
|
} else {
|
|
luaL_error (L,
|
|
"must have the item type or table on its first field");
|
|
}
|
|
}
|
|
|
|
/* Add remaining table key elements */
|
|
else if (table) {
|
|
if (!builder_add_key (builder, table, L, -1))
|
|
luaL_error (L, "key could not be added");
|
|
}
|
|
|
|
/* Add remaining value elements */
|
|
else if (type != WP_SPA_TYPE_INVALID) {
|
|
if (!builder_add_value (builder, type, L, -1))
|
|
luaL_error (L, "value could not be added");
|
|
}
|
|
|
|
lua_pop (L, 1);
|
|
}
|
|
}
|
|
|
|
/* None */
|
|
|
|
static int
|
|
spa_pod_none_new (lua_State *L)
|
|
{
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_none ());
|
|
return 1;
|
|
}
|
|
|
|
/* Boolean */
|
|
|
|
static int
|
|
spa_pod_boolean_new (lua_State *L)
|
|
{
|
|
gboolean value = lua_toboolean (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_boolean (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Id */
|
|
|
|
static int
|
|
spa_pod_id_new (lua_State *L)
|
|
{
|
|
/* Id number */
|
|
if (lua_type (L, 1) == LUA_TNUMBER) {
|
|
gint64 value = lua_tointeger (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_id (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Table name and key name */
|
|
else if (lua_type (L, 1) == LUA_TSTRING) {
|
|
const gchar *table_name = lua_tostring (L, 1);
|
|
const gchar *key_name = lua_tostring (L, 2);
|
|
WpSpaIdTable table = NULL;
|
|
WpSpaIdValue value = NULL;
|
|
table = wp_spa_id_table_from_name (table_name);
|
|
if (!table)
|
|
luaL_error (L, "table '%s' does not exist", table_name);
|
|
value = wp_spa_id_table_find_value_from_short_name (table, key_name);
|
|
if (!value)
|
|
luaL_error (L, "key '%s' does not exist in '%s'", key_name, table_name);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD,
|
|
wp_spa_pod_new_id (wp_spa_id_value_number (value)));
|
|
return 1;
|
|
}
|
|
|
|
/* Error */
|
|
luaL_error (L, "Invalid parameters");
|
|
return 0;
|
|
}
|
|
|
|
/* Int */
|
|
|
|
static int
|
|
spa_pod_int_new (lua_State *L)
|
|
{
|
|
gint64 value = lua_tointeger (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_int (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Long */
|
|
|
|
static int
|
|
spa_pod_long_new (lua_State *L)
|
|
{
|
|
gint64 value = lua_tointeger (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_long (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Float */
|
|
|
|
static int
|
|
spa_pod_float_new (lua_State *L)
|
|
{
|
|
float value = lua_tonumber (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_float (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Double */
|
|
|
|
static int
|
|
spa_pod_double_new (lua_State *L)
|
|
{
|
|
double value = lua_tonumber (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_double (value));
|
|
return 1;
|
|
}
|
|
|
|
/* String */
|
|
|
|
static int
|
|
spa_pod_string_new (lua_State *L)
|
|
{
|
|
const gchar *value = lua_tostring (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_string (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Bytes */
|
|
|
|
static int
|
|
spa_pod_bytes_new (lua_State *L)
|
|
{
|
|
switch (lua_type (L, 1)) {
|
|
case LUA_TNUMBER: {
|
|
if (lua_isinteger (L, 1)) {
|
|
guint64 value = lua_tointeger (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD,
|
|
wp_spa_pod_new_bytes (&value, sizeof (guint64)));
|
|
} else {
|
|
double value = lua_tonumber (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD,
|
|
wp_spa_pod_new_bytes (&value, sizeof (double)));
|
|
}
|
|
return 1;
|
|
}
|
|
case LUA_TSTRING: {
|
|
const gchar *str = lua_tostring (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD,
|
|
wp_spa_pod_new_bytes (str, strlen (str)));
|
|
return 1;
|
|
}
|
|
default:
|
|
luaL_error (L, "Only number and strings are valid for bytes pod");
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Pointer */
|
|
|
|
static int
|
|
spa_pod_pointer_new (lua_State *L)
|
|
{
|
|
const gchar *type = lua_tostring (L, 1);
|
|
gconstpointer value = lua_touserdata (L, 2);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_pointer (type, value));
|
|
return 1;
|
|
}
|
|
|
|
/* Fd */
|
|
|
|
static int
|
|
spa_pod_fd_new (lua_State *L)
|
|
{
|
|
gint64 value = lua_tointeger (L, 1);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_fd (value));
|
|
return 1;
|
|
}
|
|
|
|
/* Rectangle */
|
|
|
|
static int
|
|
spa_pod_rectangle_new (lua_State *L)
|
|
{
|
|
gint64 width = lua_tointeger (L, 1);
|
|
gint64 height = lua_tointeger (L, 2);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD,
|
|
wp_spa_pod_new_rectangle (width, height));
|
|
return 1;
|
|
}
|
|
|
|
/* Fraction */
|
|
|
|
static int
|
|
spa_pod_fraction_new (lua_State *L)
|
|
{
|
|
gint64 num = lua_tointeger (L, 1);
|
|
gint64 denom = lua_tointeger (L, 2);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_new_fraction (num, denom));
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* Object */
|
|
|
|
static gboolean
|
|
object_add_property (WpSpaPodBuilder *b, WpSpaIdTable table,
|
|
const gchar *key, lua_State *L, int idx)
|
|
{
|
|
guint i;
|
|
WpSpaIdValue prop_id = NULL;
|
|
int ltype = lua_type (L, idx);
|
|
|
|
if (ltype < 0 || ltype >= MAX_LUA_TYPES)
|
|
return FALSE;
|
|
|
|
/* Check if we can add primitive property directly from LUA type */
|
|
prop_id = wp_spa_id_table_find_value_from_short_name (table, key);
|
|
if (prop_id) {
|
|
WpSpaType prop_type = wp_spa_id_value_get_value_type (prop_id, NULL);
|
|
if (prop_type != WP_SPA_TYPE_INVALID) {
|
|
for (i = 0; primitive_lua_types[i].primitive_type; i++) {
|
|
const struct primitive_lua_type *t = primitive_lua_types + i;
|
|
if (t->primitive_type == prop_type) {
|
|
primitive_lua_add_func f = t->primitive_lua_add_funcs[ltype];
|
|
if (f) {
|
|
wp_spa_pod_builder_add_property (b, key);
|
|
return f (b, prop_id, L, idx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Otherwise just add pod property */
|
|
if (lua_type (L, idx) == LUA_TUSERDATA) {
|
|
wp_spa_pod_builder_add_property (b, key);
|
|
return builder_add_lua_userdata (b, prop_id, L, idx);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int
|
|
spa_pod_object_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = NULL;
|
|
const gchar *fields[2] = { NULL, NULL }; // type_name, name_id
|
|
WpSpaType object_type = WP_SPA_TYPE_INVALID;
|
|
WpSpaIdTable table = NULL;
|
|
|
|
luaL_checktype (L, 1, LUA_TTABLE);
|
|
|
|
lua_geti (L, 1, 1);
|
|
fields[0] = lua_tostring (L, -1);
|
|
lua_geti (L, 1, 2);
|
|
fields[1] = lua_tostring (L, -1);
|
|
|
|
object_type = wp_spa_type_from_name (fields[0]);
|
|
if (object_type == WP_SPA_TYPE_INVALID)
|
|
luaL_error (L, "Invalid object type '%s'", fields[0]);
|
|
|
|
table = wp_spa_type_get_values_table (object_type);
|
|
if (!table)
|
|
luaL_error (L, "Object type '%s' has incomplete type information",
|
|
fields[0]);
|
|
|
|
builder = wp_spa_pod_builder_new_object (fields[0], fields[1]);
|
|
if (!builder)
|
|
luaL_error (L, "Could not create pod object");
|
|
|
|
lua_pop (L, 2);
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next (L, -2)) {
|
|
/* Remaining fields with string keys are the object properties */
|
|
if (lua_type (L, -2) == LUA_TSTRING) {
|
|
const gchar *key = lua_tostring (L, -2);
|
|
if (!object_add_property (builder, table, key, L, -1))
|
|
luaL_error (L, "Property '%s' could not be added", key);
|
|
}
|
|
|
|
lua_pop (L, 1);
|
|
}
|
|
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
/* Struct */
|
|
|
|
static int
|
|
spa_pod_struct_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = NULL;
|
|
|
|
luaL_checktype (L, 1, LUA_TTABLE);
|
|
|
|
builder = wp_spa_pod_builder_new_struct ();
|
|
|
|
lua_pushnil (L);
|
|
while (lua_next (L, 1)) {
|
|
switch (lua_type (L, -1)) {
|
|
case LUA_TBOOLEAN:
|
|
wp_spa_pod_builder_add_boolean (builder, lua_toboolean (L, -1));
|
|
break;
|
|
case LUA_TNUMBER:
|
|
if (lua_isinteger (L, -1))
|
|
wp_spa_pod_builder_add_long (builder, lua_tointeger (L, -1));
|
|
else
|
|
wp_spa_pod_builder_add_double (builder, lua_tonumber (L, -1));
|
|
break;
|
|
case LUA_TSTRING:
|
|
wp_spa_pod_builder_add_string (builder, lua_tostring (L, -1));
|
|
break;
|
|
case LUA_TUSERDATA: {
|
|
WpSpaPod *pod = wplua_checkboxed (L, -1, WP_TYPE_SPA_POD);
|
|
wp_spa_pod_builder_add_pod (builder, pod);
|
|
break;
|
|
}
|
|
default:
|
|
luaL_error (L, "Struct does not support lua type ",
|
|
lua_typename(L, lua_type(L, -1)));
|
|
break;
|
|
}
|
|
lua_pop (L, 1);
|
|
}
|
|
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
/* Sequence */
|
|
|
|
static int
|
|
spa_pod_sequence_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = NULL;
|
|
|
|
luaL_checktype (L, 1, LUA_TTABLE);
|
|
|
|
builder = wp_spa_pod_builder_new_sequence (0);
|
|
|
|
lua_pushnil (L);
|
|
while (lua_next (L, -2)) {
|
|
guint32 offset = 0;
|
|
const gchar *type_name = NULL;
|
|
WpSpaPod *value = NULL;
|
|
|
|
/* Read Control */
|
|
if (lua_istable(L, -1)) {
|
|
lua_pushnil (L);
|
|
while (lua_next (L, -2)) {
|
|
const gchar *key = lua_tostring (L, -2);
|
|
if (g_strcmp0 (key, "offset") == 0) {
|
|
offset = lua_tointeger (L, -1);
|
|
} else if (!type_name && g_strcmp0 (key, "typename") == 0) {
|
|
type_name = lua_tostring (L, -1);
|
|
} else if (!value && g_strcmp0 (key, "value") == 0) {
|
|
switch (lua_type (L, -1)) {
|
|
case LUA_TBOOLEAN:
|
|
value = wp_spa_pod_new_boolean (lua_toboolean (L, -1));
|
|
break;
|
|
case LUA_TNUMBER:
|
|
if (lua_isinteger (L, -1))
|
|
value = wp_spa_pod_new_long (lua_tointeger (L, -1));
|
|
else
|
|
value = wp_spa_pod_new_double (lua_tonumber (L, -1));
|
|
break;
|
|
case LUA_TSTRING:
|
|
value = wp_spa_pod_new_string (lua_tostring (L, -1));
|
|
break;
|
|
case LUA_TUSERDATA: {
|
|
value = wplua_checkboxed (L, -1, WP_TYPE_SPA_POD);
|
|
break;
|
|
}
|
|
default: {
|
|
luaL_error (L, "Control value does not support lua type ",
|
|
lua_typename(L, lua_type(L, -1)));
|
|
value = NULL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
}
|
|
|
|
/* Add control */
|
|
if (type_name && value) {
|
|
wp_spa_pod_builder_add_control (builder, offset, type_name);
|
|
wp_spa_pod_builder_add_pod (builder, value);
|
|
wp_spa_pod_unref (value);
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
/* Array */
|
|
|
|
static int
|
|
spa_pod_array_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_array ();
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
/* Choice */
|
|
|
|
static int
|
|
spa_pod_choice_none_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_choice ("None");
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
spa_pod_choice_range_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_choice ("Range");
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
spa_pod_choice_step_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_choice ("Step");
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
spa_pod_choice_enum_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_choice ("Enum");
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
spa_pod_choice_flags_new (lua_State *L)
|
|
{
|
|
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_choice ("Flags");
|
|
builder_add_table (L, builder);
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, wp_spa_pod_builder_end (builder));
|
|
return 1;
|
|
}
|
|
|
|
/* API */
|
|
|
|
static int
|
|
spa_pod_get_type_name (lua_State *L)
|
|
{
|
|
WpSpaPod *pod = wplua_checkboxed (L, 1, WP_TYPE_SPA_POD);
|
|
lua_pushstring (L, wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
push_primitive_values (lua_State *L, WpSpaPod *pod, WpSpaType type,
|
|
guint start_index, WpSpaIdTable idtable)
|
|
{
|
|
g_auto (GValue) item = G_VALUE_INIT;
|
|
g_autoptr (WpIterator) it = wp_spa_pod_new_iterator (pod);
|
|
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
|
gpointer p = g_value_get_pointer (&item);
|
|
if (!p)
|
|
continue;
|
|
switch (type) {
|
|
case SPA_TYPE_Bool:
|
|
lua_pushboolean (L, *(gboolean *)p);
|
|
break;
|
|
case SPA_TYPE_Id: {
|
|
WpSpaIdValue idval = NULL;
|
|
if (idtable)
|
|
idval = wp_spa_id_table_find_value (idtable, *(guint32 *)p);
|
|
if (idval)
|
|
lua_pushstring (L, wp_spa_id_value_short_name (idval));
|
|
else
|
|
lua_pushinteger (L, *(guint32 *)p);
|
|
break;
|
|
}
|
|
case SPA_TYPE_Int:
|
|
lua_pushinteger (L, *(gint *)p);
|
|
break;
|
|
case SPA_TYPE_Long:
|
|
lua_pushinteger (L, *(long *)p);
|
|
break;
|
|
case SPA_TYPE_Float:
|
|
lua_pushnumber (L, *(float *)p);
|
|
break;
|
|
case SPA_TYPE_Double:
|
|
lua_pushnumber (L, *(double *)p);
|
|
break;
|
|
case SPA_TYPE_Fd:
|
|
lua_pushnumber (L, *(gint64 *)p);
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
lua_rawseti (L, -2, start_index++);
|
|
}
|
|
}
|
|
|
|
static void
|
|
push_luapod (lua_State *L, WpSpaPod *pod, WpSpaIdValue field_idval)
|
|
{
|
|
/* None */
|
|
if (wp_spa_pod_is_none (pod)) {
|
|
lua_pushnil (L);
|
|
}
|
|
|
|
/* Boolean */
|
|
else if (wp_spa_pod_is_boolean (pod)) {
|
|
gboolean value = FALSE;
|
|
g_warn_if_fail (wp_spa_pod_get_boolean (pod, &value));
|
|
lua_pushboolean (L, value);
|
|
}
|
|
|
|
/* Id */
|
|
else if (wp_spa_pod_is_id (pod)) {
|
|
guint32 value = 0;
|
|
WpSpaIdTable idtable = NULL;
|
|
WpSpaIdValue idval = NULL;
|
|
g_warn_if_fail (wp_spa_pod_get_id (pod, &value));
|
|
if (field_idval && SPA_TYPE_Id ==
|
|
wp_spa_id_value_get_value_type (field_idval, &idtable)) {
|
|
idval = wp_spa_id_table_find_value (idtable, value);
|
|
}
|
|
if (idval)
|
|
lua_pushstring (L, wp_spa_id_value_short_name (idval));
|
|
else
|
|
lua_pushinteger (L, value);
|
|
}
|
|
|
|
/* Int */
|
|
else if (wp_spa_pod_is_int (pod)) {
|
|
gint value = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_int (pod, &value));
|
|
lua_pushinteger (L, value);
|
|
}
|
|
|
|
/* Long */
|
|
else if (wp_spa_pod_is_long (pod)) {
|
|
gint64 value = 0;
|
|
wp_spa_pod_get_long (pod, &value);
|
|
lua_pushinteger (L, value);
|
|
}
|
|
|
|
/* Float */
|
|
else if (wp_spa_pod_is_float (pod)) {
|
|
float value = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_float (pod, &value));
|
|
lua_pushnumber (L, value);
|
|
}
|
|
|
|
/* Double */
|
|
else if (wp_spa_pod_is_double (pod)) {
|
|
double value = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_double (pod, &value));
|
|
lua_pushnumber (L, value);
|
|
}
|
|
|
|
/* String */
|
|
else if (wp_spa_pod_is_string (pod)) {
|
|
const gchar *value = NULL;
|
|
g_warn_if_fail (wp_spa_pod_get_string (pod, &value));
|
|
lua_pushstring (L, value);
|
|
}
|
|
|
|
/* Bytes */
|
|
else if (wp_spa_pod_is_bytes (pod)) {
|
|
gconstpointer value = NULL;
|
|
guint32 size = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_bytes (pod, &value, &size));
|
|
char str[size + 1];
|
|
for (guint i = 0; i < size; i++)
|
|
str[i] = ((const gchar *)value)[i];
|
|
str[size] = '\0';
|
|
lua_pushstring (L, str);
|
|
}
|
|
|
|
/* Pointer */
|
|
else if (wp_spa_pod_is_pointer (pod)) {
|
|
gconstpointer value = NULL;
|
|
g_warn_if_fail (wp_spa_pod_get_pointer (pod, &value));
|
|
if (!value)
|
|
lua_pushnil (L);
|
|
else
|
|
lua_pushlightuserdata (L, (gpointer)value);
|
|
}
|
|
|
|
/* Fd */
|
|
else if (wp_spa_pod_is_fd (pod)) {
|
|
gint64 value = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_fd (pod, &value));
|
|
lua_pushinteger (L, value);
|
|
}
|
|
|
|
/* Rectangle */
|
|
else if (wp_spa_pod_is_rectangle (pod)) {
|
|
guint32 width = 0, height = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_rectangle (pod, &width, &height));
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Rectangle");
|
|
lua_setfield (L, -2, "pod_type");
|
|
lua_pushinteger (L, width);
|
|
lua_setfield (L, -2, "width");
|
|
lua_pushinteger (L, height);
|
|
lua_setfield (L, -2, "height");
|
|
}
|
|
|
|
/* Fraction */
|
|
else if (wp_spa_pod_is_fraction (pod)) {
|
|
guint32 num = 0, denom = 0;
|
|
g_warn_if_fail (wp_spa_pod_get_fraction (pod, &num, &denom));
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Fraction");
|
|
lua_setfield (L, -2, "pod_type");
|
|
lua_pushinteger (L, num);
|
|
lua_setfield (L, -2, "num");
|
|
lua_pushinteger (L, denom);
|
|
lua_setfield (L, -2, "denom");
|
|
}
|
|
|
|
/* Object */
|
|
else if (wp_spa_pod_is_object (pod)) {
|
|
WpSpaType type = wp_spa_pod_get_spa_type (pod);
|
|
WpSpaIdTable values_table = wp_spa_type_get_values_table (type);
|
|
const gchar *id_name = NULL;
|
|
g_auto (GValue) item = G_VALUE_INIT;
|
|
g_autoptr (WpIterator) it = NULL;
|
|
g_warn_if_fail (wp_spa_pod_get_object (pod, &id_name, NULL));
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Object");
|
|
lua_setfield (L, -2, "pod_type");
|
|
lua_pushstring (L, id_name);
|
|
lua_setfield (L, -2, "object_id");
|
|
it = wp_spa_pod_new_iterator (pod);
|
|
lua_newtable (L);
|
|
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
|
WpSpaPod *prop = g_value_get_boxed (&item);
|
|
const gchar *key = NULL;
|
|
g_autoptr (WpSpaPod) val = NULL;
|
|
//FIXME: this is suboptimal because _get_property() converts
|
|
// the key to a short name and we convert it back
|
|
g_warn_if_fail (wp_spa_pod_get_property (prop, &key, &val));
|
|
if (key) {
|
|
push_luapod (L, val,
|
|
wp_spa_id_table_find_value_from_short_name (values_table, key));
|
|
lua_setfield (L, -2, key);
|
|
}
|
|
}
|
|
lua_setfield (L, -2, "properties");
|
|
}
|
|
|
|
/* Struct */
|
|
else if (wp_spa_pod_is_struct (pod)) {
|
|
g_auto (GValue) item = G_VALUE_INIT;
|
|
g_autoptr (WpIterator) it = wp_spa_pod_new_iterator (pod);
|
|
guint i = 1;
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Struct");
|
|
lua_setfield (L, -2, "pod_type");
|
|
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
|
WpSpaPod *val = g_value_get_boxed (&item);
|
|
push_luapod (L, val, NULL);
|
|
lua_rawseti (L, -2, i++);
|
|
}
|
|
}
|
|
|
|
/* Sequence */
|
|
else if (wp_spa_pod_is_sequence (pod)) {
|
|
g_auto (GValue) item = G_VALUE_INIT;
|
|
g_autoptr (WpIterator) it = wp_spa_pod_new_iterator (pod);
|
|
guint i = 1;
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Sequence");
|
|
lua_setfield (L, -2, "pod_type");
|
|
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
|
WpSpaPod *control = g_value_get_boxed (&item);
|
|
guint32 offset = 0;
|
|
const char *type_name = NULL;
|
|
g_autoptr (WpSpaPod) val = NULL;
|
|
g_warn_if_fail (wp_spa_pod_get_control (control, &offset, &type_name,
|
|
&val));
|
|
lua_newtable (L);
|
|
lua_pushinteger (L, offset);
|
|
lua_setfield (L, -2, "offset");
|
|
lua_pushstring (L, type_name);
|
|
lua_setfield (L, -2, "typename");
|
|
push_luapod (L, val, NULL);
|
|
lua_setfield (L, -2, "value");
|
|
lua_rawseti (L, -2, i++);
|
|
}
|
|
}
|
|
|
|
/* Array */
|
|
else if (wp_spa_pod_is_array (pod)) {
|
|
g_autoptr (WpSpaPod) child = wp_spa_pod_get_array_child (pod);
|
|
WpSpaType type = wp_spa_pod_get_spa_type (child);
|
|
WpSpaIdTable idtable = NULL;
|
|
if (field_idval && type == SPA_TYPE_Id && SPA_TYPE_Array ==
|
|
wp_spa_id_value_get_value_type (field_idval, &idtable))
|
|
wp_spa_id_value_array_get_item_type (field_idval, &idtable);
|
|
lua_newtable (L);
|
|
lua_pushstring (L, "Array");
|
|
lua_setfield (L, -2, "pod_type");
|
|
lua_pushstring (L, wp_spa_type_name (type));
|
|
lua_setfield (L, -2, "value_type");
|
|
push_primitive_values (L, pod, type, 1, idtable);
|
|
}
|
|
|
|
/* Choice */
|
|
else if (wp_spa_pod_is_choice (pod)) {
|
|
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod);
|
|
WpSpaType type = wp_spa_pod_get_spa_type (child);
|
|
g_autofree const gchar *choice_type = g_strdup_printf ("Choice.%s",
|
|
wp_spa_id_value_short_name (wp_spa_pod_get_choice_type (pod)));
|
|
WpSpaIdTable idtable = NULL;
|
|
if (field_idval && type == SPA_TYPE_Id)
|
|
wp_spa_id_value_get_value_type (field_idval, &idtable);
|
|
lua_newtable (L);
|
|
lua_pushstring (L, choice_type);
|
|
lua_setfield (L, -2, "pod_type");
|
|
lua_pushstring (L, wp_spa_type_name (type));
|
|
lua_setfield (L, -2, "value_type");
|
|
push_primitive_values (L, pod, type, 1, idtable);
|
|
}
|
|
|
|
/* Error */
|
|
else {
|
|
luaL_error (L, "Unsupported pod type ",
|
|
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
|
}
|
|
}
|
|
|
|
static int
|
|
spa_pod_parse (lua_State *L)
|
|
{
|
|
WpSpaPod *pod = wplua_checkboxed (L, 1, WP_TYPE_SPA_POD);
|
|
push_luapod (L, pod, NULL);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
spa_pod_fixate (lua_State *L)
|
|
{
|
|
WpSpaPod *pod = wplua_checkboxed (L, 1, WP_TYPE_SPA_POD);
|
|
gboolean res = wp_spa_pod_fixate (pod);
|
|
lua_pushboolean (L, res);
|
|
return 1;
|
|
}
|
|
|
|
static inline WpSpaPod *
|
|
_checkpod (lua_State *L, int n)
|
|
{
|
|
return wplua_checkboxed (L, n, WP_TYPE_SPA_POD);
|
|
}
|
|
|
|
static int
|
|
spa_pod_filter (lua_State *L)
|
|
{
|
|
WpSpaPod *pod = wplua_checkboxed (L, 1, WP_TYPE_SPA_POD);
|
|
WpSpaPod *filter = luaL_opt (L, _checkpod, 2, NULL);
|
|
WpSpaPod *result = wp_spa_pod_filter (pod, filter);
|
|
if (result) {
|
|
wplua_pushboxed (L, WP_TYPE_SPA_POD, result);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const luaL_Reg spa_pod_methods[] = {
|
|
{ "get_type_name", spa_pod_get_type_name },
|
|
{ "parse", spa_pod_parse },
|
|
{ "fixate", spa_pod_fixate },
|
|
{ "filter", spa_pod_filter },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg spa_pod_constructors[] = {
|
|
{ "None", spa_pod_none_new },
|
|
{ "Boolean", spa_pod_boolean_new },
|
|
{ "Id", spa_pod_id_new },
|
|
{ "Int", spa_pod_int_new },
|
|
{ "Long", spa_pod_long_new },
|
|
{ "Float", spa_pod_float_new },
|
|
{ "Double", spa_pod_double_new },
|
|
{ "String", spa_pod_string_new },
|
|
{ "Bytes", spa_pod_bytes_new },
|
|
{ "Pointer", spa_pod_pointer_new },
|
|
{ "Fd", spa_pod_fd_new },
|
|
{ "Rectangle", spa_pod_rectangle_new },
|
|
{ "Fraction", spa_pod_fraction_new },
|
|
{ "Object", spa_pod_object_new },
|
|
{ "Struct", spa_pod_struct_new },
|
|
{ "Sequence", spa_pod_sequence_new },
|
|
{ "Array", spa_pod_array_new },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg spa_pod_choice_constructors[] = {
|
|
{ "None", spa_pod_choice_none_new },
|
|
{ "Range", spa_pod_choice_range_new },
|
|
{ "Step", spa_pod_choice_step_new },
|
|
{ "Enum", spa_pod_choice_enum_new },
|
|
{ "Flags", spa_pod_choice_flags_new },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
/* Init */
|
|
|
|
void
|
|
wp_lua_scripting_pod_init (lua_State *L)
|
|
{
|
|
luaL_newlib (L, spa_pod_constructors);
|
|
luaL_newlib (L, spa_pod_choice_constructors);
|
|
lua_setfield (L, -2, "Choice");
|
|
lua_setglobal (L, "WpSpaPod");
|
|
|
|
wplua_register_type_methods (L, WP_TYPE_SPA_POD, NULL, spa_pod_methods);
|
|
}
|