/* WirePlumber * * Copyright © 2020 Collabora Ltd. * @author George Kiagiadakis * * SPDX-License-Identifier: MIT */ #include #include #include void wp_lua_scripting_api_init (lua_State *L); gboolean wp_lua_scripting_load_configuration (const gchar * conf_file, WpCore * core, GError ** error); struct _WpLuaScriptingPlugin { WpComponentLoader parent; WpCore *export_core; lua_State *L; }; G_DECLARE_FINAL_TYPE (WpLuaScriptingPlugin, wp_lua_scripting_plugin, WP, LUA_SCRIPTING_PLUGIN, WpComponentLoader) G_DEFINE_TYPE (WpLuaScriptingPlugin, wp_lua_scripting_plugin, WP_TYPE_COMPONENT_LOADER) static void wp_lua_scripting_plugin_init (WpLuaScriptingPlugin * self) { } static void wp_lua_scripting_plugin_enable (WpPlugin * plugin, WpTransition * transition) { WpLuaScriptingPlugin * self = WP_LUA_SCRIPTING_PLUGIN (plugin); g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (plugin)); /* initialize secondary connection to pipewire */ self->export_core = wp_core_clone (core); wp_core_update_properties (self->export_core, wp_properties_new ( PW_KEY_APP_NAME, "WirePlumber (export)", NULL)); if (!wp_core_connect (self->export_core)) { wp_transition_return_error (transition, g_error_new ( WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, "failed to connect export core")); return; } /* init lua engine */ self->L = wplua_new (); lua_pushliteral (self->L, "wireplumber_core"); lua_pushlightuserdata (self->L, core); lua_settable (self->L, LUA_REGISTRYINDEX); lua_pushliteral (self->L, "wireplumber_export_core"); lua_pushlightuserdata (self->L, self->export_core); lua_settable (self->L, LUA_REGISTRYINDEX); wp_lua_scripting_api_init (self->L); wplua_enable_sandbox (self->L, WP_LUA_SANDBOX_ISOLATE_ENV); wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); } static void wp_lua_scripting_plugin_disable (WpPlugin * plugin) { WpLuaScriptingPlugin * self = WP_LUA_SCRIPTING_PLUGIN (plugin); g_clear_pointer (&self->L, wplua_free); g_clear_object (&self->export_core); } static gboolean wp_lua_scripting_plugin_supports_type (WpComponentLoader * cl, const gchar * type) { return (!g_strcmp0 (type, "script/lua") || !g_strcmp0 (type, "config/lua")); } static gchar * find_script (const gchar * script) { if (g_path_is_absolute (script) && g_file_test (script, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_strdup (script); /* /etc/wireplumber/scripts */ { g_autofree gchar * file = g_build_filename ( wp_get_config_dir (), "scripts", script, NULL); if (g_file_test (file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_steal_pointer (&file); } /* {XDG_DATA_DIRS,/usr/local/share,/usr/share}/wireplumber/scripts */ const gchar * const * data_dirs = g_get_system_data_dirs (); while (*data_dirs) { g_autofree gchar * file = g_build_filename ( *data_dirs, "wireplumber", "scripts", script, NULL); if (g_file_test (file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_steal_pointer (&file); data_dirs++; } return NULL; } static gboolean wp_lua_scripting_plugin_load (WpComponentLoader * cl, const gchar * component, const gchar * type, GVariant * args, GError ** error) { WpLuaScriptingPlugin * self = WP_LUA_SCRIPTING_PLUGIN (cl); /* interpret component as a script */ if (!g_strcmp0 (type, "script/lua")) { g_autofree gchar * file = find_script (component); if (!file) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Could not locate script '%s'", component); return FALSE; } return wplua_load_path (self->L, file, error); } /* interpret component as a configuration file */ else if (!g_strcmp0 (type, "config/lua")) { g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (cl)); return wp_lua_scripting_load_configuration (component, core, error); } g_return_val_if_reached (FALSE); } static void wp_lua_scripting_plugin_class_init (WpLuaScriptingPluginClass * klass) { WpPluginClass *plugin_class = (WpPluginClass *) klass; WpComponentLoaderClass *cl_class = (WpComponentLoaderClass *) klass; plugin_class->enable = wp_lua_scripting_plugin_enable; plugin_class->disable = wp_lua_scripting_plugin_disable; cl_class->supports_type = wp_lua_scripting_plugin_supports_type; cl_class->load = wp_lua_scripting_plugin_load; } WP_PLUGIN_EXPORT gboolean wireplumber__module_init (WpCore * core, GVariant * args, GError ** error) { wp_plugin_register (g_object_new (wp_lua_scripting_plugin_get_type (), "name", "lua-scripting", "core", core, NULL)); return TRUE; }