docs: shuffle files to have the same logical hierarchy as on the generated doc

Also:
 - rename some files to remove redundant information from the filenames
 - rename many labels to match the filename and its place in the hierarchy
 - move lua_api under the scripting section
This commit is contained in:
George Kiagiadakis
2023-12-23 12:36:27 +02:00
parent 7dfc346a7b
commit f3f89b8fc1
87 changed files with 82 additions and 63 deletions

View File

@@ -0,0 +1,144 @@
.. _lua_core_api:
Core
====
The :ref:`WpCore <core_api>` API is mostly transparent to lua, as the core
object is not exposed to the scripts.
For some functionality, though, the following static functions are exposed.
.. function:: Core.get_properties()
Binds :c:func:`wp_core_get_properties`
Returns a table with the properties of the core. These are the same
properties that appear on WirePlumber's *client* object in the PipeWire
global registry.
:returns: the properties of the core
:rtype: table
.. function:: Core.get_info()
Returns a table with information about the core. The table contains
the following fields:
=========== ===========
Field Contains
=========== ===========
cookie The value of :c:func:`wp_core_get_remote_cookie`
name The value of :c:func:`wp_core_get_remote_name`
user_name The value of :c:func:`wp_core_get_remote_user_name`
host_name The value of :c:func:`wp_core_get_remote_host_name`
version The value of :c:func:`wp_core_get_remote_version`
properties The value of :c:func:`wp_core_get_remote_properties`
=========== ===========
:returns: information about the core
:rtype: table
.. function:: Core.idle_add(callback)
Binds :c:func:`wp_core_idle_add_closure`
Schedules to call *callback* the next time that the event loop will be idle
:param function callback: the function to call; the function takes no
arguments and must return true/false, as it is a GSourceFunc:
return true to have the event loop call it again the next time it is idle,
false to stop calling it and remove the associated GSource
:returns: the GSource associated with this idle callback
:rtype: GSource, see :func:`GSource.destroy`
.. function:: Core.timeout_add(timeout_ms, callback)
Binds :c:func:`wp_core_timeout_add_closure`
Schedules to call *callback* after *timeout_ms* milliseconds
:param function callback: the function to call; the function takes no
arguments and must return true/false, as it is a GSourceFunc:
return true to have the event loop call it again periodically every
*timeout_ms* milliseconds, false to stop calling it and remove the
associated GSource
:returns: the GSource associated with this idle callback
:rtype: GSource, see :func:`GSource.destroy`
.. function:: GSource.destroy(self)
For the purpose of working with :func:`Core.idle_add` and
:func:`Core.timeout_add`, the GSource object that is returned by those
functions contains this method.
Call this method to destroy the source, so that the associated callback
is not called again. This can be used to stop a repeating timer callback
or just to abort some idle operation
This method binds *g_source_destroy*
.. function:: Core.sync(callback)
Binds :c:func:`wp_core_sync`
Calls *callback* after synchronizing the transaction state with PipeWire
:param function callback: a function to be called after syncing with PipeWire;
the function takes one argument that will be an error string, if something
went wrong and nil otherwise and returns nothing
.. function:: Core.quit()
Quits the current *wpexec* process
.. note::
This can only be called when the script is running in *wpexec*;
if it is running in the main WirePlumber daemon, it will print
a warning and do nothing
.. function:: Core.require_api(..., callback)
Ensures that the specified API plugins are loaded.
API plugins are plugins that provide some API extensions for use in scripts.
These plugins must always have their name end in "-api" and the names
specified here must not have the "-api" extension.
For instance, the "mixer-api" module provides an API to change volume/mute
controls from scripts, via action signals. It can be used like this:
.. code-block:: lua
Core.require_api("mixer", function(mixer)
-- get the volume of node 35
local volume = mixer:call("get-volume", 35)
-- the return value of "get-volume" is a GVariant(a{sv}),
-- which gets translated to a Lua table
Debug.dump_table(volume)
end)
See also the example in :func:`GObject.call`
.. note::
This can only be called when the script is running in *wpexec*;
if it is running in the main WirePlumber daemon, it will print
a warning and do nothing
:param strings ...: a list of string arguments, which specify the names of
the api plugins to load, if they are not already loaded
:param callback: the function to call after the plugins have been loaded;
this function takes references to the plugins as parameters
.. function:: Core.test_feature()
Binds :c:func:`wp_core_test_feature`
Tests if the specified feature is provided in the current WirePlumber
configuration.
:param string feature: the name of the feature to test
:returns: true if the feature is provided, false otherwise
:rtype: boolean

