When writing a custom SPA plugin, it is very useful to get more detailed
errors related to libdl. One common error is that a symbol is not present
because a related library was not properly linked into the plugin. With
this change, the error will tell the user about the exact missing symbol.
This gets the next key and value from an object. This function is better
because it will skip key/value pairs that don't fit in the array to hold
the key.
The previous code patter would stop parsing the object as soon as a key
larger than the available space was found.
Add struct spa_error_location that holds information about some parsing
context such as the line and column number, error and line fragment
with the error.
Make spa_json_get_error() fill in the spa_error_location instead. Add
some error codes to the error state and use this to add a parsing reason
to the location.
Add a debug function to log the error location in a nice way. Also
add a FILE based debug context to log to any FILE.
Replace pw_properties_check_string() with
pw_properties_update_string_checked() and add
pw_properties_new_string_checked(). The check string behaviour can still
be done by setting props to NULL but the main purpose is to be able to
avoid parsing the json file twice in the future.
When using the old pw_properties_update_string(), log a warning to the
log when we fail to parse the complete string.
Use the new checked functions and the debug functions to report about
parsing errors in the tools and conf parsing.
This gives errors like:
```
> pw-loopback --playback-props '{ foo = [ f : g ] }'
error: syntax error in --playback-props: Invalid array separator
line: 1 | { foo = [ f : g ] }
col: 14 | ^
```
Support reading from stdin and report syntax errors.
Also don't do extra spa_json_enter when inserting a dummy "{" when
parsing files with top-level keys. In this case the tokenizer is
already "entered" after spa_json_init, and will give parse error when we
are not inserting the closing "}" for the dummy "{".
This is more in line with wayland and it allows us to create new
interfaces in modules without having to add anything to the type
enum. It also removes some lookups to map type_id to readable
name in debug.
FreeBSD doesn't provide timerfd and eventfd functions. These are implemented in
3rd party library called epoll-shim. Link targets requiring these functions to
this library.
Remove the monitor API, we can use the device API for it. Make sure
we support creating devices (like alsa) from another device (udev).
Use new object.id to store the object id in the object properties. Use
the port.id/node.id etc to make relations to other objects.
Define a set of standard factory names and document what they
contain. This makes it possible to change the implementation by
mapping the factory-name to a different shared library.
The interface struct has the type,version and methods of the
interface.
Make spa interfaces extend from spa_interface and make a
separate structure for the methods.
Pass a generic void* as the first argument of methods, like
we don in PipeWire.
Bundle the methods + implementation in a versioned inteface
and use that to invoke methods. This way we can do version
checks on the methods.
Make resource and proxy interfaces that we can can call. We
can then make the core interfaces independent on proxy/resource and
hide them in the lower layers.
Add add_listener method to methods of core interfaces, just
like SPA.
Make struct spa_node_events for events emited from the main thread
and keep the spa_node_callbacks for the data thread callbacks.
The add_listener method installs the events and it's possible to
install multiple handles. Adding a listener first emits the info
and port_info events when installed, similar to how the PipeWire
proxy bind works.
This removes the need for the spa_pending_queue and makes it easier
to implement the _sync versions.
Add some helpers to make it easier for plugins to emit all the info
to new listeners.
Use the listeners for devices as well.
Add a new struct spa_param_info that lists the available params on
a node/port and if they are readable/writable/updated. We can use
this to replace and improve the PARAM_List and also to notify
property change and updates.
Update elements and code to deal with this new param stuff. Add
port and node info to most elements and signal changes.
Use async enum_params in -inspect and use the param info to know
which ones to enumerate.
Use the port info to know what parameters to update in the
remote-node.
Don't use special callback in node to receive the results. Instead,
use a generic result callback to receive the result. This makes things
a bit more symetric and generic again because then you can choose how
to match the result to the request and you have a generic way to handle
both the sync and async case. We can then also remove the wait method.
This also makes the remote interface and spa interface to objects very
similar.
Make a helper object to receive and dispatch results. Use this in the
helper for enum_params.
Make device use the same result callbacks.
Remove the done and error callbacks. The error callback is in an
error message. The done callback is replace with spa_pending.
Make enum_params take a callback and data for the results. This allows
us to push the results one after another to the app and avoids ownership
issues of the passed data. We can then extend this to handle the async
case by doing a _wait call with a spa_pending+callback+data that will
be called when the _enum_params returns and async result.
Add a sync method.
All methods can now return SPA_RESULT_IS_ASYNC return values and you
can use spa_node_wait() to register a callback when they complete
with optional extra parameters. This makes it easier to sync and
handle the reply.
Make helper methods to simulate the sync enum_params behaviour for
sync nodes.
Let the transport generate the sequence number for pw_resource_sync()
and pw_proxy_sync(). That way we don't need to keep track of numbers
ourselves and we can match the reply to the request easily.
Add return values to events and method callbacks. This makes it
possible to pass any error or async return value.
Add sync/done/error in both directions so that both proxy and resource
and perform/reply sync and produce errors.
Return a SPA_ASYNC from remote method calls (and events), keep the
sequence number in the connection.
With the core sync/done we can remove the client-node done method and
it's internal sequence number along with the seq number in method calls.
We can also use the method/event async return value to perform a sync
with as the unique sequence number for this method.
Add sync method and done/error event to proxy and resource.
Add a port_info event. With this, we get updates to ports pushed to
us, which is more convenient and also allows for better dynamic
add/remove of ports.
We don't need to the PortChanged event anymore
We can remove the get_port_ids/get_n_ports/port_get_info methods.
Update plugins