86 lines
3.6 KiB
Go
86 lines
3.6 KiB
Go
// Cthulhu screen reader.
|
|
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package remote
|
|
|
|
import "github.com/godbus/dbus/v5/introspect"
|
|
|
|
// service_bindings builds exports in their existing registration order. Start
|
|
// performs exports and rollback; Stop reverses this list before releasing names.
|
|
func service_bindings(endpoint *endpoint, orca bool, handler Handler) []serviceBinding {
|
|
path, iface := ObjectPath, InterfaceName
|
|
if orca {
|
|
path, iface = OrcaObjectPath, OrcaInterfaceName
|
|
}
|
|
var mainEndpoint any = endpoint
|
|
if orca {
|
|
mainEndpoint = &orcaServiceEndpoint{endpoint: endpoint}
|
|
}
|
|
registrations := []serviceBinding{
|
|
{path, iface, mainEndpoint},
|
|
{path, "org.freedesktop.DBus.Introspectable", introspect.NewIntrospectable(&introspect.Node{
|
|
Name: string(path),
|
|
Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(orca)}},
|
|
})},
|
|
}
|
|
if !orca {
|
|
registrations[1].value = introspect.NewIntrospectable(&introspect.Node{
|
|
Name: string(path), Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(false)}},
|
|
Children: []introspect.Node{{Name: "SpeechManager"}},
|
|
})
|
|
registrations = append(registrations, serviceBinding{SpeechManagerPath, SpeechManagerInterface, &speechManagerEndpoint{endpoint: endpoint}})
|
|
registrations = append(registrations, serviceBinding{SpeechManagerPath, "org.freedesktop.DBus.Introspectable", introspect.NewIntrospectable(&introspect.Node{
|
|
Name: string(SpeechManagerPath),
|
|
Interfaces: []introspect.Interface{{Name: SpeechManagerInterface, Methods: []introspect.Method{
|
|
{Name: "InterruptSpeech", Args: []introspect.Arg{
|
|
{Name: "notify_user", Type: "b", Direction: "in"},
|
|
{Name: "accepted", Type: "b", Direction: "out"},
|
|
}},
|
|
}}},
|
|
})})
|
|
}
|
|
_, hasModules := handler.(ModuleHandler)
|
|
if available, ok := handler.(ModuleAvailability); ok && !available.RemoteModulesAvailable() {
|
|
hasModules = false
|
|
}
|
|
if hasModules {
|
|
children := make([]introspect.Node, 0, len(modules))
|
|
for _, spec := range modules {
|
|
module := &moduleEndpoint{endpoint: endpoint, spec: spec}
|
|
moduleObjectPath := modulePath(path, spec.name)
|
|
moduleIface := "org.stormux.Cthulhu1." + spec.name
|
|
var object any
|
|
if orca {
|
|
moduleIface = orcaModuleInterface
|
|
object = module
|
|
} else if spec.name == "SpeechManager" {
|
|
// SpeechManager was registered above for existing self-voice clients.
|
|
object = nil
|
|
} else {
|
|
object = &typingEchoEndpoint{endpoint: endpoint}
|
|
}
|
|
if object != nil {
|
|
registrations = append(registrations, serviceBinding{moduleObjectPath, moduleIface, object})
|
|
}
|
|
registrations = append(registrations, serviceBinding{moduleObjectPath, "org.freedesktop.DBus.Properties", &modulePropertiesEndpoint{module: module, iface: moduleIface}})
|
|
introspection := introspect.NewIntrospectable(&introspect.Node{
|
|
Name: string(moduleObjectPath), Interfaces: []introspect.Interface{spec.introspection(orca)},
|
|
})
|
|
if !orca && spec.name == "SpeechManager" {
|
|
registrations[3].value = introspection
|
|
} else {
|
|
registrations = append(registrations, serviceBinding{moduleObjectPath, "org.freedesktop.DBus.Introspectable", introspection})
|
|
}
|
|
children = append(children, introspect.Node{Name: spec.name})
|
|
}
|
|
root := &introspect.Node{Name: string(path), Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(orca)}}, Children: children}
|
|
registrations[1].value = introspect.NewIntrospectable(root)
|
|
if orca {
|
|
registrations[0].value = &orcaServiceEndpoint{endpoint: endpoint, modules: sortedModuleNames()}
|
|
}
|
|
}
|
|
return registrations
|
|
}
|