View File

@@ -0,0 +1,300 @@
.. _lua_gobject:
GObject Integration
===================
The Lua engine that powers WirePlumber's scripts provides direct integration
with `GObject`_. Most of the objects that you will deal with in the lua scripts
are wrapping GObjects. In order to work with the scripts, you will first need
to have a basic understanding of GObject's basic concepts, such as signals and
properties.
Properties
----------
All GObjects have the ability to have `properties`_.
In C we normally use `g_object_get`_ to retrieve them and `g_object_set`_
to set them.
In WirePlumber's lua engine, these properties are exposed as object members
of the Lua object.
For example:
.. code-block:: lua
-- read the "bound-id" GObject property from the proxy
local proxy = function_that_returns_a_wp_proxy()
local proxy_id = proxy["bound-id"]
print("Bound ID: " .. proxy_id)
Writable properties can also be set in a similar fashion:
.. code-block:: lua
-- set the "scale" GObject property to the enum value "cubic"
local mixer = ...
mixer["scale"] = "cubic"
Signals
-------
GObjects also have a generic mechanism to deliver events to external callbacks.
These events are called `signals`_.
To connect to a signal and handle it, you may use the *connect* method:
.. function:: GObject.connect(self, detailed_signal, callback)
Connects the signal to a callback. When the signal is emitted by the
underlying object, the callback will be executed.
The signature of the callback is expected to match the signature of the
signal, with the first parameter being the object itself.
**Example:**
.. code-block:: lua
-- connects the "bound" signal from WpProxy to a callback
local proxy = function_that_returns_a_wp_proxy()
proxy:connect("bound", function(p, id)
print("Proxy " .. tostring(p) .. " bound to " .. tostring(id))
end)
In this example, the ``p`` variable in the callback is the ``proxy`` object,
while ``id`` is the first parameter of the *"bound"* signal, as documented
in :c:struct:`WpProxy`
:param detailed_signal: the signal name to listen to
(of the form "signal-name::detail")
:param callback: a lua function that will be called when the signal is emitted
Signals may also be used as a way to have dynamic methods on objects. These
signals are meant to be called by external code and not handled. These signals
are called **action signals**.
You may call an action signal using the *call* method:
.. function:: GObject.call(self, action_signal, ...)
Calls an action signal on this object.
**Example:**
.. code-block:: lua
Core.require_api("default-nodes", "mixer", function(...)
local default_nodes, mixer = ...
-- "get-default-node" and "get-volume" are action signals of the
-- "default-nodes-api" and "mixer-api" plugins respectively
local id = default_nodes:call("get-default-node", "Audio/Sink")
local volume = mixer:call("get-volume", id)
-- the return value of "get-volume" is a GVariant(a{sv}),
-- which gets translated to a Lua table
Debug.dump_table(volume)
end)
:param action_signal: the signal name to call
:param ...: a list of arguments that will be passed to the signal
:returns: the return value of the action signal, if any
Type conversions
----------------
When working with GObject properties and signals, variables need to be
converted from C types to Lua types and vice versa. The following tables
list the type conversions that happen automatically:
C to Lua
^^^^^^^^
Conversion from C to lua is based on the C type.
================================ ===============================================
C Lua
================================ ===============================================
gchar, guchar, gint, guint integer
glong, gulong, gint64, guint64 integer
gfloat, gdouble number
gboolean boolean
gchar * string
gpointer lightuserdata
WpProperties * table (keys: string, values: string)
enum string containing the nickname (short name) of
the enum, or integer if the enum is not
registered with GType
flags integer (as in C)
GVariant * a native type, see below
other GObject, GInterface userdata holding reference to the object
other GBoxed userdata holding reference to the object
================================ ===============================================
.. _lua_gobject_lua_to_c:
Lua to C
^^^^^^^^
Conversion from Lua to C is based on the expected type in C.
============================== ==================================================
Expecting Lua
============================== ==================================================
gchar, guchar, gint, guint, convertible to integer
glong, gulong, gint64, guint64 convertible to integer
gfloat, gdouble convertible to number
gboolean convertible to boolean
gchar * convertible to string
gpointer must be lightuserdata
WpProperties * must be table (keys: string, values: convertible
to string)
enum must be string holding the nickname of the enum,
or convertible to integer
flags convertible to integer
GVariant * see below
other GObject, GInterface must be userdata holding a compatible GObject type
other GBoxed must be userdata holding the same GBoxed type
============================== ==================================================
GVariant to Lua
^^^^^^^^^^^^^^^
============================= =============================================
GVariant Lua
============================= =============================================
NULL or G_VARIANT_TYPE_UNIT nil
G_VARIANT_TYPE_INT16 integer
G_VARIANT_TYPE_INT32 integer
G_VARIANT_TYPE_INT64 integer
G_VARIANT_TYPE_UINT16 integer
G_VARIANT_TYPE_UINT32 integer
G_VARIANT_TYPE_UINT64 integer
G_VARIANT_TYPE_DOUBLE number
G_VARIANT_TYPE_BOOLEAN boolean
G_VARIANT_TYPE_STRING string
G_VARIANT_TYPE_VARIANT converted recursively
G_VARIANT_TYPE_DICTIONARY table (keys & values converted recursively)
G_VARIANT_TYPE_ARRAY table (children converted recursively)
============================= =============================================
Lua to GVariant
^^^^^^^^^^^^^^^
Conversion from Lua to GVariant is based on the lua type and is quite limited.
There is no way to recover an array, for instance, because there is no way
in Lua to tell if a table contains an array or a dictionary. All Lua tables
are converted to dictionaries and integer keys are converted to strings.
========= ================================
Lua GVariant
========= ================================
nil G_VARIANT_TYPE_UNIT
boolean G_VARIANT_TYPE_BOOLEAN
integer G_VARIANT_TYPE_INT64
number G_VARIANT_TYPE_DOUBLE
string G_VARIANT_TYPE_STRING
table G_VARIANT_TYPE_VARDICT (a{sv})
========= ================================
Closures
--------
When a C function is expecting a GClosure, in Lua it is possible to pass
a Lua function directly. The function is then wrapped into a custom GClosure.
When this GClosure is invalidated, the reference to the Lua function is dropped.
Similarly, when the lua engine is stopped, all the GClosures that were
created by this engine are invalidated.
Reference counting
------------------
GObject references in Lua always hold a reference to the underlying GObject.
When moving this reference around to other variables in Lua, the underlying
GObject reference is shared, but Lua reference counts the wrapper "userdata"
object.
.. code-block:: lua
-- creating a new FooObject instance; obj holds the GObject reference
local obj = FooObject()
-- GObject reference is dropped and FooObject is finalized
obj = nil
.. code-block:: lua
-- creating a new FooObject instance; obj holds the GObject reference
local obj = FooObject()
function store_global(o)
-- o is now stored in the global 'obj_global' variable
-- the GObject ref count is still 1
obj_global = o
end
-- obj userdata reference is passed to o, the GObject ref count is still 1
store_global(obj)
-- userdata reference dropped from obj, the GObject is still alive
obj = nil
-- userdata reference dropped from obj_global,
-- the GObject ref is dropped and FooObject is finalized
obj_global = nil
.. note::
When assigning a variable to nil, Lua may not immediately drop
the reference of the underlying object. This is because Lua uses a garbage
collector and goes through all the unreferenced objects to cleanup when
the garbage collector runs.
When a GObject that is already referenced in Lua re-appears somewhere else
through calling some API or because of a callback from C, a new reference is
added on the GObject.
.. code-block:: lua
-- ObjectManager is created in Lua, om holds 1 ref
local om = ObjectManager(...)
om:connect("objects-changed", function (om)
-- om in this scope is a local function argument that was created
-- by the signal's closure marshaller and holds a second reference
-- to the ObjectManager
do_some_stuff()
-- this second reference is dropped when the function goes out of scope
end)
.. danger::
Because Lua variables hold strong references to GObjects, it is dangerous
to create closures that reference such variables, because these closures
may create reference loops and **leak** objects
.. code-block:: lua
local om = ObjectManager(...)
om:connect("objects-changed", function (obj_mgr)
-- using 'om' here instead of the local 'obj_mgr'
-- creates a dangerous reference from the closure to 'om'
for obj in om:iterate() do
do_stuff(obj)
end
end)
-- local userdata reference dropped, but the GClosure that was generated
-- from the above function is still holding a reference and keeps
-- the ObjectManager alive; the GClosure is referenced by the ObjectManager
-- because of the signal connection, so the ObjectManager is leaked
om = nil
.. _GObject: https://developer.gnome.org/gobject/stable/
.. _properties: https://developer.gnome.org/gobject/stable/gobject-properties.html
.. _g_object_get: https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-get
.. _g_object_set: https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-set
.. _signals: https://developer.gnome.org/gobject/stable/signal.html

