14template <
typename Closure>
15auto runWithEventLoopLock(Closure &&closure)
17 auto instance = QPipeWireInstance::instance();
19 return instance->runWithEventLoopLock(
std::forward<Closure>(closure));
31 :
m_sequenceNumber(s_sequenceNumberAllocator.fetch_add(1, std::memory_order_relaxed))
47 static constexpr struct pw_node_events nodeEvents{
48 .version = PW_VERSION_NODE_EVENTS,
49 .info = NodeEventListener::onInfo,
50 .param = NodeEventListener::onParam,
53 int status = pw_node_add_listener(m_node.get(), &m_listenerHook, &nodeEvents,
this);
55 qFatal() <<
"Failed to add listener: " << make_error_code(-status).message();
61 runWithEventLoopLock([&] {
68 int status = pw_node_enum_params(m_node.get(), m_sequenceNumber, type, 0, 0,
nullptr);
70 qCritical() <<
"pw_node_enum_params failed:" << make_error_code(-status).message();
76 if (self->m_handler.infoHandler)
77 self->m_handler.infoHandler(info);
80void NodeEventListener::onParam(
void *data,
int seq, uint32_t id, uint32_t index, uint32_t next,
84 if (self->m_handler.paramHandler)
85 self->m_handler.paramHandler(seq, id, index, next, param);
94 coreEvents.version = PW_VERSION_CORE_EVENTS;
99 runWithEventLoopLock([&] {
110 coreEvents.done = [](
void *self, uint32_t id,
int seq) {
111 Q_ASSERT(QPipeWireInstance::instance()->isInPwThreadLoop());
112 CoreEventDoneListener *listener =
reinterpret_cast<CoreEventDoneListener *>(self);
113 if (id == PW_ID_CORE && listener->m_seqnum == seq) {
114 listener->m_seqnum = -1;
115 if (
auto handler = std::exchange(listener->m_handler, {}))
122 std::function<
void()> handler)
124 m_handler = std::move(handler);
126 return runWithEventLoopLock([&]() -> q23::expected<
void,
int> {
127 int status = pw_core_add_listener(coreConnection, &m_listenerHook, &coreEvents,
this);
129 qFatal() <<
"pw_core_add_listener failed" << make_error_code(-status).message();
130 return q23::unexpected(status);
133 Q_ASSERT(m_seqnum == -1);
134 status = pw_core_sync(coreConnection, PW_ID_CORE, 0);
136 return q23::unexpected(status);