Files
cthulhu/internal/app/braille_routing.go

80 lines
2.7 KiB
Go

package app
import (
"context"
"time"
"unicode/utf8"
"git.stormux.org/storm/cthulhu/internal/atspi"
"git.stormux.org/storm/cthulhu/internal/braille"
)
type brailleRouter interface {
RouteBraille(context.Context, atspi.BrailleRoute) error
}
func (worker *brailleWorker) route(ctx context.Context, event braille.RoutingEvent) {
worker.mu.Lock()
frame := worker.frame
length := utf8.RuneCountInString(frame.Text)
if worker.secure || worker.stopping || frame.ID == 0 || event.ID != frame.ID || event.Offset < 0 ||
(frame.Virtual == nil && event.Offset >= length) || (frame.Virtual != nil && event.Offset > length) {
worker.mu.Unlock()
return
}
if route := frame.Virtual; route != nil {
if worker.ocr == nil || event.Offset < route.Start || event.Offset > route.End {
worker.mu.Unlock()
return
}
routeCtx, cancel := context.WithTimeout(ctx, time.Second)
worker.routeCancel = cancel
worker.mu.Unlock()
defer cancel()
worker.ocr.RouteBraille(routeCtx, route.Generation, route.SourceStart+event.Offset-route.Start)
return
}
if worker.router == nil && frame.Document == nil {
worker.mu.Unlock()
return
}
var target *braille.TextRoute
for _, route := range frame.Routes {
if event.Offset >= route.Start && event.Offset < route.End {
target = &route
break
}
}
if target == nil {
worker.mu.Unlock()
return
}
routeCtx, cancel := context.WithTimeout(ctx, time.Second)
worker.routeCancel = cancel
worker.mu.Unlock()
defer cancel()
if document := frame.Document; document != nil {
if worker.document == nil {
return
}
worker.logger.Debug("routing document braille", "frame_id", frame.ID, "document_epoch", document.Epoch,
"source_bus", target.BusName, "source_path", target.Path, "source_start", target.SourceStart,
"native_offset", target.SourceStart+min(event.Offset-target.Start, target.TextLength))
err := worker.document.RouteDocumentBraille(routeCtx, document.Epoch,
atspi.NewObjectID(document.FocusBus, document.FocusPath), atspi.NewObjectID(document.DocumentBus, document.DocumentPath),
atspi.NewObjectID(target.BusName, target.Path), target.SourceText, target.SourceStart,
target.SourceStart+min(event.Offset-target.Start, target.TextLength))
if err != nil && routeCtx.Err() == nil {
worker.logger.Debug("document braille routing rejected", "error", err)
}
return
}
err := worker.router.RouteBraille(routeCtx, atspi.BrailleRoute{
Focus: atspi.NewObjectID(target.BusName, target.Path), Line: target.SourceText, Start: target.SourceStart,
Offset: target.SourceStart + min(event.Offset-target.Start, target.TextLength),
})
if err != nil && routeCtx.Err() == nil {
worker.logger.Debug("braille routing rejected", "error", err)
}
}