summaryrefslogtreecommitdiff
path: root/py/pykms/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'py/pykms/__init__.py')
-rw-r--r--py/pykms/__init__.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/py/pykms/__init__.py b/py/pykms/__init__.py
index d4cdc43..41c1219 100644
--- a/py/pykms/__init__.py
+++ b/py/pykms/__init__.py
@@ -1,4 +1,7 @@
from .pykms import *
+from enum import Enum
+import os
+import struct
#
# Common RGB colours
@@ -58,3 +61,65 @@ def __card_disable_planes(self):
print("disabling planes failed")
Card.disable_planes = __card_disable_planes
+
+class DrmEventType(Enum):
+ VBLANK = 0x01
+ FLIP_COMPLETE = 0x02
+
+# struct drm_event {
+# __u32 type;
+# __u32 length;
+#};
+#
+
+_drm_ev = struct.Struct("II")
+
+#struct drm_event_vblank {
+# struct drm_event base;
+# __u64 user_data;
+# __u32 tv_sec;
+# __u32 tv_usec;
+# __u32 sequence;
+# __u32 reserved;
+#};
+
+_drm_ev_vbl = struct.Struct("QIIII") # Note: doesn't contain drm_event
+
+class DrmEvent:
+ def __init__(self, type, seq, time, data):
+ self.type = type
+ self.seq = seq
+ self.time = time
+ self.data = data
+
+# Return DrmEvents. Note: blocks if there's nothing to read
+def __card_read_events(self):
+ buf = os.read(self.fd, _drm_ev_vbl.size * 20)
+
+ if len(buf) == 0:
+ return
+
+ if len(buf) < _drm_ev.size:
+ raise RuntimeError("Partial DRM event")
+
+ idx = 0
+
+ while idx < len(buf):
+ ev_tuple = _drm_ev.unpack_from(buf, idx)
+
+ type = DrmEventType(ev_tuple[0])
+
+ if type != DrmEventType.VBLANK and type != DrmEventType.FLIP_COMPLETE:
+ raise RuntimeError("Illegal DRM event type")
+
+ vbl_tuple = _drm_ev_vbl.unpack_from(buf, idx + _drm_ev.size)
+
+ seq = vbl_tuple[3]
+ time = vbl_tuple[1] + vbl_tuple[2] / 1000000.0;
+ udata = pykms.__ob_unpack_helper(vbl_tuple[0])
+
+ yield DrmEvent(type, seq, time, udata)
+
+ idx += ev_tuple[1]
+
+Card.read_events = __card_read_events