View File

@@ -0,0 +1,63 @@
.. _lua_introduction:
Introduction
============
`Lua <https://www.lua.org/>`_ is a powerful, efficient, lightweight,
embeddable scripting language.
WirePlumber uses `Lua version 5.4 <https://www.lua.org/versions.html>`_ to
implement its engine. For older systems, Lua 5.3 is also supported.
Scripts can be ran with the ``wpexec`` tool.
Example scripts can be found in the `tests/examples` directory of the wireplumber source tree.
Lua Reference
-------------
If you are not familiar with the Lua language and its API, please refer to
the `Lua 5.4 Reference Manual <https://www.lua.org/manual/5.4/manual.html>`_
Sandbox
-------
WirePlumber's scripting engine sandboxes the lua scripts to a safe environment.
In this environment, the following rules apply:
- Scripts are isolated from one another; global variables in one script
are not visible from another, even though they are actually executed in
the same ``lua_State``
- Tables that hold API methods are not writable. While this may sound strange,
standard Lua allows you to change standard API, for instance
``string.format = rogue_format`` is valid outside the sandbox.
WirePlumber does not allow that.
- The standard Lua API is limited to a subset of safe functions. For instance,
functions that interact with the file system (io.*) and the process's state
(ex.: os.exit) are **not** allowed.
Here is a full list of Lua functions (and API tables) that are exposed:
.. literalinclude:: ../../../../modules/module-lua-scripting/wplua/sandbox.lua
:language: lua
:lines: 27-30
- Object methods are not exposed in public tables. To call an object method
you must use the method call syntax of Lua, i.e. ``object:method(params)``
The following, for instance, is **not** valid:
.. code-block:: lua
-- this will cause an exception
local node = ...
Node.send_command(node, "Suspend")
The correct form is this:
.. code-block:: lua
local node = ...
node:send_command("Suspend")

