package drmdb import ( "sort" "git.sr.ht/~emersion/drmdb/database" "git.sr.ht/~emersion/drmdb/drmtree" "git.sr.ht/~emersion/go-drm" "github.com/mcuadros/go-version" ) func walkProps(props drmtree.PropertyMap, obj drm.AnyID, f func(drm.AnyID, string, *drmtree.Property) error) error { for name, prop := range props { if err := f(obj, name, &prop); err != nil { return err } } return nil } func walkNodeProps(n *drmtree.Node, f func(drm.AnyID, string, *drmtree.Property) error) error { for _, conn := range n.Connectors { if err := walkProps(conn.Properties, conn.ID, f); err != nil { return err } } for _, crtc := range n.CRTCs { if err := walkProps(crtc.Properties, crtc.ID, f); err != nil { return err } } for _, plane := range n.Planes { if err := walkProps(plane.Properties, plane.ID, f); err != nil { return err } } return nil } func driverLess(a *drmtree.Driver, b *drmtree.Driver) bool { if a.Version.Less(&b.Version) { return true } // Linux is the upstream if b.Kernel.SysName == "Linux" && a.Kernel.SysName != "Linux" { return true } return version.Compare(a.Kernel.Release, b.Kernel.Release, "<") } type walkLatestField int const ( walkLatestDriver walkLatestField = iota walkLatestDevice ) func walkLatest(db *database.DB, f walkLatestField, fn func(k string, n *drmtree.Node) error) error { type node struct { k string n *drmtree.Node } latest := make(map[string]node) err := db.Walk(func(k string, n *drmtree.Node) error { var latestKey string switch f { case walkLatestDriver: latestKey = n.Driver.Name case walkLatestDevice: latestKey = n.Device.BusID() } if latestKey == "" { return nil } other, ok := latest[latestKey] if ok && driverLess(n.Driver, other.n.Driver) { return nil } latest[latestKey] = node{k, n} return nil }) if err != nil { return err } keys := make([]string, 0, len(latest)) for k := range latest { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { n := latest[k] if err := fn(n.k, n.n); err != nil { return err } } return nil }