1package drm
2
3import (
4 "unsafe"
5
6 "golang.org/x/sys/unix"
7)
8
9// KMS object properties, read by name; atomic commits set them.
10
11const (
12 ioctlObjGetProps = 0xC02064B9 // DRM_IOWR('d', 0xB9, struct drm_mode_obj_get_properties)
13 ioctlGetProp = 0xC04064AA // DRM_IOWR('d', 0xAA, struct drm_mode_get_property)
14
15 objCrtc = 0xcccccccc
16 objConnector = 0xc0c0c0c0
17)
18
19type objGetProps struct {
20 props, values uint64
21 count, objID uint32
22 objType, _ uint32
23}
24
25type getProp struct {
26 values, enumBlobs uint64
27 propID, flags uint32
28 name [32]byte
29 countValues, countEn uint32
30}
31
32// objProps returns an object's property IDs and values by name.
33func objProps(fd int, obj, typ uint32) (map[string][2]uint64, error) {
34 q := objGetProps{objID: obj, objType: typ}
35 if err := ioctl(fd, ioctlObjGetProps, unsafe.Pointer(&q)); err != nil {
36 return nil, err
37 }
38 out := map[string][2]uint64{}
39 if q.count == 0 {
40 return out, nil
41 }
42 ids := make([]uint32, q.count)
43 vals := make([]uint64, q.count)
44 q.props, q.values = uint64(uintptr(unsafe.Pointer(&ids[0]))), uint64(uintptr(unsafe.Pointer(&vals[0])))
45 if err := ioctl(fd, ioctlObjGetProps, unsafe.Pointer(&q)); err != nil {
46 return nil, err
47 }
48 for i := range min(int(q.count), len(ids)) {
49 p := getProp{propID: ids[i]}
50 if ioctl(fd, ioctlGetProp, unsafe.Pointer(&p)) != nil {
51 continue
52 }
53 out[unix.ByteSliceToString(p.name[:])] = [2]uint64{uint64(ids[i]), vals[i]}
54 }
55 return out, nil
56}
57
58// vrrProperty returns the CRTC's VRR_ENABLED property when the connector
59// is VRR capable, else 0.
60func vrrProperty(k kms, conn, crtc uint32) uint32 {
61 cp, err := k.objProps(conn, objConnector)
62 if err != nil || cp["vrr_capable"][1] != 1 {
63 return 0
64 }
65 rp, err := k.objProps(crtc, objCrtc)
66 if err != nil {
67 return 0
68 }
69 return uint32(rp["VRR_ENABLED"][0])
70}