View File

@@ -0,0 +1,26 @@
.. _lua_local_module_api:
Local Modules
=============
The `LocalModule` object (which binds the :c:struct:`WpImplModule` C API) provides a way
to load PipeWire modules in the WirePlumber process. Instantiating the object
loads the module, and when the last reference to the returned module object is
dropped, the module is unloaded.
Constructors
~~~~~~~~~~~~
.. function:: LocalModule(name, arguments, properties)
Loads the named module with the provided arguments and properties (either of
which can be ``nil``).
:param string name: the module name, such as ``"libpipewire-module-loopback"``
:param string arguments: should be either ``nil`` or a string with the desired
module arguments
:param table properties: can be ``nil`` or a table that can be
:ref:`converted <lua_gobject_lua_to_c>` to :c:struct:`WpProperties`
:returns: a new LocalModule
:rtype: LocalModule (:c:struct:`WpImplModule`)
:since: 0.4.2

View File

@@ -0,0 +1,56 @@
.. _lua_log_api:
Debug Logging
=============
.. function:: Log.warning(object, message)
Logs a warning message, like :c:macro:`wp_warning_object`
:param object: optional object to associate the message with; you
may skip this and just start with the *message* as the first parameter
:type object: GObject or GBoxed
:param string message: the warning message to log
.. function:: Log.notice(object, message)
Logs a notice message, like :c:macro:`wp_notice_object`
:param object: optional object to associate the message with; you
may skip this and just start with the *message* as the first parameter
:type object: GObject or GBoxed
:param string message: the normal message to log
.. function:: Log.info(object, message)
Logs a info message, like :c:macro:`wp_info_object`
:param object: optional object to associate the message with; you
may skip this and just start with the *message* as the first parameter
:type object: GObject or GBoxed
:param string message: the info message to log
.. function:: Log.debug(object, message)
Logs a debug message, like :c:macro:`wp_debug_object`
:param object: optional object to associate the message with; you
may skip this and just start with the *message* as the first parameter
:type object: GObject or GBoxed
:param string message: the debug message to log
.. function:: Log.trace(object, message)
Logs a trace message, like :c:macro:`wp_trace_object`
:param object: optional object to associate the message with; you
may skip this and just start with the *message* as the first parameter
:type object: GObject or GBoxed
:param string message: the trace message to log
.. function:: Debug.dump_table(t)
Prints a table with all its contents, recursively, to stdout
for debugging purposes
:param table t: any table

