80 lines
2.7 KiB
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)
|
|
}
|
|
}
|