211 lines
5.1 KiB
Go
211 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
"github.com/rs/zerolog/log"
|
|
"go.arsenm.dev/infinitime"
|
|
)
|
|
|
|
const (
|
|
interfaceName = "io.github.rinigus.PureMaps.navigator"
|
|
iconProperty = interfaceName + ".icon"
|
|
narrativeProperty = interfaceName + ".narrative"
|
|
manDistProperty = interfaceName + ".manDist"
|
|
progressProperty = interfaceName + ".progress"
|
|
)
|
|
|
|
func initPureMaps(ctx context.Context, dev *infinitime.Device) error {
|
|
// Connect to session bus. This connection is for method calls.
|
|
conn, err := newSessionBusConn(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
exists, err := pureMapsExists(ctx, conn)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Connect to session bus. This connection is for method calls.
|
|
monitorConn, err := newSessionBusConn(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Define rules to listen for
|
|
var rules = []string{
|
|
"type='signal',interface='io.github.rinigus.PureMaps.navigator'",
|
|
}
|
|
var flag uint = 0
|
|
// Becode monitor for notifications
|
|
call := monitorConn.BusObject().CallWithContext(
|
|
ctx, "org.freedesktop.DBus.Monitoring.BecomeMonitor", 0, rules, flag,
|
|
)
|
|
if call.Err != nil {
|
|
return call.Err
|
|
}
|
|
|
|
var navigator dbus.BusObject
|
|
|
|
if exists {
|
|
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
|
|
err = setAll(navigator, dev)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error setting all navigation fields")
|
|
}
|
|
}
|
|
|
|
go func() {
|
|
signalCh := make(chan *dbus.Message, 10)
|
|
monitorConn.Eavesdrop(signalCh)
|
|
|
|
for {
|
|
select {
|
|
case sig := <-signalCh:
|
|
if sig.Type != dbus.TypeSignal {
|
|
continue
|
|
}
|
|
|
|
var member string
|
|
err = sig.Headers[dbus.FieldMember].Store(&member)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error getting dbus member field")
|
|
continue
|
|
}
|
|
|
|
if !strings.HasSuffix(member, "Changed") {
|
|
continue
|
|
}
|
|
|
|
log.Debug().Str("member", member).Msg("Signal received from PureMaps navigator")
|
|
|
|
// The object must be retrieved in this loop in case PureMaps was not
|
|
// open at the time ITD was started.
|
|
navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator")
|
|
member = strings.TrimSuffix(member, "Changed")
|
|
|
|
switch member {
|
|
case "icon":
|
|
var icon string
|
|
err = navigator.StoreProperty(iconProperty, &icon)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
|
continue
|
|
}
|
|
|
|
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
|
continue
|
|
}
|
|
case "narrative":
|
|
var narrative string
|
|
err = navigator.StoreProperty(narrativeProperty, &narrative)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
|
continue
|
|
}
|
|
|
|
err = dev.Navigation.SetNarrative(narrative)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
|
continue
|
|
}
|
|
case "manDist":
|
|
var manDist string
|
|
err = navigator.StoreProperty(manDistProperty, &manDist)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
|
continue
|
|
}
|
|
|
|
err = dev.Navigation.SetManDist(manDist)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
|
continue
|
|
}
|
|
case "progress":
|
|
var progress int32
|
|
err = navigator.StoreProperty(progressProperty, &progress)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error getting property")
|
|
continue
|
|
}
|
|
|
|
err = dev.Navigation.SetProgress(uint8(progress))
|
|
if err != nil {
|
|
log.Error().Err(err).Str("property", member).Msg("Error setting flag")
|
|
continue
|
|
}
|
|
}
|
|
case <-ctx.Done():
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
if exists {
|
|
log.Info().Msg("Sending PureMaps data to InfiniTime")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setAll(navigator dbus.BusObject, dev *infinitime.Device) error {
|
|
var icon string
|
|
err := navigator.StoreProperty(iconProperty, &icon)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = dev.Navigation.SetFlag(infinitime.NavFlag(icon))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var narrative string
|
|
err = navigator.StoreProperty(narrativeProperty, &narrative)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = dev.Navigation.SetNarrative(narrative)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var manDist string
|
|
err = navigator.StoreProperty(manDistProperty, &manDist)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = dev.Navigation.SetManDist(manDist)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var progress int32
|
|
err = navigator.StoreProperty(progressProperty, &progress)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return dev.Navigation.SetProgress(uint8(progress))
|
|
}
|
|
|
|
// pureMapsExists checks to make sure the PureMaps service exists on the bus
|
|
func pureMapsExists(ctx context.Context, conn *dbus.Conn) (bool, error) {
|
|
var names []string
|
|
err := conn.BusObject().CallWithContext(
|
|
ctx, "org.freedesktop.DBus.ListNames", 0,
|
|
).Store(&names)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return strSlcContains(names, "io.github.rinigus.PureMaps"), nil
|
|
}
|