View File

@@ -0,0 +1,4 @@
.. _lua_object_api:
WpObject
========

View File

@@ -0,0 +1,189 @@
.. _lua_object_interest_api:
Object Interest
===============
The Interest object allows you to declare interest in a specific object, or
a set of objects, and filter them. This is used in the
:ref:`ObjectManager <lua_object_manager_api>` but also in other places where
methods allow you to iterate over a set of objects or lookup a specific object.
*Interest* is a binding of :c:struct:`WpObjectInterest`, but it uses a
Lua-idiomatic way of construction instead of mapping directly the C functions,
for convenience.
Construction
~~~~~~~~~~~~
The most common use for *Interest* is in the
:ref:`ObjectManager <lua_object_manager_api>`, where you have to use the
following construction method to create it.
.. function:: Interest(decl)
:param table decl: an interest declaration
:returns: the interest
:rtype: Interest (:c:struct:`WpObjectInterest`)
The interest consists of a GType and an array of constraints. It is constructed
with a table that contains all the constraints, plus the GType in the ``type``
field.
.. code-block:: lua
local om = ObjectManager {
Interest {
type = "node",
Constraint { "node.name", "matches", "alsa*", type = "pw-global" },
Constraint { "media.class", "equals", "Audio/Sink", type = "pw-global" },
}
}
In the above example, the interest will match all objects of type
:c:struct:`WpNode` that contain the following 2 global properties:
- "node.name", with a value that begins with the string "alsa"
- "media.class", with a value that equals exactly the string "Audio/Sink"
When an object method requires an *Interest* as an argument, you may as well
directly pass the declaration table as argument instead of using the
:func:`Interest` constructor function. For instance,
.. code-block:: lua
local fl_port = node:lookup_port {
Constraint { "port.name", "equals", "playback_FL" }
}
In the above example, we lookup a port in a node. The :func:`Node.lookup_port`
method takes an *Interest* as an argument, but we can pass the interest
declaration table directly. Note also that such a method does not require
declaring the ``type`` of the interest, as it has :c:struct:`WpPort` as a
hardcoded default.
The type
........
The type of an interest must be a valid GType, written as a string without the
"Wp" prefix and with the first letter optionally being lowercase. The type may
match any wireplumber object or interface.
Examples:
============= ============
type string parsed as
============= ============
node WpNode
Node WpNode
device WpDevice
plugin WpPlugin
siLink WpSiLink
SiLink WpSiLink
properties WpProperties
============= ============
The Constraint
..............
The *Constraint* is constructed also with a table, like *Interest* itself. This
table must have the following items in this very strict order:
- a subject string: a string that specifies the name of a property to match
- a verb string: a string that specifies the match operation
- an object, if the verb requires it
The verb may be any verb listed in :c:enum:`WpConstraintVerb`, using either
the nickname of the enum or the character value of it.
Allowed verbs:
============ ========= =======================================
nickname character value
============ ========= =======================================
"equals" "=" :c:enum:`WP_CONSTRAINT_VERB_EQUALS`
"not-equals" "!" :c:enum:`WP_CONSTRAINT_VERB_NOT_EQUALS`
"in-list" "c" :c:enum:`WP_CONSTRAINT_VERB_IN_LIST`
"in-range" "~" :c:enum:`WP_CONSTRAINT_VERB_IN_RANGE`
"matches" "#" :c:enum:`WP_CONSTRAINT_VERB_MATCHES`
"is-present" "+" :c:enum:`WP_CONSTRAINT_VERB_IS_PRESENT`
"is-absent" "-" :c:enum:`WP_CONSTRAINT_VERB_IS_ABSENT`
============ ========= =======================================
The values that are expected for each verb are primarily documented in
:c:func:`wp_object_interest_add_constraint`. In Lua, though, native types are
expected instead of GVariant and then they are converted according to the rules
documented in the :ref:`GObject Integration <lua_gobject>` page.
Examples of constraints:
.. code-block:: lua
Constraint { "node.id", "equals", "42" }
Constraint { "node.id", "equals", 42 }
Constraint { "port.physical", "=", true }
Constraint { "audio.channel", "not-equals", "FL" }
Constraint { "node.name", "matches", "v4l2_input*" }
Constraint { "format.dsp", "#", "*mono audio*" }
-- matches either "default" or "settings" as a possible value for "metadata.name"
Constraint { "metadata.name", "in-list", "default", "settings" }
-- matches any priority.session between 0 and 1000, inclusive
Constraint { "priority.session", "in-range", 0, 1000 }
-- matches when the object has a "media.role" property
Constraint { "media.role", "is-present" }
-- matches when "media.role" is not present in the properties list
Constraint { "media.role", "is-absent" }
Constraint types
................
PipeWire objects have multiple properties lists, therefore constraints also need
to have a way to specify on which property list they apply. The constraint type
may be any of the types listed in :c:enum:`WpConstraintType` and can be
specified with an additional field in the *Constraint* construction table,
called ``type``.
For instance:
.. code-block:: lua
Constraint { "node.id", "equals", "42", type = "pw-global" }
Constraint { "api.alsa.card.name", "matches", "*Intel*", type = "pw" }
Constraint { "bound-id", "=", 42, type = "gobject" }
Valid types are:
========= ===============================================
type value
========= ===============================================
pw-global :c:enum:`WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY`
pw :c:enum:`WP_CONSTRAINT_TYPE_PW_PROPERTY`
gobject :c:enum:`WP_CONSTRAINT_TYPE_G_PROPERTY`
========= ===============================================
Methods
~~~~~~~
.. function:: Interest.matches(self, obj)
Binds :c:func:`wp_object_interest_matches`
Checks if a specific object matches the interest. The object may be a GObject
or a table convertible to :c:struct:`WpProperties`, if the interest is for
properties.
This is rarely useful to use directly on objects, but it may be useful to
check if a specific table contains key-value pairs that match specific
constraints, using "properties" as the interest type and passing a table as
the object.
:param self: the interest
:param obj: an object to check for a match
:type obj: GObject or table
:returns: whether the object matches the interest
:rtype: boolean

