1from .pykms import * 2from enum import Enum 3import os 4import struct 5 6# 7# Common RGB colours 8# 9 10red = RGB(255, 0, 0) 11green = RGB(0, 255, 0) 12blue = RGB(0, 0, 255) 13yellow = RGB(255, 255, 0) 14purple = RGB(255, 0, 255) 15white = RGB(255, 255, 255) 16cyan = RGB(0, 255, 255) 17 18# 19# Rotation enum 20# 21 22class Rotation(int, Enum): 23 ROTATE_0 = 1 << 0 24 ROTATE_90 = 1 << 1 25 ROTATE_180 = 1 << 2 26 ROTATE_270 = 1 << 3 27 ROTATE_MASK = ROTATE_0 | ROTATE_90 | ROTATE_180 | ROTATE_270 28 REFLECT_X = 1 << 4 29 REFLECT_Y = 1 << 5 30 REFLECT_MASK = REFLECT_X | REFLECT_Y 31 32# 33# DrmObject API extensions 34# 35 36def __obj_set_prop(self, prop, value): 37 if self.card.has_atomic: 38 areq = AtomicReq(self.card) 39 areq.add(self, prop, value) 40 if areq.commit_sync() != 0: 41 print("commit failed") 42 else: 43 if self.set_prop_value(prop, value) != 0: 44 print("setting property failed") 45 46def __obj_set_props(self, map): 47 if self.card.has_atomic: 48 areq = AtomicReq(self.card) 49 50 for key, value in map.items(): 51 areq.add(self, key, value) 52 53 if areq.commit_sync() != 0: 54 print("commit failed") 55 else: 56 for propid,propval in map.items(): 57 if self.set_prop_value(propid, propval) != 0: 58 print("setting property failed") 59 60DrmObject.set_prop = __obj_set_prop 61DrmObject.set_props = __obj_set_props 62 63# 64# Card API extensions 65# 66 67def __card_disable_planes(self): 68 areq = AtomicReq(self) 69 70 for p in self.planes: 71 areq.add(p, "FB_ID", 0) 72 areq.add(p, "CRTC_ID", 0) 73 74 if areq.commit_sync() != 0: 75 print("disabling planes failed") 76 77Card.disable_planes = __card_disable_planes 78 79class DrmEventType(Enum): 80 VBLANK = 0x01 81 FLIP_COMPLETE = 0x02 82 83# 84# AtomicReq API extensions 85# 86 87def __atomic_req_add_connector(req, conn, crtc): 88 req.add(conn, "CRTC_ID", crtc.id if crtc else 0) 89 90def __atomic_req_add_crtc(req, crtc, mode_blob): 91 if mode_blob: 92 req.add(crtc, {"ACTIVE": 1, "MODE_ID": mode_blob.id}) 93 else: 94 req.add(crtc, {"ACTIVE": 0, "MODE_ID": 0}) 95 96def __atomic_req_add_plane(req, plane, fb, crtc, 97 src=None, dst=None, zpos=None, 98 params={}): 99 if not src and fb: 100 src = (0, 0, fb.width, fb.height) 101 102 if not dst: 103 dst = src 104 105 m = {"FB_ID": fb.id if fb else 0, 106 "CRTC_ID": crtc.id if crtc else 0} 107 108 if src is not None: 109 src_x = int(round(src[0] * 65536)) 110 src_y = int(round(src[1] * 65536)) 111 src_w = int(round(src[2] * 65536)) 112 src_h = int(round(src[3] * 65536)) 113 114 m["SRC_X"] = src_x 115 m["SRC_Y"] = src_y 116 m["SRC_W"] = src_w 117 m["SRC_H"] = src_h 118 119 if dst is not None: 120 crtc_x = int(round(dst[0])) 121 crtc_y = int(round(dst[1])) 122 crtc_w = int(round(dst[2])) 123 crtc_h = int(round(dst[3])) 124 125 m["CRTC_X"] = crtc_x 126 m["CRTC_Y"] = crtc_y 127 m["CRTC_W"] = crtc_w 128 m["CRTC_H"] = crtc_h 129 130 if zpos is not None: 131 m["zpos"] = zpos 132 133 m.update(params) 134 135 req.add(plane, m) 136 137pykms.AtomicReq.add_connector = __atomic_req_add_connector 138pykms.AtomicReq.add_crtc = __atomic_req_add_crtc 139pykms.AtomicReq.add_plane = __atomic_req_add_plane 140 141# struct drm_event { 142# __u32 type; 143# __u32 length; 144#}; 145# 146 147_drm_ev = struct.Struct("II") 148 149#struct drm_event_vblank { 150# struct drm_event base; 151# __u64 user_data; 152# __u32 tv_sec; 153# __u32 tv_usec; 154# __u32 sequence; 155# __u32 reserved; 156#}; 157 158_drm_ev_vbl = struct.Struct("QIIII") # Note: doesn't contain drm_event 159 160class DrmEvent: 161 def __init__(self, type, seq, time, data): 162 self.type = type 163 self.seq = seq 164 self.time = time 165 self.data = data 166 167# Return DrmEvents. Note: blocks if there's nothing to read 168def __card_read_events(self): 169 buf = os.read(self.fd, _drm_ev_vbl.size * 20) 170 171 if len(buf) == 0: 172 return 173 174 if len(buf) < _drm_ev.size: 175 raise RuntimeError("Partial DRM event") 176 177 idx = 0 178 179 while idx < len(buf): 180 ev_tuple = _drm_ev.unpack_from(buf, idx) 181 182 type = DrmEventType(ev_tuple[0]) 183 184 if type != DrmEventType.VBLANK and type != DrmEventType.FLIP_COMPLETE: 185 raise RuntimeError("Illegal DRM event type") 186 187 vbl_tuple = _drm_ev_vbl.unpack_from(buf, idx + _drm_ev.size) 188 189 seq = vbl_tuple[3] 190 time = vbl_tuple[1] + vbl_tuple[2] / 1000000.0; 191 udata = vbl_tuple[0] 192 193 yield DrmEvent(type, seq, time, udata) 194 195 idx += ev_tuple[1] 196 197Card.read_events = __card_read_events 198