1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
type buffer = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
let ( !@ ) = Ctypes.( !@ )
module Vblank = struct
type t = {
sequence : Unsigned.UInt32.t;
tv_sec : Unsigned.UInt32.t;
tv_usec : int;
crtc_id : Kms.Crtc.id;
user_data : nativeint;
}
let of_c c =
let module T = C.Types.Drm_event_vblank in
assert (Ctypes.CArray.length c >= Ctypes.sizeof T.t);
let t = !@ (Ctypes.from_voidp T.t (Ctypes.to_voidp c.astart)) in
{
sequence = Ctypes.getf t T.sequence;
tv_sec = Ctypes.getf t T.tv_sec;
tv_usec = Ctypes.getf t T.tv_usec;
crtc_id = Ctypes.getf t T.crtc_id;
user_data = Ctypes.getf t T.user_data;
}
let pp f { sequence; tv_sec; tv_usec; crtc_id; user_data } =
Fmt.pf f "{@[sequence = %a;@ tv_sec,tv_usec = %a.%06d;@ crtc_id = %a;@ user_data = %nd@]}"
Unsigned.UInt32.pp sequence
Unsigned.UInt32.pp tv_sec tv_usec
Id.pp crtc_id
user_data
end
module Crtc_sequence = struct
type t = {
sequence : Unsigned.UInt64.t;
time_ns : Unsigned.UInt64.t;
user_data : nativeint;
}
let of_c c =
let module T = C.Types.Drm_event_crtc_sequence in
assert (Ctypes.CArray.length c >= Ctypes.sizeof T.t);
let t = !@ (Ctypes.from_voidp T.t (Ctypes.to_voidp c.astart)) in
{
sequence = Ctypes.getf t T.sequence;
time_ns = Unsigned.UInt64.of_int64 (Ctypes.getf t T.time_ns);
user_data = Ctypes.getf t T.user_data;
}
let pp f { sequence; time_ns; user_data } =
Fmt.pf f "{@[sequence = %a;@ time_ns = %a;@ user_data = %nd@]}"
Unsigned.UInt64.pp sequence
Unsigned.UInt64.pp time_ns
user_data
end
type t =
| Vblank of Vblank.t
| Flip_complete of Vblank.t
| Crtc_sequence of Crtc_sequence.t
| Unknown of Unsigned.UInt32.t * char Ctypes.CArray.t
let pp f = function
| Vblank e -> Fmt.pf f "Vblank %a" Vblank.pp e
| Flip_complete e -> Fmt.pf f "Flip_complete %a" Vblank.pp e
| Crtc_sequence e -> Fmt.pf f "Crtc_sequence %a" Crtc_sequence.pp e
| Unknown (x, _) -> Fmt.pf f "Unknown event (type %a)" Unsigned.UInt32.pp x
let create_buffer () = Bigarray.Array1.create Char C_layout 1024
let parse buffer len =
let rec aux buffer =
if Ctypes.CArray.length buffer = 0 then []
else (
assert (Ctypes.CArray.length buffer >= Ctypes.sizeof C.Types.Drm_event.t);
let hdr = !@ (Ctypes.from_voidp C.Types.Drm_event.t (Ctypes.to_voidp buffer.astart)) in
let event_type = Ctypes.getf hdr C.Types.Drm_event.typ in
let event_len = Ctypes.getf hdr C.Types.Drm_event.length in
let event_data = Ctypes.CArray.sub buffer ~pos:0 ~length:event_len in
let module T = C.Types.Drm_event_type in
let event =
if event_type = T.vblank then Vblank (Vblank.of_c event_data)
else if event_type = T.flip_complete then Flip_complete (Vblank.of_c event_data)
else if event_type = T.crtc_sequence then Crtc_sequence (Crtc_sequence.of_c event_data)
else Unknown (event_type, event_data)
in
let buffer = Ctypes.CArray.sub buffer ~pos:event_len ~length:(Ctypes.CArray.length buffer - event_len) in
event :: aux buffer
)
in
let events =
buffer
|> Ctypes.(array_of_bigarray array1)
|> Ctypes.CArray.sub ~pos:0 ~length:len
|> aux
in
ignore (Sys.opaque_identity buffer);
events