View File

@@ -0,0 +1,104 @@
.. _lua_object_manager_api:
Object Manager
==============
The ObjectManager (binding for :c:struct:`WpObjectManager`) provides a way to
collect a set of objects and be notified when objects that fulfill a certain
set of criteria are created or destroyed.
To start an object manager, you first need to declare interest in a certain
kind of object specifying a set of :ref:`Interests <lua_object_interest_api>`
in the constructor and then you need to activate it by calling
:func:`ObjectManager.activate`
Upon activating an ObjectManager, any pre-existing objects that match the
specified interests will immediately become available to get through
:func:`ObjectManager.iterate` and the :c:struct:`WpObjectManager` "object-added"
signal will be emitted for all of them.
Constructors
~~~~~~~~~~~~
.. function:: ObjectManager(interest_list)
Constructs a new object manager.
Combines :c:func:`wp_object_manager_new` and
:c:func:`wp_object_manager_add_interest_full`
The argument needs to be a table that contains one or more
:ref:`Interest <lua_object_interest_api>` objects. The object manager
will then contain all objects that match any one of the supplied interests.
Example:
.. code-block:: lua
streams_om = ObjectManager {
-- match stream nodes
Interest {
type = "node",
Constraint { "media.class", "matches", "Stream/*", type = "pw-global" },
},
-- and device nodes that are not associated with any routes
Interest {
type = "node",
Constraint { "media.class", "matches", "Audio/*", type = "pw-global" },
Constraint { "device.routes", "equals", "0", type = "pw" },
},
Interest {
type = "node",
Constraint { "media.class", "matches", "Audio/*", type = "pw-global" },
Constraint { "device.routes", "is-absent", type = "pw" },
},
}
The above example will create an ObjectManager that matches all nodes with
a "media.class" global property that starts with the string "Stream/"
and additionally all those whose "media.class" starts with "Audio/" and
they have either a "device.routes" property that equals zero or they
don't have a "device.routes" property at all.
:param table interest_list: a list of :ref:`interests <lua_object_interest_api>`
to objects
:returns: a new object manager
:rtype: ObjectManager (:c:struct:`WpObjectManager`)
Methods
~~~~~~~
.. function:: ObjectManager.activate(self)
Activates the object manager.
Binds :c:func:`wp_core_install_object_manager`.
:param self: the object manager
.. function:: ObjectManager.get_n_objects(self)
Binds :c:func:`wp_object_manager_get_n_objects`
:param self: the object manager
:returns: the number of objects managed by the object manager
:rtype: integer
.. function:: ObjectManager.iterate(self, interest)
Binds :c:func:`wp_object_manager_new_filtered_iterator_full`
:param self: the object manager
:param interest: an interest to filter objects
:type interest: :ref:`Interest <lua_object_interest_api>` or nil or none
:returns: all the managed objects that match the interest
:rtype: Iterator; the iteration items are of type :ref:`GObject <lua_gobject>`
.. function:: ObjectManager.lookup(self, interest)
Binds :c:func:`wp_object_manager_lookup`
:param self: the object manager
:param interest: the interest to use for the lookup
:type interest: :ref:`Interest <lua_object_interest_api>` or nil or none
:returns: the first managed object that matches the interest
:rtype: :ref:`GObject <lua_gobject>`

View File

@@ -0,0 +1,200 @@
.. _lua_proxies_api:
PipeWire Proxies
================
Proxy
.....
Lua objects that bind a :ref:`WpProxy <proxy_api>` contain the following methods:
.. function:: Proxy.get_interface_type(self)
Binds :c:func:`wp_proxy_get_interface_type`
:param self: the proxy
:returns: the proxy type, the proxy type version
:rtype: string, integer
PipeWire Object
...............
Lua objects that bind a :ref:`WpPipewireObject <pipewire_object_api>`
contain the following methods:
.. function:: PipewireObject.iterate_params(self, param_name)
Binds :c:func:`wp_pipewire_object_enum_params_sync`
:param self: the proxy
:param string param_name: the PipeWire param name to enumerate,
ex "Props", "Route"
:returns: the available parameters
:rtype: Iterator; the iteration items are Spa Pod objects
.. function:: PipewireObject.set_param(self, param_name, pod)
Binds :c:func:`wp_pipewire_object_set_param`
:param self: the proxy
:param string param_name: The PipeWire param name to set, ex "Props", "Route"
:param Pod pod: A Spa Pod object containing the new params
Global Proxy
............
Lua objects that bind a :ref:`WpGlobalProxy <global_proxy_api>`
contain the following methods:
.. function:: GlobalProxy.request_destroy(self)
Binds :c:func:`wp_global_proxy_request_destroy`
:param self: the proxy
PipeWire Node
.............
Lua objects that bind a :ref:`WpNode <node_api>` contain the following methods:
.. function:: Node.get_state(self)
Binds :c:func:`wp_node_get_state`
:param self: the proxy
:returns: the current state of the node and an error message, if any
:rtype: string (:c:enum:`WpNodeState`), string (error message)
:since: 0.4.2
.. function:: Node.get_n_input_ports(self)
Binds :c:func:`wp_node_get_n_input_ports`
:param self: the proxy
:returns: the current and max numbers of input ports on the node
:rtype: integer (current), integer (max)
:since: 0.4.2
.. function:: Node.get_n_output_ports(self)
Binds :c:func:`wp_node_get_n_output_ports`
:param self: the proxy
:returns: the current and max numbers of output ports on the node
:rtype: integer (current), integer (max)
:since: 0.4.2
.. function:: Node.get_n_ports(self)
Binds :c:func:`wp_node_get_n_ports`
:param self: the proxy
:returns: the number of ports on the node
:since: 0.4.2
.. function:: Node.iterate_ports(self, interest)
Binds :c:func:`wp_node_iterate_ports`
:param self: the proxy
:param interest: an interest to filter objects
:type interest: :ref:`Interest <lua_object_interest_api>` or nil or none
:returns: all the ports of this node that that match the interest
:rtype: Iterator; the iteration items are of type :ref:`WpPort <port_api>`
:since: 0.4.2
.. function:: Node.lookup_port(self, interest)
Binds :c:func:`wp_node_lookup_port`
:param self: the proxy
:param interest: the interest to use for the lookup
:type interest: :ref:`Interest <lua_object_interest_api>` or nil or none
:returns: the first port of this node that matches the interest
:rtype: :ref:`WpPort <port_api>`
:since: 0.4.2
.. function:: Node.send_command(self, command)
Binds :c:func:`wp_node_send_command`
:param self: the proxy
:param string command: the command to send to the node (ex "Suspend")
PipeWire Port
.............
Lua objects that bind a :ref:`WpPort <port_api>` contain the following methods:
.. function:: Port.get_direction(self)
Binds :c:func:`wp_port_get_direction`
:param self: the port
:returns: the direction of the Port
:rtype: string (:c:enum:`WpDirection`)
:since: 0.4.2
PipeWire Client
...............
Lua objects that bind a :ref:`WpClient <client_api>`
contain the following methods:
.. function:: Client.update_permissions(self, perms)
Binds :c:func:`wp_client_update_permissions`
Takes a table where the keys are object identifiers and the values are
permission strings.
Valid object identifiers are:
- A number, meaning the bound ID of a proxy
- The string "any" or the string "all", which sets the default permissions
for this client
The permission strings have a chmod-like syntax (ex. "rwx" or "r-xm"), where:
- "r" means permission to read the object
- "w" means permission to write data to the object
- "x" means permission to call methods on the object
- "m" means permission to set metadata for the object
- "-" is ignored and can be used to make the string more readable when
a permission flag is omitted
**Example:**
.. code-block:: lua
client:update_permissions {
["all"] = "r-x",
[35] = "rwxm",
}
:param self: the proxy
:param table perms: the permissions to update for this client
PipeWire Metadata
.................
Lua objects that bind a :ref:`WpMetadata <metadata_api>`
contain the following methods:
.. function:: Metadata.iterate(self, subject)
Binds :c:func:`wp_metadata_new_iterator`
:param self: the proxy
:param integer subject: the subject id
:returns: an iterator
.. function:: Metadata.find(self, subject, key)
Binds :c:func:`wp_metadata_find`
:param self: the proxy
:param string subject: the subject id
:param string key: the metadata key to find
:returns: the value for this metadata key, the type of the value
:rtype: string, string

View File

@@ -0,0 +1,42 @@
.. _lua_session_item_api:
Session Item
============
Lua objects that bind a :ref:`WpSessionItem <session_item_api>`
contain the following methods:
.. function:: SessionItem.get_associated_proxy(self, type)
Binds :c:func:`wp_session_item_get_associated_proxy`
:param self: the session item
:param string type: the proxy type name
:returns: the proxy object or nil
.. function:: SessionItem.reset(self)
Binds :c:func:`wp_session_item_reset`
:param self: the session item
.. function:: SessionItem.configure(self, properties)
Binds :c:func:`wp_session_item_configure`
:param self: the session item
:param table properties: The configuration properties
:returns: true on success, false on failure
:rtype: boolean
.. function:: SessionItem.register(self)
Binds :c:func:`wp_session_item_register`
:param self: the session item
.. function:: SessionItem.remove(self)
Binds :c:func:`wp_session_item_remove`
:param self: the session item

View File

@@ -0,0 +1,21 @@
.. _lua_spa_device_api:
Spa Device
==========
.. function:: SpaDevice.get_managed_object(self, id)
Binds :c:func:`wp_spa_device_get_managed_object`
:param self: the spa device
:param integer id: the object id
:returns: the managed object or nil
.. function:: SpaDevice.store_managed_object(self, id, object)
Binds :c:func:`wp_spa_device_store_managed_object`
:param self: the spa device
:param integer id: the object id
:param GObject object: a GObject to store or nil to remove the existing
stored object

View File

@@ -0,0 +1,4 @@
.. _lua_spa_pod:
Spa Pod
=======

View File

@@ -0,0 +1,15 @@
# you need to add here any files you add to the toc directory as well
sphinx_files += files(
'lua_core_api.rst',
'lua_gobject.rst',
'lua_local_module_api.rst',
'lua_introduction.rst',
'lua_log_api.rst',
'lua_object_api.rst',
'lua_object_interest_api.rst',
'lua_object_manager_api.rst',
'lua_proxies_api.rst',
'lua_session_item_api.rst',
'lua_spa_device_api.rst',
'lua_spa_pod.rst',
)